File indexing completed on 2026-05-10 08:36:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
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
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)
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)
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)
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
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 using DocComment = std::vector<RawComment::CommentLine>;
0152
0153 struct APIRecord;
0154
0155
0156
0157 struct SymbolReference {
0158 StringRef Name;
0159 StringRef USR;
0160
0161
0162 StringRef Source;
0163
0164
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
0173
0174
0175 bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
0176 };
0177
0178 class RecordContext;
0179
0180
0181
0182
0183
0184
0185 struct APIRecord {
0186
0187 enum RecordKind {
0188 RK_Unknown,
0189
0190
0191
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
0244 DocComment Comment;
0245
0246
0247 DeclarationFragments Declaration;
0248
0249
0250
0251
0252
0253
0254
0255 DeclarationFragments SubHeading;
0256
0257
0258 bool IsFromSystemHeader;
0259
0260 AccessControl Access;
0261
0262 RecordKind KindForDisplay;
0263
0264 private:
0265 const RecordKind Kind;
0266 friend class RecordContext;
0267
0268
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
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
0305
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
0321
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
0343
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
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
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
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
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
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
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
1002 struct ObjCPropertyRecord : APIRecord {
1003
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
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
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
1178
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
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
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
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
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
1400
1401
1402
1403
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
1427 class APISet {
1428 public:
1429
1430 const llvm::Triple &getTarget() const { return Target; }
1431
1432
1433 Language getLanguage() const { return Lang; }
1434
1435
1436
1437
1438 APIRecord *findRecordForUSR(StringRef USR) const;
1439
1440
1441
1442
1443 StringRef copyString(StringRef String);
1444
1445 SymbolReference createSymbolReference(StringRef Name, StringRef USR,
1446 StringRef Source = "");
1447
1448
1449
1450
1451
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
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
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
1486
1487
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
1501 auto USRString = copyString(USR);
1502 auto Result = USRBasedLookupTable.insert({USRString, nullptr});
1503 RecordTy *Record;
1504
1505
1506 if (Result.second) {
1507 Record = new (Allocator) RecordTy(
1508 USRString, copyString(Name), std::forward<CtorArgsContTy>(CtorArgs)...);
1509
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
1525
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
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
1550
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
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 }
1581 }
1582
1583
1584
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 }
1634
1635 #endif