Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:53

0001 //===- ExtractAPI/API.h -----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines the APIRecord-based structs and the APISet class.
0011 ///
0012 /// Clang ExtractAPI is a tool to collect API information from a given set of
0013 /// header files. The structures in this file describe data representations of
0014 /// the API information collected for various kinds of symbols.
0015 ///
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_CLANG_EXTRACTAPI_API_H
0019 #define LLVM_CLANG_EXTRACTAPI_API_H
0020 
0021 #include "clang/AST/Availability.h"
0022 #include "clang/AST/DeclBase.h"
0023 #include "clang/AST/RawCommentList.h"
0024 #include "clang/Basic/SourceLocation.h"
0025 #include "clang/ExtractAPI/DeclarationFragments.h"
0026 #include "llvm/ADT/SmallVector.h"
0027 #include "llvm/Support/Allocator.h"
0028 #include "llvm/Support/Casting.h"
0029 #include "llvm/Support/Compiler.h"
0030 #include "llvm/TargetParser/Triple.h"
0031 #include <cstddef>
0032 #include <iterator>
0033 #include <memory>
0034 #include <optional>
0035 #include <type_traits>
0036 
0037 namespace clang {
0038 namespace extractapi {
0039 
0040 class Template {
0041   struct TemplateParameter {
0042     // "class", "typename", or concept name
0043     std::string Type;
0044     std::string Name;
0045     unsigned int Index;
0046     unsigned int Depth;
0047     bool IsParameterPack;
0048 
0049     TemplateParameter(std::string Type, std::string Name, unsigned int Index,
0050                       unsigned int Depth, bool IsParameterPack)
0051         : Type(Type), Name(Name), Index(Index), Depth(Depth),
0052           IsParameterPack(IsParameterPack) {}
0053   };
0054 
0055   struct TemplateConstraint {
0056     // type name of the constraint, if it has one
0057     std::string Type;
0058     std::string Kind;
0059     std::string LHS, RHS;
0060   };
0061   llvm::SmallVector<TemplateParameter> Parameters;
0062   llvm::SmallVector<TemplateConstraint> Constraints;
0063 
0064 public:
0065   Template() = default;
0066 
0067   Template(const TemplateDecl *Decl) {
0068     for (auto *const Parameter : *Decl->getTemplateParameters()) {
0069       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
0070       if (!Param) // some params are null
0071         continue;
0072       std::string Type;
0073       if (Param->hasTypeConstraint())
0074         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
0075       else if (Param->wasDeclaredWithTypename())
0076         Type = "typename";
0077       else
0078         Type = "class";
0079 
0080       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
0081                            Param->getDepth(), Param->isParameterPack());
0082     }
0083   }
0084 
0085   Template(const ClassTemplatePartialSpecializationDecl *Decl) {
0086     for (auto *const Parameter : *Decl->getTemplateParameters()) {
0087       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
0088       if (!Param) // some params are null
0089         continue;
0090       std::string Type;
0091       if (Param->hasTypeConstraint())
0092         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
0093       else if (Param->wasDeclaredWithTypename())
0094         Type = "typename";
0095       else
0096         Type = "class";
0097 
0098       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
0099                            Param->getDepth(), Param->isParameterPack());
0100     }
0101   }
0102 
0103   Template(const VarTemplatePartialSpecializationDecl *Decl) {
0104     for (auto *const Parameter : *Decl->getTemplateParameters()) {
0105       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
0106       if (!Param) // some params are null
0107         continue;
0108       std::string Type;
0109       if (Param->hasTypeConstraint())
0110         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
0111       else if (Param->wasDeclaredWithTypename())
0112         Type = "typename";
0113       else
0114         Type = "class";
0115 
0116       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
0117                            Param->getDepth(), Param->isParameterPack());
0118     }
0119   }
0120 
0121   const llvm::SmallVector<TemplateParameter> &getParameters() const {
0122     return Parameters;
0123   }
0124 
0125   const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
0126     return Constraints;
0127   }
0128 
0129   void addTemplateParameter(std::string Type, std::string Name,
0130                             unsigned int Index, unsigned int Depth,
0131                             bool IsParameterPack) {
0132     Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
0133   }
0134 
0135   bool empty() const { return Parameters.empty() && Constraints.empty(); }
0136 };
0137 
0138 /// DocComment is a vector of RawComment::CommentLine.
0139 ///
0140 /// Each line represents one line of striped documentation comment,
0141 /// with source range information. This simplifies calculating the source
0142 /// location of a character in the doc comment for pointing back to the source
0143 /// file.
0144 /// e.g.
0145 /// \code
0146 ///   /// This is a documentation comment
0147 ///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
0148 ///   ///     with multiple lines.
0149 ///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
0150 /// \endcode
0151 using DocComment = std::vector<RawComment::CommentLine>;
0152 
0153 struct APIRecord;
0154 
0155 // This represents a reference to another symbol that might come from external
0156 /// sources.
0157 struct SymbolReference {
0158   StringRef Name;
0159   StringRef USR;
0160 
0161   /// The source project/module/product of the referred symbol.
0162   StringRef Source;
0163 
0164   // A Pointer to the APIRecord for this reference if known
0165   const APIRecord *Record = nullptr;
0166 
0167   SymbolReference() = default;
0168   SymbolReference(StringRef Name, StringRef USR, StringRef Source = "")
0169       : Name(Name), USR(USR), Source(Source) {}
0170   SymbolReference(const APIRecord *R);
0171 
0172   /// Determine if this SymbolReference is empty.
0173   ///
0174   /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
0175   bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
0176 };
0177 
0178 class RecordContext;
0179 
0180 // Concrete classes deriving from APIRecord need to have a construct with first
0181 // arguments USR, and Name, in that order. This is so that they
0182 // are compatible with `APISet::createRecord`.
0183 // When adding a new kind of record don't forget to update APIRecords.inc!
0184 /// The base representation of an API record. Holds common symbol information.
0185 struct APIRecord {
0186   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
0187   enum RecordKind {
0188     RK_Unknown,
0189     // If adding a record context record kind here make sure to update
0190     // RecordContext::classof if needed and add a RECORD_CONTEXT entry to
0191     // APIRecords.inc
0192     RK_FirstRecordContext,
0193     RK_Namespace,
0194     RK_Enum,
0195     RK_Struct,
0196     RK_Union,
0197     RK_ObjCInterface,
0198     RK_ObjCCategory,
0199     RK_ObjCProtocol,
0200     RK_CXXClass,
0201     RK_ClassTemplate,
0202     RK_ClassTemplateSpecialization,
0203     RK_ClassTemplatePartialSpecialization,
0204     RK_StructField,
0205     RK_UnionField,
0206     RK_CXXField,
0207     RK_StaticField,
0208     RK_CXXFieldTemplate,
0209     RK_GlobalVariable,
0210     RK_GlobalVariableTemplate,
0211     RK_GlobalVariableTemplateSpecialization,
0212     RK_GlobalVariableTemplatePartialSpecialization,
0213     RK_LastRecordContext,
0214     RK_GlobalFunction,
0215     RK_GlobalFunctionTemplate,
0216     RK_GlobalFunctionTemplateSpecialization,
0217     RK_EnumConstant,
0218     RK_Concept,
0219     RK_CXXStaticMethod,
0220     RK_CXXInstanceMethod,
0221     RK_CXXConstructorMethod,
0222     RK_CXXDestructorMethod,
0223     RK_CXXMethodTemplate,
0224     RK_CXXMethodTemplateSpecialization,
0225     RK_ObjCInstanceProperty,
0226     RK_ObjCClassProperty,
0227     RK_ObjCIvar,
0228     RK_ObjCClassMethod,
0229     RK_ObjCInstanceMethod,
0230     RK_MacroDefinition,
0231     RK_Typedef,
0232   };
0233 
0234   StringRef USR;
0235   StringRef Name;
0236 
0237   SymbolReference Parent;
0238 
0239   PresumedLoc Location;
0240   AvailabilityInfo Availability;
0241   LinkageInfo Linkage;
0242 
0243   /// Documentation comment lines attached to this symbol declaration.
0244   DocComment Comment;
0245 
0246   /// Declaration fragments of this symbol declaration.
0247   DeclarationFragments Declaration;
0248 
0249   /// SubHeading provides a more detailed representation than the plain
0250   /// declaration name.
0251   ///
0252   /// SubHeading is an array of declaration fragments of tagged declaration
0253   /// name, with potentially more tokens (for example the \c +/- symbol for
0254   /// Objective-C class/instance methods).
0255   DeclarationFragments SubHeading;
0256 
0257   /// Whether the symbol was defined in a system header.
0258   bool IsFromSystemHeader;
0259 
0260   AccessControl Access;
0261 
0262   RecordKind KindForDisplay;
0263 
0264 private:
0265   const RecordKind Kind;
0266   friend class RecordContext;
0267   // Used to store the next child record in RecordContext. This works because
0268   // APIRecords semantically only have one parent.
0269   mutable APIRecord *NextInContext = nullptr;
0270 
0271 public:
0272   APIRecord *getNextInContext() const { return NextInContext; }
0273 
0274   RecordKind getKind() const { return Kind; }
0275   RecordKind getKindForDisplay() const { return KindForDisplay; }
0276 
0277   static APIRecord *castFromRecordContext(const RecordContext *Ctx);
0278   static RecordContext *castToRecordContext(const APIRecord *Record);
0279 
0280   APIRecord() = delete;
0281 
0282   APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
0283             SymbolReference Parent, PresumedLoc Location,
0284             AvailabilityInfo Availability, LinkageInfo Linkage,
0285             const DocComment &Comment, DeclarationFragments Declaration,
0286             DeclarationFragments SubHeading, bool IsFromSystemHeader,
0287             AccessControl Access = AccessControl())
0288       : USR(USR), Name(Name), Parent(std::move(Parent)), Location(Location),
0289         Availability(std::move(Availability)), Linkage(Linkage),
0290         Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
0291         IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
0292         KindForDisplay(Kind), Kind(Kind) {}
0293 
0294   APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
0295       : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {}
0296 
0297   // Pure virtual destructor to make APIRecord abstract
0298   virtual ~APIRecord() = 0;
0299   static bool classof(const APIRecord *Record) { return true; }
0300   static bool classofKind(RecordKind K) { return true; }
0301   static bool classof(const RecordContext *Ctx) { return true; }
0302 };
0303 
0304 /// Base class used for specific record types that have children records this is
0305 /// analogous to the DeclContext for the AST
0306 class RecordContext {
0307 public:
0308   static bool classof(const APIRecord *Record) {
0309     return classofKind(Record->getKind());
0310   }
0311   static bool classofKind(APIRecord::RecordKind K) {
0312     return K > APIRecord::RK_FirstRecordContext &&
0313            K < APIRecord::RK_LastRecordContext;
0314   }
0315 
0316   static bool classof(const RecordContext *Context) { return true; }
0317 
0318   RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
0319 
0320   /// Append \p Other children chain into ours and empty out Other's record
0321   /// chain.
0322   void stealRecordChain(RecordContext &Other);
0323 
0324   void removeFromRecordChain(APIRecord *Record);
0325 
0326   APIRecord::RecordKind getKind() const { return Kind; }
0327 
0328   struct record_iterator {
0329   private:
0330     APIRecord *Current = nullptr;
0331 
0332   public:
0333     using value_type = APIRecord *;
0334     using reference = const value_type &;
0335     using pointer = const value_type *;
0336     using iterator_category = std::forward_iterator_tag;
0337     using difference_type = std::ptrdiff_t;
0338 
0339     record_iterator() = default;
0340     explicit record_iterator(value_type R) : Current(R) {}
0341     reference operator*() const { return Current; }
0342     // This doesn't strictly meet the iterator requirements, but it's the
0343     // behavior we want here.
0344     value_type operator->() const { return Current; }
0345     record_iterator &operator++() {
0346       Current = Current->getNextInContext();
0347       return *this;
0348     }
0349     record_iterator operator++(int) {
0350       record_iterator tmp(*this);
0351       ++(*this);
0352       return tmp;
0353     }
0354 
0355     friend bool operator==(record_iterator x, record_iterator y) {
0356       return x.Current == y.Current;
0357     }
0358     friend bool operator!=(record_iterator x, record_iterator y) {
0359       return x.Current != y.Current;
0360     }
0361   };
0362 
0363   using record_range = llvm::iterator_range<record_iterator>;
0364   record_range records() const {
0365     return record_range(records_begin(), records_end());
0366   }
0367   record_iterator records_begin() const { return record_iterator(First); };
0368   record_iterator records_end() const { return record_iterator(); }
0369   bool records_empty() const { return First == nullptr; };
0370 
0371 private:
0372   APIRecord::RecordKind Kind;
0373   mutable APIRecord *First = nullptr;
0374   mutable APIRecord *Last = nullptr;
0375   bool IsWellFormed() const;
0376 
0377 protected:
0378   friend class APISet;
0379   void addToRecordChain(APIRecord *) const;
0380 };
0381 
0382 struct NamespaceRecord : APIRecord, RecordContext {
0383   NamespaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0384                   PresumedLoc Loc, AvailabilityInfo Availability,
0385                   LinkageInfo Linkage, const DocComment &Comment,
0386                   DeclarationFragments Declaration,
0387                   DeclarationFragments SubHeading, bool IsFromSystemHeader)
0388       : APIRecord(RK_Namespace, USR, Name, Parent, Loc, std::move(Availability),
0389                   Linkage, Comment, Declaration, SubHeading,
0390                   IsFromSystemHeader),
0391         RecordContext(RK_Namespace) {}
0392 
0393   static bool classof(const APIRecord *Record) {
0394     return classofKind(Record->getKind());
0395   }
0396   static bool classofKind(RecordKind K) { return K == RK_Namespace; }
0397 };
0398 
0399 /// This holds information associated with global functions.
0400 struct GlobalFunctionRecord : APIRecord {
0401   FunctionSignature Signature;
0402 
0403   GlobalFunctionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0404                        PresumedLoc Loc, AvailabilityInfo Availability,
0405                        LinkageInfo Linkage, const DocComment &Comment,
0406                        DeclarationFragments Declaration,
0407                        DeclarationFragments SubHeading,
0408                        FunctionSignature Signature, bool IsFromSystemHeader)
0409       : APIRecord(RK_GlobalFunction, USR, Name, Parent, Loc,
0410                   std::move(Availability), Linkage, Comment, Declaration,
0411                   SubHeading, IsFromSystemHeader),
0412         Signature(Signature) {}
0413 
0414   GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
0415                        SymbolReference Parent, PresumedLoc Loc,
0416                        AvailabilityInfo Availability, LinkageInfo Linkage,
0417                        const DocComment &Comment,
0418                        DeclarationFragments Declaration,
0419                        DeclarationFragments SubHeading,
0420                        FunctionSignature Signature, bool IsFromSystemHeader)
0421       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0422                   Linkage, Comment, Declaration, SubHeading,
0423                   IsFromSystemHeader),
0424         Signature(Signature) {}
0425 
0426   static bool classof(const APIRecord *Record) {
0427     return classofKind(Record->getKind());
0428   }
0429   static bool classofKind(RecordKind K) { return K == RK_GlobalFunction; }
0430 
0431 private:
0432   virtual void anchor();
0433 };
0434 
0435 struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
0436   Template Templ;
0437 
0438   GlobalFunctionTemplateRecord(StringRef USR, StringRef Name,
0439                                SymbolReference Parent, PresumedLoc Loc,
0440                                AvailabilityInfo Availability,
0441                                LinkageInfo Linkage, const DocComment &Comment,
0442                                DeclarationFragments Declaration,
0443                                DeclarationFragments SubHeading,
0444                                FunctionSignature Signature, Template Template,
0445                                bool IsFromSystemHeader)
0446       : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Parent, Loc,
0447                              std::move(Availability), Linkage, Comment,
0448                              Declaration, SubHeading, Signature,
0449                              IsFromSystemHeader),
0450         Templ(Template) {}
0451 
0452   static bool classof(const APIRecord *Record) {
0453     return classofKind(Record->getKind());
0454   }
0455   static bool classofKind(RecordKind K) {
0456     return K == RK_GlobalFunctionTemplate;
0457   }
0458 };
0459 
0460 struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
0461   GlobalFunctionTemplateSpecializationRecord(
0462       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
0463       AvailabilityInfo Availability, LinkageInfo Linkage,
0464       const DocComment &Comment, DeclarationFragments Declaration,
0465       DeclarationFragments SubHeading, FunctionSignature Signature,
0466       bool IsFromSystemHeader)
0467       : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
0468                              Parent, Loc, std::move(Availability), Linkage,
0469                              Comment, Declaration, SubHeading, Signature,
0470                              IsFromSystemHeader) {}
0471 
0472   static bool classof(const APIRecord *Record) {
0473     return classofKind(Record->getKind());
0474   }
0475   static bool classofKind(RecordKind K) {
0476     return K == RK_GlobalFunctionTemplateSpecialization;
0477   }
0478 };
0479 
0480 /// This holds information associated with global functions.
0481 struct GlobalVariableRecord : APIRecord, RecordContext {
0482   GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0483                        PresumedLoc Loc, AvailabilityInfo Availability,
0484                        LinkageInfo Linkage, const DocComment &Comment,
0485                        DeclarationFragments Declaration,
0486                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
0487       : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
0488                   std::move(Availability), Linkage, Comment, Declaration,
0489                   SubHeading, IsFromSystemHeader),
0490         RecordContext(RK_GlobalVariable) {}
0491 
0492   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
0493                        SymbolReference Parent, PresumedLoc Loc,
0494                        AvailabilityInfo Availability, LinkageInfo Linkage,
0495                        const DocComment &Comment,
0496                        DeclarationFragments Declaration,
0497                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
0498       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0499                   Linkage, Comment, Declaration, SubHeading,
0500                   IsFromSystemHeader),
0501         RecordContext(Kind) {}
0502 
0503   static bool classof(const APIRecord *Record) {
0504     return classofKind(Record->getKind());
0505   }
0506   static bool classofKind(RecordKind K) {
0507     return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
0508            K == RK_GlobalVariableTemplateSpecialization ||
0509            K == RK_GlobalVariableTemplatePartialSpecialization;
0510   }
0511 
0512 private:
0513   virtual void anchor();
0514 };
0515 
0516 struct GlobalVariableTemplateRecord : GlobalVariableRecord {
0517   Template Templ;
0518 
0519   GlobalVariableTemplateRecord(StringRef USR, StringRef Name,
0520                                SymbolReference Parent, PresumedLoc Loc,
0521                                AvailabilityInfo Availability,
0522                                LinkageInfo Linkage, const DocComment &Comment,
0523                                DeclarationFragments Declaration,
0524                                DeclarationFragments SubHeading,
0525                                class Template Template, bool IsFromSystemHeader)
0526       : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Parent, Loc,
0527                              std::move(Availability), Linkage, Comment,
0528                              Declaration, SubHeading, IsFromSystemHeader),
0529         Templ(Template) {}
0530 
0531   static bool classof(const APIRecord *Record) {
0532     return classofKind(Record->getKind());
0533   }
0534   static bool classofKind(RecordKind K) {
0535     return K == RK_GlobalVariableTemplate;
0536   }
0537 };
0538 
0539 struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
0540   GlobalVariableTemplateSpecializationRecord(
0541       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
0542       AvailabilityInfo Availability, LinkageInfo Linkage,
0543       const DocComment &Comment, DeclarationFragments Declaration,
0544       DeclarationFragments SubHeading, bool IsFromSystemHeader)
0545       : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
0546                              Parent, Loc, std::move(Availability), Linkage,
0547                              Comment, Declaration, SubHeading,
0548                              IsFromSystemHeader) {}
0549 
0550   static bool classof(const APIRecord *Record) {
0551     return classofKind(Record->getKind());
0552   }
0553   static bool classofKind(RecordKind K) {
0554     return K == RK_GlobalVariableTemplateSpecialization;
0555   }
0556 };
0557 
0558 struct GlobalVariableTemplatePartialSpecializationRecord
0559     : GlobalVariableRecord {
0560   Template Templ;
0561 
0562   GlobalVariableTemplatePartialSpecializationRecord(
0563       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
0564       AvailabilityInfo Availability, LinkageInfo Linkage,
0565       const DocComment &Comment, DeclarationFragments Declaration,
0566       DeclarationFragments SubHeading, class Template Template,
0567       bool IsFromSystemHeader)
0568       : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
0569                              USR, Name, Parent, Loc, std::move(Availability),
0570                              Linkage, Comment, Declaration, SubHeading,
0571                              IsFromSystemHeader),
0572         Templ(Template) {}
0573 
0574   static bool classof(const APIRecord *Record) {
0575     return classofKind(Record->getKind());
0576   }
0577   static bool classofKind(RecordKind K) {
0578     return K == RK_GlobalVariableTemplatePartialSpecialization;
0579   }
0580 };
0581 
0582 /// This holds information associated with enum constants.
0583 struct EnumConstantRecord : APIRecord {
0584   EnumConstantRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0585                      PresumedLoc Loc, AvailabilityInfo Availability,
0586                      const DocComment &Comment,
0587                      DeclarationFragments Declaration,
0588                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
0589       : APIRecord(RK_EnumConstant, USR, Name, Parent, Loc,
0590                   std::move(Availability), LinkageInfo::none(), Comment,
0591                   Declaration, SubHeading, IsFromSystemHeader) {}
0592 
0593   static bool classof(const APIRecord *Record) {
0594     return classofKind(Record->getKind());
0595   }
0596   static bool classofKind(RecordKind K) { return K == RK_EnumConstant; }
0597 
0598 private:
0599   virtual void anchor();
0600 };
0601 
0602 struct TagRecord : APIRecord, RecordContext {
0603   TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
0604             SymbolReference Parent, PresumedLoc Loc,
0605             AvailabilityInfo Availability, const DocComment &Comment,
0606             DeclarationFragments Declaration, DeclarationFragments SubHeading,
0607             bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
0608             AccessControl Access = AccessControl())
0609       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0610                   LinkageInfo::none(), Comment, Declaration, SubHeading,
0611                   IsFromSystemHeader, std::move(Access)),
0612         RecordContext(Kind),
0613         IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};
0614 
0615   static bool classof(const APIRecord *Record) {
0616     return classofKind(Record->getKind());
0617   }
0618   static bool classofKind(RecordKind K) {
0619     switch (K) {
0620     case RK_Enum:
0621       LLVM_FALLTHROUGH;
0622     case RK_Struct:
0623       LLVM_FALLTHROUGH;
0624     case RK_Union:
0625       LLVM_FALLTHROUGH;
0626     case RK_CXXClass:
0627       LLVM_FALLTHROUGH;
0628     case RK_ClassTemplate:
0629       LLVM_FALLTHROUGH;
0630     case RK_ClassTemplateSpecialization:
0631       LLVM_FALLTHROUGH;
0632     case RK_ClassTemplatePartialSpecialization:
0633       return true;
0634     default:
0635       return false;
0636     }
0637   }
0638 
0639   bool IsEmbeddedInVarDeclarator;
0640 
0641   virtual ~TagRecord() = 0;
0642 };
0643 
0644 /// This holds information associated with enums.
0645 struct EnumRecord : TagRecord {
0646   EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0647              PresumedLoc Loc, AvailabilityInfo Availability,
0648              const DocComment &Comment, DeclarationFragments Declaration,
0649              DeclarationFragments SubHeading, bool IsFromSystemHeader,
0650              bool IsEmbeddedInVarDeclarator,
0651              AccessControl Access = AccessControl())
0652       : TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
0653                   Comment, Declaration, SubHeading, IsFromSystemHeader,
0654                   IsEmbeddedInVarDeclarator, std::move(Access)) {}
0655 
0656   static bool classof(const APIRecord *Record) {
0657     return classofKind(Record->getKind());
0658   }
0659 
0660   static bool classofKind(RecordKind K) { return K == RK_Enum; }
0661 
0662 private:
0663   virtual void anchor();
0664 };
0665 
0666 /// This holds information associated with struct or union fields fields.
0667 struct RecordFieldRecord : APIRecord, RecordContext {
0668   RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
0669                     SymbolReference Parent, PresumedLoc Loc,
0670                     AvailabilityInfo Availability, const DocComment &Comment,
0671                     DeclarationFragments Declaration,
0672                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
0673       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0674                   LinkageInfo::none(), Comment, Declaration, SubHeading,
0675                   IsFromSystemHeader),
0676         RecordContext(Kind) {}
0677 
0678   static bool classof(const APIRecord *Record) {
0679     return classofKind(Record->getKind());
0680   }
0681   static bool classofKind(RecordKind K) {
0682     return K == RK_StructField || K == RK_UnionField;
0683   }
0684 
0685   virtual ~RecordFieldRecord() = 0;
0686 };
0687 
0688 /// This holds information associated with structs and unions.
0689 struct RecordRecord : TagRecord {
0690   RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
0691                SymbolReference Parent, PresumedLoc Loc,
0692                AvailabilityInfo Availability, const DocComment &Comment,
0693                DeclarationFragments Declaration,
0694                DeclarationFragments SubHeading, bool IsFromSystemHeader,
0695                bool IsEmbeddedInVarDeclarator,
0696                AccessControl Access = AccessControl())
0697       : TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0698                   Comment, Declaration, SubHeading, IsFromSystemHeader,
0699                   IsEmbeddedInVarDeclarator, std::move(Access)) {}
0700 
0701   static bool classof(const APIRecord *Record) {
0702     return classofKind(Record->getKind());
0703   }
0704   static bool classofKind(RecordKind K) {
0705     switch (K) {
0706     case RK_Struct:
0707       LLVM_FALLTHROUGH;
0708     case RK_Union:
0709       LLVM_FALLTHROUGH;
0710     case RK_CXXClass:
0711       LLVM_FALLTHROUGH;
0712     case RK_ClassTemplate:
0713       LLVM_FALLTHROUGH;
0714     case RK_ClassTemplateSpecialization:
0715       LLVM_FALLTHROUGH;
0716     case RK_ClassTemplatePartialSpecialization:
0717       return true;
0718     default:
0719       return false;
0720     }
0721   }
0722 
0723   bool isAnonymousWithNoTypedef() { return Name.empty(); }
0724 
0725   virtual ~RecordRecord() = 0;
0726 };
0727 
0728 struct StructFieldRecord : RecordFieldRecord {
0729   StructFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0730                     PresumedLoc Loc, AvailabilityInfo Availability,
0731                     const DocComment &Comment, DeclarationFragments Declaration,
0732                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
0733       : RecordFieldRecord(RK_StructField, USR, Name, Parent, Loc,
0734                           std::move(Availability), Comment, Declaration,
0735                           SubHeading, IsFromSystemHeader) {}
0736 
0737   static bool classof(const APIRecord *Record) {
0738     return classofKind(Record->getKind());
0739   }
0740   static bool classofKind(RecordKind K) { return K == RK_StructField; }
0741 
0742 private:
0743   virtual void anchor();
0744 };
0745 
0746 struct StructRecord : RecordRecord {
0747   StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0748                PresumedLoc Loc, AvailabilityInfo Availability,
0749                const DocComment &Comment, DeclarationFragments Declaration,
0750                DeclarationFragments SubHeading, bool IsFromSystemHeader,
0751                bool IsEmbeddedInVarDeclarator)
0752       : RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
0753                      Comment, Declaration, SubHeading, IsFromSystemHeader,
0754                      IsEmbeddedInVarDeclarator) {}
0755 
0756   static bool classof(const APIRecord *Record) {
0757     return classofKind(Record->getKind());
0758   }
0759   static bool classofKind(RecordKind K) { return K == RK_Struct; }
0760 
0761 private:
0762   virtual void anchor();
0763 };
0764 
0765 struct UnionFieldRecord : RecordFieldRecord {
0766   UnionFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0767                    PresumedLoc Loc, AvailabilityInfo Availability,
0768                    const DocComment &Comment, DeclarationFragments Declaration,
0769                    DeclarationFragments SubHeading, bool IsFromSystemHeader)
0770       : RecordFieldRecord(RK_UnionField, USR, Name, Parent, Loc,
0771                           std::move(Availability), Comment, Declaration,
0772                           SubHeading, IsFromSystemHeader) {}
0773 
0774   static bool classof(const APIRecord *Record) {
0775     return classofKind(Record->getKind());
0776   }
0777   static bool classofKind(RecordKind K) { return K == RK_UnionField; }
0778 
0779 private:
0780   virtual void anchor();
0781 };
0782 
0783 struct UnionRecord : RecordRecord {
0784   UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0785               PresumedLoc Loc, AvailabilityInfo Availability,
0786               const DocComment &Comment, DeclarationFragments Declaration,
0787               DeclarationFragments SubHeading, bool IsFromSystemHeader,
0788               bool IsEmbeddedInVarDeclarator)
0789       : RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
0790                      Comment, Declaration, SubHeading, IsFromSystemHeader,
0791                      IsEmbeddedInVarDeclarator) {}
0792 
0793   static bool classof(const APIRecord *Record) {
0794     return classofKind(Record->getKind());
0795   }
0796   static bool classofKind(RecordKind K) { return K == RK_Union; }
0797 
0798 private:
0799   virtual void anchor();
0800 };
0801 
0802 struct CXXFieldRecord : APIRecord, RecordContext {
0803   CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0804                  PresumedLoc Loc, AvailabilityInfo Availability,
0805                  const DocComment &Comment, DeclarationFragments Declaration,
0806                  DeclarationFragments SubHeading, AccessControl Access,
0807                  bool IsFromSystemHeader)
0808       : APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
0809                   LinkageInfo::none(), Comment, Declaration, SubHeading,
0810                   IsFromSystemHeader, std::move(Access)),
0811         RecordContext(RK_CXXField) {}
0812 
0813   CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
0814                  SymbolReference Parent, PresumedLoc Loc,
0815                  AvailabilityInfo Availability, const DocComment &Comment,
0816                  DeclarationFragments Declaration,
0817                  DeclarationFragments SubHeading, AccessControl Access,
0818                  bool IsFromSystemHeader)
0819       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0820                   LinkageInfo::none(), Comment, Declaration, SubHeading,
0821                   IsFromSystemHeader, std::move(Access)),
0822         RecordContext(Kind) {}
0823 
0824   static bool classof(const APIRecord *Record) {
0825     return classofKind(Record->getKind());
0826   }
0827   static bool classofKind(RecordKind K) {
0828     return K == RK_CXXField || K == RK_CXXFieldTemplate || K == RK_StaticField;
0829   }
0830 
0831 private:
0832   virtual void anchor();
0833 };
0834 
0835 struct CXXFieldTemplateRecord : CXXFieldRecord {
0836   Template Templ;
0837 
0838   CXXFieldTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0839                          PresumedLoc Loc, AvailabilityInfo Availability,
0840                          const DocComment &Comment,
0841                          DeclarationFragments Declaration,
0842                          DeclarationFragments SubHeading, AccessControl Access,
0843                          Template Template, bool IsFromSystemHeader)
0844       : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Parent, Loc,
0845                        std::move(Availability), Comment, Declaration,
0846                        SubHeading, std::move(Access), IsFromSystemHeader),
0847         Templ(Template) {}
0848 
0849   static bool classof(const APIRecord *Record) {
0850     return classofKind(Record->getKind());
0851   }
0852   static bool classofKind(RecordKind K) { return K == RK_CXXFieldTemplate; }
0853 };
0854 
0855 struct CXXMethodRecord : APIRecord {
0856   FunctionSignature Signature;
0857 
0858   CXXMethodRecord() = delete;
0859 
0860   CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
0861                   SymbolReference Parent, PresumedLoc Loc,
0862                   AvailabilityInfo Availability, const DocComment &Comment,
0863                   DeclarationFragments Declaration,
0864                   DeclarationFragments SubHeading, FunctionSignature Signature,
0865                   AccessControl Access, bool IsFromSystemHeader)
0866       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
0867                   LinkageInfo::none(), Comment, Declaration, SubHeading,
0868                   IsFromSystemHeader, std::move(Access)),
0869         Signature(Signature) {}
0870 
0871   virtual ~CXXMethodRecord() = 0;
0872 };
0873 
0874 struct CXXConstructorRecord : CXXMethodRecord {
0875   CXXConstructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0876                        PresumedLoc Loc, AvailabilityInfo Availability,
0877                        const DocComment &Comment,
0878                        DeclarationFragments Declaration,
0879                        DeclarationFragments SubHeading,
0880                        FunctionSignature Signature, AccessControl Access,
0881                        bool IsFromSystemHeader)
0882       : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Parent, Loc,
0883                         std::move(Availability), Comment, Declaration,
0884                         SubHeading, Signature, std::move(Access),
0885                         IsFromSystemHeader) {}
0886   static bool classof(const APIRecord *Record) {
0887     return classofKind(Record->getKind());
0888   }
0889   static bool classofKind(RecordKind K) { return K == RK_CXXConstructorMethod; }
0890 
0891 private:
0892   virtual void anchor();
0893 };
0894 
0895 struct CXXDestructorRecord : CXXMethodRecord {
0896   CXXDestructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0897                       PresumedLoc Loc, AvailabilityInfo Availability,
0898                       const DocComment &Comment,
0899                       DeclarationFragments Declaration,
0900                       DeclarationFragments SubHeading,
0901                       FunctionSignature Signature, AccessControl Access,
0902                       bool IsFromSystemHeader)
0903       : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Parent, Loc,
0904                         std::move(Availability), Comment, Declaration,
0905                         SubHeading, Signature, std::move(Access),
0906                         IsFromSystemHeader) {}
0907   static bool classof(const APIRecord *Record) {
0908     return classofKind(Record->getKind());
0909   }
0910   static bool classofKind(RecordKind K) { return K == RK_CXXDestructorMethod; }
0911 
0912 private:
0913   virtual void anchor();
0914 };
0915 
0916 struct CXXStaticMethodRecord : CXXMethodRecord {
0917   CXXStaticMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0918                         PresumedLoc Loc, AvailabilityInfo Availability,
0919                         const DocComment &Comment,
0920                         DeclarationFragments Declaration,
0921                         DeclarationFragments SubHeading,
0922                         FunctionSignature Signature, AccessControl Access,
0923                         bool IsFromSystemHeader)
0924       : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Parent, Loc,
0925                         std::move(Availability), Comment, Declaration,
0926                         SubHeading, Signature, std::move(Access),
0927                         IsFromSystemHeader) {}
0928   static bool classof(const APIRecord *Record) {
0929     return classofKind(Record->getKind());
0930   }
0931   static bool classofKind(RecordKind K) { return K == RK_CXXStaticMethod; }
0932 
0933 private:
0934   virtual void anchor();
0935 };
0936 
0937 struct CXXInstanceMethodRecord : CXXMethodRecord {
0938   CXXInstanceMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0939                           PresumedLoc Loc, AvailabilityInfo Availability,
0940                           const DocComment &Comment,
0941                           DeclarationFragments Declaration,
0942                           DeclarationFragments SubHeading,
0943                           FunctionSignature Signature, AccessControl Access,
0944                           bool IsFromSystemHeader)
0945       : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Parent, Loc,
0946                         std::move(Availability), Comment, Declaration,
0947                         SubHeading, Signature, std::move(Access),
0948                         IsFromSystemHeader) {}
0949 
0950   static bool classof(const APIRecord *Record) {
0951     return classofKind(Record->getKind());
0952   }
0953   static bool classofKind(RecordKind K) { return K == RK_CXXInstanceMethod; }
0954 
0955 private:
0956   virtual void anchor();
0957 };
0958 
0959 struct CXXMethodTemplateRecord : CXXMethodRecord {
0960   Template Templ;
0961 
0962   CXXMethodTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
0963                           PresumedLoc Loc, AvailabilityInfo Availability,
0964                           const DocComment &Comment,
0965                           DeclarationFragments Declaration,
0966                           DeclarationFragments SubHeading,
0967                           FunctionSignature Signature, AccessControl Access,
0968                           Template Template, bool IsFromSystemHeader)
0969       : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Parent, Loc,
0970                         std::move(Availability), Comment, Declaration,
0971                         SubHeading, Signature, std::move(Access),
0972                         IsFromSystemHeader),
0973         Templ(Template) {}
0974 
0975   static bool classof(const APIRecord *Record) {
0976     return classofKind(Record->getKind());
0977   }
0978   static bool classofKind(RecordKind K) { return K == RK_CXXMethodTemplate; }
0979 };
0980 
0981 struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
0982   CXXMethodTemplateSpecializationRecord(
0983       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
0984       AvailabilityInfo Availability, const DocComment &Comment,
0985       DeclarationFragments Declaration, DeclarationFragments SubHeading,
0986       FunctionSignature Signature, AccessControl Access,
0987       bool IsFromSystemHeader)
0988       : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Parent,
0989                         Loc, std::move(Availability), Comment, Declaration,
0990                         SubHeading, Signature, std::move(Access),
0991                         IsFromSystemHeader) {}
0992 
0993   static bool classof(const APIRecord *Record) {
0994     return classofKind(Record->getKind());
0995   }
0996   static bool classofKind(RecordKind K) {
0997     return K == RK_CXXMethodTemplateSpecialization;
0998   }
0999 };
1000 
1001 /// This holds information associated with Objective-C properties.
1002 struct ObjCPropertyRecord : APIRecord {
1003   /// The attributes associated with an Objective-C property.
1004   enum AttributeKind : unsigned {
1005     NoAttr = 0,
1006     ReadOnly = 1,
1007     Dynamic = 1 << 2,
1008   };
1009 
1010   AttributeKind Attributes;
1011   StringRef GetterName;
1012   StringRef SetterName;
1013   bool IsOptional;
1014 
1015   ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
1016                      SymbolReference Parent, PresumedLoc Loc,
1017                      AvailabilityInfo Availability, const DocComment &Comment,
1018                      DeclarationFragments Declaration,
1019                      DeclarationFragments SubHeading, AttributeKind Attributes,
1020                      StringRef GetterName, StringRef SetterName,
1021                      bool IsOptional, bool IsFromSystemHeader)
1022       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1023                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1024                   IsFromSystemHeader),
1025         Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
1026         IsOptional(IsOptional) {}
1027 
1028   bool isReadOnly() const { return Attributes & ReadOnly; }
1029   bool isDynamic() const { return Attributes & Dynamic; }
1030 
1031   virtual ~ObjCPropertyRecord() = 0;
1032 };
1033 
1034 struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
1035   ObjCInstancePropertyRecord(
1036       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1037       AvailabilityInfo Availability, const DocComment &Comment,
1038       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1039       AttributeKind Attributes, StringRef GetterName, StringRef SetterName,
1040       bool IsOptional, bool IsFromSystemHeader)
1041       : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Parent, Loc,
1042                            std::move(Availability), Comment, Declaration,
1043                            SubHeading, Attributes, GetterName, SetterName,
1044                            IsOptional, IsFromSystemHeader) {}
1045 
1046   static bool classof(const APIRecord *Record) {
1047     return classofKind(Record->getKind());
1048   }
1049   static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceProperty; }
1050 
1051 private:
1052   virtual void anchor();
1053 };
1054 
1055 struct ObjCClassPropertyRecord : ObjCPropertyRecord {
1056   ObjCClassPropertyRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1057                           PresumedLoc Loc, AvailabilityInfo Availability,
1058                           const DocComment &Comment,
1059                           DeclarationFragments Declaration,
1060                           DeclarationFragments SubHeading,
1061                           AttributeKind Attributes, StringRef GetterName,
1062                           StringRef SetterName, bool IsOptional,
1063                           bool IsFromSystemHeader)
1064       : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Parent, Loc,
1065                            std::move(Availability), Comment, Declaration,
1066                            SubHeading, Attributes, GetterName, SetterName,
1067                            IsOptional, IsFromSystemHeader) {}
1068 
1069   static bool classof(const APIRecord *Record) {
1070     return classofKind(Record->getKind());
1071   }
1072   static bool classofKind(RecordKind K) { return K == RK_ObjCClassProperty; }
1073 
1074 private:
1075   virtual void anchor();
1076 };
1077 
1078 /// This holds information associated with Objective-C instance variables.
1079 struct ObjCInstanceVariableRecord : APIRecord {
1080   ObjCInstanceVariableRecord(StringRef USR, StringRef Name,
1081                              SymbolReference Parent, PresumedLoc Loc,
1082                              AvailabilityInfo Availability,
1083                              const DocComment &Comment,
1084                              DeclarationFragments Declaration,
1085                              DeclarationFragments SubHeading,
1086                              bool IsFromSystemHeader)
1087       : APIRecord(RK_ObjCIvar, USR, Name, Parent, Loc, std::move(Availability),
1088                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1089                   IsFromSystemHeader) {}
1090 
1091   static bool classof(const APIRecord *Record) {
1092     return classofKind(Record->getKind());
1093   }
1094   static bool classofKind(RecordKind K) { return K == RK_ObjCIvar; }
1095 
1096 private:
1097   virtual void anchor();
1098 };
1099 
1100 /// This holds information associated with Objective-C methods.
1101 struct ObjCMethodRecord : APIRecord {
1102   FunctionSignature Signature;
1103 
1104   ObjCMethodRecord() = delete;
1105 
1106   ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
1107                    SymbolReference Parent, PresumedLoc Loc,
1108                    AvailabilityInfo Availability, const DocComment &Comment,
1109                    DeclarationFragments Declaration,
1110                    DeclarationFragments SubHeading, FunctionSignature Signature,
1111                    bool IsFromSystemHeader)
1112       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1113                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1114                   IsFromSystemHeader),
1115         Signature(Signature) {}
1116 
1117   virtual ~ObjCMethodRecord() = 0;
1118 };
1119 
1120 struct ObjCInstanceMethodRecord : ObjCMethodRecord {
1121   ObjCInstanceMethodRecord(StringRef USR, StringRef Name,
1122                            SymbolReference Parent, PresumedLoc Loc,
1123                            AvailabilityInfo Availability,
1124                            const DocComment &Comment,
1125                            DeclarationFragments Declaration,
1126                            DeclarationFragments SubHeading,
1127                            FunctionSignature Signature, bool IsFromSystemHeader)
1128       : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Parent, Loc,
1129                          std::move(Availability), Comment, Declaration,
1130                          SubHeading, Signature, IsFromSystemHeader) {}
1131   static bool classof(const APIRecord *Record) {
1132     return classofKind(Record->getKind());
1133   }
1134   static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceMethod; }
1135 
1136 private:
1137   virtual void anchor();
1138 };
1139 
1140 struct ObjCClassMethodRecord : ObjCMethodRecord {
1141   ObjCClassMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1142                         PresumedLoc Loc, AvailabilityInfo Availability,
1143                         const DocComment &Comment,
1144                         DeclarationFragments Declaration,
1145                         DeclarationFragments SubHeading,
1146                         FunctionSignature Signature, bool IsFromSystemHeader)
1147       : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Parent, Loc,
1148                          std::move(Availability), Comment, Declaration,
1149                          SubHeading, Signature, IsFromSystemHeader) {}
1150 
1151   static bool classof(const APIRecord *Record) {
1152     return classofKind(Record->getKind());
1153   }
1154   static bool classofKind(RecordKind K) { return K == RK_ObjCClassMethod; }
1155 
1156 private:
1157   virtual void anchor();
1158 };
1159 
1160 struct StaticFieldRecord : CXXFieldRecord {
1161   StaticFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1162                     PresumedLoc Loc, AvailabilityInfo Availability,
1163                     LinkageInfo Linkage, const DocComment &Comment,
1164                     DeclarationFragments Declaration,
1165                     DeclarationFragments SubHeading, AccessControl Access,
1166                     bool IsFromSystemHeader)
1167       : CXXFieldRecord(RK_StaticField, USR, Name, Parent, Loc,
1168                        std::move(Availability), Comment, Declaration,
1169                        SubHeading, std::move(Access), IsFromSystemHeader) {}
1170 
1171   static bool classof(const APIRecord *Record) {
1172     return classofKind(Record->getKind());
1173   }
1174   static bool classofKind(RecordKind K) { return K == RK_StaticField; }
1175 };
1176 
1177 /// The base representation of an Objective-C container record. Holds common
1178 /// information associated with Objective-C containers.
1179 struct ObjCContainerRecord : APIRecord, RecordContext {
1180   SmallVector<SymbolReference> Protocols;
1181 
1182   ObjCContainerRecord() = delete;
1183 
1184   ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
1185                       SymbolReference Parent, PresumedLoc Loc,
1186                       AvailabilityInfo Availability, LinkageInfo Linkage,
1187                       const DocComment &Comment,
1188                       DeclarationFragments Declaration,
1189                       DeclarationFragments SubHeading, bool IsFromSystemHeader)
1190       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1191                   Linkage, Comment, Declaration, SubHeading,
1192                   IsFromSystemHeader),
1193         RecordContext(Kind) {}
1194 
1195   virtual ~ObjCContainerRecord() = 0;
1196 };
1197 
1198 struct CXXClassRecord : RecordRecord {
1199   SmallVector<SymbolReference> Bases;
1200 
1201   CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1202                  PresumedLoc Loc, AvailabilityInfo Availability,
1203                  const DocComment &Comment, DeclarationFragments Declaration,
1204                  DeclarationFragments SubHeading, RecordKind Kind,
1205                  AccessControl Access, bool IsFromSystemHeader,
1206                  bool IsEmbeddedInVarDeclarator = false)
1207       : RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1208                      Comment, Declaration, SubHeading, IsFromSystemHeader,
1209                      IsEmbeddedInVarDeclarator, std::move(Access)) {}
1210 
1211   static bool classof(const APIRecord *Record) {
1212     return classofKind(Record->getKind());
1213   }
1214   static bool classofKind(RecordKind K) {
1215     return K == RK_CXXClass || K == RK_ClassTemplate ||
1216            K == RK_ClassTemplateSpecialization ||
1217            K == RK_ClassTemplatePartialSpecialization;
1218   }
1219 
1220 private:
1221   virtual void anchor();
1222 };
1223 
1224 struct ClassTemplateRecord : CXXClassRecord {
1225   Template Templ;
1226 
1227   ClassTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1228                       PresumedLoc Loc, AvailabilityInfo Availability,
1229                       const DocComment &Comment,
1230                       DeclarationFragments Declaration,
1231                       DeclarationFragments SubHeading, Template Template,
1232                       AccessControl Access, bool IsFromSystemHeader)
1233       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1234                        Declaration, SubHeading, RK_ClassTemplate,
1235                        std::move(Access), IsFromSystemHeader),
1236         Templ(Template) {}
1237 
1238   static bool classof(const APIRecord *Record) {
1239     return classofKind(Record->getKind());
1240   }
1241   static bool classofKind(RecordKind K) { return K == RK_ClassTemplate; }
1242 };
1243 
1244 struct ClassTemplateSpecializationRecord : CXXClassRecord {
1245   ClassTemplateSpecializationRecord(
1246       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1247       AvailabilityInfo Availability, const DocComment &Comment,
1248       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1249       AccessControl Access, bool IsFromSystemHeader)
1250       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1251                        Declaration, SubHeading, RK_ClassTemplateSpecialization,
1252                        Access, IsFromSystemHeader) {}
1253 
1254   static bool classof(const APIRecord *Record) {
1255     return classofKind(Record->getKind());
1256   }
1257   static bool classofKind(RecordKind K) {
1258     return K == RK_ClassTemplateSpecialization;
1259   }
1260 };
1261 
1262 struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
1263   Template Templ;
1264   ClassTemplatePartialSpecializationRecord(
1265       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1266       AvailabilityInfo Availability, const DocComment &Comment,
1267       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1268       Template Template, AccessControl Access, bool IsFromSystemHeader)
1269       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1270                        Declaration, SubHeading,
1271                        RK_ClassTemplatePartialSpecialization, Access,
1272                        IsFromSystemHeader),
1273         Templ(Template) {}
1274 
1275   static bool classof(const APIRecord *Record) {
1276     return classofKind(Record->getKind());
1277   }
1278   static bool classofKind(RecordKind K) {
1279     return K == RK_ClassTemplatePartialSpecialization;
1280   }
1281 };
1282 
1283 struct ConceptRecord : APIRecord {
1284   Template Templ;
1285 
1286   ConceptRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1287                 PresumedLoc Loc, AvailabilityInfo Availability,
1288                 const DocComment &Comment, DeclarationFragments Declaration,
1289                 DeclarationFragments SubHeading, Template Template,
1290                 bool IsFromSystemHeader)
1291       : APIRecord(RK_Concept, USR, Name, Parent, Loc, std::move(Availability),
1292                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1293                   IsFromSystemHeader),
1294         Templ(Template) {}
1295 
1296   static bool classof(const APIRecord *Record) {
1297     return classofKind(Record->getKind());
1298   }
1299   static bool classofKind(RecordKind K) { return K == RK_Concept; }
1300 };
1301 
1302 /// This holds information associated with Objective-C categories.
1303 struct ObjCCategoryRecord : ObjCContainerRecord {
1304   SymbolReference Interface;
1305 
1306   ObjCCategoryRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1307                      PresumedLoc Loc, AvailabilityInfo Availability,
1308                      const DocComment &Comment,
1309                      DeclarationFragments Declaration,
1310                      DeclarationFragments SubHeading, SymbolReference Interface,
1311                      bool IsFromSystemHeader)
1312       : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Parent, Loc,
1313                             std::move(Availability), LinkageInfo::none(),
1314                             Comment, Declaration, SubHeading,
1315                             IsFromSystemHeader),
1316         Interface(Interface) {}
1317 
1318   static bool classof(const APIRecord *Record) {
1319     return classofKind(Record->getKind());
1320   }
1321   static bool classofKind(RecordKind K) { return K == RK_ObjCCategory; }
1322 
1323   bool isExtendingExternalModule() const { return !Interface.Source.empty(); }
1324 
1325   std::optional<StringRef> getExtendedExternalModule() const {
1326     if (!isExtendingExternalModule())
1327       return {};
1328     return Interface.Source;
1329   }
1330 
1331 private:
1332   virtual void anchor();
1333 };
1334 
1335 /// This holds information associated with Objective-C interfaces/classes.
1336 struct ObjCInterfaceRecord : ObjCContainerRecord {
1337   SymbolReference SuperClass;
1338 
1339   ObjCInterfaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1340                       PresumedLoc Loc, AvailabilityInfo Availability,
1341                       LinkageInfo Linkage, const DocComment &Comment,
1342                       DeclarationFragments Declaration,
1343                       DeclarationFragments SubHeading,
1344                       SymbolReference SuperClass, bool IsFromSystemHeader)
1345       : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Parent, Loc,
1346                             std::move(Availability), Linkage, Comment,
1347                             Declaration, SubHeading, IsFromSystemHeader),
1348         SuperClass(SuperClass) {}
1349 
1350   static bool classof(const APIRecord *Record) {
1351     return classofKind(Record->getKind());
1352   }
1353   static bool classofKind(RecordKind K) { return K == RK_ObjCInterface; }
1354 
1355 private:
1356   virtual void anchor();
1357 };
1358 
1359 /// This holds information associated with Objective-C protocols.
1360 struct ObjCProtocolRecord : ObjCContainerRecord {
1361   ObjCProtocolRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1362                      PresumedLoc Loc, AvailabilityInfo Availability,
1363                      const DocComment &Comment,
1364                      DeclarationFragments Declaration,
1365                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
1366       : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Parent, Loc,
1367                             std::move(Availability), LinkageInfo::none(),
1368                             Comment, Declaration, SubHeading,
1369                             IsFromSystemHeader) {}
1370 
1371   static bool classof(const APIRecord *Record) {
1372     return classofKind(Record->getKind());
1373   }
1374   static bool classofKind(RecordKind K) { return K == RK_ObjCProtocol; }
1375 
1376 private:
1377   virtual void anchor();
1378 };
1379 
1380 /// This holds information associated with macro definitions.
1381 struct MacroDefinitionRecord : APIRecord {
1382   MacroDefinitionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1383                         PresumedLoc Loc, DeclarationFragments Declaration,
1384                         DeclarationFragments SubHeading,
1385                         bool IsFromSystemHeader)
1386       : APIRecord(RK_MacroDefinition, USR, Name, Parent, Loc,
1387                   AvailabilityInfo(), LinkageInfo(), {}, Declaration,
1388                   SubHeading, IsFromSystemHeader) {}
1389 
1390   static bool classof(const APIRecord *Record) {
1391     return classofKind(Record->getKind());
1392   }
1393   static bool classofKind(RecordKind K) { return K == RK_MacroDefinition; }
1394 
1395 private:
1396   virtual void anchor();
1397 };
1398 
1399 /// This holds information associated with typedefs.
1400 ///
1401 /// Note: Typedefs for anonymous enums and structs typically don't get emitted
1402 /// by the serializers but still get a TypedefRecord. Instead we use the
1403 /// typedef name as a name for the underlying anonymous struct or enum.
1404 struct TypedefRecord : APIRecord {
1405   SymbolReference UnderlyingType;
1406 
1407   TypedefRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1408                 PresumedLoc Loc, AvailabilityInfo Availability,
1409                 const DocComment &Comment, DeclarationFragments Declaration,
1410                 DeclarationFragments SubHeading, SymbolReference UnderlyingType,
1411                 bool IsFromSystemHeader)
1412       : APIRecord(RK_Typedef, USR, Name, Parent, Loc, std::move(Availability),
1413                   LinkageInfo(), Comment, Declaration, SubHeading,
1414                   IsFromSystemHeader),
1415         UnderlyingType(UnderlyingType) {}
1416 
1417   static bool classof(const APIRecord *Record) {
1418     return classofKind(Record->getKind());
1419   }
1420   static bool classofKind(RecordKind K) { return K == RK_Typedef; }
1421 
1422 private:
1423   virtual void anchor();
1424 };
1425 
1426 /// APISet holds the set of API records collected from given inputs.
1427 class APISet {
1428 public:
1429   /// Get the target triple for the ExtractAPI invocation.
1430   const llvm::Triple &getTarget() const { return Target; }
1431 
1432   /// Get the language used by the APIs.
1433   Language getLanguage() const { return Lang; }
1434 
1435   /// Finds the APIRecord for a given USR.
1436   ///
1437   /// \returns a pointer to the APIRecord associated with that USR or nullptr.
1438   APIRecord *findRecordForUSR(StringRef USR) const;
1439 
1440   /// Copy \p String into the Allocator in this APISet.
1441   ///
1442   /// \returns a StringRef of the copied string in APISet::Allocator.
1443   StringRef copyString(StringRef String);
1444 
1445   SymbolReference createSymbolReference(StringRef Name, StringRef USR,
1446                                         StringRef Source = "");
1447 
1448   /// Create a subclass of \p APIRecord and store it in the APISet.
1449   ///
1450   /// \returns A pointer to the created record or the already existing record
1451   /// matching this USR.
1452   template <typename RecordTy, typename... CtorArgsContTy>
1453   typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
1454   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
1455 
1456   ArrayRef<const APIRecord *> getTopLevelRecords() const {
1457     return TopLevelRecords;
1458   }
1459 
1460   void removeRecord(StringRef USR);
1461 
1462   void removeRecord(APIRecord *Record);
1463 
1464   APISet(const llvm::Triple &Target, Language Lang,
1465          const std::string &ProductName)
1466       : Target(Target), Lang(Lang), ProductName(ProductName) {}
1467 
1468   // Prevent moves and copies
1469   APISet(const APISet &Other) = delete;
1470   APISet &operator=(const APISet &Other) = delete;
1471   APISet(APISet &&Other) = delete;
1472   APISet &operator=(APISet &&Other) = delete;
1473 
1474 private:
1475   /// BumpPtrAllocator that serves as the memory arena for the allocated objects
1476   llvm::BumpPtrAllocator Allocator;
1477 
1478   const llvm::Triple Target;
1479   const Language Lang;
1480 
1481   struct APIRecordDeleter {
1482     void operator()(APIRecord *Record) { Record->~APIRecord(); }
1483   };
1484 
1485   // Ensure that the destructor of each record is called when the LookupTable is
1486   // destroyed without calling delete operator as the memory for the record
1487   // lives in the BumpPtrAllocator.
1488   using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
1489   llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
1490   llvm::SmallVector<const APIRecord *, 32> TopLevelRecords;
1491 
1492 public:
1493   const std::string ProductName;
1494 };
1495 
1496 template <typename RecordTy, typename... CtorArgsContTy>
1497 typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
1498 APISet::createRecord(StringRef USR, StringRef Name,
1499                      CtorArgsContTy &&...CtorArgs) {
1500   // Ensure USR refers to a String stored in the allocator.
1501   auto USRString = copyString(USR);
1502   auto Result = USRBasedLookupTable.insert({USRString, nullptr});
1503   RecordTy *Record;
1504 
1505   // Create the record if it does not already exist
1506   if (Result.second) {
1507     Record = new (Allocator) RecordTy(
1508         USRString, copyString(Name), std::forward<CtorArgsContTy>(CtorArgs)...);
1509     // Store the record in the record lookup map
1510     Result.first->second = APIRecordStoredPtr(Record);
1511 
1512     if (auto *ParentContext =
1513             dyn_cast_if_present<RecordContext>(Record->Parent.Record))
1514       ParentContext->addToRecordChain(Record);
1515     else
1516       TopLevelRecords.push_back(Record);
1517   } else {
1518     Record = dyn_cast<RecordTy>(Result.first->second.get());
1519   }
1520 
1521   return Record;
1522 }
1523 
1524 // Helper type for implementing casting to RecordContext pointers.
1525 // Selected when FromTy not a known subclass of RecordContext.
1526 template <typename FromTy,
1527           bool IsKnownSubType = std::is_base_of_v<RecordContext, FromTy>>
1528 struct ToRecordContextCastInfoWrapper {
1529   static_assert(std::is_base_of_v<APIRecord, FromTy>,
1530                 "Can only cast APIRecord and derived classes to RecordContext");
1531 
1532   static bool isPossible(FromTy *From) { return RecordContext::classof(From); }
1533 
1534   static RecordContext *doCast(FromTy *From) {
1535     return APIRecord::castToRecordContext(From);
1536   }
1537 };
1538 
1539 // Selected when FromTy is a known subclass of RecordContext.
1540 template <typename FromTy> struct ToRecordContextCastInfoWrapper<FromTy, true> {
1541   static_assert(std::is_base_of_v<APIRecord, FromTy>,
1542                 "Can only cast APIRecord and derived classes to RecordContext");
1543   static bool isPossible(const FromTy *From) { return true; }
1544   static RecordContext *doCast(FromTy *From) {
1545     return static_cast<RecordContext *>(From);
1546   }
1547 };
1548 
1549 // Helper type for implementing casting to RecordContext pointers.
1550 // Selected when ToTy isn't a known subclass of RecordContext
1551 template <typename ToTy,
1552           bool IsKnownSubType = std::is_base_of_v<RecordContext, ToTy>>
1553 struct FromRecordContextCastInfoWrapper {
1554   static_assert(
1555       std::is_base_of_v<APIRecord, ToTy>,
1556       "Can only class RecordContext to APIRecord and derived classes");
1557 
1558   static bool isPossible(RecordContext *Ctx) {
1559     return ToTy::classofKind(Ctx->getKind());
1560   }
1561 
1562   static ToTy *doCast(RecordContext *Ctx) {
1563     return APIRecord::castFromRecordContext(Ctx);
1564   }
1565 };
1566 
1567 // Selected when ToTy is a known subclass of RecordContext.
1568 template <typename ToTy> struct FromRecordContextCastInfoWrapper<ToTy, true> {
1569   static_assert(
1570       std::is_base_of_v<APIRecord, ToTy>,
1571       "Can only class RecordContext to APIRecord and derived classes");
1572   static bool isPossible(RecordContext *Ctx) {
1573     return ToTy::classof(Ctx->getKind());
1574   }
1575   static RecordContext *doCast(RecordContext *Ctx) {
1576     return static_cast<ToTy *>(Ctx);
1577   }
1578 };
1579 
1580 } // namespace extractapi
1581 } // namespace clang
1582 
1583 // Implement APIRecord (and derived classes) to and from RecordContext
1584 // conversions
1585 namespace llvm {
1586 
1587 template <typename FromTy>
1588 struct CastInfo<::clang::extractapi::RecordContext, FromTy *>
1589     : public NullableValueCastFailed<::clang::extractapi::RecordContext *>,
1590       public DefaultDoCastIfPossible<
1591           ::clang::extractapi::RecordContext *, FromTy *,
1592           CastInfo<::clang::extractapi::RecordContext, FromTy *>> {
1593   static inline bool isPossible(FromTy *From) {
1594     return ::clang::extractapi::ToRecordContextCastInfoWrapper<
1595         FromTy>::isPossible(From);
1596   }
1597 
1598   static inline ::clang::extractapi::RecordContext *doCast(FromTy *From) {
1599     return ::clang::extractapi::ToRecordContextCastInfoWrapper<FromTy>::doCast(
1600         From);
1601   }
1602 };
1603 
1604 template <typename FromTy>
1605 struct CastInfo<::clang::extractapi::RecordContext, const FromTy *>
1606     : public ConstStrippingForwardingCast<
1607           ::clang::extractapi::RecordContext, const FromTy *,
1608           CastInfo<::clang::extractapi::RecordContext, FromTy *>> {};
1609 
1610 template <typename ToTy>
1611 struct CastInfo<ToTy, ::clang::extractapi::RecordContext *>
1612     : public NullableValueCastFailed<ToTy *>,
1613       public DefaultDoCastIfPossible<
1614           ToTy *, ::clang::extractapi::RecordContext *,
1615           CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {
1616   static inline bool isPossible(::clang::extractapi::RecordContext *Ctx) {
1617     return ::clang::extractapi::FromRecordContextCastInfoWrapper<
1618         ToTy>::isPossible(Ctx);
1619   }
1620 
1621   static inline ToTy *doCast(::clang::extractapi::RecordContext *Ctx) {
1622     return ::clang::extractapi::FromRecordContextCastInfoWrapper<ToTy>::doCast(
1623         Ctx);
1624   }
1625 };
1626 
1627 template <typename ToTy>
1628 struct CastInfo<ToTy, const ::clang::extractapi::RecordContext *>
1629     : public ConstStrippingForwardingCast<
1630           ToTy, const ::clang::extractapi::RecordContext *,
1631           CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {};
1632 
1633 } // namespace llvm
1634 
1635 #endif // LLVM_CLANG_EXTRACTAPI_API_H