xref: /freebsd/contrib/llvm-project/clang/include/clang/ExtractAPI/API.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- ExtractAPI/API.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file defines the APIRecord-based structs and the APISet class.
11 ///
12 /// Clang ExtractAPI is a tool to collect API information from a given set of
13 /// header files. The structures in this file describe data representations of
14 /// the API information collected for various kinds of symbols.
15 ///
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CLANG_EXTRACTAPI_API_H
19 #define LLVM_CLANG_EXTRACTAPI_API_H
20 
21 #include "clang/AST/Availability.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/AST/DeclBase.h"
24 #include "clang/AST/DeclObjC.h"
25 #include "clang/AST/RawCommentList.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "clang/Basic/Specifiers.h"
28 #include "clang/ExtractAPI/DeclarationFragments.h"
29 #include "llvm/ADT/ArrayRef.h"
30 #include "llvm/ADT/MapVector.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/Support/Allocator.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/Compiler.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/TargetParser/Triple.h"
38 #include <cstddef>
39 #include <iterator>
40 #include <memory>
41 #include <optional>
42 #include <type_traits>
43 
44 namespace clang {
45 namespace extractapi {
46 
47 class Template {
48   struct TemplateParameter {
49     // "class", "typename", or concept name
50     std::string Type;
51     std::string Name;
52     unsigned int Index;
53     unsigned int Depth;
54     bool IsParameterPack;
55 
TemplateParameterTemplateParameter56     TemplateParameter(std::string Type, std::string Name, unsigned int Index,
57                       unsigned int Depth, bool IsParameterPack)
58         : Type(Type), Name(Name), Index(Index), Depth(Depth),
59           IsParameterPack(IsParameterPack) {}
60   };
61 
62   struct TemplateConstraint {
63     // type name of the constraint, if it has one
64     std::string Type;
65     std::string Kind;
66     std::string LHS, RHS;
67   };
68   llvm::SmallVector<TemplateParameter> Parameters;
69   llvm::SmallVector<TemplateConstraint> Constraints;
70 
71 public:
72   Template() = default;
73 
Template(const TemplateDecl * Decl)74   Template(const TemplateDecl *Decl) {
75     for (auto *const Parameter : *Decl->getTemplateParameters()) {
76       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
77       if (!Param) // some params are null
78         continue;
79       std::string Type;
80       if (Param->hasTypeConstraint())
81         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
82       else if (Param->wasDeclaredWithTypename())
83         Type = "typename";
84       else
85         Type = "class";
86 
87       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
88                            Param->getDepth(), Param->isParameterPack());
89     }
90   }
91 
Template(const ClassTemplatePartialSpecializationDecl * Decl)92   Template(const ClassTemplatePartialSpecializationDecl *Decl) {
93     for (auto *const Parameter : *Decl->getTemplateParameters()) {
94       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
95       if (!Param) // some params are null
96         continue;
97       std::string Type;
98       if (Param->hasTypeConstraint())
99         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
100       else if (Param->wasDeclaredWithTypename())
101         Type = "typename";
102       else
103         Type = "class";
104 
105       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
106                            Param->getDepth(), Param->isParameterPack());
107     }
108   }
109 
Template(const VarTemplatePartialSpecializationDecl * Decl)110   Template(const VarTemplatePartialSpecializationDecl *Decl) {
111     for (auto *const Parameter : *Decl->getTemplateParameters()) {
112       const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
113       if (!Param) // some params are null
114         continue;
115       std::string Type;
116       if (Param->hasTypeConstraint())
117         Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
118       else if (Param->wasDeclaredWithTypename())
119         Type = "typename";
120       else
121         Type = "class";
122 
123       addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
124                            Param->getDepth(), Param->isParameterPack());
125     }
126   }
127 
getParameters()128   const llvm::SmallVector<TemplateParameter> &getParameters() const {
129     return Parameters;
130   }
131 
getConstraints()132   const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
133     return Constraints;
134   }
135 
addTemplateParameter(std::string Type,std::string Name,unsigned int Index,unsigned int Depth,bool IsParameterPack)136   void addTemplateParameter(std::string Type, std::string Name,
137                             unsigned int Index, unsigned int Depth,
138                             bool IsParameterPack) {
139     Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
140   }
141 
empty()142   bool empty() const { return Parameters.empty() && Constraints.empty(); }
143 };
144 
145 /// DocComment is a vector of RawComment::CommentLine.
146 ///
147 /// Each line represents one line of striped documentation comment,
148 /// with source range information. This simplifies calculating the source
149 /// location of a character in the doc comment for pointing back to the source
150 /// file.
151 /// e.g.
152 /// \code
153 ///   /// This is a documentation comment
154 ///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
155 ///   ///     with multiple lines.
156 ///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
157 /// \endcode
158 using DocComment = std::vector<RawComment::CommentLine>;
159 
160 struct APIRecord;
161 
162 // This represents a reference to another symbol that might come from external
163 /// sources.
164 struct SymbolReference {
165   StringRef Name;
166   StringRef USR;
167 
168   /// The source project/module/product of the referred symbol.
169   StringRef Source;
170 
171   // A Pointer to the APIRecord for this reference if known
172   const APIRecord *Record = nullptr;
173 
174   SymbolReference() = default;
175   SymbolReference(StringRef Name, StringRef USR, StringRef Source = "")
NameSymbolReference176       : Name(Name), USR(USR), Source(Source) {}
177   SymbolReference(const APIRecord *R);
178 
179   /// Determine if this SymbolReference is empty.
180   ///
181   /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
emptySymbolReference182   bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
183 };
184 
185 class RecordContext;
186 
187 // Concrete classes deriving from APIRecord need to have a construct with first
188 // arguments USR, and Name, in that order. This is so that they
189 // are compatible with `APISet::createRecord`.
190 // When adding a new kind of record don't forget to update APIRecords.inc!
191 /// The base representation of an API record. Holds common symbol information.
192 struct APIRecord {
193   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
194   enum RecordKind {
195     RK_Unknown,
196     // If adding a record context record kind here make sure to update
197     // RecordContext::classof if needed and add a RECORD_CONTEXT entry to
198     // APIRecords.inc
199     RK_FirstRecordContext,
200     RK_Namespace,
201     RK_Enum,
202     RK_Struct,
203     RK_Union,
204     RK_ObjCInterface,
205     RK_ObjCCategory,
206     RK_ObjCProtocol,
207     RK_CXXClass,
208     RK_ClassTemplate,
209     RK_ClassTemplateSpecialization,
210     RK_ClassTemplatePartialSpecialization,
211     RK_StructField,
212     RK_UnionField,
213     RK_CXXField,
214     RK_StaticField,
215     RK_CXXFieldTemplate,
216     RK_GlobalVariable,
217     RK_GlobalVariableTemplate,
218     RK_GlobalVariableTemplateSpecialization,
219     RK_GlobalVariableTemplatePartialSpecialization,
220     RK_LastRecordContext,
221     RK_GlobalFunction,
222     RK_GlobalFunctionTemplate,
223     RK_GlobalFunctionTemplateSpecialization,
224     RK_EnumConstant,
225     RK_Concept,
226     RK_CXXStaticMethod,
227     RK_CXXInstanceMethod,
228     RK_CXXConstructorMethod,
229     RK_CXXDestructorMethod,
230     RK_CXXMethodTemplate,
231     RK_CXXMethodTemplateSpecialization,
232     RK_ObjCInstanceProperty,
233     RK_ObjCClassProperty,
234     RK_ObjCIvar,
235     RK_ObjCClassMethod,
236     RK_ObjCInstanceMethod,
237     RK_MacroDefinition,
238     RK_Typedef,
239   };
240 
241   StringRef USR;
242   StringRef Name;
243 
244   SymbolReference Parent;
245 
246   PresumedLoc Location;
247   AvailabilityInfo Availability;
248   LinkageInfo Linkage;
249 
250   /// Documentation comment lines attached to this symbol declaration.
251   DocComment Comment;
252 
253   /// Declaration fragments of this symbol declaration.
254   DeclarationFragments Declaration;
255 
256   /// SubHeading provides a more detailed representation than the plain
257   /// declaration name.
258   ///
259   /// SubHeading is an array of declaration fragments of tagged declaration
260   /// name, with potentially more tokens (for example the \c +/- symbol for
261   /// Objective-C class/instance methods).
262   DeclarationFragments SubHeading;
263 
264   /// Whether the symbol was defined in a system header.
265   bool IsFromSystemHeader;
266 
267   AccessControl Access;
268 
269   RecordKind KindForDisplay;
270 
271 private:
272   const RecordKind Kind;
273   friend class RecordContext;
274   // Used to store the next child record in RecordContext. This works because
275   // APIRecords semantically only have one parent.
276   mutable APIRecord *NextInContext = nullptr;
277 
278 public:
getNextInContextAPIRecord279   APIRecord *getNextInContext() const { return NextInContext; }
280 
getKindAPIRecord281   RecordKind getKind() const { return Kind; }
getKindForDisplayAPIRecord282   RecordKind getKindForDisplay() const { return KindForDisplay; }
283 
284   static APIRecord *castFromRecordContext(const RecordContext *Ctx);
285   static RecordContext *castToRecordContext(const APIRecord *Record);
286 
287   APIRecord() = delete;
288 
289   APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
290             SymbolReference Parent, PresumedLoc Location,
291             AvailabilityInfo Availability, LinkageInfo Linkage,
292             const DocComment &Comment, DeclarationFragments Declaration,
293             DeclarationFragments SubHeading, bool IsFromSystemHeader,
294             AccessControl Access = AccessControl())
USRAPIRecord295       : USR(USR), Name(Name), Parent(std::move(Parent)), Location(Location),
296         Availability(std::move(Availability)), Linkage(Linkage),
297         Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
298         IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
299         KindForDisplay(Kind), Kind(Kind) {}
300 
APIRecordAPIRecord301   APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
302       : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {}
303 
304   // Pure virtual destructor to make APIRecord abstract
305   virtual ~APIRecord() = 0;
classofAPIRecord306   static bool classof(const APIRecord *Record) { return true; }
classofKindAPIRecord307   static bool classofKind(RecordKind K) { return true; }
classofAPIRecord308   static bool classof(const RecordContext *Ctx) { return true; }
309 };
310 
311 /// Base class used for specific record types that have children records this is
312 /// analogous to the DeclContext for the AST
313 class RecordContext {
314 public:
classof(const APIRecord * Record)315   static bool classof(const APIRecord *Record) {
316     return classofKind(Record->getKind());
317   }
classofKind(APIRecord::RecordKind K)318   static bool classofKind(APIRecord::RecordKind K) {
319     return K > APIRecord::RK_FirstRecordContext &&
320            K < APIRecord::RK_LastRecordContext;
321   }
322 
classof(const RecordContext * Context)323   static bool classof(const RecordContext *Context) { return true; }
324 
RecordContext(APIRecord::RecordKind Kind)325   RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
326 
327   /// Append \p Other children chain into ours and empty out Other's record
328   /// chain.
329   void stealRecordChain(RecordContext &Other);
330 
getKind()331   APIRecord::RecordKind getKind() const { return Kind; }
332 
333   struct record_iterator {
334   private:
335     APIRecord *Current = nullptr;
336 
337   public:
338     using value_type = APIRecord *;
339     using reference = const value_type &;
340     using pointer = const value_type *;
341     using iterator_category = std::forward_iterator_tag;
342     using difference_type = std::ptrdiff_t;
343 
344     record_iterator() = default;
record_iteratorrecord_iterator345     explicit record_iterator(value_type R) : Current(R) {}
346     reference operator*() const { return Current; }
347     // This doesn't strictly meet the iterator requirements, but it's the
348     // behavior we want here.
349     value_type operator->() const { return Current; }
350     record_iterator &operator++() {
351       Current = Current->getNextInContext();
352       return *this;
353     }
354     record_iterator operator++(int) {
355       record_iterator tmp(*this);
356       ++(*this);
357       return tmp;
358     }
359 
360     friend bool operator==(record_iterator x, record_iterator y) {
361       return x.Current == y.Current;
362     }
363     friend bool operator!=(record_iterator x, record_iterator y) {
364       return x.Current != y.Current;
365     }
366   };
367 
368   using record_range = llvm::iterator_range<record_iterator>;
records()369   record_range records() const {
370     return record_range(records_begin(), records_end());
371   }
records_begin()372   record_iterator records_begin() const { return record_iterator(First); };
records_end()373   record_iterator records_end() const { return record_iterator(); }
records_empty()374   bool records_empty() const { return First == nullptr; };
375 
376 private:
377   APIRecord::RecordKind Kind;
378   mutable APIRecord *First = nullptr;
379   mutable APIRecord *Last = nullptr;
380   bool IsWellFormed() const;
381 
382 protected:
383   friend class APISet;
384   void addToRecordChain(APIRecord *) const;
385 };
386 
387 struct NamespaceRecord : APIRecord, RecordContext {
NamespaceRecordNamespaceRecord388   NamespaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
389                   PresumedLoc Loc, AvailabilityInfo Availability,
390                   LinkageInfo Linkage, const DocComment &Comment,
391                   DeclarationFragments Declaration,
392                   DeclarationFragments SubHeading, bool IsFromSystemHeader)
393       : APIRecord(RK_Namespace, USR, Name, Parent, Loc, std::move(Availability),
394                   Linkage, Comment, Declaration, SubHeading,
395                   IsFromSystemHeader),
396         RecordContext(RK_Namespace) {}
397 
classofNamespaceRecord398   static bool classof(const APIRecord *Record) {
399     return classofKind(Record->getKind());
400   }
classofKindNamespaceRecord401   static bool classofKind(RecordKind K) { return K == RK_Namespace; }
402 };
403 
404 /// This holds information associated with global functions.
405 struct GlobalFunctionRecord : APIRecord {
406   FunctionSignature Signature;
407 
GlobalFunctionRecordGlobalFunctionRecord408   GlobalFunctionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
409                        PresumedLoc Loc, AvailabilityInfo Availability,
410                        LinkageInfo Linkage, const DocComment &Comment,
411                        DeclarationFragments Declaration,
412                        DeclarationFragments SubHeading,
413                        FunctionSignature Signature, bool IsFromSystemHeader)
414       : APIRecord(RK_GlobalFunction, USR, Name, Parent, Loc,
415                   std::move(Availability), Linkage, Comment, Declaration,
416                   SubHeading, IsFromSystemHeader),
417         Signature(Signature) {}
418 
GlobalFunctionRecordGlobalFunctionRecord419   GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
420                        SymbolReference Parent, PresumedLoc Loc,
421                        AvailabilityInfo Availability, LinkageInfo Linkage,
422                        const DocComment &Comment,
423                        DeclarationFragments Declaration,
424                        DeclarationFragments SubHeading,
425                        FunctionSignature Signature, bool IsFromSystemHeader)
426       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
427                   Linkage, Comment, Declaration, SubHeading,
428                   IsFromSystemHeader),
429         Signature(Signature) {}
430 
classofGlobalFunctionRecord431   static bool classof(const APIRecord *Record) {
432     return classofKind(Record->getKind());
433   }
classofKindGlobalFunctionRecord434   static bool classofKind(RecordKind K) { return K == RK_GlobalFunction; }
435 
436 private:
437   virtual void anchor();
438 };
439 
440 struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
441   Template Templ;
442 
GlobalFunctionTemplateRecordGlobalFunctionTemplateRecord443   GlobalFunctionTemplateRecord(StringRef USR, StringRef Name,
444                                SymbolReference Parent, PresumedLoc Loc,
445                                AvailabilityInfo Availability,
446                                LinkageInfo Linkage, const DocComment &Comment,
447                                DeclarationFragments Declaration,
448                                DeclarationFragments SubHeading,
449                                FunctionSignature Signature, Template Template,
450                                bool IsFromSystemHeader)
451       : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Parent, Loc,
452                              std::move(Availability), Linkage, Comment,
453                              Declaration, SubHeading, Signature,
454                              IsFromSystemHeader),
455         Templ(Template) {}
456 
classofGlobalFunctionTemplateRecord457   static bool classof(const APIRecord *Record) {
458     return classofKind(Record->getKind());
459   }
classofKindGlobalFunctionTemplateRecord460   static bool classofKind(RecordKind K) {
461     return K == RK_GlobalFunctionTemplate;
462   }
463 };
464 
465 struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
GlobalFunctionTemplateSpecializationRecordGlobalFunctionTemplateSpecializationRecord466   GlobalFunctionTemplateSpecializationRecord(
467       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
468       AvailabilityInfo Availability, LinkageInfo Linkage,
469       const DocComment &Comment, DeclarationFragments Declaration,
470       DeclarationFragments SubHeading, FunctionSignature Signature,
471       bool IsFromSystemHeader)
472       : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
473                              Parent, Loc, std::move(Availability), Linkage,
474                              Comment, Declaration, SubHeading, Signature,
475                              IsFromSystemHeader) {}
476 
classofGlobalFunctionTemplateSpecializationRecord477   static bool classof(const APIRecord *Record) {
478     return classofKind(Record->getKind());
479   }
classofKindGlobalFunctionTemplateSpecializationRecord480   static bool classofKind(RecordKind K) {
481     return K == RK_GlobalFunctionTemplateSpecialization;
482   }
483 };
484 
485 /// This holds information associated with global functions.
486 struct GlobalVariableRecord : APIRecord, RecordContext {
GlobalVariableRecordGlobalVariableRecord487   GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
488                        PresumedLoc Loc, AvailabilityInfo Availability,
489                        LinkageInfo Linkage, const DocComment &Comment,
490                        DeclarationFragments Declaration,
491                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
492       : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
493                   std::move(Availability), Linkage, Comment, Declaration,
494                   SubHeading, IsFromSystemHeader),
495         RecordContext(RK_GlobalVariable) {}
496 
GlobalVariableRecordGlobalVariableRecord497   GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
498                        SymbolReference Parent, PresumedLoc Loc,
499                        AvailabilityInfo Availability, LinkageInfo Linkage,
500                        const DocComment &Comment,
501                        DeclarationFragments Declaration,
502                        DeclarationFragments SubHeading, bool IsFromSystemHeader)
503       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
504                   Linkage, Comment, Declaration, SubHeading,
505                   IsFromSystemHeader),
506         RecordContext(Kind) {}
507 
classofGlobalVariableRecord508   static bool classof(const APIRecord *Record) {
509     return classofKind(Record->getKind());
510   }
classofKindGlobalVariableRecord511   static bool classofKind(RecordKind K) {
512     return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
513            K == RK_GlobalVariableTemplateSpecialization ||
514            K == RK_GlobalVariableTemplatePartialSpecialization;
515   }
516 
517 private:
518   virtual void anchor();
519 };
520 
521 struct GlobalVariableTemplateRecord : GlobalVariableRecord {
522   Template Templ;
523 
GlobalVariableTemplateRecordGlobalVariableTemplateRecord524   GlobalVariableTemplateRecord(StringRef USR, StringRef Name,
525                                SymbolReference Parent, PresumedLoc Loc,
526                                AvailabilityInfo Availability,
527                                LinkageInfo Linkage, const DocComment &Comment,
528                                DeclarationFragments Declaration,
529                                DeclarationFragments SubHeading,
530                                class Template Template, bool IsFromSystemHeader)
531       : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Parent, Loc,
532                              std::move(Availability), Linkage, Comment,
533                              Declaration, SubHeading, IsFromSystemHeader),
534         Templ(Template) {}
535 
classofGlobalVariableTemplateRecord536   static bool classof(const APIRecord *Record) {
537     return classofKind(Record->getKind());
538   }
classofKindGlobalVariableTemplateRecord539   static bool classofKind(RecordKind K) {
540     return K == RK_GlobalVariableTemplate;
541   }
542 };
543 
544 struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
GlobalVariableTemplateSpecializationRecordGlobalVariableTemplateSpecializationRecord545   GlobalVariableTemplateSpecializationRecord(
546       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
547       AvailabilityInfo Availability, LinkageInfo Linkage,
548       const DocComment &Comment, DeclarationFragments Declaration,
549       DeclarationFragments SubHeading, bool IsFromSystemHeader)
550       : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
551                              Parent, Loc, std::move(Availability), Linkage,
552                              Comment, Declaration, SubHeading,
553                              IsFromSystemHeader) {}
554 
classofGlobalVariableTemplateSpecializationRecord555   static bool classof(const APIRecord *Record) {
556     return classofKind(Record->getKind());
557   }
classofKindGlobalVariableTemplateSpecializationRecord558   static bool classofKind(RecordKind K) {
559     return K == RK_GlobalVariableTemplateSpecialization;
560   }
561 };
562 
563 struct GlobalVariableTemplatePartialSpecializationRecord
564     : GlobalVariableRecord {
565   Template Templ;
566 
GlobalVariableTemplatePartialSpecializationRecordGlobalVariableTemplatePartialSpecializationRecord567   GlobalVariableTemplatePartialSpecializationRecord(
568       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
569       AvailabilityInfo Availability, LinkageInfo Linkage,
570       const DocComment &Comment, DeclarationFragments Declaration,
571       DeclarationFragments SubHeading, class Template Template,
572       bool IsFromSystemHeader)
573       : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
574                              USR, Name, Parent, Loc, std::move(Availability),
575                              Linkage, Comment, Declaration, SubHeading,
576                              IsFromSystemHeader),
577         Templ(Template) {}
578 
classofGlobalVariableTemplatePartialSpecializationRecord579   static bool classof(const APIRecord *Record) {
580     return classofKind(Record->getKind());
581   }
classofKindGlobalVariableTemplatePartialSpecializationRecord582   static bool classofKind(RecordKind K) {
583     return K == RK_GlobalVariableTemplatePartialSpecialization;
584   }
585 };
586 
587 /// This holds information associated with enum constants.
588 struct EnumConstantRecord : APIRecord {
EnumConstantRecordEnumConstantRecord589   EnumConstantRecord(StringRef USR, StringRef Name, SymbolReference Parent,
590                      PresumedLoc Loc, AvailabilityInfo Availability,
591                      const DocComment &Comment,
592                      DeclarationFragments Declaration,
593                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
594       : APIRecord(RK_EnumConstant, USR, Name, Parent, Loc,
595                   std::move(Availability), LinkageInfo::none(), Comment,
596                   Declaration, SubHeading, IsFromSystemHeader) {}
597 
classofEnumConstantRecord598   static bool classof(const APIRecord *Record) {
599     return classofKind(Record->getKind());
600   }
classofKindEnumConstantRecord601   static bool classofKind(RecordKind K) { return K == RK_EnumConstant; }
602 
603 private:
604   virtual void anchor();
605 };
606 
607 struct TagRecord : APIRecord, RecordContext {
608   TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
609             SymbolReference Parent, PresumedLoc Loc,
610             AvailabilityInfo Availability, const DocComment &Comment,
611             DeclarationFragments Declaration, DeclarationFragments SubHeading,
612             bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
613             AccessControl Access = AccessControl())
APIRecordTagRecord614       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
615                   LinkageInfo::none(), Comment, Declaration, SubHeading,
616                   IsFromSystemHeader, std::move(Access)),
617         RecordContext(Kind),
618         IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};
619 
classofTagRecord620   static bool classof(const APIRecord *Record) {
621     return classofKind(Record->getKind());
622   }
classofKindTagRecord623   static bool classofKind(RecordKind K) {
624     return K == RK_Struct || K == RK_Union || K == RK_Enum;
625   }
626 
627   bool IsEmbeddedInVarDeclarator;
628 
629   virtual ~TagRecord() = 0;
630 };
631 
632 /// This holds information associated with enums.
633 struct EnumRecord : TagRecord {
634   EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
635              PresumedLoc Loc, AvailabilityInfo Availability,
636              const DocComment &Comment, DeclarationFragments Declaration,
637              DeclarationFragments SubHeading, bool IsFromSystemHeader,
638              bool IsEmbeddedInVarDeclarator,
639              AccessControl Access = AccessControl())
TagRecordEnumRecord640       : TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
641                   Comment, Declaration, SubHeading, IsFromSystemHeader,
642                   IsEmbeddedInVarDeclarator, std::move(Access)) {}
643 
classofEnumRecord644   static bool classof(const APIRecord *Record) {
645     return classofKind(Record->getKind());
646   }
647 
classofKindEnumRecord648   static bool classofKind(RecordKind K) { return K == RK_Enum; }
649 
650 private:
651   virtual void anchor();
652 };
653 
654 /// This holds information associated with struct or union fields fields.
655 struct RecordFieldRecord : APIRecord, RecordContext {
RecordFieldRecordRecordFieldRecord656   RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
657                     SymbolReference Parent, PresumedLoc Loc,
658                     AvailabilityInfo Availability, const DocComment &Comment,
659                     DeclarationFragments Declaration,
660                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
661       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
662                   LinkageInfo::none(), Comment, Declaration, SubHeading,
663                   IsFromSystemHeader),
664         RecordContext(Kind) {}
665 
classofRecordFieldRecord666   static bool classof(const APIRecord *Record) {
667     return classofKind(Record->getKind());
668   }
classofKindRecordFieldRecord669   static bool classofKind(RecordKind K) {
670     return K == RK_StructField || K == RK_UnionField;
671   }
672 
673   virtual ~RecordFieldRecord() = 0;
674 };
675 
676 /// This holds information associated with structs and unions.
677 struct RecordRecord : TagRecord {
678   RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
679                SymbolReference Parent, PresumedLoc Loc,
680                AvailabilityInfo Availability, const DocComment &Comment,
681                DeclarationFragments Declaration,
682                DeclarationFragments SubHeading, bool IsFromSystemHeader,
683                bool IsEmbeddedInVarDeclarator,
684                AccessControl Access = AccessControl())
TagRecordRecordRecord685       : TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
686                   Comment, Declaration, SubHeading, IsFromSystemHeader,
687                   IsEmbeddedInVarDeclarator, std::move(Access)) {}
688 
classofRecordRecord689   static bool classof(const APIRecord *Record) {
690     return classofKind(Record->getKind());
691   }
classofKindRecordRecord692   static bool classofKind(RecordKind K) {
693     return K == RK_Struct || K == RK_Union;
694   }
695 
isAnonymousWithNoTypedefRecordRecord696   bool isAnonymousWithNoTypedef() { return Name.empty(); }
697 
698   virtual ~RecordRecord() = 0;
699 };
700 
701 struct StructFieldRecord : RecordFieldRecord {
StructFieldRecordStructFieldRecord702   StructFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
703                     PresumedLoc Loc, AvailabilityInfo Availability,
704                     const DocComment &Comment, DeclarationFragments Declaration,
705                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
706       : RecordFieldRecord(RK_StructField, USR, Name, Parent, Loc,
707                           std::move(Availability), Comment, Declaration,
708                           SubHeading, IsFromSystemHeader) {}
709 
classofStructFieldRecord710   static bool classof(const APIRecord *Record) {
711     return classofKind(Record->getKind());
712   }
classofKindStructFieldRecord713   static bool classofKind(RecordKind K) { return K == RK_StructField; }
714 
715 private:
716   virtual void anchor();
717 };
718 
719 struct StructRecord : RecordRecord {
StructRecordStructRecord720   StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
721                PresumedLoc Loc, AvailabilityInfo Availability,
722                const DocComment &Comment, DeclarationFragments Declaration,
723                DeclarationFragments SubHeading, bool IsFromSystemHeader,
724                bool IsEmbeddedInVarDeclarator)
725       : RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
726                      Comment, Declaration, SubHeading, IsFromSystemHeader,
727                      IsEmbeddedInVarDeclarator) {}
728 
classofStructRecord729   static bool classof(const APIRecord *Record) {
730     return classofKind(Record->getKind());
731   }
classofKindStructRecord732   static bool classofKind(RecordKind K) { return K == RK_Struct; }
733 
734 private:
735   virtual void anchor();
736 };
737 
738 struct UnionFieldRecord : RecordFieldRecord {
UnionFieldRecordUnionFieldRecord739   UnionFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
740                    PresumedLoc Loc, AvailabilityInfo Availability,
741                    const DocComment &Comment, DeclarationFragments Declaration,
742                    DeclarationFragments SubHeading, bool IsFromSystemHeader)
743       : RecordFieldRecord(RK_UnionField, USR, Name, Parent, Loc,
744                           std::move(Availability), Comment, Declaration,
745                           SubHeading, IsFromSystemHeader) {}
746 
classofUnionFieldRecord747   static bool classof(const APIRecord *Record) {
748     return classofKind(Record->getKind());
749   }
classofKindUnionFieldRecord750   static bool classofKind(RecordKind K) { return K == RK_UnionField; }
751 
752 private:
753   virtual void anchor();
754 };
755 
756 struct UnionRecord : RecordRecord {
UnionRecordUnionRecord757   UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
758               PresumedLoc Loc, AvailabilityInfo Availability,
759               const DocComment &Comment, DeclarationFragments Declaration,
760               DeclarationFragments SubHeading, bool IsFromSystemHeader,
761               bool IsEmbeddedInVarDeclarator)
762       : RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
763                      Comment, Declaration, SubHeading, IsFromSystemHeader,
764                      IsEmbeddedInVarDeclarator) {}
765 
classofUnionRecord766   static bool classof(const APIRecord *Record) {
767     return classofKind(Record->getKind());
768   }
classofKindUnionRecord769   static bool classofKind(RecordKind K) { return K == RK_Union; }
770 
771 private:
772   virtual void anchor();
773 };
774 
775 struct CXXFieldRecord : APIRecord, RecordContext {
CXXFieldRecordCXXFieldRecord776   CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
777                  PresumedLoc Loc, AvailabilityInfo Availability,
778                  const DocComment &Comment, DeclarationFragments Declaration,
779                  DeclarationFragments SubHeading, AccessControl Access,
780                  bool IsFromSystemHeader)
781       : APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
782                   LinkageInfo::none(), Comment, Declaration, SubHeading,
783                   IsFromSystemHeader, std::move(Access)),
784         RecordContext(RK_CXXField) {}
785 
CXXFieldRecordCXXFieldRecord786   CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
787                  SymbolReference Parent, PresumedLoc Loc,
788                  AvailabilityInfo Availability, const DocComment &Comment,
789                  DeclarationFragments Declaration,
790                  DeclarationFragments SubHeading, AccessControl Access,
791                  bool IsFromSystemHeader)
792       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
793                   LinkageInfo::none(), Comment, Declaration, SubHeading,
794                   IsFromSystemHeader, std::move(Access)),
795         RecordContext(Kind) {}
796 
classofCXXFieldRecord797   static bool classof(const APIRecord *Record) {
798     return classofKind(Record->getKind());
799   }
classofKindCXXFieldRecord800   static bool classofKind(RecordKind K) {
801     return K == RK_CXXField || K == RK_CXXFieldTemplate || K == RK_StaticField;
802   }
803 
804 private:
805   virtual void anchor();
806 };
807 
808 struct CXXFieldTemplateRecord : CXXFieldRecord {
809   Template Templ;
810 
CXXFieldTemplateRecordCXXFieldTemplateRecord811   CXXFieldTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
812                          PresumedLoc Loc, AvailabilityInfo Availability,
813                          const DocComment &Comment,
814                          DeclarationFragments Declaration,
815                          DeclarationFragments SubHeading, AccessControl Access,
816                          Template Template, bool IsFromSystemHeader)
817       : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Parent, Loc,
818                        std::move(Availability), Comment, Declaration,
819                        SubHeading, std::move(Access), IsFromSystemHeader),
820         Templ(Template) {}
821 
classofCXXFieldTemplateRecord822   static bool classof(const APIRecord *Record) {
823     return classofKind(Record->getKind());
824   }
classofKindCXXFieldTemplateRecord825   static bool classofKind(RecordKind K) { return K == RK_CXXFieldTemplate; }
826 };
827 
828 struct CXXMethodRecord : APIRecord {
829   FunctionSignature Signature;
830 
831   CXXMethodRecord() = delete;
832 
CXXMethodRecordCXXMethodRecord833   CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
834                   SymbolReference Parent, PresumedLoc Loc,
835                   AvailabilityInfo Availability, const DocComment &Comment,
836                   DeclarationFragments Declaration,
837                   DeclarationFragments SubHeading, FunctionSignature Signature,
838                   AccessControl Access, bool IsFromSystemHeader)
839       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
840                   LinkageInfo::none(), Comment, Declaration, SubHeading,
841                   IsFromSystemHeader, std::move(Access)),
842         Signature(Signature) {}
843 
844   virtual ~CXXMethodRecord() = 0;
845 };
846 
847 struct CXXConstructorRecord : CXXMethodRecord {
CXXConstructorRecordCXXConstructorRecord848   CXXConstructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
849                        PresumedLoc Loc, AvailabilityInfo Availability,
850                        const DocComment &Comment,
851                        DeclarationFragments Declaration,
852                        DeclarationFragments SubHeading,
853                        FunctionSignature Signature, AccessControl Access,
854                        bool IsFromSystemHeader)
855       : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Parent, Loc,
856                         std::move(Availability), Comment, Declaration,
857                         SubHeading, Signature, std::move(Access),
858                         IsFromSystemHeader) {}
classofCXXConstructorRecord859   static bool classof(const APIRecord *Record) {
860     return classofKind(Record->getKind());
861   }
classofKindCXXConstructorRecord862   static bool classofKind(RecordKind K) { return K == RK_CXXConstructorMethod; }
863 
864 private:
865   virtual void anchor();
866 };
867 
868 struct CXXDestructorRecord : CXXMethodRecord {
CXXDestructorRecordCXXDestructorRecord869   CXXDestructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
870                       PresumedLoc Loc, AvailabilityInfo Availability,
871                       const DocComment &Comment,
872                       DeclarationFragments Declaration,
873                       DeclarationFragments SubHeading,
874                       FunctionSignature Signature, AccessControl Access,
875                       bool IsFromSystemHeader)
876       : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Parent, Loc,
877                         std::move(Availability), Comment, Declaration,
878                         SubHeading, Signature, std::move(Access),
879                         IsFromSystemHeader) {}
classofCXXDestructorRecord880   static bool classof(const APIRecord *Record) {
881     return classofKind(Record->getKind());
882   }
classofKindCXXDestructorRecord883   static bool classofKind(RecordKind K) { return K == RK_CXXDestructorMethod; }
884 
885 private:
886   virtual void anchor();
887 };
888 
889 struct CXXStaticMethodRecord : CXXMethodRecord {
CXXStaticMethodRecordCXXStaticMethodRecord890   CXXStaticMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
891                         PresumedLoc Loc, AvailabilityInfo Availability,
892                         const DocComment &Comment,
893                         DeclarationFragments Declaration,
894                         DeclarationFragments SubHeading,
895                         FunctionSignature Signature, AccessControl Access,
896                         bool IsFromSystemHeader)
897       : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Parent, Loc,
898                         std::move(Availability), Comment, Declaration,
899                         SubHeading, Signature, std::move(Access),
900                         IsFromSystemHeader) {}
classofCXXStaticMethodRecord901   static bool classof(const APIRecord *Record) {
902     return classofKind(Record->getKind());
903   }
classofKindCXXStaticMethodRecord904   static bool classofKind(RecordKind K) { return K == RK_CXXStaticMethod; }
905 
906 private:
907   virtual void anchor();
908 };
909 
910 struct CXXInstanceMethodRecord : CXXMethodRecord {
CXXInstanceMethodRecordCXXInstanceMethodRecord911   CXXInstanceMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
912                           PresumedLoc Loc, AvailabilityInfo Availability,
913                           const DocComment &Comment,
914                           DeclarationFragments Declaration,
915                           DeclarationFragments SubHeading,
916                           FunctionSignature Signature, AccessControl Access,
917                           bool IsFromSystemHeader)
918       : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Parent, Loc,
919                         std::move(Availability), Comment, Declaration,
920                         SubHeading, Signature, std::move(Access),
921                         IsFromSystemHeader) {}
922 
classofCXXInstanceMethodRecord923   static bool classof(const APIRecord *Record) {
924     return classofKind(Record->getKind());
925   }
classofKindCXXInstanceMethodRecord926   static bool classofKind(RecordKind K) { return K == RK_CXXInstanceMethod; }
927 
928 private:
929   virtual void anchor();
930 };
931 
932 struct CXXMethodTemplateRecord : CXXMethodRecord {
933   Template Templ;
934 
CXXMethodTemplateRecordCXXMethodTemplateRecord935   CXXMethodTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
936                           PresumedLoc Loc, AvailabilityInfo Availability,
937                           const DocComment &Comment,
938                           DeclarationFragments Declaration,
939                           DeclarationFragments SubHeading,
940                           FunctionSignature Signature, AccessControl Access,
941                           Template Template, bool IsFromSystemHeader)
942       : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Parent, Loc,
943                         std::move(Availability), Comment, Declaration,
944                         SubHeading, Signature, std::move(Access),
945                         IsFromSystemHeader),
946         Templ(Template) {}
947 
classofCXXMethodTemplateRecord948   static bool classof(const APIRecord *Record) {
949     return classofKind(Record->getKind());
950   }
classofKindCXXMethodTemplateRecord951   static bool classofKind(RecordKind K) { return K == RK_CXXMethodTemplate; }
952 };
953 
954 struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
CXXMethodTemplateSpecializationRecordCXXMethodTemplateSpecializationRecord955   CXXMethodTemplateSpecializationRecord(
956       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
957       AvailabilityInfo Availability, const DocComment &Comment,
958       DeclarationFragments Declaration, DeclarationFragments SubHeading,
959       FunctionSignature Signature, AccessControl Access,
960       bool IsFromSystemHeader)
961       : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Parent,
962                         Loc, std::move(Availability), Comment, Declaration,
963                         SubHeading, Signature, std::move(Access),
964                         IsFromSystemHeader) {}
965 
classofCXXMethodTemplateSpecializationRecord966   static bool classof(const APIRecord *Record) {
967     return classofKind(Record->getKind());
968   }
classofKindCXXMethodTemplateSpecializationRecord969   static bool classofKind(RecordKind K) {
970     return K == RK_CXXMethodTemplateSpecialization;
971   }
972 };
973 
974 /// This holds information associated with Objective-C properties.
975 struct ObjCPropertyRecord : APIRecord {
976   /// The attributes associated with an Objective-C property.
977   enum AttributeKind : unsigned {
978     NoAttr = 0,
979     ReadOnly = 1,
980     Dynamic = 1 << 2,
981   };
982 
983   AttributeKind Attributes;
984   StringRef GetterName;
985   StringRef SetterName;
986   bool IsOptional;
987 
ObjCPropertyRecordObjCPropertyRecord988   ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
989                      SymbolReference Parent, PresumedLoc Loc,
990                      AvailabilityInfo Availability, const DocComment &Comment,
991                      DeclarationFragments Declaration,
992                      DeclarationFragments SubHeading, AttributeKind Attributes,
993                      StringRef GetterName, StringRef SetterName,
994                      bool IsOptional, bool IsFromSystemHeader)
995       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
996                   LinkageInfo::none(), Comment, Declaration, SubHeading,
997                   IsFromSystemHeader),
998         Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
999         IsOptional(IsOptional) {}
1000 
isReadOnlyObjCPropertyRecord1001   bool isReadOnly() const { return Attributes & ReadOnly; }
isDynamicObjCPropertyRecord1002   bool isDynamic() const { return Attributes & Dynamic; }
1003 
1004   virtual ~ObjCPropertyRecord() = 0;
1005 };
1006 
1007 struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
ObjCInstancePropertyRecordObjCInstancePropertyRecord1008   ObjCInstancePropertyRecord(
1009       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1010       AvailabilityInfo Availability, const DocComment &Comment,
1011       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1012       AttributeKind Attributes, StringRef GetterName, StringRef SetterName,
1013       bool IsOptional, bool IsFromSystemHeader)
1014       : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Parent, Loc,
1015                            std::move(Availability), Comment, Declaration,
1016                            SubHeading, Attributes, GetterName, SetterName,
1017                            IsOptional, IsFromSystemHeader) {}
1018 
classofObjCInstancePropertyRecord1019   static bool classof(const APIRecord *Record) {
1020     return classofKind(Record->getKind());
1021   }
classofKindObjCInstancePropertyRecord1022   static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceProperty; }
1023 
1024 private:
1025   virtual void anchor();
1026 };
1027 
1028 struct ObjCClassPropertyRecord : ObjCPropertyRecord {
ObjCClassPropertyRecordObjCClassPropertyRecord1029   ObjCClassPropertyRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1030                           PresumedLoc Loc, AvailabilityInfo Availability,
1031                           const DocComment &Comment,
1032                           DeclarationFragments Declaration,
1033                           DeclarationFragments SubHeading,
1034                           AttributeKind Attributes, StringRef GetterName,
1035                           StringRef SetterName, bool IsOptional,
1036                           bool IsFromSystemHeader)
1037       : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Parent, Loc,
1038                            std::move(Availability), Comment, Declaration,
1039                            SubHeading, Attributes, GetterName, SetterName,
1040                            IsOptional, IsFromSystemHeader) {}
1041 
classofObjCClassPropertyRecord1042   static bool classof(const APIRecord *Record) {
1043     return classofKind(Record->getKind());
1044   }
classofKindObjCClassPropertyRecord1045   static bool classofKind(RecordKind K) { return K == RK_ObjCClassProperty; }
1046 
1047 private:
1048   virtual void anchor();
1049 };
1050 
1051 /// This holds information associated with Objective-C instance variables.
1052 struct ObjCInstanceVariableRecord : APIRecord {
ObjCInstanceVariableRecordObjCInstanceVariableRecord1053   ObjCInstanceVariableRecord(StringRef USR, StringRef Name,
1054                              SymbolReference Parent, PresumedLoc Loc,
1055                              AvailabilityInfo Availability,
1056                              const DocComment &Comment,
1057                              DeclarationFragments Declaration,
1058                              DeclarationFragments SubHeading,
1059                              bool IsFromSystemHeader)
1060       : APIRecord(RK_ObjCIvar, USR, Name, Parent, Loc, std::move(Availability),
1061                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1062                   IsFromSystemHeader) {}
1063 
classofObjCInstanceVariableRecord1064   static bool classof(const APIRecord *Record) {
1065     return classofKind(Record->getKind());
1066   }
classofKindObjCInstanceVariableRecord1067   static bool classofKind(RecordKind K) { return K == RK_ObjCIvar; }
1068 
1069 private:
1070   virtual void anchor();
1071 };
1072 
1073 /// This holds information associated with Objective-C methods.
1074 struct ObjCMethodRecord : APIRecord {
1075   FunctionSignature Signature;
1076 
1077   ObjCMethodRecord() = delete;
1078 
ObjCMethodRecordObjCMethodRecord1079   ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
1080                    SymbolReference Parent, PresumedLoc Loc,
1081                    AvailabilityInfo Availability, const DocComment &Comment,
1082                    DeclarationFragments Declaration,
1083                    DeclarationFragments SubHeading, FunctionSignature Signature,
1084                    bool IsFromSystemHeader)
1085       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1086                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1087                   IsFromSystemHeader),
1088         Signature(Signature) {}
1089 
1090   virtual ~ObjCMethodRecord() = 0;
1091 };
1092 
1093 struct ObjCInstanceMethodRecord : ObjCMethodRecord {
ObjCInstanceMethodRecordObjCInstanceMethodRecord1094   ObjCInstanceMethodRecord(StringRef USR, StringRef Name,
1095                            SymbolReference Parent, PresumedLoc Loc,
1096                            AvailabilityInfo Availability,
1097                            const DocComment &Comment,
1098                            DeclarationFragments Declaration,
1099                            DeclarationFragments SubHeading,
1100                            FunctionSignature Signature, bool IsFromSystemHeader)
1101       : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Parent, Loc,
1102                          std::move(Availability), Comment, Declaration,
1103                          SubHeading, Signature, IsFromSystemHeader) {}
classofObjCInstanceMethodRecord1104   static bool classof(const APIRecord *Record) {
1105     return classofKind(Record->getKind());
1106   }
classofKindObjCInstanceMethodRecord1107   static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceMethod; }
1108 
1109 private:
1110   virtual void anchor();
1111 };
1112 
1113 struct ObjCClassMethodRecord : ObjCMethodRecord {
ObjCClassMethodRecordObjCClassMethodRecord1114   ObjCClassMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1115                         PresumedLoc Loc, AvailabilityInfo Availability,
1116                         const DocComment &Comment,
1117                         DeclarationFragments Declaration,
1118                         DeclarationFragments SubHeading,
1119                         FunctionSignature Signature, bool IsFromSystemHeader)
1120       : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Parent, Loc,
1121                          std::move(Availability), Comment, Declaration,
1122                          SubHeading, Signature, IsFromSystemHeader) {}
1123 
classofObjCClassMethodRecord1124   static bool classof(const APIRecord *Record) {
1125     return classofKind(Record->getKind());
1126   }
classofKindObjCClassMethodRecord1127   static bool classofKind(RecordKind K) { return K == RK_ObjCClassMethod; }
1128 
1129 private:
1130   virtual void anchor();
1131 };
1132 
1133 struct StaticFieldRecord : CXXFieldRecord {
StaticFieldRecordStaticFieldRecord1134   StaticFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1135                     PresumedLoc Loc, AvailabilityInfo Availability,
1136                     LinkageInfo Linkage, const DocComment &Comment,
1137                     DeclarationFragments Declaration,
1138                     DeclarationFragments SubHeading, AccessControl Access,
1139                     bool IsFromSystemHeader)
1140       : CXXFieldRecord(RK_StaticField, USR, Name, Parent, Loc,
1141                        std::move(Availability), Comment, Declaration,
1142                        SubHeading, std::move(Access), IsFromSystemHeader) {}
1143 
classofStaticFieldRecord1144   static bool classof(const APIRecord *Record) {
1145     return classofKind(Record->getKind());
1146   }
classofKindStaticFieldRecord1147   static bool classofKind(RecordKind K) { return K == RK_StaticField; }
1148 };
1149 
1150 /// The base representation of an Objective-C container record. Holds common
1151 /// information associated with Objective-C containers.
1152 struct ObjCContainerRecord : APIRecord, RecordContext {
1153   SmallVector<SymbolReference> Protocols;
1154 
1155   ObjCContainerRecord() = delete;
1156 
ObjCContainerRecordObjCContainerRecord1157   ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
1158                       SymbolReference Parent, PresumedLoc Loc,
1159                       AvailabilityInfo Availability, LinkageInfo Linkage,
1160                       const DocComment &Comment,
1161                       DeclarationFragments Declaration,
1162                       DeclarationFragments SubHeading, bool IsFromSystemHeader)
1163       : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1164                   Linkage, Comment, Declaration, SubHeading,
1165                   IsFromSystemHeader),
1166         RecordContext(Kind) {}
1167 
1168   virtual ~ObjCContainerRecord() = 0;
1169 };
1170 
1171 struct CXXClassRecord : RecordRecord {
1172   SmallVector<SymbolReference> Bases;
1173 
1174   CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1175                  PresumedLoc Loc, AvailabilityInfo Availability,
1176                  const DocComment &Comment, DeclarationFragments Declaration,
1177                  DeclarationFragments SubHeading, RecordKind Kind,
1178                  AccessControl Access, bool IsFromSystemHeader,
1179                  bool IsEmbeddedInVarDeclarator = false)
RecordRecordCXXClassRecord1180       : RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1181                      Comment, Declaration, SubHeading, IsFromSystemHeader,
1182                      IsEmbeddedInVarDeclarator, std::move(Access)) {}
1183 
classofCXXClassRecord1184   static bool classof(const APIRecord *Record) {
1185     return classofKind(Record->getKind());
1186   }
classofKindCXXClassRecord1187   static bool classofKind(RecordKind K) {
1188     return K == RK_CXXClass || K == RK_ClassTemplate ||
1189            K == RK_ClassTemplateSpecialization ||
1190            K == RK_ClassTemplatePartialSpecialization;
1191   }
1192 
1193 private:
1194   virtual void anchor();
1195 };
1196 
1197 struct ClassTemplateRecord : CXXClassRecord {
1198   Template Templ;
1199 
ClassTemplateRecordClassTemplateRecord1200   ClassTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1201                       PresumedLoc Loc, AvailabilityInfo Availability,
1202                       const DocComment &Comment,
1203                       DeclarationFragments Declaration,
1204                       DeclarationFragments SubHeading, Template Template,
1205                       AccessControl Access, bool IsFromSystemHeader)
1206       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1207                        Declaration, SubHeading, RK_ClassTemplate,
1208                        std::move(Access), IsFromSystemHeader),
1209         Templ(Template) {}
1210 
classofClassTemplateRecord1211   static bool classof(const APIRecord *Record) {
1212     return classofKind(Record->getKind());
1213   }
classofKindClassTemplateRecord1214   static bool classofKind(RecordKind K) { return K == RK_ClassTemplate; }
1215 };
1216 
1217 struct ClassTemplateSpecializationRecord : CXXClassRecord {
ClassTemplateSpecializationRecordClassTemplateSpecializationRecord1218   ClassTemplateSpecializationRecord(
1219       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1220       AvailabilityInfo Availability, const DocComment &Comment,
1221       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1222       AccessControl Access, bool IsFromSystemHeader)
1223       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1224                        Declaration, SubHeading, RK_ClassTemplateSpecialization,
1225                        Access, IsFromSystemHeader) {}
1226 
classofClassTemplateSpecializationRecord1227   static bool classof(const APIRecord *Record) {
1228     return classofKind(Record->getKind());
1229   }
classofKindClassTemplateSpecializationRecord1230   static bool classofKind(RecordKind K) {
1231     return K == RK_ClassTemplateSpecialization;
1232   }
1233 };
1234 
1235 struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
1236   Template Templ;
ClassTemplatePartialSpecializationRecordClassTemplatePartialSpecializationRecord1237   ClassTemplatePartialSpecializationRecord(
1238       StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
1239       AvailabilityInfo Availability, const DocComment &Comment,
1240       DeclarationFragments Declaration, DeclarationFragments SubHeading,
1241       Template Template, AccessControl Access, bool IsFromSystemHeader)
1242       : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
1243                        Declaration, SubHeading,
1244                        RK_ClassTemplatePartialSpecialization, Access,
1245                        IsFromSystemHeader),
1246         Templ(Template) {}
1247 
classofClassTemplatePartialSpecializationRecord1248   static bool classof(const APIRecord *Record) {
1249     return classofKind(Record->getKind());
1250   }
classofKindClassTemplatePartialSpecializationRecord1251   static bool classofKind(RecordKind K) {
1252     return K == RK_ClassTemplatePartialSpecialization;
1253   }
1254 };
1255 
1256 struct ConceptRecord : APIRecord {
1257   Template Templ;
1258 
ConceptRecordConceptRecord1259   ConceptRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1260                 PresumedLoc Loc, AvailabilityInfo Availability,
1261                 const DocComment &Comment, DeclarationFragments Declaration,
1262                 DeclarationFragments SubHeading, Template Template,
1263                 bool IsFromSystemHeader)
1264       : APIRecord(RK_Concept, USR, Name, Parent, Loc, std::move(Availability),
1265                   LinkageInfo::none(), Comment, Declaration, SubHeading,
1266                   IsFromSystemHeader),
1267         Templ(Template) {}
1268 
classofConceptRecord1269   static bool classof(const APIRecord *Record) {
1270     return classofKind(Record->getKind());
1271   }
classofKindConceptRecord1272   static bool classofKind(RecordKind K) { return K == RK_Concept; }
1273 };
1274 
1275 /// This holds information associated with Objective-C categories.
1276 struct ObjCCategoryRecord : ObjCContainerRecord {
1277   SymbolReference Interface;
1278 
ObjCCategoryRecordObjCCategoryRecord1279   ObjCCategoryRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1280                      PresumedLoc Loc, AvailabilityInfo Availability,
1281                      const DocComment &Comment,
1282                      DeclarationFragments Declaration,
1283                      DeclarationFragments SubHeading, SymbolReference Interface,
1284                      bool IsFromSystemHeader)
1285       : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Parent, Loc,
1286                             std::move(Availability), LinkageInfo::none(),
1287                             Comment, Declaration, SubHeading,
1288                             IsFromSystemHeader),
1289         Interface(Interface) {}
1290 
classofObjCCategoryRecord1291   static bool classof(const APIRecord *Record) {
1292     return classofKind(Record->getKind());
1293   }
classofKindObjCCategoryRecord1294   static bool classofKind(RecordKind K) { return K == RK_ObjCCategory; }
1295 
isExtendingExternalModuleObjCCategoryRecord1296   bool isExtendingExternalModule() const { return !Interface.Source.empty(); }
1297 
getExtendedExternalModuleObjCCategoryRecord1298   std::optional<StringRef> getExtendedExternalModule() const {
1299     if (!isExtendingExternalModule())
1300       return {};
1301     return Interface.Source;
1302   }
1303 
1304 private:
1305   virtual void anchor();
1306 };
1307 
1308 /// This holds information associated with Objective-C interfaces/classes.
1309 struct ObjCInterfaceRecord : ObjCContainerRecord {
1310   SymbolReference SuperClass;
1311 
ObjCInterfaceRecordObjCInterfaceRecord1312   ObjCInterfaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1313                       PresumedLoc Loc, AvailabilityInfo Availability,
1314                       LinkageInfo Linkage, const DocComment &Comment,
1315                       DeclarationFragments Declaration,
1316                       DeclarationFragments SubHeading,
1317                       SymbolReference SuperClass, bool IsFromSystemHeader)
1318       : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Parent, Loc,
1319                             std::move(Availability), Linkage, Comment,
1320                             Declaration, SubHeading, IsFromSystemHeader),
1321         SuperClass(SuperClass) {}
1322 
classofObjCInterfaceRecord1323   static bool classof(const APIRecord *Record) {
1324     return classofKind(Record->getKind());
1325   }
classofKindObjCInterfaceRecord1326   static bool classofKind(RecordKind K) { return K == RK_ObjCInterface; }
1327 
1328 private:
1329   virtual void anchor();
1330 };
1331 
1332 /// This holds information associated with Objective-C protocols.
1333 struct ObjCProtocolRecord : ObjCContainerRecord {
ObjCProtocolRecordObjCProtocolRecord1334   ObjCProtocolRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1335                      PresumedLoc Loc, AvailabilityInfo Availability,
1336                      const DocComment &Comment,
1337                      DeclarationFragments Declaration,
1338                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
1339       : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Parent, Loc,
1340                             std::move(Availability), LinkageInfo::none(),
1341                             Comment, Declaration, SubHeading,
1342                             IsFromSystemHeader) {}
1343 
classofObjCProtocolRecord1344   static bool classof(const APIRecord *Record) {
1345     return classofKind(Record->getKind());
1346   }
classofKindObjCProtocolRecord1347   static bool classofKind(RecordKind K) { return K == RK_ObjCProtocol; }
1348 
1349 private:
1350   virtual void anchor();
1351 };
1352 
1353 /// This holds information associated with macro definitions.
1354 struct MacroDefinitionRecord : APIRecord {
MacroDefinitionRecordMacroDefinitionRecord1355   MacroDefinitionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1356                         PresumedLoc Loc, DeclarationFragments Declaration,
1357                         DeclarationFragments SubHeading,
1358                         bool IsFromSystemHeader)
1359       : APIRecord(RK_MacroDefinition, USR, Name, Parent, Loc,
1360                   AvailabilityInfo(), LinkageInfo(), {}, Declaration,
1361                   SubHeading, IsFromSystemHeader) {}
1362 
classofMacroDefinitionRecord1363   static bool classof(const APIRecord *Record) {
1364     return classofKind(Record->getKind());
1365   }
classofKindMacroDefinitionRecord1366   static bool classofKind(RecordKind K) { return K == RK_MacroDefinition; }
1367 
1368 private:
1369   virtual void anchor();
1370 };
1371 
1372 /// This holds information associated with typedefs.
1373 ///
1374 /// Note: Typedefs for anonymous enums and structs typically don't get emitted
1375 /// by the serializers but still get a TypedefRecord. Instead we use the
1376 /// typedef name as a name for the underlying anonymous struct or enum.
1377 struct TypedefRecord : APIRecord {
1378   SymbolReference UnderlyingType;
1379 
TypedefRecordTypedefRecord1380   TypedefRecord(StringRef USR, StringRef Name, SymbolReference Parent,
1381                 PresumedLoc Loc, AvailabilityInfo Availability,
1382                 const DocComment &Comment, DeclarationFragments Declaration,
1383                 DeclarationFragments SubHeading, SymbolReference UnderlyingType,
1384                 bool IsFromSystemHeader)
1385       : APIRecord(RK_Typedef, USR, Name, Parent, Loc, std::move(Availability),
1386                   LinkageInfo(), Comment, Declaration, SubHeading,
1387                   IsFromSystemHeader),
1388         UnderlyingType(UnderlyingType) {}
1389 
classofTypedefRecord1390   static bool classof(const APIRecord *Record) {
1391     return classofKind(Record->getKind());
1392   }
classofKindTypedefRecord1393   static bool classofKind(RecordKind K) { return K == RK_Typedef; }
1394 
1395 private:
1396   virtual void anchor();
1397 };
1398 
1399 /// APISet holds the set of API records collected from given inputs.
1400 class APISet {
1401 public:
1402   /// Get the target triple for the ExtractAPI invocation.
getTarget()1403   const llvm::Triple &getTarget() const { return Target; }
1404 
1405   /// Get the language used by the APIs.
getLanguage()1406   Language getLanguage() const { return Lang; }
1407 
1408   /// Finds the APIRecord for a given USR.
1409   ///
1410   /// \returns a pointer to the APIRecord associated with that USR or nullptr.
1411   APIRecord *findRecordForUSR(StringRef USR) const;
1412 
1413   /// Copy \p String into the Allocator in this APISet.
1414   ///
1415   /// \returns a StringRef of the copied string in APISet::Allocator.
1416   StringRef copyString(StringRef String);
1417 
1418   SymbolReference createSymbolReference(StringRef Name, StringRef USR,
1419                                         StringRef Source = "");
1420 
1421   /// Create a subclass of \p APIRecord and store it in the APISet.
1422   ///
1423   /// \returns A pointer to the created record or the already existing record
1424   /// matching this USR.
1425   template <typename RecordTy, typename... CtorArgsContTy>
1426   typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
1427   createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
1428 
getTopLevelRecords()1429   ArrayRef<const APIRecord *> getTopLevelRecords() const {
1430     return TopLevelRecords;
1431   }
1432 
APISet(const llvm::Triple & Target,Language Lang,const std::string & ProductName)1433   APISet(const llvm::Triple &Target, Language Lang,
1434          const std::string &ProductName)
1435       : Target(Target), Lang(Lang), ProductName(ProductName) {}
1436 
1437   // Prevent moves and copies
1438   APISet(const APISet &Other) = delete;
1439   APISet &operator=(const APISet &Other) = delete;
1440   APISet(APISet &&Other) = delete;
1441   APISet &operator=(APISet &&Other) = delete;
1442 
1443 private:
1444   /// BumpPtrAllocator that serves as the memory arena for the allocated objects
1445   llvm::BumpPtrAllocator Allocator;
1446 
1447   const llvm::Triple Target;
1448   const Language Lang;
1449 
1450   struct APIRecordDeleter {
operatorAPIRecordDeleter1451     void operator()(APIRecord *Record) { Record->~APIRecord(); }
1452   };
1453 
1454   // Ensure that the destructor of each record is called when the LookupTable is
1455   // destroyed without calling delete operator as the memory for the record
1456   // lives in the BumpPtrAllocator.
1457   using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
1458   llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
1459   std::vector<const APIRecord *> TopLevelRecords;
1460 
1461 public:
1462   const std::string ProductName;
1463 };
1464 
1465 template <typename RecordTy, typename... CtorArgsContTy>
1466 typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
createRecord(StringRef USR,StringRef Name,CtorArgsContTy &&...CtorArgs)1467 APISet::createRecord(StringRef USR, StringRef Name,
1468                      CtorArgsContTy &&...CtorArgs) {
1469   // Ensure USR refers to a String stored in the allocator.
1470   auto USRString = copyString(USR);
1471   auto Result = USRBasedLookupTable.insert({USRString, nullptr});
1472   RecordTy *Record;
1473 
1474   // Create the record if it does not already exist
1475   if (Result.second) {
1476     Record = new (Allocator) RecordTy(
1477         USRString, copyString(Name), std::forward<CtorArgsContTy>(CtorArgs)...);
1478     // Store the record in the record lookup map
1479     Result.first->second = APIRecordStoredPtr(Record);
1480 
1481     if (auto *ParentContext =
1482             dyn_cast_if_present<RecordContext>(Record->Parent.Record))
1483       ParentContext->addToRecordChain(Record);
1484     else
1485       TopLevelRecords.push_back(Record);
1486   } else {
1487     Record = dyn_cast<RecordTy>(Result.first->second.get());
1488   }
1489 
1490   return Record;
1491 }
1492 
1493 // Helper type for implementing casting to RecordContext pointers.
1494 // Selected when FromTy not a known subclass of RecordContext.
1495 template <typename FromTy,
1496           bool IsKnownSubType = std::is_base_of_v<RecordContext, FromTy>>
1497 struct ToRecordContextCastInfoWrapper {
1498   static_assert(std::is_base_of_v<APIRecord, FromTy>,
1499                 "Can only cast APIRecord and derived classes to RecordContext");
1500 
isPossibleToRecordContextCastInfoWrapper1501   static bool isPossible(FromTy *From) { return RecordContext::classof(From); }
1502 
doCastToRecordContextCastInfoWrapper1503   static RecordContext *doCast(FromTy *From) {
1504     return APIRecord::castToRecordContext(From);
1505   }
1506 };
1507 
1508 // Selected when FromTy is a known subclass of RecordContext.
1509 template <typename FromTy> struct ToRecordContextCastInfoWrapper<FromTy, true> {
1510   static_assert(std::is_base_of_v<APIRecord, FromTy>,
1511                 "Can only cast APIRecord and derived classes to RecordContext");
1512   static bool isPossible(const FromTy *From) { return true; }
1513   static RecordContext *doCast(FromTy *From) {
1514     return static_cast<RecordContext *>(From);
1515   }
1516 };
1517 
1518 // Helper type for implementing casting to RecordContext pointers.
1519 // Selected when ToTy isn't a known subclass of RecordContext
1520 template <typename ToTy,
1521           bool IsKnownSubType = std::is_base_of_v<RecordContext, ToTy>>
1522 struct FromRecordContextCastInfoWrapper {
1523   static_assert(
1524       std::is_base_of_v<APIRecord, ToTy>,
1525       "Can only class RecordContext to APIRecord and derived classes");
1526 
1527   static bool isPossible(RecordContext *Ctx) {
1528     return ToTy::classofKind(Ctx->getKind());
1529   }
1530 
1531   static ToTy *doCast(RecordContext *Ctx) {
1532     return APIRecord::castFromRecordContext(Ctx);
1533   }
1534 };
1535 
1536 // Selected when ToTy is a known subclass of RecordContext.
1537 template <typename ToTy> struct FromRecordContextCastInfoWrapper<ToTy, true> {
1538   static_assert(
1539       std::is_base_of_v<APIRecord, ToTy>,
1540       "Can only class RecordContext to APIRecord and derived classes");
1541   static bool isPossible(RecordContext *Ctx) {
1542     return ToTy::classof(Ctx->getKind());
1543   }
1544   static RecordContext *doCast(RecordContext *Ctx) {
1545     return static_cast<ToTy *>(Ctx);
1546   }
1547 };
1548 
1549 } // namespace extractapi
1550 } // namespace clang
1551 
1552 // Implement APIRecord (and derived classes) to and from RecordContext
1553 // conversions
1554 namespace llvm {
1555 
1556 template <typename FromTy>
1557 struct CastInfo<::clang::extractapi::RecordContext, FromTy *>
1558     : public NullableValueCastFailed<::clang::extractapi::RecordContext *>,
1559       public DefaultDoCastIfPossible<
1560           ::clang::extractapi::RecordContext *, FromTy *,
1561           CastInfo<::clang::extractapi::RecordContext, FromTy *>> {
1562   static inline bool isPossible(FromTy *From) {
1563     return ::clang::extractapi::ToRecordContextCastInfoWrapper<
1564         FromTy>::isPossible(From);
1565   }
1566 
1567   static inline ::clang::extractapi::RecordContext *doCast(FromTy *From) {
1568     return ::clang::extractapi::ToRecordContextCastInfoWrapper<FromTy>::doCast(
1569         From);
1570   }
1571 };
1572 
1573 template <typename FromTy>
1574 struct CastInfo<::clang::extractapi::RecordContext, const FromTy *>
1575     : public ConstStrippingForwardingCast<
1576           ::clang::extractapi::RecordContext, const FromTy *,
1577           CastInfo<::clang::extractapi::RecordContext, FromTy *>> {};
1578 
1579 template <typename ToTy>
1580 struct CastInfo<ToTy, ::clang::extractapi::RecordContext *>
1581     : public NullableValueCastFailed<ToTy *>,
1582       public DefaultDoCastIfPossible<
1583           ToTy *, ::clang::extractapi::RecordContext *,
1584           CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {
1585   static inline bool isPossible(::clang::extractapi::RecordContext *Ctx) {
1586     return ::clang::extractapi::FromRecordContextCastInfoWrapper<
1587         ToTy>::isPossible(Ctx);
1588   }
1589 
1590   static inline ToTy *doCast(::clang::extractapi::RecordContext *Ctx) {
1591     return ::clang::extractapi::FromRecordContextCastInfoWrapper<ToTy>::doCast(
1592         Ctx);
1593   }
1594 };
1595 
1596 template <typename ToTy>
1597 struct CastInfo<ToTy, const ::clang::extractapi::RecordContext *>
1598     : public ConstStrippingForwardingCast<
1599           ToTy, const ::clang::extractapi::RecordContext *,
1600           CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {};
1601 
1602 } // namespace llvm
1603 
1604 #endif // LLVM_CLANG_EXTRACTAPI_API_H
1605