1 //===- ExtractAPI/API.cpp ---------------------------------------*- 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 /// \file
10 /// This file implements the APIRecord and derived record structs,
11 /// and the APISet class.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/ExtractAPI/API.h"
16 #include "clang/AST/CommentCommandTraits.h"
17 #include "clang/AST/CommentLexer.h"
18 #include "clang/AST/RawCommentList.h"
19 #include "clang/Index/USRGeneration.h"
20 #include "llvm/ADT/StringRef.h"
21 #include <memory>
22
23 using namespace clang::extractapi;
24 using namespace llvm;
25
26 namespace {
27
28 template <typename RecordTy, typename... CtorArgsTy>
addTopLevelRecord(DenseMap<StringRef,APIRecord * > & USRLookupTable,APISet::RecordMap<RecordTy> & RecordMap,StringRef USR,CtorArgsTy &&...CtorArgs)29 RecordTy *addTopLevelRecord(DenseMap<StringRef, APIRecord *> &USRLookupTable,
30 APISet::RecordMap<RecordTy> &RecordMap,
31 StringRef USR, CtorArgsTy &&...CtorArgs) {
32 auto Result = RecordMap.insert({USR, nullptr});
33
34 // Create the record if it does not already exist
35 if (Result.second)
36 Result.first->second =
37 std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
38
39 auto *Record = Result.first->second.get();
40 USRLookupTable.insert({USR, Record});
41 return Record;
42 }
43
44 } // namespace
45
46 NamespaceRecord *
addNamespace(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)47 APISet::addNamespace(APIRecord *Parent, StringRef Name, StringRef USR,
48 PresumedLoc Loc, AvailabilityInfo Availability,
49 LinkageInfo Linkage, const DocComment &Comment,
50 DeclarationFragments Declaration,
51 DeclarationFragments SubHeading, bool IsFromSystemHeader) {
52 auto *Record = addTopLevelRecord(
53 USRBasedLookupTable, Namespaces, USR, Name, Loc, std::move(Availability),
54 Linkage, Comment, Declaration, SubHeading, IsFromSystemHeader);
55
56 if (Parent)
57 Record->ParentInformation = APIRecord::HierarchyInformation(
58 Parent->USR, Parent->Name, Parent->getKind(), Parent);
59 return Record;
60 }
61
62 GlobalVariableRecord *
addGlobalVar(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Fragments,DeclarationFragments SubHeading,bool IsFromSystemHeader)63 APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
64 AvailabilityInfo Availability, LinkageInfo Linkage,
65 const DocComment &Comment, DeclarationFragments Fragments,
66 DeclarationFragments SubHeading, bool IsFromSystemHeader) {
67 return addTopLevelRecord(USRBasedLookupTable, GlobalVariables, USR, Name, Loc,
68 std::move(Availability), Linkage, Comment, Fragments,
69 SubHeading, IsFromSystemHeader);
70 }
71
addGlobalVariableTemplate(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,Template Template,bool IsFromSystemHeader)72 GlobalVariableTemplateRecord *APISet::addGlobalVariableTemplate(
73 StringRef Name, StringRef USR, PresumedLoc Loc,
74 AvailabilityInfo Availability, LinkageInfo Linkage,
75 const DocComment &Comment, DeclarationFragments Declaration,
76 DeclarationFragments SubHeading, Template Template,
77 bool IsFromSystemHeader) {
78 return addTopLevelRecord(USRBasedLookupTable, GlobalVariableTemplates, USR,
79 Name, Loc, std::move(Availability), Linkage, Comment,
80 Declaration, SubHeading, Template,
81 IsFromSystemHeader);
82 }
83
addGlobalFunction(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Fragments,DeclarationFragments SubHeading,FunctionSignature Signature,bool IsFromSystemHeader)84 GlobalFunctionRecord *APISet::addGlobalFunction(
85 StringRef Name, StringRef USR, PresumedLoc Loc,
86 AvailabilityInfo Availability, LinkageInfo Linkage,
87 const DocComment &Comment, DeclarationFragments Fragments,
88 DeclarationFragments SubHeading, FunctionSignature Signature,
89 bool IsFromSystemHeader) {
90 return addTopLevelRecord(USRBasedLookupTable, GlobalFunctions, USR, Name, Loc,
91 std::move(Availability), Linkage, Comment, Fragments,
92 SubHeading, Signature, IsFromSystemHeader);
93 }
94
addGlobalFunctionTemplate(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,Template Template,bool IsFromSystemHeader)95 GlobalFunctionTemplateRecord *APISet::addGlobalFunctionTemplate(
96 StringRef Name, StringRef USR, PresumedLoc Loc,
97 AvailabilityInfo Availability, LinkageInfo Linkage,
98 const DocComment &Comment, DeclarationFragments Declaration,
99 DeclarationFragments SubHeading, FunctionSignature Signature,
100 Template Template, bool IsFromSystemHeader) {
101 return addTopLevelRecord(USRBasedLookupTable, GlobalFunctionTemplates, USR,
102 Name, Loc, std::move(Availability), Linkage, Comment,
103 Declaration, SubHeading, Signature, Template,
104 IsFromSystemHeader);
105 }
106
107 GlobalFunctionTemplateSpecializationRecord *
addGlobalFunctionTemplateSpecialization(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,bool IsFromSystemHeader)108 APISet::addGlobalFunctionTemplateSpecialization(
109 StringRef Name, StringRef USR, PresumedLoc Loc,
110 AvailabilityInfo Availability, LinkageInfo Linkage,
111 const DocComment &Comment, DeclarationFragments Declaration,
112 DeclarationFragments SubHeading, FunctionSignature Signature,
113 bool IsFromSystemHeader) {
114 return addTopLevelRecord(
115 USRBasedLookupTable, GlobalFunctionTemplateSpecializations, USR, Name,
116 Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading,
117 Signature, IsFromSystemHeader);
118 }
119
addEnumConstant(EnumRecord * Enum,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)120 EnumConstantRecord *APISet::addEnumConstant(EnumRecord *Enum, StringRef Name,
121 StringRef USR, PresumedLoc Loc,
122 AvailabilityInfo Availability,
123 const DocComment &Comment,
124 DeclarationFragments Declaration,
125 DeclarationFragments SubHeading,
126 bool IsFromSystemHeader) {
127 auto Record = std::make_unique<EnumConstantRecord>(
128 USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
129 IsFromSystemHeader);
130 Record->ParentInformation = APIRecord::HierarchyInformation(
131 Enum->USR, Enum->Name, Enum->getKind(), Enum);
132 USRBasedLookupTable.insert({USR, Record.get()});
133 return Enum->Constants.emplace_back(std::move(Record)).get();
134 }
135
addEnum(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)136 EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
137 AvailabilityInfo Availability,
138 const DocComment &Comment,
139 DeclarationFragments Declaration,
140 DeclarationFragments SubHeading,
141 bool IsFromSystemHeader) {
142 return addTopLevelRecord(USRBasedLookupTable, Enums, USR, Name, Loc,
143 std::move(Availability), Comment, Declaration,
144 SubHeading, IsFromSystemHeader);
145 }
146
addRecordField(RecordRecord * Record,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,APIRecord::RecordKind Kind,bool IsFromSystemHeader)147 RecordFieldRecord *APISet::addRecordField(
148 RecordRecord *Record, StringRef Name, StringRef USR, PresumedLoc Loc,
149 AvailabilityInfo Availability, const DocComment &Comment,
150 DeclarationFragments Declaration, DeclarationFragments SubHeading,
151 APIRecord::RecordKind Kind, bool IsFromSystemHeader) {
152 auto RecordField = std::make_unique<RecordFieldRecord>(
153 USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
154 Kind, IsFromSystemHeader);
155 RecordField->ParentInformation = APIRecord::HierarchyInformation(
156 Record->USR, Record->Name, Record->getKind(), Record);
157 USRBasedLookupTable.insert({USR, RecordField.get()});
158 return Record->Fields.emplace_back(std::move(RecordField)).get();
159 }
160
addRecord(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,APIRecord::RecordKind Kind,bool IsFromSystemHeader)161 RecordRecord *APISet::addRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
162 AvailabilityInfo Availability,
163 const DocComment &Comment,
164 DeclarationFragments Declaration,
165 DeclarationFragments SubHeading,
166 APIRecord::RecordKind Kind,
167 bool IsFromSystemHeader) {
168 return addTopLevelRecord(USRBasedLookupTable, Records, USR, Name, Loc,
169 std::move(Availability), Comment, Declaration,
170 SubHeading, Kind, IsFromSystemHeader);
171 }
172
173 StaticFieldRecord *
addStaticField(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,SymbolReference Context,AccessControl Access,bool IsFromSystemHeader)174 APISet::addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
175 AvailabilityInfo Availability, LinkageInfo Linkage,
176 const DocComment &Comment,
177 DeclarationFragments Declaration,
178 DeclarationFragments SubHeading, SymbolReference Context,
179 AccessControl Access, bool IsFromSystemHeader) {
180 return addTopLevelRecord(USRBasedLookupTable, StaticFields, USR, Name, Loc,
181 std::move(Availability), Linkage, Comment,
182 Declaration, SubHeading, Context, Access,
183 IsFromSystemHeader);
184 }
185
186 CXXFieldRecord *
addCXXField(APIRecord * CXXClass,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,AccessControl Access,bool IsFromSystemHeader)187 APISet::addCXXField(APIRecord *CXXClass, StringRef Name, StringRef USR,
188 PresumedLoc Loc, AvailabilityInfo Availability,
189 const DocComment &Comment, DeclarationFragments Declaration,
190 DeclarationFragments SubHeading, AccessControl Access,
191 bool IsFromSystemHeader) {
192 auto *Record = addTopLevelRecord(
193 USRBasedLookupTable, CXXFields, USR, Name, Loc, std::move(Availability),
194 Comment, Declaration, SubHeading, Access, IsFromSystemHeader);
195 Record->ParentInformation = APIRecord::HierarchyInformation(
196 CXXClass->USR, CXXClass->Name, CXXClass->getKind(), CXXClass);
197 return Record;
198 }
199
addCXXFieldTemplate(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,AccessControl Access,Template Template,bool IsFromSystemHeader)200 CXXFieldTemplateRecord *APISet::addCXXFieldTemplate(
201 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
202 AvailabilityInfo Availability, const DocComment &Comment,
203 DeclarationFragments Declaration, DeclarationFragments SubHeading,
204 AccessControl Access, Template Template, bool IsFromSystemHeader) {
205 auto *Record =
206 addTopLevelRecord(USRBasedLookupTable, CXXFieldTemplates, USR, Name, Loc,
207 std::move(Availability), Comment, Declaration,
208 SubHeading, Access, Template, IsFromSystemHeader);
209 Record->ParentInformation = APIRecord::HierarchyInformation(
210 Parent->USR, Parent->Name, Parent->getKind(), Parent);
211
212 return Record;
213 }
214
215 CXXClassRecord *
addCXXClass(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,APIRecord::RecordKind Kind,AccessControl Access,bool IsFromSystemHeader)216 APISet::addCXXClass(APIRecord *Parent, StringRef Name, StringRef USR,
217 PresumedLoc Loc, AvailabilityInfo Availability,
218 const DocComment &Comment, DeclarationFragments Declaration,
219 DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
220 AccessControl Access, bool IsFromSystemHeader) {
221 auto *Record = addTopLevelRecord(
222 USRBasedLookupTable, CXXClasses, USR, Name, Loc, std::move(Availability),
223 Comment, Declaration, SubHeading, Kind, Access, IsFromSystemHeader);
224 if (Parent)
225 Record->ParentInformation = APIRecord::HierarchyInformation(
226 Parent->USR, Parent->Name, Parent->getKind(), Parent);
227 return Record;
228 }
229
addClassTemplate(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,Template Template,AccessControl Access,bool IsFromSystemHeader)230 ClassTemplateRecord *APISet::addClassTemplate(
231 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
232 AvailabilityInfo Availability, const DocComment &Comment,
233 DeclarationFragments Declaration, DeclarationFragments SubHeading,
234 Template Template, AccessControl Access, bool IsFromSystemHeader) {
235 auto *Record =
236 addTopLevelRecord(USRBasedLookupTable, ClassTemplates, USR, Name, Loc,
237 std::move(Availability), Comment, Declaration,
238 SubHeading, Template, Access, IsFromSystemHeader);
239 if (Parent)
240 Record->ParentInformation = APIRecord::HierarchyInformation(
241 Parent->USR, Parent->Name, Parent->getKind(), Parent);
242 return Record;
243 }
244
addClassTemplateSpecialization(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,AccessControl Access,bool IsFromSystemHeader)245 ClassTemplateSpecializationRecord *APISet::addClassTemplateSpecialization(
246 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
247 AvailabilityInfo Availability, const DocComment &Comment,
248 DeclarationFragments Declaration, DeclarationFragments SubHeading,
249 AccessControl Access, bool IsFromSystemHeader) {
250 auto *Record =
251 addTopLevelRecord(USRBasedLookupTable, ClassTemplateSpecializations, USR,
252 Name, Loc, std::move(Availability), Comment,
253 Declaration, SubHeading, Access, IsFromSystemHeader);
254 if (Parent)
255 Record->ParentInformation = APIRecord::HierarchyInformation(
256 Parent->USR, Parent->Name, Parent->getKind(), Parent);
257 return Record;
258 }
259
260 ClassTemplatePartialSpecializationRecord *
addClassTemplatePartialSpecialization(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,Template Template,AccessControl Access,bool IsFromSystemHeader)261 APISet::addClassTemplatePartialSpecialization(
262 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
263 AvailabilityInfo Availability, const DocComment &Comment,
264 DeclarationFragments Declaration, DeclarationFragments SubHeading,
265 Template Template, AccessControl Access, bool IsFromSystemHeader) {
266 auto *Record = addTopLevelRecord(
267 USRBasedLookupTable, ClassTemplatePartialSpecializations, USR, Name, Loc,
268 std::move(Availability), Comment, Declaration, SubHeading, Template,
269 Access, IsFromSystemHeader);
270 if (Parent)
271 Record->ParentInformation = APIRecord::HierarchyInformation(
272 Parent->USR, Parent->Name, Parent->getKind(), Parent);
273 return Record;
274 }
275
276 GlobalVariableTemplateSpecializationRecord *
addGlobalVariableTemplateSpecialization(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)277 APISet::addGlobalVariableTemplateSpecialization(
278 StringRef Name, StringRef USR, PresumedLoc Loc,
279 AvailabilityInfo Availability, LinkageInfo Linkage,
280 const DocComment &Comment, DeclarationFragments Declaration,
281 DeclarationFragments SubHeading, bool IsFromSystemHeader) {
282 return addTopLevelRecord(USRBasedLookupTable,
283 GlobalVariableTemplateSpecializations, USR, Name,
284 Loc, std::move(Availability), Linkage, Comment,
285 Declaration, SubHeading, IsFromSystemHeader);
286 }
287
288 GlobalVariableTemplatePartialSpecializationRecord *
addGlobalVariableTemplatePartialSpecialization(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,Template Template,bool IsFromSystemHeader)289 APISet::addGlobalVariableTemplatePartialSpecialization(
290 StringRef Name, StringRef USR, PresumedLoc Loc,
291 AvailabilityInfo Availability, LinkageInfo Linkage,
292 const DocComment &Comment, DeclarationFragments Declaration,
293 DeclarationFragments SubHeading, Template Template,
294 bool IsFromSystemHeader) {
295 return addTopLevelRecord(
296 USRBasedLookupTable, GlobalVariableTemplatePartialSpecializations, USR,
297 Name, Loc, std::move(Availability), Linkage, Comment, Declaration,
298 SubHeading, Template, IsFromSystemHeader);
299 }
300
addConcept(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,Template Template,bool IsFromSystemHeader)301 ConceptRecord *APISet::addConcept(StringRef Name, StringRef USR,
302 PresumedLoc Loc,
303 AvailabilityInfo Availability,
304 const DocComment &Comment,
305 DeclarationFragments Declaration,
306 DeclarationFragments SubHeading,
307 Template Template, bool IsFromSystemHeader) {
308 return addTopLevelRecord(USRBasedLookupTable, Concepts, USR, Name, Loc,
309 std::move(Availability), Comment, Declaration,
310 SubHeading, Template, IsFromSystemHeader);
311 }
312
addCXXInstanceMethod(APIRecord * CXXClassRecord,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,AccessControl Access,bool IsFromSystemHeader)313 CXXMethodRecord *APISet::addCXXInstanceMethod(
314 APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc,
315 AvailabilityInfo Availability, const DocComment &Comment,
316 DeclarationFragments Declaration, DeclarationFragments SubHeading,
317 FunctionSignature Signature, AccessControl Access,
318 bool IsFromSystemHeader) {
319 CXXMethodRecord *Record =
320 addTopLevelRecord(USRBasedLookupTable, CXXInstanceMethods, USR, Name, Loc,
321 std::move(Availability), Comment, Declaration,
322 SubHeading, Signature, Access, IsFromSystemHeader);
323
324 Record->ParentInformation = APIRecord::HierarchyInformation(
325 CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(),
326 CXXClassRecord);
327 return Record;
328 }
329
addCXXStaticMethod(APIRecord * CXXClassRecord,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,AccessControl Access,bool IsFromSystemHeader)330 CXXMethodRecord *APISet::addCXXStaticMethod(
331 APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc,
332 AvailabilityInfo Availability, const DocComment &Comment,
333 DeclarationFragments Declaration, DeclarationFragments SubHeading,
334 FunctionSignature Signature, AccessControl Access,
335 bool IsFromSystemHeader) {
336 CXXMethodRecord *Record =
337 addTopLevelRecord(USRBasedLookupTable, CXXStaticMethods, USR, Name, Loc,
338 std::move(Availability), Comment, Declaration,
339 SubHeading, Signature, Access, IsFromSystemHeader);
340
341 Record->ParentInformation = APIRecord::HierarchyInformation(
342 CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(),
343 CXXClassRecord);
344 return Record;
345 }
346
addCXXMethodTemplate(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,AccessControl Access,Template Template,bool IsFromSystemHeader)347 CXXMethodTemplateRecord *APISet::addCXXMethodTemplate(
348 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
349 AvailabilityInfo Availability, const DocComment &Comment,
350 DeclarationFragments Declaration, DeclarationFragments SubHeading,
351 FunctionSignature Signature, AccessControl Access, Template Template,
352 bool IsFromSystemHeader) {
353 auto *Record = addTopLevelRecord(USRBasedLookupTable, CXXMethodTemplates, USR,
354 Name, Loc, std::move(Availability), Comment,
355 Declaration, SubHeading, Signature, Access,
356 Template, IsFromSystemHeader);
357 Record->ParentInformation = APIRecord::HierarchyInformation(
358 Parent->USR, Parent->Name, Parent->getKind(), Parent);
359
360 return Record;
361 }
362
addCXXMethodTemplateSpec(APIRecord * Parent,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,AccessControl Access,bool IsFromSystemHeader)363 CXXMethodTemplateSpecializationRecord *APISet::addCXXMethodTemplateSpec(
364 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
365 AvailabilityInfo Availability, const DocComment &Comment,
366 DeclarationFragments Declaration, DeclarationFragments SubHeading,
367 FunctionSignature Signature, AccessControl Access,
368 bool IsFromSystemHeader) {
369
370 auto *Record = addTopLevelRecord(
371 USRBasedLookupTable, CXXMethodTemplateSpecializations, USR, Name, Loc,
372 std::move(Availability), Comment, Declaration, SubHeading, Signature,
373 Access, IsFromSystemHeader);
374 Record->ParentInformation = APIRecord::HierarchyInformation(
375 Parent->USR, Parent->Name, Parent->getKind(), Parent);
376
377 return Record;
378 }
379
addObjCCategory(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,SymbolReference Interface,bool IsFromSystemHeader,bool IsFromExternalModule)380 ObjCCategoryRecord *APISet::addObjCCategory(
381 StringRef Name, StringRef USR, PresumedLoc Loc,
382 AvailabilityInfo Availability, const DocComment &Comment,
383 DeclarationFragments Declaration, DeclarationFragments SubHeading,
384 SymbolReference Interface, bool IsFromSystemHeader,
385 bool IsFromExternalModule) {
386 // Create the category record.
387 auto *Record =
388 addTopLevelRecord(USRBasedLookupTable, ObjCCategories, USR, Name, Loc,
389 std::move(Availability), Comment, Declaration,
390 SubHeading, Interface, IsFromSystemHeader);
391
392 Record->IsFromExternalModule = IsFromExternalModule;
393
394 auto It = ObjCInterfaces.find(Interface.USR);
395 if (It != ObjCInterfaces.end())
396 It->second->Categories.push_back(Record);
397
398 return Record;
399 }
400
401 ObjCInterfaceRecord *
addObjCInterface(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,LinkageInfo Linkage,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,SymbolReference SuperClass,bool IsFromSystemHeader)402 APISet::addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
403 AvailabilityInfo Availability, LinkageInfo Linkage,
404 const DocComment &Comment,
405 DeclarationFragments Declaration,
406 DeclarationFragments SubHeading,
407 SymbolReference SuperClass, bool IsFromSystemHeader) {
408 return addTopLevelRecord(USRBasedLookupTable, ObjCInterfaces, USR, Name, Loc,
409 std::move(Availability), Linkage, Comment,
410 Declaration, SubHeading, SuperClass,
411 IsFromSystemHeader);
412 }
413
addObjCMethod(ObjCContainerRecord * Container,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,FunctionSignature Signature,bool IsInstanceMethod,bool IsFromSystemHeader)414 ObjCMethodRecord *APISet::addObjCMethod(
415 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
416 PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
417 DeclarationFragments Declaration, DeclarationFragments SubHeading,
418 FunctionSignature Signature, bool IsInstanceMethod,
419 bool IsFromSystemHeader) {
420 std::unique_ptr<ObjCMethodRecord> Record;
421 if (IsInstanceMethod)
422 Record = std::make_unique<ObjCInstanceMethodRecord>(
423 USR, Name, Loc, std::move(Availability), Comment, Declaration,
424 SubHeading, Signature, IsFromSystemHeader);
425 else
426 Record = std::make_unique<ObjCClassMethodRecord>(
427 USR, Name, Loc, std::move(Availability), Comment, Declaration,
428 SubHeading, Signature, IsFromSystemHeader);
429
430 Record->ParentInformation = APIRecord::HierarchyInformation(
431 Container->USR, Container->Name, Container->getKind(), Container);
432 USRBasedLookupTable.insert({USR, Record.get()});
433 return Container->Methods.emplace_back(std::move(Record)).get();
434 }
435
addObjCProperty(ObjCContainerRecord * Container,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,ObjCPropertyRecord::AttributeKind Attributes,StringRef GetterName,StringRef SetterName,bool IsOptional,bool IsInstanceProperty,bool IsFromSystemHeader)436 ObjCPropertyRecord *APISet::addObjCProperty(
437 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
438 PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
439 DeclarationFragments Declaration, DeclarationFragments SubHeading,
440 ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
441 StringRef SetterName, bool IsOptional, bool IsInstanceProperty,
442 bool IsFromSystemHeader) {
443 std::unique_ptr<ObjCPropertyRecord> Record;
444 if (IsInstanceProperty)
445 Record = std::make_unique<ObjCInstancePropertyRecord>(
446 USR, Name, Loc, std::move(Availability), Comment, Declaration,
447 SubHeading, Attributes, GetterName, SetterName, IsOptional,
448 IsFromSystemHeader);
449 else
450 Record = std::make_unique<ObjCClassPropertyRecord>(
451 USR, Name, Loc, std::move(Availability), Comment, Declaration,
452 SubHeading, Attributes, GetterName, SetterName, IsOptional,
453 IsFromSystemHeader);
454 Record->ParentInformation = APIRecord::HierarchyInformation(
455 Container->USR, Container->Name, Container->getKind(), Container);
456 USRBasedLookupTable.insert({USR, Record.get()});
457 return Container->Properties.emplace_back(std::move(Record)).get();
458 }
459
addObjCInstanceVariable(ObjCContainerRecord * Container,StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,ObjCInstanceVariableRecord::AccessControl Access,bool IsFromSystemHeader)460 ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
461 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
462 PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
463 DeclarationFragments Declaration, DeclarationFragments SubHeading,
464 ObjCInstanceVariableRecord::AccessControl Access, bool IsFromSystemHeader) {
465 auto Record = std::make_unique<ObjCInstanceVariableRecord>(
466 USR, Name, Loc, std::move(Availability), Comment, Declaration, SubHeading,
467 Access, IsFromSystemHeader);
468 Record->ParentInformation = APIRecord::HierarchyInformation(
469 Container->USR, Container->Name, Container->getKind(), Container);
470 USRBasedLookupTable.insert({USR, Record.get()});
471 return Container->Ivars.emplace_back(std::move(Record)).get();
472 }
473
addObjCProtocol(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)474 ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR,
475 PresumedLoc Loc,
476 AvailabilityInfo Availability,
477 const DocComment &Comment,
478 DeclarationFragments Declaration,
479 DeclarationFragments SubHeading,
480 bool IsFromSystemHeader) {
481 return addTopLevelRecord(USRBasedLookupTable, ObjCProtocols, USR, Name, Loc,
482 std::move(Availability), Comment, Declaration,
483 SubHeading, IsFromSystemHeader);
484 }
485
486 MacroDefinitionRecord *
addMacroDefinition(StringRef Name,StringRef USR,PresumedLoc Loc,DeclarationFragments Declaration,DeclarationFragments SubHeading,bool IsFromSystemHeader)487 APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
488 DeclarationFragments Declaration,
489 DeclarationFragments SubHeading,
490 bool IsFromSystemHeader) {
491 return addTopLevelRecord(USRBasedLookupTable, Macros, USR, Name, Loc,
492 Declaration, SubHeading, IsFromSystemHeader);
493 }
494
495 TypedefRecord *
addTypedef(StringRef Name,StringRef USR,PresumedLoc Loc,AvailabilityInfo Availability,const DocComment & Comment,DeclarationFragments Declaration,DeclarationFragments SubHeading,SymbolReference UnderlyingType,bool IsFromSystemHeader)496 APISet::addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
497 AvailabilityInfo Availability, const DocComment &Comment,
498 DeclarationFragments Declaration,
499 DeclarationFragments SubHeading,
500 SymbolReference UnderlyingType, bool IsFromSystemHeader) {
501 return addTopLevelRecord(USRBasedLookupTable, Typedefs, USR, Name, Loc,
502 std::move(Availability), Comment, Declaration,
503 SubHeading, UnderlyingType, IsFromSystemHeader);
504 }
505
findRecordForUSR(StringRef USR) const506 APIRecord *APISet::findRecordForUSR(StringRef USR) const {
507 if (USR.empty())
508 return nullptr;
509
510 return USRBasedLookupTable.lookup(USR);
511 }
512
recordUSR(const Decl * D)513 StringRef APISet::recordUSR(const Decl *D) {
514 SmallString<128> USR;
515 index::generateUSRForDecl(D, USR);
516 return copyString(USR);
517 }
518
recordUSRForMacro(StringRef Name,SourceLocation SL,const SourceManager & SM)519 StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL,
520 const SourceManager &SM) {
521 SmallString<128> USR;
522 index::generateUSRForMacro(Name, SL, SM, USR);
523 return copyString(USR);
524 }
525
copyString(StringRef String)526 StringRef APISet::copyString(StringRef String) {
527 if (String.empty())
528 return {};
529
530 // No need to allocate memory and copy if the string has already been stored.
531 if (StringAllocator.identifyObject(String.data()))
532 return String;
533
534 void *Ptr = StringAllocator.Allocate(String.size(), 1);
535 memcpy(Ptr, String.data(), String.size());
536 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
537 }
538
~APIRecord()539 APIRecord::~APIRecord() {}
~ObjCContainerRecord()540 ObjCContainerRecord::~ObjCContainerRecord() {}
~ObjCMethodRecord()541 ObjCMethodRecord::~ObjCMethodRecord() {}
~ObjCPropertyRecord()542 ObjCPropertyRecord::~ObjCPropertyRecord() {}
~CXXMethodRecord()543 CXXMethodRecord::~CXXMethodRecord() {}
544
anchor()545 void GlobalFunctionRecord::anchor() {}
anchor()546 void GlobalVariableRecord::anchor() {}
anchor()547 void EnumConstantRecord::anchor() {}
anchor()548 void EnumRecord::anchor() {}
anchor()549 void RecordFieldRecord::anchor() {}
anchor()550 void RecordRecord::anchor() {}
anchor()551 void CXXFieldRecord::anchor() {}
anchor()552 void CXXClassRecord::anchor() {}
anchor()553 void CXXConstructorRecord::anchor() {}
anchor()554 void CXXDestructorRecord::anchor() {}
anchor()555 void CXXInstanceMethodRecord::anchor() {}
anchor()556 void CXXStaticMethodRecord::anchor() {}
anchor()557 void ObjCInstancePropertyRecord::anchor() {}
anchor()558 void ObjCClassPropertyRecord::anchor() {}
anchor()559 void ObjCInstanceVariableRecord::anchor() {}
anchor()560 void ObjCInstanceMethodRecord::anchor() {}
anchor()561 void ObjCClassMethodRecord::anchor() {}
anchor()562 void ObjCCategoryRecord::anchor() {}
anchor()563 void ObjCInterfaceRecord::anchor() {}
anchor()564 void ObjCProtocolRecord::anchor() {}
anchor()565 void MacroDefinitionRecord::anchor() {}
anchor()566 void TypedefRecord::anchor() {}
567