1 //===- ExtractAPI/API.h -----------------------------------------*- 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 defines the APIRecord-based structs and the APISet class.
11 ///
12 /// Clang ExtractAPI is a tool to collect API information from a given set of
13 /// header files. The structures in this file describe data representations of
14 /// the API information collected for various kinds of symbols.
15 ///
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CLANG_EXTRACTAPI_API_H
19 #define LLVM_CLANG_EXTRACTAPI_API_H
20 
21 #include "clang/AST/Availability.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/AST/DeclObjC.h"
24 #include "clang/AST/RawCommentList.h"
25 #include "clang/Basic/SourceLocation.h"
26 #include "clang/Basic/Specifiers.h"
27 #include "clang/ExtractAPI/DeclarationFragments.h"
28 #include "llvm/ADT/MapVector.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/Allocator.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/TargetParser/Triple.h"
33 #include <memory>
34 #include <type_traits>
35 
36 namespace clang {
37 namespace extractapi {
38 
39 class Template {
40   struct TemplateParameter {
41     // "class", "typename", or concept name
42     std::string Type;
43     std::string Name;
44     unsigned int Index;
45     unsigned int Depth;
46     bool IsParameterPack;
47 
TemplateParameterTemplateParameter48     TemplateParameter(std::string Type, std::string Name, unsigned int Index,
49                       unsigned int Depth, bool IsParameterPack)
50         : Type(Type), Name(Name), Index(Index), Depth(Depth),
51           IsParameterPack(IsParameterPack) {}
52   };
53 
54   struct TemplateConstraint {
55     // type name of the constraint, if it has one
56     std::string Type;
57     std::string Kind;
58     std::string LHS, RHS;
59   };
60   llvm::SmallVector<TemplateParameter> Parameters;
61   llvm::SmallVector<TemplateConstraint> Constraints;
62 
63 public:
64   Template() = default;
65 
Template(const TemplateDecl * Decl)66   Template(const TemplateDecl *Decl) {
67     for (auto *const Parameter : *Decl->getTemplateParameters()) {
68       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
69       if (!Param) // some params are null
70         continue;
71       std::string Type;
72       if (Param->hasTypeConstraint())
73         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
74       else if (Param->wasDeclaredWithTypename())
75         Type = "typename";
76       else
77         Type = "class";
78 
79       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
80                            Param->getDepth(), Param->isParameterPack());
81     }
82   }
83 
Template(const ClassTemplatePartialSpecializationDecl * Decl)84   Template(const ClassTemplatePartialSpecializationDecl *Decl) {
85     for (auto *const Parameter : *Decl->getTemplateParameters()) {
86       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
87       if (!Param) // some params are null
88         continue;
89       std::string Type;
90       if (Param->hasTypeConstraint())
91         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
92       else if (Param->wasDeclaredWithTypename())
93         Type = "typename";
94       else
95         Type = "class";
96 
97       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
98                            Param->getDepth(), Param->isParameterPack());
99     }
100   }
101 
Template(const VarTemplatePartialSpecializationDecl * Decl)102   Template(const VarTemplatePartialSpecializationDecl *Decl) {
103     for (auto *const Parameter : *Decl->getTemplateParameters()) {
104       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
105       if (!Param) // some params are null
106         continue;
107       std::string Type;
108       if (Param->hasTypeConstraint())
109         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
110       else if (Param->wasDeclaredWithTypename())
111         Type = "typename";
112       else
113         Type = "class";
114 
115       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
116                            Param->getDepth(), Param->isParameterPack());
117     }
118   }
119 
getParameters()120   const llvm::SmallVector<TemplateParameter> &getParameters() const {
121     return Parameters;
122   }
123 
getConstraints()124   const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
125     return Constraints;
126   }
127 
addTemplateParameter(std::string Type,std::string Name,unsigned int Index,unsigned int Depth,bool IsParameterPack)128   void addTemplateParameter(std::string Type, std::string Name,
129                             unsigned int Index, unsigned int Depth,
130                             bool IsParameterPack) {
131     Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
132   }
133 
empty()134   bool empty() const { return Parameters.empty() && Constraints.empty(); }
135 };
136 
137 /// DocComment is a vector of RawComment::CommentLine.
138 ///
139 /// Each line represents one line of striped documentation comment,
140 /// with source range information. This simplifies calculating the source
141 /// location of a character in the doc comment for pointing back to the source
142 /// file.
143 /// e.g.
144 /// \code
145 ///   /// This is a documentation comment
146 ///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
147 ///   ///     with multiple lines.
148 ///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
149 /// \endcode
150 using DocComment = std::vector<RawComment::CommentLine>;
151 
152 // Classes deriving from APIRecord need to have USR be the first constructor
153 // argument. This is so that they are compatible with `addTopLevelRecord`
154 // defined in API.cpp
155 /// The base representation of an API record. Holds common symbol information.
156 struct APIRecord {
157   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
158   enum RecordKind {
159     RK_Unknown,
160     RK_Namespace,
161     RK_GlobalFunction,
162     RK_GlobalFunctionTemplate,
163     RK_GlobalFunctionTemplateSpecialization,
164     RK_GlobalVariable,
165     RK_GlobalVariableTemplate,
166     RK_GlobalVariableTemplateSpecialization,
167     RK_GlobalVariableTemplatePartialSpecialization,
168     RK_EnumConstant,
169     RK_Enum,
170     RK_StructField,
171     RK_Struct,
172     RK_UnionField,
173     RK_Union,
174     RK_StaticField,
175     RK_CXXField,
176     RK_CXXFieldTemplate,
177     RK_CXXClass,
178     RK_ClassTemplate,
179     RK_ClassTemplateSpecialization,
180     RK_ClassTemplatePartialSpecialization,
181     RK_Concept,
182     RK_CXXStaticMethod,
183     RK_CXXInstanceMethod,
184     RK_CXXConstructorMethod,
185     RK_CXXDestructorMethod,
186     RK_CXXMethodTemplate,
187     RK_CXXMethodTemplateSpecialization,
188     RK_ObjCInstanceProperty,
189     RK_ObjCClassProperty,
190     RK_ObjCIvar,
191     RK_ObjCClassMethod,
192     RK_ObjCInstanceMethod,
193     RK_ObjCInterface,
194     RK_ObjCCategory,
195     RK_ObjCCategoryModule,
196     RK_ObjCProtocol,
197     RK_MacroDefinition,
198     RK_Typedef,
199   };
200 
201   /// Stores information about the context of the declaration of this API.
202   /// This is roughly analogous to the DeclContext hierarchy for an AST Node.
203   struct HierarchyInformation {
204     /// The USR of the parent API.
205     StringRef ParentUSR;
206     /// The name of the parent API.
207     StringRef ParentName;
208     /// The record kind of the parent API.
209     RecordKind ParentKind = RK_Unknown;
210     /// A pointer to the parent APIRecord if known.
211     APIRecord *ParentRecord = nullptr;
212 
213     HierarchyInformation() = default;
214     HierarchyInformation(StringRef ParentUSR, StringRef ParentName,
215                          RecordKind Kind, APIRecord *ParentRecord = nullptr)
ParentUSRAPIRecord::HierarchyInformation216         : ParentUSR(ParentUSR), ParentName(ParentName), ParentKind(Kind),
217           ParentRecord(ParentRecord) {}
218 
emptyAPIRecord::HierarchyInformation219     bool empty() const {
220       return ParentUSR.empty() && ParentName.empty() &&
221              ParentKind == RK_Unknown && ParentRecord == nullptr;
222     }
223   };
224 
225   StringRef USR;
226   StringRef Name;
227   PresumedLoc Location;
228   AvailabilityInfo Availability;
229   LinkageInfo Linkage;
230 
231   /// Documentation comment lines attached to this symbol declaration.
232   DocComment Comment;
233 
234   /// Declaration fragments of this symbol declaration.
235   DeclarationFragments Declaration;
236 
237   /// SubHeading provides a more detailed representation than the plain
238   /// declaration name.
239   ///
240   /// SubHeading is an array of declaration fragments of tagged declaration
241   /// name, with potentially more tokens (for example the \c +/- symbol for
242   /// Objective-C class/instance methods).
243   DeclarationFragments SubHeading;
244 
245   /// Information about the parent record of this record.
246   HierarchyInformation ParentInformation;
247 
248   /// Whether the symbol was defined in a system header.
249   bool IsFromSystemHeader;
250 
251 private:
252   const RecordKind Kind;
253 
254 public:
getKindAPIRecord255   RecordKind getKind() const { return Kind; }
256 
257   APIRecord() = delete;
258 
APIRecordAPIRecord259   APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
260             PresumedLoc Location, AvailabilityInfo Availability,
261             LinkageInfo Linkage, const DocComment &Comment,
262             DeclarationFragments Declaration, DeclarationFragments SubHeading,
263             bool IsFromSystemHeader)
264       : USR(USR), Name(Name), Location(Location),
265         Availability(std::move(Availability)), Linkage(Linkage),
266         Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
267         IsFromSystemHeader(IsFromSystemHeader), Kind(Kind) {}
268 
APIRecordAPIRecord269   APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
270       : USR(USR), Name(Name), Kind(Kind) {}
271 
272   // Pure virtual destructor to make APIRecord abstract
273   virtual ~APIRecord() = 0;
274 };
275 
276 struct NamespaceRecord : APIRecord {
NamespaceRecordNamespaceRecord277   NamespaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
278                   AvailabilityInfo Availability, LinkageInfo Linkage,
279                   const DocComment &Comment, DeclarationFragments Declaration,
280                   DeclarationFragments SubHeading, bool IsFromSystemHeader)
281       : APIRecord(RK_Namespace, USR, Name, Loc, std::move(Availability),
282                   Linkage, Comment, Declaration, SubHeading,
283                   IsFromSystemHeader) {}
284 
classofNamespaceRecord285   static bool classof(const APIRecord *Record) {
286     return Record->getKind() == RK_Namespace;
287   }
288 };
289 
290 /// This holds information associated with global functions.
291 struct GlobalFunctionRecord : APIRecord {
292   FunctionSignature Signature;
293 
GlobalFunctionRecordGlobalFunctionRecord294   GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
295                        AvailabilityInfo Availability, LinkageInfo Linkage,
296                        const DocComment &Comment,
297                        DeclarationFragments Declaration,
298                        DeclarationFragments SubHeading,
299                        FunctionSignature Signature, bool IsFromSystemHeader)
300       : APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availability),
301                   Linkage, Comment, Declaration, SubHeading,
302                   IsFromSystemHeader),
303         Signature(Signature) {}
304 
GlobalFunctionRecordGlobalFunctionRecord305   GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
306                        PresumedLoc Loc, AvailabilityInfo Availability,
307                        LinkageInfo Linkage, const DocComment &Comment,
308                        DeclarationFragments Declaration,
309                        DeclarationFragments SubHeading,
310                        FunctionSignature Signature, bool IsFromSystemHeader)
311       : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
312                   Comment, Declaration, SubHeading, IsFromSystemHeader),
313         Signature(Signature) {}
314 
classofGlobalFunctionRecord315   static bool classof(const APIRecord *Record) {
316     return Record->getKind() == RK_GlobalFunction;
317   }
318 
319 private:
320   virtual void anchor();
321 };
322 
323 struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
324   Template Templ;
325 
GlobalFunctionTemplateRecordGlobalFunctionTemplateRecord326   GlobalFunctionTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
327                                AvailabilityInfo Availability,
328                                LinkageInfo Linkage, const DocComment &Comment,
329                                DeclarationFragments Declaration,
330                                DeclarationFragments SubHeading,
331                                FunctionSignature Signature, Template Template,
332                                bool IsFromSystemHeader)
333       : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Loc,
334                              std::move(Availability), Linkage, Comment,
335                              Declaration, SubHeading, Signature,
336                              IsFromSystemHeader),
337         Templ(Template) {}
338 
classofGlobalFunctionTemplateRecord339   static bool classof(const APIRecord *Record) {
340     return Record->getKind() == RK_GlobalFunctionTemplate;
341   }
342 };
343 
344 struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
GlobalFunctionTemplateSpecializationRecordGlobalFunctionTemplateSpecializationRecord345   GlobalFunctionTemplateSpecializationRecord(
346       StringRef USR, StringRef Name, PresumedLoc Loc,
347       AvailabilityInfo Availability, LinkageInfo Linkage,
348       const DocComment &Comment, DeclarationFragments Declaration,
349       DeclarationFragments SubHeading, FunctionSignature Signature,
350       bool IsFromSystemHeader)
351       : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
352                              Loc, std::move(Availability), Linkage, Comment,
353                              Declaration, SubHeading, Signature,
354                              IsFromSystemHeader) {}
355 
classofGlobalFunctionTemplateSpecializationRecord356   static bool classof(const APIRecord *Record) {
357     return Record->getKind() == RK_GlobalFunctionTemplateSpecialization;
358   }
359 };
360 
361 /// This holds information associated with global functions.
362 struct GlobalVariableRecord : APIRecord {
GlobalVariableRecordGlobalVariableRecord363   GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
364                        AvailabilityInfo Availability, LinkageInfo Linkage,
365                        const DocComment &Comment,
366                        DeclarationFragments Declaration,
367                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
368       : APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availability),
369                   Linkage, Comment, Declaration, SubHeading,
370                   IsFromSystemHeader) {}
371 
GlobalVariableRecordGlobalVariableRecord372   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
373                        PresumedLoc Loc, AvailabilityInfo Availability,
374                        LinkageInfo Linkage, const DocComment &Comment,
375                        DeclarationFragments Declaration,
376                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
377       : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
378                   Comment, Declaration, SubHeading, IsFromSystemHeader) {}
379 
classofGlobalVariableRecord380   static bool classof(const APIRecord *Record) {
381     return Record->getKind() == RK_GlobalVariable;
382   }
383 
384 private:
385   virtual void anchor();
386 };
387 
388 struct GlobalVariableTemplateRecord : GlobalVariableRecord {
389   Template Templ;
390 
GlobalVariableTemplateRecordGlobalVariableTemplateRecord391   GlobalVariableTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
392                                AvailabilityInfo Availability,
393                                LinkageInfo Linkage, const DocComment &Comment,
394                                DeclarationFragments Declaration,
395                                DeclarationFragments SubHeading,
396                                class Template Template, bool IsFromSystemHeader)
397       : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Loc,
398                              std::move(Availability), Linkage, Comment,
399                              Declaration, SubHeading, IsFromSystemHeader),
400         Templ(Template) {}
401 
classofGlobalVariableTemplateRecord402   static bool classof(const APIRecord *Record) {
403     return Record->getKind() == RK_GlobalVariableTemplate;
404   }
405 };
406 
407 struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
GlobalVariableTemplateSpecializationRecordGlobalVariableTemplateSpecializationRecord408   GlobalVariableTemplateSpecializationRecord(
409       StringRef USR, StringRef Name, PresumedLoc Loc,
410       AvailabilityInfo Availability, LinkageInfo Linkage,
411       const DocComment &Comment, DeclarationFragments Declaration,
412       DeclarationFragments SubHeading, bool IsFromSystemHeader)
413       : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
414                              Loc, std::move(Availability), Linkage, Comment,
415                              Declaration, SubHeading, IsFromSystemHeader) {}
416 
classofGlobalVariableTemplateSpecializationRecord417   static bool classof(const APIRecord *Record) {
418     return Record->getKind() == RK_GlobalVariableTemplateSpecialization;
419   }
420 };
421 
422 struct GlobalVariableTemplatePartialSpecializationRecord
423     : GlobalVariableRecord {
424   Template Templ;
425 
GlobalVariableTemplatePartialSpecializationRecordGlobalVariableTemplatePartialSpecializationRecord426   GlobalVariableTemplatePartialSpecializationRecord(
427       StringRef USR, StringRef Name, PresumedLoc Loc,
428       AvailabilityInfo Availability, LinkageInfo Linkage,
429       const DocComment &Comment, DeclarationFragments Declaration,
430       DeclarationFragments SubHeading, class Template Template,
431       bool IsFromSystemHeader)
432       : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
433                              USR, Name, Loc, std::move(Availability), Linkage,
434                              Comment, Declaration, SubHeading,
435                              IsFromSystemHeader),
436         Templ(Template) {}
437 
classofGlobalVariableTemplatePartialSpecializationRecord438   static bool classof(const APIRecord *Record) {
439     return Record->getKind() == RK_GlobalVariableTemplatePartialSpecialization;
440   }
441 };
442 
443 /// This holds information associated with enum constants.
444 struct EnumConstantRecord : APIRecord {
EnumConstantRecordEnumConstantRecord445   EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
446                      AvailabilityInfo Availability, const DocComment &Comment,
447                      DeclarationFragments Declaration,
448                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
449       : APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availability),
450                   LinkageInfo::none(), Comment, Declaration, SubHeading,
451                   IsFromSystemHeader) {}
452 
classofEnumConstantRecord453   static bool classof(const APIRecord *Record) {
454     return Record->getKind() == RK_EnumConstant;
455   }
456 
457 private:
458   virtual void anchor();
459 };
460 
461 /// This holds information associated with enums.
462 struct EnumRecord : APIRecord {
463   SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
464 
EnumRecordEnumRecord465   EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
466              AvailabilityInfo Availability, const DocComment &Comment,
467              DeclarationFragments Declaration, DeclarationFragments SubHeading,
468              bool IsFromSystemHeader)
469       : APIRecord(RK_Enum, USR, Name, Loc, std::move(Availability),
470                   LinkageInfo::none(), Comment, Declaration, SubHeading,
471                   IsFromSystemHeader) {}
472 
classofEnumRecord473   static bool classof(const APIRecord *Record) {
474     return Record->getKind() == RK_Enum;
475   }
476 
477 private:
478   virtual void anchor();
479 };
480 
481 /// This holds information associated with struct fields.
482 struct RecordFieldRecord : APIRecord {
RecordFieldRecordRecordFieldRecord483   RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
484                     AvailabilityInfo Availability, const DocComment &Comment,
485                     DeclarationFragments Declaration,
486                     DeclarationFragments SubHeading, RecordKind Kind,
487                     bool IsFromSystemHeader)
488       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
489                   LinkageInfo::none(), Comment, Declaration, SubHeading,
490                   IsFromSystemHeader) {}
491 
classofRecordFieldRecord492   static bool classof(const APIRecord *Record) {
493     return Record->getKind() == RK_StructField ||
494            Record->getKind() == RK_UnionField;
495   }
496 
497 private:
498   virtual void anchor();
499 };
500 
501 /// This holds information associated with structs.
502 struct RecordRecord : APIRecord {
503   SmallVector<std::unique_ptr<RecordFieldRecord>> Fields;
504 
RecordRecordRecordRecord505   RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
506                AvailabilityInfo Availability, const DocComment &Comment,
507                DeclarationFragments Declaration,
508                DeclarationFragments SubHeading, RecordKind Kind,
509                bool IsFromSystemHeader)
510       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
511                   LinkageInfo::none(), Comment, Declaration, SubHeading,
512                   IsFromSystemHeader) {}
513 
classofRecordRecord514   static bool classof(const APIRecord *Record) {
515     return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
516   }
517 
518 private:
519   virtual void anchor();
520 };
521 
522 struct CXXFieldRecord : APIRecord {
523   AccessControl Access;
524 
CXXFieldRecordCXXFieldRecord525   CXXFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
526                  AvailabilityInfo Availability, const DocComment &Comment,
527                  DeclarationFragments Declaration,
528                  DeclarationFragments SubHeading, AccessControl Access,
529                  bool IsFromSystemHeader)
530       : APIRecord(RK_CXXField, USR, Name, Loc, std::move(Availability),
531                   LinkageInfo::none(), Comment, Declaration, SubHeading,
532                   IsFromSystemHeader),
533         Access(Access) {}
534 
CXXFieldRecordCXXFieldRecord535   CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
536                  PresumedLoc Loc, AvailabilityInfo Availability,
537                  const DocComment &Comment, DeclarationFragments Declaration,
538                  DeclarationFragments SubHeading, AccessControl Access,
539                  bool IsFromSystemHeader)
540       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
541                   LinkageInfo::none(), Comment, Declaration, SubHeading,
542                   IsFromSystemHeader),
543         Access(Access) {}
544 
classofCXXFieldRecord545   static bool classof(const APIRecord *Record) {
546     return Record->getKind() == RK_CXXField;
547   }
548 
549 private:
550   virtual void anchor();
551 };
552 
553 struct CXXFieldTemplateRecord : CXXFieldRecord {
554   Template Templ;
555 
CXXFieldTemplateRecordCXXFieldTemplateRecord556   CXXFieldTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
557                          AvailabilityInfo Availability,
558                          const DocComment &Comment,
559                          DeclarationFragments Declaration,
560                          DeclarationFragments SubHeading, AccessControl Access,
561                          Template Template, bool IsFromSystemHeader)
562       : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Loc,
563                        std::move(Availability), Comment, Declaration,
564                        SubHeading, Access, IsFromSystemHeader),
565         Templ(Template) {}
566 
classofCXXFieldTemplateRecord567   static bool classof(const APIRecord *Record) {
568     return Record->getKind() == RK_CXXFieldTemplate;
569   }
570 };
571 
572 struct CXXMethodRecord : APIRecord {
573   FunctionSignature Signature;
574   AccessControl Access;
575 
576   CXXMethodRecord() = delete;
577 
CXXMethodRecordCXXMethodRecord578   CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
579                   PresumedLoc Loc, AvailabilityInfo Availability,
580                   const DocComment &Comment, DeclarationFragments Declaration,
581                   DeclarationFragments SubHeading, FunctionSignature Signature,
582                   AccessControl Access, bool IsFromSystemHeader)
583       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
584                   LinkageInfo::none(), Comment, Declaration, SubHeading,
585                   IsFromSystemHeader),
586         Signature(Signature), Access(Access) {}
587 
588   virtual ~CXXMethodRecord() = 0;
589 };
590 
591 struct CXXConstructorRecord : CXXMethodRecord {
CXXConstructorRecordCXXConstructorRecord592   CXXConstructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
593                        AvailabilityInfo Availability, const DocComment &Comment,
594                        DeclarationFragments Declaration,
595                        DeclarationFragments SubHeading,
596                        FunctionSignature Signature, AccessControl Access,
597                        bool IsFromSystemHeader)
598       : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Loc,
599                         std::move(Availability), Comment, Declaration,
600                         SubHeading, Signature, Access, IsFromSystemHeader) {}
classofCXXConstructorRecord601   static bool classof(const APIRecord *Record) {
602     return Record->getKind() == RK_CXXConstructorMethod;
603   }
604 
605 private:
606   virtual void anchor();
607 };
608 
609 struct CXXDestructorRecord : CXXMethodRecord {
CXXDestructorRecordCXXDestructorRecord610   CXXDestructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
611                       AvailabilityInfo Availability, const DocComment &Comment,
612                       DeclarationFragments Declaration,
613                       DeclarationFragments SubHeading,
614                       FunctionSignature Signature, AccessControl Access,
615                       bool IsFromSystemHeader)
616       : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Loc,
617                         std::move(Availability), Comment, Declaration,
618                         SubHeading, Signature, Access, IsFromSystemHeader) {}
classofCXXDestructorRecord619   static bool classof(const APIRecord *Record) {
620     return Record->getKind() == RK_CXXDestructorMethod;
621   }
622 
623 private:
624   virtual void anchor();
625 };
626 
627 struct CXXStaticMethodRecord : CXXMethodRecord {
CXXStaticMethodRecordCXXStaticMethodRecord628   CXXStaticMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
629                         AvailabilityInfo Availability,
630                         const DocComment &Comment,
631                         DeclarationFragments Declaration,
632                         DeclarationFragments SubHeading,
633                         FunctionSignature Signature, AccessControl Access,
634                         bool IsFromSystemHeader)
635       : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Loc,
636                         std::move(Availability), Comment, Declaration,
637                         SubHeading, Signature, Access, IsFromSystemHeader) {}
classofCXXStaticMethodRecord638   static bool classof(const APIRecord *Record) {
639     return Record->getKind() == RK_CXXStaticMethod;
640   }
641 
642 private:
643   virtual void anchor();
644 };
645 
646 struct CXXInstanceMethodRecord : CXXMethodRecord {
CXXInstanceMethodRecordCXXInstanceMethodRecord647   CXXInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
648                           AvailabilityInfo Availability,
649                           const DocComment &Comment,
650                           DeclarationFragments Declaration,
651                           DeclarationFragments SubHeading,
652                           FunctionSignature Signature, AccessControl Access,
653                           bool IsFromSystemHeader)
654       : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Loc,
655                         std::move(Availability), Comment, Declaration,
656                         SubHeading, Signature, Access, IsFromSystemHeader) {}
657 
classofCXXInstanceMethodRecord658   static bool classof(const APIRecord *Record) {
659     return Record->getKind() == RK_CXXInstanceMethod;
660   }
661 
662 private:
663   virtual void anchor();
664 };
665 
666 struct CXXMethodTemplateRecord : CXXMethodRecord {
667   Template Templ;
668 
CXXMethodTemplateRecordCXXMethodTemplateRecord669   CXXMethodTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
670                           AvailabilityInfo Availability,
671                           const DocComment &Comment,
672                           DeclarationFragments Declaration,
673                           DeclarationFragments SubHeading,
674                           FunctionSignature Signature, AccessControl Access,
675                           Template Template, bool IsFromSystemHeader)
676       : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Loc,
677                         std::move(Availability), Comment, Declaration,
678                         SubHeading, Signature, Access, IsFromSystemHeader),
679         Templ(Template) {}
680 
classofCXXMethodTemplateRecord681   static bool classof(const APIRecord *Record) {
682     return Record->getKind() == RK_CXXMethodTemplate;
683   }
684 };
685 
686 struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
CXXMethodTemplateSpecializationRecordCXXMethodTemplateSpecializationRecord687   CXXMethodTemplateSpecializationRecord(
688       StringRef USR, StringRef Name, PresumedLoc Loc,
689       AvailabilityInfo Availability, const DocComment &Comment,
690       DeclarationFragments Declaration, DeclarationFragments SubHeading,
691       FunctionSignature Signature, AccessControl Access,
692       bool IsFromSystemHeader)
693       : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Loc,
694                         std::move(Availability), Comment, Declaration,
695                         SubHeading, Signature, Access, IsFromSystemHeader) {}
696 
classofCXXMethodTemplateSpecializationRecord697   static bool classof(const APIRecord *Record) {
698     return Record->getKind() == RK_CXXMethodTemplateSpecialization;
699   }
700 };
701 
702 /// This holds information associated with Objective-C properties.
703 struct ObjCPropertyRecord : APIRecord {
704   /// The attributes associated with an Objective-C property.
705   enum AttributeKind : unsigned {
706     NoAttr = 0,
707     ReadOnly = 1,
708     Dynamic = 1 << 2,
709   };
710 
711   AttributeKind Attributes;
712   StringRef GetterName;
713   StringRef SetterName;
714   bool IsOptional;
715 
ObjCPropertyRecordObjCPropertyRecord716   ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
717                      PresumedLoc Loc, AvailabilityInfo Availability,
718                      const DocComment &Comment,
719                      DeclarationFragments Declaration,
720                      DeclarationFragments SubHeading, AttributeKind Attributes,
721                      StringRef GetterName, StringRef SetterName,
722                      bool IsOptional, bool IsFromSystemHeader)
723       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
724                   LinkageInfo::none(), Comment, Declaration, SubHeading,
725                   IsFromSystemHeader),
726         Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
727         IsOptional(IsOptional) {}
728 
isReadOnlyObjCPropertyRecord729   bool isReadOnly() const { return Attributes & ReadOnly; }
isDynamicObjCPropertyRecord730   bool isDynamic() const { return Attributes & Dynamic; }
731 
732   virtual ~ObjCPropertyRecord() = 0;
733 };
734 
735 struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
ObjCInstancePropertyRecordObjCInstancePropertyRecord736   ObjCInstancePropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
737                              AvailabilityInfo Availability,
738                              const DocComment &Comment,
739                              DeclarationFragments Declaration,
740                              DeclarationFragments SubHeading,
741                              AttributeKind Attributes, StringRef GetterName,
742                              StringRef SetterName, bool IsOptional,
743                              bool IsFromSystemHeader)
744       : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Loc,
745                            std::move(Availability), Comment, Declaration,
746                            SubHeading, Attributes, GetterName, SetterName,
747                            IsOptional, IsFromSystemHeader) {}
748 
classofObjCInstancePropertyRecord749   static bool classof(const APIRecord *Record) {
750     return Record->getKind() == RK_ObjCInstanceProperty;
751   }
752 
753 private:
754   virtual void anchor();
755 };
756 
757 struct ObjCClassPropertyRecord : ObjCPropertyRecord {
ObjCClassPropertyRecordObjCClassPropertyRecord758   ObjCClassPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
759                           AvailabilityInfo Availability,
760                           const DocComment &Comment,
761                           DeclarationFragments Declaration,
762                           DeclarationFragments SubHeading,
763                           AttributeKind Attributes, StringRef GetterName,
764                           StringRef SetterName, bool IsOptional,
765                           bool IsFromSystemHeader)
766       : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Loc,
767                            std::move(Availability), Comment, Declaration,
768                            SubHeading, Attributes, GetterName, SetterName,
769                            IsOptional, IsFromSystemHeader) {}
770 
classofObjCClassPropertyRecord771   static bool classof(const APIRecord *Record) {
772     return Record->getKind() == RK_ObjCClassProperty;
773   }
774 
775 private:
776   virtual void anchor();
777 };
778 
779 /// This holds information associated with Objective-C instance variables.
780 struct ObjCInstanceVariableRecord : APIRecord {
781   using AccessControl = ObjCIvarDecl::AccessControl;
782   AccessControl Access;
783 
ObjCInstanceVariableRecordObjCInstanceVariableRecord784   ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
785                              AvailabilityInfo Availability,
786                              const DocComment &Comment,
787                              DeclarationFragments Declaration,
788                              DeclarationFragments SubHeading,
789                              AccessControl Access, bool IsFromSystemHeader)
790       : APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availability),
791                   LinkageInfo::none(), Comment, Declaration, SubHeading,
792                   IsFromSystemHeader),
793         Access(Access) {}
794 
classofObjCInstanceVariableRecord795   static bool classof(const APIRecord *Record) {
796     return Record->getKind() == RK_ObjCIvar;
797   }
798 
799 private:
800   virtual void anchor();
801 };
802 
803 /// This holds information associated with Objective-C methods.
804 struct ObjCMethodRecord : APIRecord {
805   FunctionSignature Signature;
806 
807   ObjCMethodRecord() = delete;
808 
ObjCMethodRecordObjCMethodRecord809   ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
810                    PresumedLoc Loc, AvailabilityInfo Availability,
811                    const DocComment &Comment, DeclarationFragments Declaration,
812                    DeclarationFragments SubHeading, FunctionSignature Signature,
813                    bool IsFromSystemHeader)
814       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
815                   LinkageInfo::none(), Comment, Declaration, SubHeading,
816                   IsFromSystemHeader),
817         Signature(Signature) {}
818 
819   virtual ~ObjCMethodRecord() = 0;
820 };
821 
822 struct ObjCInstanceMethodRecord : ObjCMethodRecord {
ObjCInstanceMethodRecordObjCInstanceMethodRecord823   ObjCInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
824                            AvailabilityInfo Availability,
825                            const DocComment &Comment,
826                            DeclarationFragments Declaration,
827                            DeclarationFragments SubHeading,
828                            FunctionSignature Signature, bool IsFromSystemHeader)
829       : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Loc,
830                          std::move(Availability), Comment, Declaration,
831                          SubHeading, Signature, IsFromSystemHeader) {}
classofObjCInstanceMethodRecord832   static bool classof(const APIRecord *Record) {
833     return Record->getKind() == RK_ObjCInstanceMethod;
834   }
835 
836 private:
837   virtual void anchor();
838 };
839 
840 struct ObjCClassMethodRecord : ObjCMethodRecord {
ObjCClassMethodRecordObjCClassMethodRecord841   ObjCClassMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
842                         AvailabilityInfo Availability,
843                         const DocComment &Comment,
844                         DeclarationFragments Declaration,
845                         DeclarationFragments SubHeading,
846                         FunctionSignature Signature, bool IsFromSystemHeader)
847       : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Loc,
848                          std::move(Availability), Comment, Declaration,
849                          SubHeading, Signature, IsFromSystemHeader) {}
850 
classofObjCClassMethodRecord851   static bool classof(const APIRecord *Record) {
852     return Record->getKind() == RK_ObjCClassMethod;
853   }
854 
855 private:
856   virtual void anchor();
857 };
858 
859 /// This represents a reference to another symbol that might come from external
860 /// sources.
861 struct SymbolReference {
862   StringRef Name;
863   StringRef USR;
864 
865   /// The source project/module/product of the referred symbol.
866   StringRef Source;
867 
868   SymbolReference() = default;
869   SymbolReference(StringRef Name, StringRef USR = "", StringRef Source = "")
NameSymbolReference870       : Name(Name), USR(USR), Source(Source) {}
SymbolReferenceSymbolReference871   SymbolReference(const APIRecord &Record)
872       : Name(Record.Name), USR(Record.USR) {}
SymbolReferenceSymbolReference873   SymbolReference(const APIRecord *Record)
874       : Name(Record->Name), USR(Record->USR) {}
875 
876   /// Determine if this SymbolReference is empty.
877   ///
878   /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
emptySymbolReference879   bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
880 };
881 
882 struct StaticFieldRecord : CXXFieldRecord {
883   SymbolReference Context;
884 
StaticFieldRecordStaticFieldRecord885   StaticFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
886                     AvailabilityInfo Availability, LinkageInfo Linkage,
887                     const DocComment &Comment, DeclarationFragments Declaration,
888                     DeclarationFragments SubHeading, SymbolReference Context,
889                     AccessControl Access, bool IsFromSystemHeader)
890       : CXXFieldRecord(RK_StaticField, USR, Name, Loc, std::move(Availability),
891                        Comment, Declaration, SubHeading, Access,
892                        IsFromSystemHeader),
893         Context(Context) {}
894 
classofStaticFieldRecord895   static bool classof(const APIRecord *Record) {
896     return Record->getKind() == RK_StaticField;
897   }
898 };
899 
900 /// The base representation of an Objective-C container record. Holds common
901 /// information associated with Objective-C containers.
902 struct ObjCContainerRecord : APIRecord {
903   SmallVector<std::unique_ptr<ObjCMethodRecord>> Methods;
904   SmallVector<std::unique_ptr<ObjCPropertyRecord>> Properties;
905   SmallVector<std::unique_ptr<ObjCInstanceVariableRecord>> Ivars;
906   SmallVector<SymbolReference> Protocols;
907 
908   ObjCContainerRecord() = delete;
909 
ObjCContainerRecordObjCContainerRecord910   ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
911                       PresumedLoc Loc, AvailabilityInfo Availability,
912                       LinkageInfo Linkage, const DocComment &Comment,
913                       DeclarationFragments Declaration,
914                       DeclarationFragments SubHeading, bool IsFromSystemHeader)
915       : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
916                   Comment, Declaration, SubHeading, IsFromSystemHeader) {}
917 
918   virtual ~ObjCContainerRecord() = 0;
919 };
920 
921 struct CXXClassRecord : APIRecord {
922   SmallVector<std::unique_ptr<CXXFieldRecord>> Fields;
923   SmallVector<std::unique_ptr<CXXMethodRecord>> Methods;
924   SmallVector<SymbolReference> Bases;
925   AccessControl Access;
926 
CXXClassRecordCXXClassRecord927   CXXClassRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
928                  AvailabilityInfo Availability, const DocComment &Comment,
929                  DeclarationFragments Declaration,
930                  DeclarationFragments SubHeading, RecordKind Kind,
931                  AccessControl Access, bool IsFromSystemHeader)
932       : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
933                   LinkageInfo::none(), Comment, Declaration, SubHeading,
934                   IsFromSystemHeader),
935         Access(Access) {}
936 
classofCXXClassRecord937   static bool classof(const APIRecord *Record) {
938     return (Record->getKind() == RK_CXXClass);
939   }
940 
941 private:
942   virtual void anchor();
943 };
944 
945 struct ClassTemplateRecord : CXXClassRecord {
946   Template Templ;
947 
ClassTemplateRecordClassTemplateRecord948   ClassTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
949                       AvailabilityInfo Availability, const DocComment &Comment,
950                       DeclarationFragments Declaration,
951                       DeclarationFragments SubHeading, Template Template,
952                       AccessControl Access, bool IsFromSystemHeader)
953       : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
954                        Declaration, SubHeading, RK_ClassTemplate, Access,
955                        IsFromSystemHeader),
956         Templ(Template) {}
957 
classofClassTemplateRecord958   static bool classof(const APIRecord *Record) {
959     return Record->getKind() == RK_ClassTemplate;
960   }
961 };
962 
963 struct ClassTemplateSpecializationRecord : CXXClassRecord {
ClassTemplateSpecializationRecordClassTemplateSpecializationRecord964   ClassTemplateSpecializationRecord(
965       StringRef USR, StringRef Name, PresumedLoc Loc,
966       AvailabilityInfo Availability, const DocComment &Comment,
967       DeclarationFragments Declaration, DeclarationFragments SubHeading,
968       AccessControl Access, bool IsFromSystemHeader)
969       : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
970                        Declaration, SubHeading, RK_ClassTemplateSpecialization,
971                        Access, IsFromSystemHeader) {}
972 
classofClassTemplateSpecializationRecord973   static bool classof(const APIRecord *Record) {
974     return Record->getKind() == RK_ClassTemplateSpecialization;
975   }
976 };
977 
978 struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
979   Template Templ;
ClassTemplatePartialSpecializationRecordClassTemplatePartialSpecializationRecord980   ClassTemplatePartialSpecializationRecord(
981       StringRef USR, StringRef Name, PresumedLoc Loc,
982       AvailabilityInfo Availability, const DocComment &Comment,
983       DeclarationFragments Declaration, DeclarationFragments SubHeading,
984       Template Template, AccessControl Access, bool IsFromSystemHeader)
985       : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
986                        Declaration, SubHeading, RK_ClassTemplateSpecialization,
987                        Access, IsFromSystemHeader),
988         Templ(Template) {}
989 
classofClassTemplatePartialSpecializationRecord990   static bool classof(const APIRecord *Record) {
991     return Record->getKind() == RK_ClassTemplatePartialSpecialization;
992   }
993 };
994 
995 struct ConceptRecord : APIRecord {
996   Template Templ;
997 
ConceptRecordConceptRecord998   ConceptRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
999                 AvailabilityInfo Availability, const DocComment &Comment,
1000                 DeclarationFragments Declaration,
1001                 DeclarationFragments SubHeading, Template Template,
1002                 bool IsFromSystemHeader)
1003       : APIRecord(RK_Concept, USR, Name, Loc, std::move(Availability),
1004                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1005                   IsFromSystemHeader),
1006         Templ(Template) {}
1007 };
1008 
1009 /// This holds information associated with Objective-C categories.
1010 struct ObjCCategoryRecord : ObjCContainerRecord {
1011   SymbolReference Interface;
1012   /// Determine whether the Category is derived from external class interface.
1013   bool IsFromExternalModule = false;
1014 
ObjCCategoryRecordObjCCategoryRecord1015   ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
1016                      AvailabilityInfo Availability, const DocComment &Comment,
1017                      DeclarationFragments Declaration,
1018                      DeclarationFragments SubHeading, SymbolReference Interface,
1019                      bool IsFromSystemHeader)
1020       : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc,
1021                             std::move(Availability), LinkageInfo::none(),
1022                             Comment, Declaration, SubHeading,
1023                             IsFromSystemHeader),
1024         Interface(Interface) {}
1025 
classofObjCCategoryRecord1026   static bool classof(const APIRecord *Record) {
1027     return Record->getKind() == RK_ObjCCategory;
1028   }
1029 
1030 private:
1031   virtual void anchor();
1032 };
1033 
1034 /// This holds information associated with Objective-C interfaces/classes.
1035 struct ObjCInterfaceRecord : ObjCContainerRecord {
1036   SymbolReference SuperClass;
1037   // ObjCCategoryRecord%s are stored in and owned by APISet.
1038   SmallVector<ObjCCategoryRecord *> Categories;
1039 
ObjCInterfaceRecordObjCInterfaceRecord1040   ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
1041                       AvailabilityInfo Availability, LinkageInfo Linkage,
1042                       const DocComment &Comment,
1043                       DeclarationFragments Declaration,
1044                       DeclarationFragments SubHeading,
1045                       SymbolReference SuperClass, bool IsFromSystemHeader)
1046       : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc,
1047                             std::move(Availability), Linkage, Comment,
1048                             Declaration, SubHeading, IsFromSystemHeader),
1049         SuperClass(SuperClass) {}
1050 
classofObjCInterfaceRecord1051   static bool classof(const APIRecord *Record) {
1052     return Record->getKind() == RK_ObjCInterface;
1053   }
1054 
1055 private:
1056   virtual void anchor();
1057 };
1058 
1059 /// This holds information associated with Objective-C protocols.
1060 struct ObjCProtocolRecord : ObjCContainerRecord {
ObjCProtocolRecordObjCProtocolRecord1061   ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
1062                      AvailabilityInfo Availability, const DocComment &Comment,
1063                      DeclarationFragments Declaration,
1064                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
1065       : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc,
1066                             std::move(Availability), LinkageInfo::none(),
1067                             Comment, Declaration, SubHeading,
1068                             IsFromSystemHeader) {}
1069 
classofObjCProtocolRecord1070   static bool classof(const APIRecord *Record) {
1071     return Record->getKind() == RK_ObjCProtocol;
1072   }
1073 
1074 private:
1075   virtual void anchor();
1076 };
1077 
1078 /// This holds information associated with macro definitions.
1079 struct MacroDefinitionRecord : APIRecord {
MacroDefinitionRecordMacroDefinitionRecord1080   MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
1081                         DeclarationFragments Declaration,
1082                         DeclarationFragments SubHeading,
1083                         bool IsFromSystemHeader)
1084       : APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
1085                   LinkageInfo(), {}, Declaration, SubHeading,
1086                   IsFromSystemHeader) {}
1087 
classofMacroDefinitionRecord1088   static bool classof(const APIRecord *Record) {
1089     return Record->getKind() == RK_MacroDefinition;
1090   }
1091 
1092 private:
1093   virtual void anchor();
1094 };
1095 
1096 /// This holds information associated with typedefs.
1097 ///
1098 /// Note: Typedefs for anonymous enums and structs typically don't get emitted
1099 /// by the serializers but still get a TypedefRecord. Instead we use the
1100 /// typedef name as a name for the underlying anonymous struct or enum.
1101 struct TypedefRecord : APIRecord {
1102   SymbolReference UnderlyingType;
1103 
TypedefRecordTypedefRecord1104   TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
1105                 AvailabilityInfo Availability, const DocComment &Comment,
1106                 DeclarationFragments Declaration,
1107                 DeclarationFragments SubHeading, SymbolReference UnderlyingType,
1108                 bool IsFromSystemHeader)
1109       : APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availability),
1110                   LinkageInfo(), Comment, Declaration, SubHeading,
1111                   IsFromSystemHeader),
1112         UnderlyingType(UnderlyingType) {}
1113 
classofTypedefRecord1114   static bool classof(const APIRecord *Record) {
1115     return Record->getKind() == RK_Typedef;
1116   }
1117 
1118 private:
1119   virtual void anchor();
1120 };
1121 
1122 /// Check if a record type has a function signature mixin.
1123 ///
1124 /// This is denoted by the record type having a ``Signature`` field of type
1125 /// FunctionSignature.
1126 template <typename RecordTy>
1127 struct has_function_signature : public std::false_type {};
1128 template <>
1129 struct has_function_signature<GlobalFunctionRecord> : public std::true_type {};
1130 template <>
1131 struct has_function_signature<ObjCMethodRecord> : public std::true_type {};
1132 template <>
1133 struct has_function_signature<ObjCInstanceMethodRecord>
1134     : public std::true_type {};
1135 template <>
1136 struct has_function_signature<ObjCClassMethodRecord> : public std::true_type {};
1137 template <>
1138 struct has_function_signature<CXXInstanceMethodRecord> : public std::true_type {};
1139 template <>
1140 struct has_function_signature<CXXStaticMethodRecord> : public std::true_type {};
1141 template <>
1142 struct has_function_signature<CXXMethodTemplateRecord> : public std::true_type {
1143 };
1144 template <>
1145 struct has_function_signature<CXXMethodTemplateSpecializationRecord>
1146     : public std::true_type {};
1147 
1148 template <typename RecordTy> struct has_access : public std::false_type {};
1149 template <> struct has_access<CXXInstanceMethodRecord> : public std::true_type {};
1150 template <> struct has_access<CXXStaticMethodRecord> : public std::true_type {};
1151 template <> struct has_access<CXXFieldRecord> : public std::true_type {};
1152 template <>
1153 struct has_access<CXXMethodTemplateRecord> : public std::true_type {};
1154 template <>
1155 struct has_access<CXXMethodTemplateSpecializationRecord>
1156     : public std::true_type {};
1157 template <>
1158 struct has_access<CXXFieldTemplateRecord> : public std::true_type {};
1159 template <> struct has_access<CXXClassRecord> : public std::true_type {};
1160 template <> struct has_access<ClassTemplateRecord> : public std::true_type {};
1161 template <>
1162 struct has_access<ClassTemplateSpecializationRecord> : public std::true_type {};
1163 template <>
1164 struct has_access<ClassTemplatePartialSpecializationRecord>
1165     : public std::true_type {};
1166 
1167 template <typename RecordTy> struct has_template : public std::false_type {};
1168 template <> struct has_template<ClassTemplateRecord> : public std::true_type {};
1169 template <>
1170 struct has_template<ClassTemplatePartialSpecializationRecord>
1171     : public std::true_type {};
1172 template <> struct has_template<ConceptRecord> : public std::true_type {};
1173 template <>
1174 struct has_template<GlobalVariableTemplateRecord> : public std::true_type {};
1175 template <>
1176 struct has_template<GlobalVariableTemplatePartialSpecializationRecord>
1177     : public std::true_type {};
1178 template <>
1179 struct has_template<CXXMethodTemplateRecord> : public std::true_type {};
1180 template <>
1181 struct has_template<CXXFieldTemplateRecord> : public std::true_type {};
1182 
1183 template <>
1184 struct has_template<GlobalFunctionTemplateRecord> : public std::true_type {};
1185 template <>
1186 struct has_function_signature<GlobalFunctionTemplateRecord>
1187     : public std::true_type {};
1188 template <>
1189 struct has_function_signature<GlobalFunctionTemplateSpecializationRecord>
1190     : public std::true_type {};
1191 
1192 /// APISet holds the set of API records collected from given inputs.
1193 class APISet {
1194 public:
1195   NamespaceRecord *addNamespace(APIRecord *Parent, StringRef Name,
1196                                 StringRef USR, PresumedLoc Loc,
1197                                 AvailabilityInfo Availability,
1198                                 LinkageInfo Linkage, const DocComment &Comment,
1199                                 DeclarationFragments Declaration,
1200                                 DeclarationFragments SubHeading,
1201                                 bool IsFromSystemHeaderg);
1202   /// Create and add a global variable record into the API set.
1203   ///
1204   /// Note: the caller is responsible for keeping the StringRef \p Name and
1205   /// \p USR alive. APISet::copyString provides a way to copy strings into
1206   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1207   /// to generate the USR for \c D and keep it alive in APISet.
1208   GlobalVariableRecord *
1209   addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
1210                AvailabilityInfo Availability, LinkageInfo Linkage,
1211                const DocComment &Comment, DeclarationFragments Declaration,
1212                DeclarationFragments SubHeadin, bool IsFromSystemHeaderg);
1213 
1214   GlobalVariableTemplateRecord *
1215   addGlobalVariableTemplate(StringRef Name, StringRef USR, PresumedLoc Loc,
1216                             AvailabilityInfo Availability, LinkageInfo Linkage,
1217                             const DocComment &Comment,
1218                             DeclarationFragments Declaration,
1219                             DeclarationFragments SubHeading, Template Template,
1220                             bool IsFromSystemHeader);
1221 
1222   /// Create and add a function record into the API set.
1223   ///
1224   /// Note: the caller is responsible for keeping the StringRef \p Name and
1225   /// \p USR alive. APISet::copyString provides a way to copy strings into
1226   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1227   /// to generate the USR for \c D and keep it alive in APISet.
1228   GlobalFunctionRecord *
1229   addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
1230                     AvailabilityInfo Availability, LinkageInfo Linkage,
1231                     const DocComment &Comment, DeclarationFragments Declaration,
1232                     DeclarationFragments SubHeading,
1233                     FunctionSignature Signature, bool IsFromSystemHeader);
1234 
1235   GlobalFunctionTemplateRecord *addGlobalFunctionTemplate(
1236       StringRef Name, StringRef USR, PresumedLoc Loc,
1237       AvailabilityInfo Availability, LinkageInfo Linkage,
1238       const DocComment &Comment, DeclarationFragments Declaration,
1239       DeclarationFragments SubHeading, FunctionSignature Signature,
1240       Template Template, bool IsFromSystemHeader);
1241 
1242   GlobalFunctionTemplateSpecializationRecord *
1243   addGlobalFunctionTemplateSpecialization(
1244       StringRef Name, StringRef USR, PresumedLoc Loc,
1245       AvailabilityInfo Availability, LinkageInfo Linkage,
1246       const DocComment &Comment, DeclarationFragments Declaration,
1247       DeclarationFragments SubHeading, FunctionSignature Signature,
1248       bool IsFromSystemHeader);
1249 
1250   /// Create and add an enum constant record into the API set.
1251   ///
1252   /// Note: the caller is responsible for keeping the StringRef \p Name and
1253   /// \p USR alive. APISet::copyString provides a way to copy strings into
1254   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1255   /// to generate the USR for \c D and keep it alive in APISet.
1256   EnumConstantRecord *
1257   addEnumConstant(EnumRecord *Enum, StringRef Name, StringRef USR,
1258                   PresumedLoc Loc, AvailabilityInfo Availability,
1259                   const DocComment &Comment, DeclarationFragments Declaration,
1260                   DeclarationFragments SubHeading, bool IsFromSystemHeader);
1261 
1262   /// Create and add an enum record into the API set.
1263   ///
1264   /// Note: the caller is responsible for keeping the StringRef \p Name and
1265   /// \p USR alive. APISet::copyString provides a way to copy strings into
1266   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1267   /// to generate the USR for \c D and keep it alive in APISet.
1268   EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
1269                       AvailabilityInfo Availability, const DocComment &Comment,
1270                       DeclarationFragments Declaration,
1271                       DeclarationFragments SubHeading, bool IsFromSystemHeader);
1272 
1273   /// Create and add a record field record into the API set.
1274   ///
1275   /// Note: the caller is responsible for keeping the StringRef \p Name and
1276   /// \p USR alive. APISet::copyString provides a way to copy strings into
1277   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1278   /// to generate the USR for \c D and keep it alive in APISet.
1279   RecordFieldRecord *
1280   addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
1281                  PresumedLoc Loc, AvailabilityInfo Availability,
1282                  const DocComment &Comment, DeclarationFragments Declaration,
1283                  DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
1284                  bool IsFromSystemHeader);
1285 
1286   /// Create and add a record record into the API set.
1287   ///
1288   /// Note: the caller is responsible for keeping the StringRef \p Name and
1289   /// \p USR alive. APISet::copyString provides a way to copy strings into
1290   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1291   /// to generate the USR for \c D and keep it alive in APISet.
1292   RecordRecord *addRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
1293                           AvailabilityInfo Availability,
1294                           const DocComment &Comment,
1295                           DeclarationFragments Declaration,
1296                           DeclarationFragments SubHeading,
1297                           APIRecord::RecordKind Kind, bool IsFromSystemHeader);
1298 
1299   StaticFieldRecord *
1300   addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
1301                  AvailabilityInfo Availability, LinkageInfo Linkage,
1302                  const DocComment &Comment, DeclarationFragments Declaration,
1303                  DeclarationFragments SubHeading, SymbolReference Context,
1304                  AccessControl Access, bool IsFromSystemHeaderg);
1305 
1306   CXXFieldRecord *addCXXField(APIRecord *CXXClass, StringRef Name,
1307                               StringRef USR, PresumedLoc Loc,
1308                               AvailabilityInfo Availability,
1309                               const DocComment &Comment,
1310                               DeclarationFragments Declaration,
1311                               DeclarationFragments SubHeading,
1312                               AccessControl Access, bool IsFromSystemHeader);
1313 
1314   CXXFieldTemplateRecord *addCXXFieldTemplate(
1315       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1316       AvailabilityInfo Availability, const DocComment &Comment,
1317       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1318       AccessControl Access, Template Template, bool IsFromSystemHeader);
1319 
1320   CXXClassRecord *addCXXClass(APIRecord *Parent, StringRef Name, StringRef USR,
1321                               PresumedLoc Loc, AvailabilityInfo Availability,
1322                               const DocComment &Comment,
1323                               DeclarationFragments Declaration,
1324                               DeclarationFragments SubHeading,
1325                               APIRecord::RecordKind Kind, AccessControl Access,
1326                               bool IsFromSystemHeader);
1327 
1328   ClassTemplateRecord *
1329   addClassTemplate(APIRecord *Parent, StringRef Name, StringRef USR,
1330                    PresumedLoc Loc, AvailabilityInfo Availability,
1331                    const DocComment &Comment, DeclarationFragments Declaration,
1332                    DeclarationFragments SubHeading, Template Template,
1333                    AccessControl Access, bool IsFromSystemHeader);
1334 
1335   ClassTemplateSpecializationRecord *addClassTemplateSpecialization(
1336       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1337       AvailabilityInfo Availability, const DocComment &Comment,
1338       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1339       AccessControl Access, bool IsFromSystemHeader);
1340 
1341   ClassTemplatePartialSpecializationRecord *
1342   addClassTemplatePartialSpecialization(
1343       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1344       AvailabilityInfo Availability, const DocComment &Comment,
1345       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1346       Template Template, AccessControl Access, bool IsFromSystemHeader);
1347 
1348   GlobalVariableTemplateSpecializationRecord *
1349   addGlobalVariableTemplateSpecialization(
1350       StringRef Name, StringRef USR, PresumedLoc Loc,
1351       AvailabilityInfo Availability, LinkageInfo Linkage,
1352       const DocComment &Comment, DeclarationFragments Declaration,
1353       DeclarationFragments SubHeading, bool IsFromSystemHeader);
1354 
1355   GlobalVariableTemplatePartialSpecializationRecord *
1356   addGlobalVariableTemplatePartialSpecialization(
1357       StringRef Name, StringRef USR, PresumedLoc Loc,
1358       AvailabilityInfo Availability, LinkageInfo Linkage,
1359       const DocComment &Comment, DeclarationFragments Declaration,
1360       DeclarationFragments SubHeading, Template Template,
1361       bool IsFromSystemHeader);
1362 
1363   CXXMethodRecord *addCXXInstanceMethod(
1364       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1365       AvailabilityInfo Availability, const DocComment &Comment,
1366       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1367       FunctionSignature Signature, AccessControl Access,
1368       bool IsFromSystemHeader);
1369 
1370   CXXMethodRecord *addCXXStaticMethod(
1371       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1372       AvailabilityInfo Availability, const DocComment &Comment,
1373       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1374       FunctionSignature Signature, AccessControl Access,
1375       bool IsFromSystemHeader);
1376 
1377   CXXMethodRecord *addCXXSpecialMethod(
1378       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1379       AvailabilityInfo Availability, const DocComment &Comment,
1380       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1381       FunctionSignature Signature, AccessControl Access,
1382       bool IsFromSystemHeader);
1383 
1384   CXXMethodTemplateRecord *addCXXMethodTemplate(
1385       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1386       AvailabilityInfo Availability, const DocComment &Comment,
1387       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1388       FunctionSignature Signature, AccessControl Access, Template Template,
1389       bool IsFromSystemHeader);
1390 
1391   CXXMethodTemplateSpecializationRecord *addCXXMethodTemplateSpec(
1392       APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
1393       AvailabilityInfo Availability, const DocComment &Comment,
1394       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1395       FunctionSignature Signature, AccessControl Access,
1396       bool IsFromSystemHeader);
1397 
1398   ConceptRecord *addConcept(StringRef Name, StringRef USR, PresumedLoc Loc,
1399                             AvailabilityInfo Availability,
1400                             const DocComment &Comment,
1401                             DeclarationFragments Declaration,
1402                             DeclarationFragments SubHeading, Template Template,
1403                             bool IsFromSystemHeader);
1404 
1405   /// Create and add an Objective-C category record into the API set.
1406   ///
1407   /// Note: the caller is responsible for keeping the StringRef \p Name and
1408   /// \p USR alive. APISet::copyString provides a way to copy strings into
1409   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1410   /// to generate the USR for \c D and keep it alive in APISet.
1411   ObjCCategoryRecord *
1412   addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc,
1413                   AvailabilityInfo Availability, const DocComment &Comment,
1414                   DeclarationFragments Declaration,
1415                   DeclarationFragments SubHeading, SymbolReference Interface,
1416                   bool IsFromSystemHeader, bool IsFromExternalModule);
1417 
1418   /// Create and add an Objective-C interface record into the API set.
1419   ///
1420   /// Note: the caller is responsible for keeping the StringRef \p Name and
1421   /// \p USR alive. APISet::copyString provides a way to copy strings into
1422   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1423   /// to generate the USR for \c D and keep it alive in APISet.
1424   ObjCInterfaceRecord *
1425   addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
1426                    AvailabilityInfo Availability, LinkageInfo Linkage,
1427                    const DocComment &Comment, DeclarationFragments Declaration,
1428                    DeclarationFragments SubHeading, SymbolReference SuperClass,
1429                    bool IsFromSystemHeader);
1430 
1431   /// Create and add an Objective-C method record into the API set.
1432   ///
1433   /// Note: the caller is responsible for keeping the StringRef \p Name and
1434   /// \p USR alive. APISet::copyString provides a way to copy strings into
1435   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1436   /// to generate the USR for \c D and keep it alive in APISet.
1437   ObjCMethodRecord *
1438   addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
1439                 PresumedLoc Loc, AvailabilityInfo Availability,
1440                 const DocComment &Comment, DeclarationFragments Declaration,
1441                 DeclarationFragments SubHeading, FunctionSignature Signature,
1442                 bool IsInstanceMethod, bool IsFromSystemHeader);
1443 
1444   /// Create and add an Objective-C property record into the API set.
1445   ///
1446   /// Note: the caller is responsible for keeping the StringRef \p Name and
1447   /// \p USR alive. APISet::copyString provides a way to copy strings into
1448   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1449   /// to generate the USR for \c D and keep it alive in APISet.
1450   ObjCPropertyRecord *
1451   addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
1452                   PresumedLoc Loc, AvailabilityInfo Availability,
1453                   const DocComment &Comment, DeclarationFragments Declaration,
1454                   DeclarationFragments SubHeading,
1455                   ObjCPropertyRecord::AttributeKind Attributes,
1456                   StringRef GetterName, StringRef SetterName, bool IsOptional,
1457                   bool IsInstanceProperty, bool IsFromSystemHeader);
1458 
1459   /// Create and add an Objective-C instance variable record into the API set.
1460   ///
1461   /// Note: the caller is responsible for keeping the StringRef \p Name and
1462   /// \p USR alive. APISet::copyString provides a way to copy strings into
1463   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1464   /// to generate the USR for \c D and keep it alive in APISet.
1465   ObjCInstanceVariableRecord *addObjCInstanceVariable(
1466       ObjCContainerRecord *Container, StringRef Name, StringRef USR,
1467       PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
1468       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1469       ObjCInstanceVariableRecord::AccessControl Access,
1470       bool IsFromSystemHeader);
1471 
1472   /// Create and add an Objective-C protocol record into the API set.
1473   ///
1474   /// Note: the caller is responsible for keeping the StringRef \p Name and
1475   /// \p USR alive. APISet::copyString provides a way to copy strings into
1476   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1477   /// to generate the USR for \c D and keep it alive in APISet.
1478   ObjCProtocolRecord *
1479   addObjCProtocol(StringRef Name, StringRef USR, PresumedLoc Loc,
1480                   AvailabilityInfo Availability, const DocComment &Comment,
1481                   DeclarationFragments Declaration,
1482                   DeclarationFragments SubHeading, bool IsFromSystemHeader);
1483 
1484   /// Create a macro definition record into the API set.
1485   ///
1486   /// Note: the caller is responsible for keeping the StringRef \p Name and
1487   /// \p USR alive. APISet::copyString provides a way to copy strings into
1488   /// APISet itself, and APISet::recordUSRForMacro(StringRef Name,
1489   /// SourceLocation SL, const SourceManager &SM) is a helper method to generate
1490   /// the USR for the macro and keep it alive in APISet.
1491   MacroDefinitionRecord *addMacroDefinition(StringRef Name, StringRef USR,
1492                                             PresumedLoc Loc,
1493                                             DeclarationFragments Declaration,
1494                                             DeclarationFragments SubHeading,
1495                                             bool IsFromSystemHeader);
1496 
1497   /// Create a typedef record into the API set.
1498   ///
1499   /// Note: the caller is responsible for keeping the StringRef \p Name and
1500   /// \p USR alive. APISet::copyString provides a way to copy strings into
1501   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
1502   /// to generate the USR for \c D and keep it alive in APISet.
1503   TypedefRecord *
1504   addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
1505              AvailabilityInfo Availability, const DocComment &Comment,
1506              DeclarationFragments Declaration, DeclarationFragments SubHeading,
1507              SymbolReference UnderlyingType, bool IsFromSystemHeader);
1508 
1509   /// A mapping type to store a set of APIRecord%s with the USR as the key.
1510   template <typename RecordTy,
1511             typename =
1512                 std::enable_if_t<std::is_base_of<APIRecord, RecordTy>::value>>
1513   using RecordMap = llvm::MapVector<StringRef, std::unique_ptr<RecordTy>>;
1514 
1515   /// Get the target triple for the ExtractAPI invocation.
1516   const llvm::Triple &getTarget() const { return Target; }
1517 
1518   /// Get the language used by the APIs.
1519   Language getLanguage() const { return Lang; }
1520 
1521   const RecordMap<NamespaceRecord> &getNamespaces() const { return Namespaces; }
1522   const RecordMap<GlobalFunctionRecord> &getGlobalFunctions() const {
1523     return GlobalFunctions;
1524   }
1525   const RecordMap<GlobalFunctionTemplateRecord> &
1526   getGlobalFunctionTemplates() const {
1527     return GlobalFunctionTemplates;
1528   }
1529   const RecordMap<GlobalFunctionTemplateSpecializationRecord> &
1530   getGlobalFunctionTemplateSpecializations() const {
1531     return GlobalFunctionTemplateSpecializations;
1532   }
1533   const RecordMap<GlobalVariableRecord> &getGlobalVariables() const {
1534     return GlobalVariables;
1535   }
1536   const RecordMap<GlobalVariableTemplateRecord> &
1537   getGlobalVariableTemplates() const {
1538     return GlobalVariableTemplates;
1539   }
1540   const RecordMap<StaticFieldRecord> &getStaticFields() const {
1541     return StaticFields;
1542   }
1543   const RecordMap<GlobalVariableTemplateSpecializationRecord> &
1544   getGlobalVariableTemplateSpecializations() const {
1545     return GlobalVariableTemplateSpecializations;
1546   }
1547   const RecordMap<GlobalVariableTemplatePartialSpecializationRecord> &
1548   getGlobalVariableTemplatePartialSpecializations() const {
1549     return GlobalVariableTemplatePartialSpecializations;
1550   }
1551   const RecordMap<EnumRecord> &getEnums() const { return Enums; }
1552   const RecordMap<RecordRecord> &getRecords() const { return Records; }
1553   const RecordMap<CXXClassRecord> &getCXXClasses() const { return CXXClasses; }
1554   const RecordMap<CXXMethodTemplateRecord> &getCXXMethodTemplates() const {
1555     return CXXMethodTemplates;
1556   }
1557   const RecordMap<CXXInstanceMethodRecord> &getCXXInstanceMethods() const {
1558     return CXXInstanceMethods;
1559   }
1560   const RecordMap<CXXStaticMethodRecord> &getCXXStaticMethods() const {
1561     return CXXStaticMethods;
1562   }
1563   const RecordMap<CXXFieldRecord> &getCXXFields() const { return CXXFields; }
1564   const RecordMap<CXXMethodTemplateSpecializationRecord> &
1565   getCXXMethodTemplateSpecializations() const {
1566     return CXXMethodTemplateSpecializations;
1567   }
1568   const RecordMap<CXXFieldTemplateRecord> &getCXXFieldTemplates() const {
1569     return CXXFieldTemplates;
1570   }
1571   const RecordMap<ClassTemplateRecord> &getClassTemplates() const {
1572     return ClassTemplates;
1573   }
1574   const RecordMap<ClassTemplateSpecializationRecord> &
1575   getClassTemplateSpecializations() const {
1576     return ClassTemplateSpecializations;
1577   }
1578   const RecordMap<ClassTemplatePartialSpecializationRecord> &
1579   getClassTemplatePartialSpecializations() const {
1580     return ClassTemplatePartialSpecializations;
1581   }
1582   const RecordMap<ConceptRecord> &getConcepts() const { return Concepts; }
1583   const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
1584     return ObjCCategories;
1585   }
1586   const RecordMap<ObjCInterfaceRecord> &getObjCInterfaces() const {
1587     return ObjCInterfaces;
1588   }
1589   const RecordMap<ObjCProtocolRecord> &getObjCProtocols() const {
1590     return ObjCProtocols;
1591   }
1592   const RecordMap<MacroDefinitionRecord> &getMacros() const { return Macros; }
1593   const RecordMap<TypedefRecord> &getTypedefs() const { return Typedefs; }
1594 
1595   /// Finds the APIRecord for a given USR.
1596   ///
1597   /// \returns a pointer to the APIRecord associated with that USR or nullptr.
1598   APIRecord *findRecordForUSR(StringRef USR) const;
1599 
1600   /// Generate and store the USR of declaration \p D.
1601   ///
1602   /// Note: The USR string is stored in and owned by Allocator.
1603   ///
1604   /// \returns a StringRef of the generated USR string.
1605   StringRef recordUSR(const Decl *D);
1606 
1607   /// Generate and store the USR for a macro \p Name.
1608   ///
1609   /// Note: The USR string is stored in and owned by Allocator.
1610   ///
1611   /// \returns a StringRef to the generate USR string.
1612   StringRef recordUSRForMacro(StringRef Name, SourceLocation SL,
1613                               const SourceManager &SM);
1614 
1615   /// Copy \p String into the Allocator in this APISet.
1616   ///
1617   /// \returns a StringRef of the copied string in APISet::Allocator.
1618   StringRef copyString(StringRef String);
1619 
1620   APISet(const llvm::Triple &Target, Language Lang,
1621          const std::string &ProductName)
1622       : Target(Target), Lang(Lang), ProductName(ProductName) {}
1623 
1624 private:
1625   /// BumpPtrAllocator to store generated/copied strings.
1626   ///
1627   /// Note: The main use for this is being able to deduplicate strings.
1628   llvm::BumpPtrAllocator StringAllocator;
1629 
1630   const llvm::Triple Target;
1631   const Language Lang;
1632 
1633   llvm::DenseMap<StringRef, APIRecord *> USRBasedLookupTable;
1634   RecordMap<NamespaceRecord> Namespaces;
1635   RecordMap<GlobalFunctionRecord> GlobalFunctions;
1636   RecordMap<GlobalFunctionTemplateRecord> GlobalFunctionTemplates;
1637   RecordMap<GlobalFunctionTemplateSpecializationRecord>
1638       GlobalFunctionTemplateSpecializations;
1639   RecordMap<GlobalVariableRecord> GlobalVariables;
1640   RecordMap<GlobalVariableTemplateRecord> GlobalVariableTemplates;
1641   RecordMap<GlobalVariableTemplateSpecializationRecord>
1642       GlobalVariableTemplateSpecializations;
1643   RecordMap<GlobalVariableTemplatePartialSpecializationRecord>
1644       GlobalVariableTemplatePartialSpecializations;
1645   RecordMap<ConceptRecord> Concepts;
1646   RecordMap<StaticFieldRecord> StaticFields;
1647   RecordMap<EnumRecord> Enums;
1648   RecordMap<RecordRecord> Records;
1649   RecordMap<CXXClassRecord> CXXClasses;
1650   RecordMap<CXXFieldRecord> CXXFields;
1651   RecordMap<CXXMethodRecord> CXXMethods;
1652   RecordMap<CXXInstanceMethodRecord> CXXInstanceMethods;
1653   RecordMap<CXXStaticMethodRecord> CXXStaticMethods;
1654   RecordMap<CXXMethodTemplateRecord> CXXMethodTemplates;
1655   RecordMap<CXXMethodTemplateSpecializationRecord>
1656       CXXMethodTemplateSpecializations;
1657   RecordMap<CXXFieldTemplateRecord> CXXFieldTemplates;
1658   RecordMap<ClassTemplateRecord> ClassTemplates;
1659   RecordMap<ClassTemplateSpecializationRecord> ClassTemplateSpecializations;
1660   RecordMap<ClassTemplatePartialSpecializationRecord>
1661       ClassTemplatePartialSpecializations;
1662   RecordMap<ObjCCategoryRecord> ObjCCategories;
1663   RecordMap<ObjCInterfaceRecord> ObjCInterfaces;
1664   RecordMap<ObjCProtocolRecord> ObjCProtocols;
1665   RecordMap<MacroDefinitionRecord> Macros;
1666   RecordMap<TypedefRecord> Typedefs;
1667 
1668 public:
1669   const std::string ProductName;
1670 };
1671 
1672 } // namespace extractapi
1673 } // namespace clang
1674 
1675 #endif // LLVM_CLANG_EXTRACTAPI_API_H
1676