1 | //===--- APINotesReader.h - API Notes Reader --------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the \c APINotesReader class that reads source API notes |
10 | // data providing additional information about source code as a separate input, |
11 | // such as the non-nil/nilable annotations for method parameters. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CLANG_APINOTES_READER_H |
16 | #define LLVM_CLANG_APINOTES_READER_H |
17 | |
18 | #include "clang/APINotes/Types.h" |
19 | #include "llvm/Support/MemoryBuffer.h" |
20 | #include "llvm/Support/VersionTuple.h" |
21 | #include <memory> |
22 | |
23 | namespace clang { |
24 | namespace api_notes { |
25 | |
26 | /// A class that reads API notes data from a binary file that was written by |
27 | /// the \c APINotesWriter. |
28 | class APINotesReader { |
29 | class Implementation; |
30 | std::unique_ptr<Implementation> Implementation; |
31 | |
32 | APINotesReader(llvm::MemoryBuffer *InputBuffer, |
33 | llvm::VersionTuple SwiftVersion, bool &Failed); |
34 | |
35 | public: |
36 | /// Create a new API notes reader from the given member buffer, which |
37 | /// contains the contents of a binary API notes file. |
38 | /// |
39 | /// \returns the new API notes reader, or null if an error occurred. |
40 | static std::unique_ptr<APINotesReader> |
41 | Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer, |
42 | llvm::VersionTuple SwiftVersion); |
43 | |
44 | ~APINotesReader(); |
45 | |
46 | APINotesReader(const APINotesReader &) = delete; |
47 | APINotesReader &operator=(const APINotesReader &) = delete; |
48 | |
49 | /// Captures the completed versioned information for a particular part of |
50 | /// API notes, including both unversioned API notes and each versioned API |
51 | /// note for that particular entity. |
52 | template <typename T> class VersionedInfo { |
53 | /// The complete set of results. |
54 | llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results; |
55 | |
56 | /// The index of the result that is the "selected" set based on the desired |
57 | /// Swift version, or null if nothing matched. |
58 | std::optional<unsigned> Selected; |
59 | |
60 | public: |
61 | /// Form an empty set of versioned information. |
62 | VersionedInfo(std::nullopt_t) : Selected(std::nullopt) {} |
63 | |
64 | /// Form a versioned info set given the desired version and a set of |
65 | /// results. |
66 | VersionedInfo( |
67 | llvm::VersionTuple Version, |
68 | llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results); |
69 | |
70 | /// Retrieve the selected index in the result set. |
71 | std::optional<unsigned> getSelected() const { return Selected; } |
72 | |
73 | /// Return the number of versioned results we know about. |
74 | unsigned size() const { return Results.size(); } |
75 | |
76 | /// Access all versioned results. |
77 | const std::pair<llvm::VersionTuple, T> *begin() const { |
78 | assert(!Results.empty()); |
79 | return Results.begin(); |
80 | } |
81 | const std::pair<llvm::VersionTuple, T> *end() const { |
82 | return Results.end(); |
83 | } |
84 | |
85 | /// Access a specific versioned result. |
86 | const std::pair<llvm::VersionTuple, T> &operator[](unsigned index) const { |
87 | assert(index < Results.size()); |
88 | return Results[index]; |
89 | } |
90 | }; |
91 | |
92 | /// Look for the context ID of the given Objective-C class. |
93 | /// |
94 | /// \param Name The name of the class we're looking for. |
95 | /// |
96 | /// \returns The ID, if known. |
97 | std::optional<ContextID> lookupObjCClassID(llvm::StringRef Name); |
98 | |
99 | /// Look for information regarding the given Objective-C class. |
100 | /// |
101 | /// \param Name The name of the class we're looking for. |
102 | /// |
103 | /// \returns The information about the class, if known. |
104 | VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(llvm::StringRef Name); |
105 | |
106 | /// Look for the context ID of the given Objective-C protocol. |
107 | /// |
108 | /// \param Name The name of the protocol we're looking for. |
109 | /// |
110 | /// \returns The ID of the protocol, if known. |
111 | std::optional<ContextID> lookupObjCProtocolID(llvm::StringRef Name); |
112 | |
113 | /// Look for information regarding the given Objective-C protocol. |
114 | /// |
115 | /// \param Name The name of the protocol we're looking for. |
116 | /// |
117 | /// \returns The information about the protocol, if known. |
118 | VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name); |
119 | |
120 | /// Look for information regarding the given Objective-C property in |
121 | /// the given context. |
122 | /// |
123 | /// \param CtxID The ID that references the context we are looking for. |
124 | /// \param Name The name of the property we're looking for. |
125 | /// \param IsInstance Whether we are looking for an instance property (vs. |
126 | /// a class property). |
127 | /// |
128 | /// \returns Information about the property, if known. |
129 | VersionedInfo<ObjCPropertyInfo> |
130 | lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance); |
131 | |
132 | /// Look for information regarding the given Objective-C method in |
133 | /// the given context. |
134 | /// |
135 | /// \param CtxID The ID that references the context we are looking for. |
136 | /// \param Selector The selector naming the method we're looking for. |
137 | /// \param IsInstanceMethod Whether we are looking for an instance method. |
138 | /// |
139 | /// \returns Information about the method, if known. |
140 | VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID CtxID, |
141 | ObjCSelectorRef Selector, |
142 | bool IsInstanceMethod); |
143 | |
144 | /// Look for information regarding the given global variable. |
145 | /// |
146 | /// \param Name The name of the global variable. |
147 | /// |
148 | /// \returns information about the global variable, if known. |
149 | VersionedInfo<GlobalVariableInfo> |
150 | lookupGlobalVariable(llvm::StringRef Name, |
151 | std::optional<Context> Ctx = std::nullopt); |
152 | |
153 | /// Look for information regarding the given global function. |
154 | /// |
155 | /// \param Name The name of the global function. |
156 | /// |
157 | /// \returns information about the global function, if known. |
158 | VersionedInfo<GlobalFunctionInfo> |
159 | lookupGlobalFunction(llvm::StringRef Name, |
160 | std::optional<Context> Ctx = std::nullopt); |
161 | |
162 | /// Look for information regarding the given enumerator. |
163 | /// |
164 | /// \param Name The name of the enumerator. |
165 | /// |
166 | /// \returns information about the enumerator, if known. |
167 | VersionedInfo<EnumConstantInfo> lookupEnumConstant(llvm::StringRef Name); |
168 | |
169 | /// Look for information regarding the given tag |
170 | /// (struct/union/enum/C++ class). |
171 | /// |
172 | /// \param Name The name of the tag. |
173 | /// |
174 | /// \returns information about the tag, if known. |
175 | VersionedInfo<TagInfo> lookupTag(llvm::StringRef Name, |
176 | std::optional<Context> Ctx = std::nullopt); |
177 | |
178 | /// Look for information regarding the given typedef. |
179 | /// |
180 | /// \param Name The name of the typedef. |
181 | /// |
182 | /// \returns information about the typedef, if known. |
183 | VersionedInfo<TypedefInfo> |
184 | lookupTypedef(llvm::StringRef Name, |
185 | std::optional<Context> Ctx = std::nullopt); |
186 | |
187 | /// Look for the context ID of the given C++ namespace. |
188 | /// |
189 | /// \param Name The name of the class we're looking for. |
190 | /// |
191 | /// \returns The ID, if known. |
192 | std::optional<ContextID> |
193 | lookupNamespaceID(llvm::StringRef Name, |
194 | std::optional<ContextID> ParentNamespaceID = std::nullopt); |
195 | }; |
196 | |
197 | } // end namespace api_notes |
198 | } // end namespace clang |
199 | |
200 | #endif // LLVM_CLANG_APINOTES_READER_H |
201 | |