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