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/DeclBase.h"
23 #include "clang/AST/RawCommentList.h"
24 #include "clang/Basic/SourceLocation.h"
25 #include "clang/ExtractAPI/DeclarationFragments.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/TargetParser/Triple.h"
31 #include <cstddef>
32 #include <iterator>
33 #include <memory>
34 #include <optional>
35 #include <type_traits>
36
37 namespace clang {
38 namespace extractapi {
39
40 class Template {
41 struct TemplateParameter {
42 // "class", "typename", or concept name
43 std::string Type;
44 std::string Name;
45 unsigned int Index;
46 unsigned int Depth;
47 bool IsParameterPack;
48
TemplateParameterTemplateParameter49 TemplateParameter(std::string Type, std::string Name, unsigned int Index,
50 unsigned int Depth, bool IsParameterPack)
51 : Type(Type), Name(Name), Index(Index), Depth(Depth),
52 IsParameterPack(IsParameterPack) {}
53 };
54
55 struct TemplateConstraint {
56 // type name of the constraint, if it has one
57 std::string Type;
58 std::string Kind;
59 std::string LHS, RHS;
60 };
61 llvm::SmallVector<TemplateParameter> Parameters;
62 llvm::SmallVector<TemplateConstraint> Constraints;
63
64 public:
65 Template() = default;
66
Template(const TemplateDecl * Decl)67 Template(const TemplateDecl *Decl) {
68 for (auto *const Parameter : *Decl->getTemplateParameters()) {
69 const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
70 if (!Param) // some params are null
71 continue;
72 std::string Type;
73 if (Param->hasTypeConstraint())
74 Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
75 else if (Param->wasDeclaredWithTypename())
76 Type = "typename";
77 else
78 Type = "class";
79
80 addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
81 Param->getDepth(), Param->isParameterPack());
82 }
83 }
84
Template(const ClassTemplatePartialSpecializationDecl * Decl)85 Template(const ClassTemplatePartialSpecializationDecl *Decl) {
86 for (auto *const Parameter : *Decl->getTemplateParameters()) {
87 const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
88 if (!Param) // some params are null
89 continue;
90 std::string Type;
91 if (Param->hasTypeConstraint())
92 Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
93 else if (Param->wasDeclaredWithTypename())
94 Type = "typename";
95 else
96 Type = "class";
97
98 addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
99 Param->getDepth(), Param->isParameterPack());
100 }
101 }
102
Template(const VarTemplatePartialSpecializationDecl * Decl)103 Template(const VarTemplatePartialSpecializationDecl *Decl) {
104 for (auto *const Parameter : *Decl->getTemplateParameters()) {
105 const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
106 if (!Param) // some params are null
107 continue;
108 std::string Type;
109 if (Param->hasTypeConstraint())
110 Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
111 else if (Param->wasDeclaredWithTypename())
112 Type = "typename";
113 else
114 Type = "class";
115
116 addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
117 Param->getDepth(), Param->isParameterPack());
118 }
119 }
120
getParameters()121 const llvm::SmallVector<TemplateParameter> &getParameters() const {
122 return Parameters;
123 }
124
getConstraints()125 const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
126 return Constraints;
127 }
128
addTemplateParameter(std::string Type,std::string Name,unsigned int Index,unsigned int Depth,bool IsParameterPack)129 void addTemplateParameter(std::string Type, std::string Name,
130 unsigned int Index, unsigned int Depth,
131 bool IsParameterPack) {
132 Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
133 }
134
empty()135 bool empty() const { return Parameters.empty() && Constraints.empty(); }
136 };
137
138 /// DocComment is a vector of RawComment::CommentLine.
139 ///
140 /// Each line represents one line of striped documentation comment,
141 /// with source range information. This simplifies calculating the source
142 /// location of a character in the doc comment for pointing back to the source
143 /// file.
144 /// e.g.
145 /// \code
146 /// /// This is a documentation comment
147 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' First line.
148 /// /// with multiple lines.
149 /// ^~~~~~~~~~~~~~~~~~~~~~~' Second line.
150 /// \endcode
151 using DocComment = std::vector<RawComment::CommentLine>;
152
153 struct APIRecord;
154
155 // This represents a reference to another symbol that might come from external
156 /// sources.
157 struct SymbolReference {
158 StringRef Name;
159 StringRef USR;
160
161 /// The source project/module/product of the referred symbol.
162 StringRef Source;
163
164 // A Pointer to the APIRecord for this reference if known
165 const APIRecord *Record = nullptr;
166
167 SymbolReference() = default;
168 SymbolReference(StringRef Name, StringRef USR, StringRef Source = "")
NameSymbolReference169 : Name(Name), USR(USR), Source(Source) {}
170 SymbolReference(const APIRecord *R);
171
172 /// Determine if this SymbolReference is empty.
173 ///
174 /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
emptySymbolReference175 bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
176 };
177
178 class RecordContext;
179
180 // Concrete classes deriving from APIRecord need to have a construct with first
181 // arguments USR, and Name, in that order. This is so that they
182 // are compatible with `APISet::createRecord`.
183 // When adding a new kind of record don't forget to update APIRecords.inc!
184 /// The base representation of an API record. Holds common symbol information.
185 struct APIRecord {
186 /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
187 enum RecordKind {
188 RK_Unknown,
189 // If adding a record context record kind here make sure to update
190 // RecordContext::classof if needed and add a RECORD_CONTEXT entry to
191 // APIRecords.inc
192 RK_FirstRecordContext,
193 RK_Namespace,
194 RK_Enum,
195 RK_Struct,
196 RK_Union,
197 RK_ObjCInterface,
198 RK_ObjCCategory,
199 RK_ObjCProtocol,
200 RK_CXXClass,
201 RK_ClassTemplate,
202 RK_ClassTemplateSpecialization,
203 RK_ClassTemplatePartialSpecialization,
204 RK_StructField,
205 RK_UnionField,
206 RK_CXXField,
207 RK_StaticField,
208 RK_CXXFieldTemplate,
209 RK_GlobalVariable,
210 RK_GlobalVariableTemplate,
211 RK_GlobalVariableTemplateSpecialization,
212 RK_GlobalVariableTemplatePartialSpecialization,
213 RK_LastRecordContext,
214 RK_GlobalFunction,
215 RK_GlobalFunctionTemplate,
216 RK_GlobalFunctionTemplateSpecialization,
217 RK_EnumConstant,
218 RK_Concept,
219 RK_CXXStaticMethod,
220 RK_CXXInstanceMethod,
221 RK_CXXConstructorMethod,
222 RK_CXXDestructorMethod,
223 RK_CXXMethodTemplate,
224 RK_CXXMethodTemplateSpecialization,
225 RK_ObjCInstanceProperty,
226 RK_ObjCClassProperty,
227 RK_ObjCIvar,
228 RK_ObjCClassMethod,
229 RK_ObjCInstanceMethod,
230 RK_MacroDefinition,
231 RK_Typedef,
232 };
233
234 StringRef USR;
235 StringRef Name;
236
237 SymbolReference Parent;
238
239 PresumedLoc Location;
240 AvailabilityInfo Availability;
241 LinkageInfo Linkage;
242
243 /// Documentation comment lines attached to this symbol declaration.
244 DocComment Comment;
245
246 /// Declaration fragments of this symbol declaration.
247 DeclarationFragments Declaration;
248
249 /// SubHeading provides a more detailed representation than the plain
250 /// declaration name.
251 ///
252 /// SubHeading is an array of declaration fragments of tagged declaration
253 /// name, with potentially more tokens (for example the \c +/- symbol for
254 /// Objective-C class/instance methods).
255 DeclarationFragments SubHeading;
256
257 /// Whether the symbol was defined in a system header.
258 bool IsFromSystemHeader;
259
260 AccessControl Access;
261
262 RecordKind KindForDisplay;
263
264 private:
265 const RecordKind Kind;
266 friend class RecordContext;
267 // Used to store the next child record in RecordContext. This works because
268 // APIRecords semantically only have one parent.
269 mutable APIRecord *NextInContext = nullptr;
270
271 public:
getNextInContextAPIRecord272 APIRecord *getNextInContext() const { return NextInContext; }
273
getKindAPIRecord274 RecordKind getKind() const { return Kind; }
getKindForDisplayAPIRecord275 RecordKind getKindForDisplay() const { return KindForDisplay; }
276
277 static APIRecord *castFromRecordContext(const RecordContext *Ctx);
278 static RecordContext *castToRecordContext(const APIRecord *Record);
279
280 APIRecord() = delete;
281
282 APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
283 SymbolReference Parent, PresumedLoc Location,
284 AvailabilityInfo Availability, LinkageInfo Linkage,
285 const DocComment &Comment, DeclarationFragments Declaration,
286 DeclarationFragments SubHeading, bool IsFromSystemHeader,
287 AccessControl Access = AccessControl())
USRAPIRecord288 : USR(USR), Name(Name), Parent(std::move(Parent)), Location(Location),
289 Availability(std::move(Availability)), Linkage(Linkage),
290 Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
291 IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
292 KindForDisplay(Kind), Kind(Kind) {}
293
APIRecordAPIRecord294 APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
295 : USR(USR), Name(Name), KindForDisplay(Kind), Kind(Kind) {}
296
297 // Pure virtual destructor to make APIRecord abstract
298 virtual ~APIRecord() = 0;
classofAPIRecord299 static bool classof(const APIRecord *Record) { return true; }
classofKindAPIRecord300 static bool classofKind(RecordKind K) { return true; }
classofAPIRecord301 static bool classof(const RecordContext *Ctx) { return true; }
302 };
303
304 /// Base class used for specific record types that have children records this is
305 /// analogous to the DeclContext for the AST
306 class RecordContext {
307 public:
classof(const APIRecord * Record)308 static bool classof(const APIRecord *Record) {
309 return classofKind(Record->getKind());
310 }
classofKind(APIRecord::RecordKind K)311 static bool classofKind(APIRecord::RecordKind K) {
312 return K > APIRecord::RK_FirstRecordContext &&
313 K < APIRecord::RK_LastRecordContext;
314 }
315
classof(const RecordContext * Context)316 static bool classof(const RecordContext *Context) { return true; }
317
RecordContext(APIRecord::RecordKind Kind)318 RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
319
320 /// Append \p Other children chain into ours and empty out Other's record
321 /// chain.
322 void stealRecordChain(RecordContext &Other);
323
324 void removeFromRecordChain(APIRecord *Record);
325
getKind()326 APIRecord::RecordKind getKind() const { return Kind; }
327
328 struct record_iterator {
329 private:
330 APIRecord *Current = nullptr;
331
332 public:
333 using value_type = APIRecord *;
334 using reference = const value_type &;
335 using pointer = const value_type *;
336 using iterator_category = std::forward_iterator_tag;
337 using difference_type = std::ptrdiff_t;
338
339 record_iterator() = default;
record_iteratorrecord_iterator340 explicit record_iterator(value_type R) : Current(R) {}
341 reference operator*() const { return Current; }
342 // This doesn't strictly meet the iterator requirements, but it's the
343 // behavior we want here.
344 value_type operator->() const { return Current; }
345 record_iterator &operator++() {
346 Current = Current->getNextInContext();
347 return *this;
348 }
349 record_iterator operator++(int) {
350 record_iterator tmp(*this);
351 ++(*this);
352 return tmp;
353 }
354
355 friend bool operator==(record_iterator x, record_iterator y) {
356 return x.Current == y.Current;
357 }
358 friend bool operator!=(record_iterator x, record_iterator y) {
359 return x.Current != y.Current;
360 }
361 };
362
363 using record_range = llvm::iterator_range<record_iterator>;
records()364 record_range records() const {
365 return record_range(records_begin(), records_end());
366 }
records_begin()367 record_iterator records_begin() const { return record_iterator(First); };
records_end()368 record_iterator records_end() const { return record_iterator(); }
records_empty()369 bool records_empty() const { return First == nullptr; };
370
371 private:
372 APIRecord::RecordKind Kind;
373 mutable APIRecord *First = nullptr;
374 mutable APIRecord *Last = nullptr;
375 bool IsWellFormed() const;
376
377 protected:
378 friend class APISet;
379 void addToRecordChain(APIRecord *) const;
380 };
381
382 struct NamespaceRecord : APIRecord, RecordContext {
NamespaceRecordNamespaceRecord383 NamespaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
384 PresumedLoc Loc, AvailabilityInfo Availability,
385 LinkageInfo Linkage, const DocComment &Comment,
386 DeclarationFragments Declaration,
387 DeclarationFragments SubHeading, bool IsFromSystemHeader)
388 : APIRecord(RK_Namespace, USR, Name, Parent, Loc, std::move(Availability),
389 Linkage, Comment, Declaration, SubHeading,
390 IsFromSystemHeader),
391 RecordContext(RK_Namespace) {}
392
classofNamespaceRecord393 static bool classof(const APIRecord *Record) {
394 return classofKind(Record->getKind());
395 }
classofKindNamespaceRecord396 static bool classofKind(RecordKind K) { return K == RK_Namespace; }
397 };
398
399 /// This holds information associated with global functions.
400 struct GlobalFunctionRecord : APIRecord {
401 FunctionSignature Signature;
402
GlobalFunctionRecordGlobalFunctionRecord403 GlobalFunctionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
404 PresumedLoc Loc, AvailabilityInfo Availability,
405 LinkageInfo Linkage, const DocComment &Comment,
406 DeclarationFragments Declaration,
407 DeclarationFragments SubHeading,
408 FunctionSignature Signature, bool IsFromSystemHeader)
409 : APIRecord(RK_GlobalFunction, USR, Name, Parent, Loc,
410 std::move(Availability), Linkage, Comment, Declaration,
411 SubHeading, IsFromSystemHeader),
412 Signature(Signature) {}
413
GlobalFunctionRecordGlobalFunctionRecord414 GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
415 SymbolReference Parent, PresumedLoc Loc,
416 AvailabilityInfo Availability, LinkageInfo Linkage,
417 const DocComment &Comment,
418 DeclarationFragments Declaration,
419 DeclarationFragments SubHeading,
420 FunctionSignature Signature, bool IsFromSystemHeader)
421 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
422 Linkage, Comment, Declaration, SubHeading,
423 IsFromSystemHeader),
424 Signature(Signature) {}
425
classofGlobalFunctionRecord426 static bool classof(const APIRecord *Record) {
427 return classofKind(Record->getKind());
428 }
classofKindGlobalFunctionRecord429 static bool classofKind(RecordKind K) { return K == RK_GlobalFunction; }
430
431 private:
432 virtual void anchor();
433 };
434
435 struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
436 Template Templ;
437
GlobalFunctionTemplateRecordGlobalFunctionTemplateRecord438 GlobalFunctionTemplateRecord(StringRef USR, StringRef Name,
439 SymbolReference Parent, PresumedLoc Loc,
440 AvailabilityInfo Availability,
441 LinkageInfo Linkage, const DocComment &Comment,
442 DeclarationFragments Declaration,
443 DeclarationFragments SubHeading,
444 FunctionSignature Signature, Template Template,
445 bool IsFromSystemHeader)
446 : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Parent, Loc,
447 std::move(Availability), Linkage, Comment,
448 Declaration, SubHeading, Signature,
449 IsFromSystemHeader),
450 Templ(Template) {}
451
classofGlobalFunctionTemplateRecord452 static bool classof(const APIRecord *Record) {
453 return classofKind(Record->getKind());
454 }
classofKindGlobalFunctionTemplateRecord455 static bool classofKind(RecordKind K) {
456 return K == RK_GlobalFunctionTemplate;
457 }
458 };
459
460 struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
GlobalFunctionTemplateSpecializationRecordGlobalFunctionTemplateSpecializationRecord461 GlobalFunctionTemplateSpecializationRecord(
462 StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
463 AvailabilityInfo Availability, LinkageInfo Linkage,
464 const DocComment &Comment, DeclarationFragments Declaration,
465 DeclarationFragments SubHeading, FunctionSignature Signature,
466 bool IsFromSystemHeader)
467 : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
468 Parent, Loc, std::move(Availability), Linkage,
469 Comment, Declaration, SubHeading, Signature,
470 IsFromSystemHeader) {}
471
classofGlobalFunctionTemplateSpecializationRecord472 static bool classof(const APIRecord *Record) {
473 return classofKind(Record->getKind());
474 }
classofKindGlobalFunctionTemplateSpecializationRecord475 static bool classofKind(RecordKind K) {
476 return K == RK_GlobalFunctionTemplateSpecialization;
477 }
478 };
479
480 /// This holds information associated with global functions.
481 struct GlobalVariableRecord : APIRecord, RecordContext {
GlobalVariableRecordGlobalVariableRecord482 GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
483 PresumedLoc Loc, AvailabilityInfo Availability,
484 LinkageInfo Linkage, const DocComment &Comment,
485 DeclarationFragments Declaration,
486 DeclarationFragments SubHeading, bool IsFromSystemHeader)
487 : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
488 std::move(Availability), Linkage, Comment, Declaration,
489 SubHeading, IsFromSystemHeader),
490 RecordContext(RK_GlobalVariable) {}
491
GlobalVariableRecordGlobalVariableRecord492 GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
493 SymbolReference Parent, PresumedLoc Loc,
494 AvailabilityInfo Availability, LinkageInfo Linkage,
495 const DocComment &Comment,
496 DeclarationFragments Declaration,
497 DeclarationFragments SubHeading, bool IsFromSystemHeader)
498 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
499 Linkage, Comment, Declaration, SubHeading,
500 IsFromSystemHeader),
501 RecordContext(Kind) {}
502
classofGlobalVariableRecord503 static bool classof(const APIRecord *Record) {
504 return classofKind(Record->getKind());
505 }
classofKindGlobalVariableRecord506 static bool classofKind(RecordKind K) {
507 return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
508 K == RK_GlobalVariableTemplateSpecialization ||
509 K == RK_GlobalVariableTemplatePartialSpecialization;
510 }
511
512 private:
513 virtual void anchor();
514 };
515
516 struct GlobalVariableTemplateRecord : GlobalVariableRecord {
517 Template Templ;
518
GlobalVariableTemplateRecordGlobalVariableTemplateRecord519 GlobalVariableTemplateRecord(StringRef USR, StringRef Name,
520 SymbolReference Parent, PresumedLoc Loc,
521 AvailabilityInfo Availability,
522 LinkageInfo Linkage, const DocComment &Comment,
523 DeclarationFragments Declaration,
524 DeclarationFragments SubHeading,
525 class Template Template, bool IsFromSystemHeader)
526 : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Parent, Loc,
527 std::move(Availability), Linkage, Comment,
528 Declaration, SubHeading, IsFromSystemHeader),
529 Templ(Template) {}
530
classofGlobalVariableTemplateRecord531 static bool classof(const APIRecord *Record) {
532 return classofKind(Record->getKind());
533 }
classofKindGlobalVariableTemplateRecord534 static bool classofKind(RecordKind K) {
535 return K == RK_GlobalVariableTemplate;
536 }
537 };
538
539 struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
GlobalVariableTemplateSpecializationRecordGlobalVariableTemplateSpecializationRecord540 GlobalVariableTemplateSpecializationRecord(
541 StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
542 AvailabilityInfo Availability, LinkageInfo Linkage,
543 const DocComment &Comment, DeclarationFragments Declaration,
544 DeclarationFragments SubHeading, bool IsFromSystemHeader)
545 : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
546 Parent, Loc, std::move(Availability), Linkage,
547 Comment, Declaration, SubHeading,
548 IsFromSystemHeader) {}
549
classofGlobalVariableTemplateSpecializationRecord550 static bool classof(const APIRecord *Record) {
551 return classofKind(Record->getKind());
552 }
classofKindGlobalVariableTemplateSpecializationRecord553 static bool classofKind(RecordKind K) {
554 return K == RK_GlobalVariableTemplateSpecialization;
555 }
556 };
557
558 struct GlobalVariableTemplatePartialSpecializationRecord
559 : GlobalVariableRecord {
560 Template Templ;
561
GlobalVariableTemplatePartialSpecializationRecordGlobalVariableTemplatePartialSpecializationRecord562 GlobalVariableTemplatePartialSpecializationRecord(
563 StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
564 AvailabilityInfo Availability, LinkageInfo Linkage,
565 const DocComment &Comment, DeclarationFragments Declaration,
566 DeclarationFragments SubHeading, class Template Template,
567 bool IsFromSystemHeader)
568 : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
569 USR, Name, Parent, Loc, std::move(Availability),
570 Linkage, Comment, Declaration, SubHeading,
571 IsFromSystemHeader),
572 Templ(Template) {}
573
classofGlobalVariableTemplatePartialSpecializationRecord574 static bool classof(const APIRecord *Record) {
575 return classofKind(Record->getKind());
576 }
classofKindGlobalVariableTemplatePartialSpecializationRecord577 static bool classofKind(RecordKind K) {
578 return K == RK_GlobalVariableTemplatePartialSpecialization;
579 }
580 };
581
582 /// This holds information associated with enum constants.
583 struct EnumConstantRecord : APIRecord {
EnumConstantRecordEnumConstantRecord584 EnumConstantRecord(StringRef USR, StringRef Name, SymbolReference Parent,
585 PresumedLoc Loc, AvailabilityInfo Availability,
586 const DocComment &Comment,
587 DeclarationFragments Declaration,
588 DeclarationFragments SubHeading, bool IsFromSystemHeader)
589 : APIRecord(RK_EnumConstant, USR, Name, Parent, Loc,
590 std::move(Availability), LinkageInfo::none(), Comment,
591 Declaration, SubHeading, IsFromSystemHeader) {}
592
classofEnumConstantRecord593 static bool classof(const APIRecord *Record) {
594 return classofKind(Record->getKind());
595 }
classofKindEnumConstantRecord596 static bool classofKind(RecordKind K) { return K == RK_EnumConstant; }
597
598 private:
599 virtual void anchor();
600 };
601
602 struct TagRecord : APIRecord, RecordContext {
603 TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
604 SymbolReference Parent, PresumedLoc Loc,
605 AvailabilityInfo Availability, const DocComment &Comment,
606 DeclarationFragments Declaration, DeclarationFragments SubHeading,
607 bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
608 AccessControl Access = AccessControl())
APIRecordTagRecord609 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
610 LinkageInfo::none(), Comment, Declaration, SubHeading,
611 IsFromSystemHeader, std::move(Access)),
612 RecordContext(Kind),
613 IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};
614
classofTagRecord615 static bool classof(const APIRecord *Record) {
616 return classofKind(Record->getKind());
617 }
classofKindTagRecord618 static bool classofKind(RecordKind K) {
619 switch (K) {
620 case RK_Enum:
621 LLVM_FALLTHROUGH;
622 case RK_Struct:
623 LLVM_FALLTHROUGH;
624 case RK_Union:
625 LLVM_FALLTHROUGH;
626 case RK_CXXClass:
627 LLVM_FALLTHROUGH;
628 case RK_ClassTemplate:
629 LLVM_FALLTHROUGH;
630 case RK_ClassTemplateSpecialization:
631 LLVM_FALLTHROUGH;
632 case RK_ClassTemplatePartialSpecialization:
633 return true;
634 default:
635 return false;
636 }
637 }
638
639 bool IsEmbeddedInVarDeclarator;
640
641 virtual ~TagRecord() = 0;
642 };
643
644 /// This holds information associated with enums.
645 struct EnumRecord : TagRecord {
646 EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
647 PresumedLoc Loc, AvailabilityInfo Availability,
648 const DocComment &Comment, DeclarationFragments Declaration,
649 DeclarationFragments SubHeading, bool IsFromSystemHeader,
650 bool IsEmbeddedInVarDeclarator,
651 AccessControl Access = AccessControl())
TagRecordEnumRecord652 : TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
653 Comment, Declaration, SubHeading, IsFromSystemHeader,
654 IsEmbeddedInVarDeclarator, std::move(Access)) {}
655
classofEnumRecord656 static bool classof(const APIRecord *Record) {
657 return classofKind(Record->getKind());
658 }
659
classofKindEnumRecord660 static bool classofKind(RecordKind K) { return K == RK_Enum; }
661
662 private:
663 virtual void anchor();
664 };
665
666 /// This holds information associated with struct or union fields fields.
667 struct RecordFieldRecord : APIRecord, RecordContext {
RecordFieldRecordRecordFieldRecord668 RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
669 SymbolReference Parent, PresumedLoc Loc,
670 AvailabilityInfo Availability, const DocComment &Comment,
671 DeclarationFragments Declaration,
672 DeclarationFragments SubHeading, bool IsFromSystemHeader)
673 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
674 LinkageInfo::none(), Comment, Declaration, SubHeading,
675 IsFromSystemHeader),
676 RecordContext(Kind) {}
677
classofRecordFieldRecord678 static bool classof(const APIRecord *Record) {
679 return classofKind(Record->getKind());
680 }
classofKindRecordFieldRecord681 static bool classofKind(RecordKind K) {
682 return K == RK_StructField || K == RK_UnionField;
683 }
684
685 virtual ~RecordFieldRecord() = 0;
686 };
687
688 /// This holds information associated with structs and unions.
689 struct RecordRecord : TagRecord {
690 RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
691 SymbolReference Parent, PresumedLoc Loc,
692 AvailabilityInfo Availability, const DocComment &Comment,
693 DeclarationFragments Declaration,
694 DeclarationFragments SubHeading, bool IsFromSystemHeader,
695 bool IsEmbeddedInVarDeclarator,
696 AccessControl Access = AccessControl())
TagRecordRecordRecord697 : TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
698 Comment, Declaration, SubHeading, IsFromSystemHeader,
699 IsEmbeddedInVarDeclarator, std::move(Access)) {}
700
classofRecordRecord701 static bool classof(const APIRecord *Record) {
702 return classofKind(Record->getKind());
703 }
classofKindRecordRecord704 static bool classofKind(RecordKind K) {
705 switch (K) {
706 case RK_Struct:
707 LLVM_FALLTHROUGH;
708 case RK_Union:
709 LLVM_FALLTHROUGH;
710 case RK_CXXClass:
711 LLVM_FALLTHROUGH;
712 case RK_ClassTemplate:
713 LLVM_FALLTHROUGH;
714 case RK_ClassTemplateSpecialization:
715 LLVM_FALLTHROUGH;
716 case RK_ClassTemplatePartialSpecialization:
717 return true;
718 default:
719 return false;
720 }
721 }
722
isAnonymousWithNoTypedefRecordRecord723 bool isAnonymousWithNoTypedef() { return Name.empty(); }
724
725 virtual ~RecordRecord() = 0;
726 };
727
728 struct StructFieldRecord : RecordFieldRecord {
StructFieldRecordStructFieldRecord729 StructFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
730 PresumedLoc Loc, AvailabilityInfo Availability,
731 const DocComment &Comment, DeclarationFragments Declaration,
732 DeclarationFragments SubHeading, bool IsFromSystemHeader)
733 : RecordFieldRecord(RK_StructField, USR, Name, Parent, Loc,
734 std::move(Availability), Comment, Declaration,
735 SubHeading, IsFromSystemHeader) {}
736
classofStructFieldRecord737 static bool classof(const APIRecord *Record) {
738 return classofKind(Record->getKind());
739 }
classofKindStructFieldRecord740 static bool classofKind(RecordKind K) { return K == RK_StructField; }
741
742 private:
743 virtual void anchor();
744 };
745
746 struct StructRecord : RecordRecord {
StructRecordStructRecord747 StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
748 PresumedLoc Loc, AvailabilityInfo Availability,
749 const DocComment &Comment, DeclarationFragments Declaration,
750 DeclarationFragments SubHeading, bool IsFromSystemHeader,
751 bool IsEmbeddedInVarDeclarator)
752 : RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
753 Comment, Declaration, SubHeading, IsFromSystemHeader,
754 IsEmbeddedInVarDeclarator) {}
755
classofStructRecord756 static bool classof(const APIRecord *Record) {
757 return classofKind(Record->getKind());
758 }
classofKindStructRecord759 static bool classofKind(RecordKind K) { return K == RK_Struct; }
760
761 private:
762 virtual void anchor();
763 };
764
765 struct UnionFieldRecord : RecordFieldRecord {
UnionFieldRecordUnionFieldRecord766 UnionFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
767 PresumedLoc Loc, AvailabilityInfo Availability,
768 const DocComment &Comment, DeclarationFragments Declaration,
769 DeclarationFragments SubHeading, bool IsFromSystemHeader)
770 : RecordFieldRecord(RK_UnionField, USR, Name, Parent, Loc,
771 std::move(Availability), Comment, Declaration,
772 SubHeading, IsFromSystemHeader) {}
773
classofUnionFieldRecord774 static bool classof(const APIRecord *Record) {
775 return classofKind(Record->getKind());
776 }
classofKindUnionFieldRecord777 static bool classofKind(RecordKind K) { return K == RK_UnionField; }
778
779 private:
780 virtual void anchor();
781 };
782
783 struct UnionRecord : RecordRecord {
UnionRecordUnionRecord784 UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
785 PresumedLoc Loc, AvailabilityInfo Availability,
786 const DocComment &Comment, DeclarationFragments Declaration,
787 DeclarationFragments SubHeading, bool IsFromSystemHeader,
788 bool IsEmbeddedInVarDeclarator)
789 : RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
790 Comment, Declaration, SubHeading, IsFromSystemHeader,
791 IsEmbeddedInVarDeclarator) {}
792
classofUnionRecord793 static bool classof(const APIRecord *Record) {
794 return classofKind(Record->getKind());
795 }
classofKindUnionRecord796 static bool classofKind(RecordKind K) { return K == RK_Union; }
797
798 private:
799 virtual void anchor();
800 };
801
802 struct CXXFieldRecord : APIRecord, RecordContext {
CXXFieldRecordCXXFieldRecord803 CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
804 PresumedLoc Loc, AvailabilityInfo Availability,
805 const DocComment &Comment, DeclarationFragments Declaration,
806 DeclarationFragments SubHeading, AccessControl Access,
807 bool IsFromSystemHeader)
808 : APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
809 LinkageInfo::none(), Comment, Declaration, SubHeading,
810 IsFromSystemHeader, std::move(Access)),
811 RecordContext(RK_CXXField) {}
812
CXXFieldRecordCXXFieldRecord813 CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
814 SymbolReference Parent, PresumedLoc Loc,
815 AvailabilityInfo Availability, const DocComment &Comment,
816 DeclarationFragments Declaration,
817 DeclarationFragments SubHeading, AccessControl Access,
818 bool IsFromSystemHeader)
819 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
820 LinkageInfo::none(), Comment, Declaration, SubHeading,
821 IsFromSystemHeader, std::move(Access)),
822 RecordContext(Kind) {}
823
classofCXXFieldRecord824 static bool classof(const APIRecord *Record) {
825 return classofKind(Record->getKind());
826 }
classofKindCXXFieldRecord827 static bool classofKind(RecordKind K) {
828 return K == RK_CXXField || K == RK_CXXFieldTemplate || K == RK_StaticField;
829 }
830
831 private:
832 virtual void anchor();
833 };
834
835 struct CXXFieldTemplateRecord : CXXFieldRecord {
836 Template Templ;
837
CXXFieldTemplateRecordCXXFieldTemplateRecord838 CXXFieldTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
839 PresumedLoc Loc, AvailabilityInfo Availability,
840 const DocComment &Comment,
841 DeclarationFragments Declaration,
842 DeclarationFragments SubHeading, AccessControl Access,
843 Template Template, bool IsFromSystemHeader)
844 : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Parent, Loc,
845 std::move(Availability), Comment, Declaration,
846 SubHeading, std::move(Access), IsFromSystemHeader),
847 Templ(Template) {}
848
classofCXXFieldTemplateRecord849 static bool classof(const APIRecord *Record) {
850 return classofKind(Record->getKind());
851 }
classofKindCXXFieldTemplateRecord852 static bool classofKind(RecordKind K) { return K == RK_CXXFieldTemplate; }
853 };
854
855 struct CXXMethodRecord : APIRecord {
856 FunctionSignature Signature;
857
858 CXXMethodRecord() = delete;
859
CXXMethodRecordCXXMethodRecord860 CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
861 SymbolReference Parent, PresumedLoc Loc,
862 AvailabilityInfo Availability, const DocComment &Comment,
863 DeclarationFragments Declaration,
864 DeclarationFragments SubHeading, FunctionSignature Signature,
865 AccessControl Access, bool IsFromSystemHeader)
866 : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
867 LinkageInfo::none(), Comment, Declaration, SubHeading,
868 IsFromSystemHeader, std::move(Access)),
869 Signature(Signature) {}
870
871 virtual ~CXXMethodRecord() = 0;
872 };
873
874 struct CXXConstructorRecord : CXXMethodRecord {
CXXConstructorRecordCXXConstructorRecord875 CXXConstructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
876 PresumedLoc Loc, AvailabilityInfo Availability,
877 const DocComment &Comment,
878 DeclarationFragments Declaration,
879 DeclarationFragments SubHeading,
880 FunctionSignature Signature, AccessControl Access,
881 bool IsFromSystemHeader)
882 : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Parent, Loc,
883 std::move(Availability), Comment, Declaration,
884 SubHeading, Signature, std::move(Access),
885 IsFromSystemHeader) {}
classofCXXConstructorRecord886 static bool classof(const APIRecord *Record) {
887 return classofKind(Record->getKind());
888 }
classofKindCXXConstructorRecord889 static bool classofKind(RecordKind K) { return K == RK_CXXConstructorMethod; }
890
891 private:
892 virtual void anchor();
893 };
894
895 struct CXXDestructorRecord : CXXMethodRecord {
CXXDestructorRecordCXXDestructorRecord896 CXXDestructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
897 PresumedLoc Loc, AvailabilityInfo Availability,
898 const DocComment &Comment,
899 DeclarationFragments Declaration,
900 DeclarationFragments SubHeading,
901 FunctionSignature Signature, AccessControl Access,
902 bool IsFromSystemHeader)
903 : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Parent, Loc,
904 std::move(Availability), Comment, Declaration,
905 SubHeading, Signature, std::move(Access),
906 IsFromSystemHeader) {}
classofCXXDestructorRecord907 static bool classof(const APIRecord *Record) {
908 return classofKind(Record->getKind());
909 }
classofKindCXXDestructorRecord910 static bool classofKind(RecordKind K) { return K == RK_CXXDestructorMethod; }
911
912 private:
913 virtual void anchor();
914 };
915
916 struct CXXStaticMethodRecord : CXXMethodRecord {
CXXStaticMethodRecordCXXStaticMethodRecord917 CXXStaticMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
918 PresumedLoc Loc, AvailabilityInfo Availability,
919 const DocComment &Comment,
920 DeclarationFragments Declaration,
921 DeclarationFragments SubHeading,
922 FunctionSignature Signature, AccessControl Access,
923 bool IsFromSystemHeader)
924 : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Parent, Loc,
925 std::move(Availability), Comment, Declaration,
926 SubHeading, Signature, std::move(Access),
927 IsFromSystemHeader) {}
classofCXXStaticMethodRecord928 static bool classof(const APIRecord *Record) {
929 return classofKind(Record->getKind());
930 }
classofKindCXXStaticMethodRecord931 static bool classofKind(RecordKind K) { return K == RK_CXXStaticMethod; }
932
933 private:
934 virtual void anchor();
935 };
936
937 struct CXXInstanceMethodRecord : CXXMethodRecord {
CXXInstanceMethodRecordCXXInstanceMethodRecord938 CXXInstanceMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
939 PresumedLoc Loc, AvailabilityInfo Availability,
940 const DocComment &Comment,
941 DeclarationFragments Declaration,
942 DeclarationFragments SubHeading,
943 FunctionSignature Signature, AccessControl Access,
944 bool IsFromSystemHeader)
945 : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Parent, Loc,
946 std::move(Availability), Comment, Declaration,
947 SubHeading, Signature, std::move(Access),
948 IsFromSystemHeader) {}
949
classofCXXInstanceMethodRecord950 static bool classof(const APIRecord *Record) {
951 return classofKind(Record->getKind());
952 }
classofKindCXXInstanceMethodRecord953 static bool classofKind(RecordKind K) { return K == RK_CXXInstanceMethod; }
954
955 private:
956 virtual void anchor();
957 };
958
959 struct CXXMethodTemplateRecord : CXXMethodRecord {
960 Template Templ;
961
CXXMethodTemplateRecordCXXMethodTemplateRecord962 CXXMethodTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
963 PresumedLoc Loc, AvailabilityInfo Availability,
964 const DocComment &Comment,
965 DeclarationFragments Declaration,
966 DeclarationFragments SubHeading,
967 FunctionSignature Signature, AccessControl Access,
968 Template Template, bool IsFromSystemHeader)
969 : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Parent, Loc,
970 std::move(Availability), Comment, Declaration,
971 SubHeading, Signature, std::move(Access),
972 IsFromSystemHeader),
973 Templ(Template) {}
974
classofCXXMethodTemplateRecord975 static bool classof(const APIRecord *Record) {
976 return classofKind(Record->getKind());
977 }
classofKindCXXMethodTemplateRecord978 static bool classofKind(RecordKind K) { return K == RK_CXXMethodTemplate; }
979 };
980
981 struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
CXXMethodTemplateSpecializationRecordCXXMethodTemplateSpecializationRecord982 CXXMethodTemplateSpecializationRecord(
983 StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
984 AvailabilityInfo Availability, const DocComment &Comment,
985 DeclarationFragments Declaration, DeclarationFragments SubHeading,
986 FunctionSignature Signature, AccessControl Access,
987 bool IsFromSystemHeader)
988 : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Parent,
989 Loc, std::move(Availability), Comment, Declaration,
990 SubHeading, Signature, std::move(Access),
991 IsFromSystemHeader) {}
992
classofCXXMethodTemplateSpecializationRecord993 static bool classof(const APIRecord *Record) {
994 return classofKind(Record->getKind());
995 }
classofKindCXXMethodTemplateSpecializationRecord996 static bool classofKind(RecordKind K) {
997 return K == RK_CXXMethodTemplateSpecialization;
998 }
999 };
1000
1001 /// This holds information associated with Objective-C properties.
1002 struct ObjCPropertyRecord : APIRecord {
1003 /// The attributes associated with an Objective-C property.
1004 enum AttributeKind : unsigned {
1005 NoAttr = 0,
1006 ReadOnly = 1,
1007 Dynamic = 1 << 2,
1008 };
1009
1010 AttributeKind Attributes;
1011 StringRef GetterName;
1012 StringRef SetterName;
1013 bool IsOptional;
1014
ObjCPropertyRecordObjCPropertyRecord1015 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
isReadOnlyObjCPropertyRecord1028 bool isReadOnly() const { return Attributes & ReadOnly; }
isDynamicObjCPropertyRecord1029 bool isDynamic() const { return Attributes & Dynamic; }
1030
1031 virtual ~ObjCPropertyRecord() = 0;
1032 };
1033
1034 struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
ObjCInstancePropertyRecordObjCInstancePropertyRecord1035 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
classofObjCInstancePropertyRecord1046 static bool classof(const APIRecord *Record) {
1047 return classofKind(Record->getKind());
1048 }
classofKindObjCInstancePropertyRecord1049 static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceProperty; }
1050
1051 private:
1052 virtual void anchor();
1053 };
1054
1055 struct ObjCClassPropertyRecord : ObjCPropertyRecord {
ObjCClassPropertyRecordObjCClassPropertyRecord1056 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
classofObjCClassPropertyRecord1069 static bool classof(const APIRecord *Record) {
1070 return classofKind(Record->getKind());
1071 }
classofKindObjCClassPropertyRecord1072 static bool classofKind(RecordKind K) { return K == RK_ObjCClassProperty; }
1073
1074 private:
1075 virtual void anchor();
1076 };
1077
1078 /// This holds information associated with Objective-C instance variables.
1079 struct ObjCInstanceVariableRecord : APIRecord {
ObjCInstanceVariableRecordObjCInstanceVariableRecord1080 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
classofObjCInstanceVariableRecord1091 static bool classof(const APIRecord *Record) {
1092 return classofKind(Record->getKind());
1093 }
classofKindObjCInstanceVariableRecord1094 static bool classofKind(RecordKind K) { return K == RK_ObjCIvar; }
1095
1096 private:
1097 virtual void anchor();
1098 };
1099
1100 /// This holds information associated with Objective-C methods.
1101 struct ObjCMethodRecord : APIRecord {
1102 FunctionSignature Signature;
1103
1104 ObjCMethodRecord() = delete;
1105
ObjCMethodRecordObjCMethodRecord1106 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 {
ObjCInstanceMethodRecordObjCInstanceMethodRecord1121 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) {}
classofObjCInstanceMethodRecord1131 static bool classof(const APIRecord *Record) {
1132 return classofKind(Record->getKind());
1133 }
classofKindObjCInstanceMethodRecord1134 static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceMethod; }
1135
1136 private:
1137 virtual void anchor();
1138 };
1139
1140 struct ObjCClassMethodRecord : ObjCMethodRecord {
ObjCClassMethodRecordObjCClassMethodRecord1141 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
classofObjCClassMethodRecord1151 static bool classof(const APIRecord *Record) {
1152 return classofKind(Record->getKind());
1153 }
classofKindObjCClassMethodRecord1154 static bool classofKind(RecordKind K) { return K == RK_ObjCClassMethod; }
1155
1156 private:
1157 virtual void anchor();
1158 };
1159
1160 struct StaticFieldRecord : CXXFieldRecord {
StaticFieldRecordStaticFieldRecord1161 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
classofStaticFieldRecord1171 static bool classof(const APIRecord *Record) {
1172 return classofKind(Record->getKind());
1173 }
classofKindStaticFieldRecord1174 static bool classofKind(RecordKind K) { return K == RK_StaticField; }
1175 };
1176
1177 /// The base representation of an Objective-C container record. Holds common
1178 /// information associated with Objective-C containers.
1179 struct ObjCContainerRecord : APIRecord, RecordContext {
1180 SmallVector<SymbolReference> Protocols;
1181
1182 ObjCContainerRecord() = delete;
1183
ObjCContainerRecordObjCContainerRecord1184 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)
RecordRecordCXXClassRecord1207 : RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1208 Comment, Declaration, SubHeading, IsFromSystemHeader,
1209 IsEmbeddedInVarDeclarator, std::move(Access)) {}
1210
classofCXXClassRecord1211 static bool classof(const APIRecord *Record) {
1212 return classofKind(Record->getKind());
1213 }
classofKindCXXClassRecord1214 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
ClassTemplateRecordClassTemplateRecord1227 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
classofClassTemplateRecord1238 static bool classof(const APIRecord *Record) {
1239 return classofKind(Record->getKind());
1240 }
classofKindClassTemplateRecord1241 static bool classofKind(RecordKind K) { return K == RK_ClassTemplate; }
1242 };
1243
1244 struct ClassTemplateSpecializationRecord : CXXClassRecord {
ClassTemplateSpecializationRecordClassTemplateSpecializationRecord1245 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
classofClassTemplateSpecializationRecord1254 static bool classof(const APIRecord *Record) {
1255 return classofKind(Record->getKind());
1256 }
classofKindClassTemplateSpecializationRecord1257 static bool classofKind(RecordKind K) {
1258 return K == RK_ClassTemplateSpecialization;
1259 }
1260 };
1261
1262 struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
1263 Template Templ;
ClassTemplatePartialSpecializationRecordClassTemplatePartialSpecializationRecord1264 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
classofClassTemplatePartialSpecializationRecord1275 static bool classof(const APIRecord *Record) {
1276 return classofKind(Record->getKind());
1277 }
classofKindClassTemplatePartialSpecializationRecord1278 static bool classofKind(RecordKind K) {
1279 return K == RK_ClassTemplatePartialSpecialization;
1280 }
1281 };
1282
1283 struct ConceptRecord : APIRecord {
1284 Template Templ;
1285
ConceptRecordConceptRecord1286 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
classofConceptRecord1296 static bool classof(const APIRecord *Record) {
1297 return classofKind(Record->getKind());
1298 }
classofKindConceptRecord1299 static bool classofKind(RecordKind K) { return K == RK_Concept; }
1300 };
1301
1302 /// This holds information associated with Objective-C categories.
1303 struct ObjCCategoryRecord : ObjCContainerRecord {
1304 SymbolReference Interface;
1305
ObjCCategoryRecordObjCCategoryRecord1306 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
classofObjCCategoryRecord1318 static bool classof(const APIRecord *Record) {
1319 return classofKind(Record->getKind());
1320 }
classofKindObjCCategoryRecord1321 static bool classofKind(RecordKind K) { return K == RK_ObjCCategory; }
1322
isExtendingExternalModuleObjCCategoryRecord1323 bool isExtendingExternalModule() const { return !Interface.Source.empty(); }
1324
getExtendedExternalModuleObjCCategoryRecord1325 std::optional<StringRef> getExtendedExternalModule() const {
1326 if (!isExtendingExternalModule())
1327 return {};
1328 return Interface.Source;
1329 }
1330
1331 private:
1332 virtual void anchor();
1333 };
1334
1335 /// This holds information associated with Objective-C interfaces/classes.
1336 struct ObjCInterfaceRecord : ObjCContainerRecord {
1337 SymbolReference SuperClass;
1338
ObjCInterfaceRecordObjCInterfaceRecord1339 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
classofObjCInterfaceRecord1350 static bool classof(const APIRecord *Record) {
1351 return classofKind(Record->getKind());
1352 }
classofKindObjCInterfaceRecord1353 static bool classofKind(RecordKind K) { return K == RK_ObjCInterface; }
1354
1355 private:
1356 virtual void anchor();
1357 };
1358
1359 /// This holds information associated with Objective-C protocols.
1360 struct ObjCProtocolRecord : ObjCContainerRecord {
ObjCProtocolRecordObjCProtocolRecord1361 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
classofObjCProtocolRecord1371 static bool classof(const APIRecord *Record) {
1372 return classofKind(Record->getKind());
1373 }
classofKindObjCProtocolRecord1374 static bool classofKind(RecordKind K) { return K == RK_ObjCProtocol; }
1375
1376 private:
1377 virtual void anchor();
1378 };
1379
1380 /// This holds information associated with macro definitions.
1381 struct MacroDefinitionRecord : APIRecord {
MacroDefinitionRecordMacroDefinitionRecord1382 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
classofMacroDefinitionRecord1390 static bool classof(const APIRecord *Record) {
1391 return classofKind(Record->getKind());
1392 }
classofKindMacroDefinitionRecord1393 static bool classofKind(RecordKind K) { return K == RK_MacroDefinition; }
1394
1395 private:
1396 virtual void anchor();
1397 };
1398
1399 /// This holds information associated with typedefs.
1400 ///
1401 /// Note: Typedefs for anonymous enums and structs typically don't get emitted
1402 /// by the serializers but still get a TypedefRecord. Instead we use the
1403 /// typedef name as a name for the underlying anonymous struct or enum.
1404 struct TypedefRecord : APIRecord {
1405 SymbolReference UnderlyingType;
1406
TypedefRecordTypedefRecord1407 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
classofTypedefRecord1417 static bool classof(const APIRecord *Record) {
1418 return classofKind(Record->getKind());
1419 }
classofKindTypedefRecord1420 static bool classofKind(RecordKind K) { return K == RK_Typedef; }
1421
1422 private:
1423 virtual void anchor();
1424 };
1425
1426 /// APISet holds the set of API records collected from given inputs.
1427 class APISet {
1428 public:
1429 /// Get the target triple for the ExtractAPI invocation.
getTarget()1430 const llvm::Triple &getTarget() const { return Target; }
1431
1432 /// Get the language used by the APIs.
getLanguage()1433 Language getLanguage() const { return Lang; }
1434
1435 /// Finds the APIRecord for a given USR.
1436 ///
1437 /// \returns a pointer to the APIRecord associated with that USR or nullptr.
1438 APIRecord *findRecordForUSR(StringRef USR) const;
1439
1440 /// Copy \p String into the Allocator in this APISet.
1441 ///
1442 /// \returns a StringRef of the copied string in APISet::Allocator.
1443 StringRef copyString(StringRef String);
1444
1445 SymbolReference createSymbolReference(StringRef Name, StringRef USR,
1446 StringRef Source = "");
1447
1448 /// Create a subclass of \p APIRecord and store it in the APISet.
1449 ///
1450 /// \returns A pointer to the created record or the already existing record
1451 /// matching this USR.
1452 template <typename RecordTy, typename... CtorArgsContTy>
1453 typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
1454 createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);
1455
getTopLevelRecords()1456 ArrayRef<const APIRecord *> getTopLevelRecords() const {
1457 return TopLevelRecords;
1458 }
1459
1460 void removeRecord(StringRef USR);
1461
1462 void removeRecord(APIRecord *Record);
1463
APISet(const llvm::Triple & Target,Language Lang,const std::string & ProductName)1464 APISet(const llvm::Triple &Target, Language Lang,
1465 const std::string &ProductName)
1466 : Target(Target), Lang(Lang), ProductName(ProductName) {}
1467
1468 // Prevent moves and copies
1469 APISet(const APISet &Other) = delete;
1470 APISet &operator=(const APISet &Other) = delete;
1471 APISet(APISet &&Other) = delete;
1472 APISet &operator=(APISet &&Other) = delete;
1473
1474 private:
1475 /// BumpPtrAllocator that serves as the memory arena for the allocated objects
1476 llvm::BumpPtrAllocator Allocator;
1477
1478 const llvm::Triple Target;
1479 const Language Lang;
1480
1481 struct APIRecordDeleter {
operatorAPIRecordDeleter1482 void operator()(APIRecord *Record) { Record->~APIRecord(); }
1483 };
1484
1485 // Ensure that the destructor of each record is called when the LookupTable is
1486 // destroyed without calling delete operator as the memory for the record
1487 // lives in the BumpPtrAllocator.
1488 using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
1489 llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
1490 llvm::SmallVector<const APIRecord *, 32> TopLevelRecords;
1491
1492 public:
1493 const std::string ProductName;
1494 };
1495
1496 template <typename RecordTy, typename... CtorArgsContTy>
1497 typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
createRecord(StringRef USR,StringRef Name,CtorArgsContTy &&...CtorArgs)1498 APISet::createRecord(StringRef USR, StringRef Name,
1499 CtorArgsContTy &&...CtorArgs) {
1500 // Ensure USR refers to a String stored in the allocator.
1501 auto USRString = copyString(USR);
1502 auto Result = USRBasedLookupTable.try_emplace(USRString);
1503 RecordTy *Record;
1504
1505 // Create the record if it does not already exist
1506 if (Result.second) {
1507 Record = new (Allocator) RecordTy(
1508 USRString, copyString(Name), std::forward<CtorArgsContTy>(CtorArgs)...);
1509 // Store the record in the record lookup map
1510 Result.first->second = APIRecordStoredPtr(Record);
1511
1512 if (auto *ParentContext =
1513 dyn_cast_if_present<RecordContext>(Record->Parent.Record))
1514 ParentContext->addToRecordChain(Record);
1515 else
1516 TopLevelRecords.push_back(Record);
1517 } else {
1518 Record = dyn_cast<RecordTy>(Result.first->second.get());
1519 }
1520
1521 return Record;
1522 }
1523
1524 // Helper type for implementing casting to RecordContext pointers.
1525 // Selected when FromTy not a known subclass of RecordContext.
1526 template <typename FromTy,
1527 bool IsKnownSubType = std::is_base_of_v<RecordContext, FromTy>>
1528 struct ToRecordContextCastInfoWrapper {
1529 static_assert(std::is_base_of_v<APIRecord, FromTy>,
1530 "Can only cast APIRecord and derived classes to RecordContext");
1531
isPossibleToRecordContextCastInfoWrapper1532 static bool isPossible(FromTy *From) { return RecordContext::classof(From); }
1533
doCastToRecordContextCastInfoWrapper1534 static RecordContext *doCast(FromTy *From) {
1535 return APIRecord::castToRecordContext(From);
1536 }
1537 };
1538
1539 // Selected when FromTy is a known subclass of RecordContext.
1540 template <typename FromTy> struct ToRecordContextCastInfoWrapper<FromTy, true> {
1541 static_assert(std::is_base_of_v<APIRecord, FromTy>,
1542 "Can only cast APIRecord and derived classes to RecordContext");
1543 static bool isPossible(const FromTy *From) { return true; }
1544 static RecordContext *doCast(FromTy *From) {
1545 return static_cast<RecordContext *>(From);
1546 }
1547 };
1548
1549 // Helper type for implementing casting to RecordContext pointers.
1550 // Selected when ToTy isn't a known subclass of RecordContext
1551 template <typename ToTy,
1552 bool IsKnownSubType = std::is_base_of_v<RecordContext, ToTy>>
1553 struct FromRecordContextCastInfoWrapper {
1554 static_assert(
1555 std::is_base_of_v<APIRecord, ToTy>,
1556 "Can only class RecordContext to APIRecord and derived classes");
1557
1558 static bool isPossible(RecordContext *Ctx) {
1559 return ToTy::classofKind(Ctx->getKind());
1560 }
1561
1562 static ToTy *doCast(RecordContext *Ctx) {
1563 return APIRecord::castFromRecordContext(Ctx);
1564 }
1565 };
1566
1567 // Selected when ToTy is a known subclass of RecordContext.
1568 template <typename ToTy> struct FromRecordContextCastInfoWrapper<ToTy, true> {
1569 static_assert(
1570 std::is_base_of_v<APIRecord, ToTy>,
1571 "Can only class RecordContext to APIRecord and derived classes");
1572 static bool isPossible(RecordContext *Ctx) {
1573 return ToTy::classof(Ctx->getKind());
1574 }
1575 static RecordContext *doCast(RecordContext *Ctx) {
1576 return static_cast<ToTy *>(Ctx);
1577 }
1578 };
1579
1580 } // namespace extractapi
1581 } // namespace clang
1582
1583 // Implement APIRecord (and derived classes) to and from RecordContext
1584 // conversions
1585 namespace llvm {
1586
1587 template <typename FromTy>
1588 struct CastInfo<::clang::extractapi::RecordContext, FromTy *>
1589 : public NullableValueCastFailed<::clang::extractapi::RecordContext *>,
1590 public DefaultDoCastIfPossible<
1591 ::clang::extractapi::RecordContext *, FromTy *,
1592 CastInfo<::clang::extractapi::RecordContext, FromTy *>> {
1593 static inline bool isPossible(FromTy *From) {
1594 return ::clang::extractapi::ToRecordContextCastInfoWrapper<
1595 FromTy>::isPossible(From);
1596 }
1597
1598 static inline ::clang::extractapi::RecordContext *doCast(FromTy *From) {
1599 return ::clang::extractapi::ToRecordContextCastInfoWrapper<FromTy>::doCast(
1600 From);
1601 }
1602 };
1603
1604 template <typename FromTy>
1605 struct CastInfo<::clang::extractapi::RecordContext, const FromTy *>
1606 : public ConstStrippingForwardingCast<
1607 ::clang::extractapi::RecordContext, const FromTy *,
1608 CastInfo<::clang::extractapi::RecordContext, FromTy *>> {};
1609
1610 template <typename ToTy>
1611 struct CastInfo<ToTy, ::clang::extractapi::RecordContext *>
1612 : public NullableValueCastFailed<ToTy *>,
1613 public DefaultDoCastIfPossible<
1614 ToTy *, ::clang::extractapi::RecordContext *,
1615 CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {
1616 static inline bool isPossible(::clang::extractapi::RecordContext *Ctx) {
1617 return ::clang::extractapi::FromRecordContextCastInfoWrapper<
1618 ToTy>::isPossible(Ctx);
1619 }
1620
1621 static inline ToTy *doCast(::clang::extractapi::RecordContext *Ctx) {
1622 return ::clang::extractapi::FromRecordContextCastInfoWrapper<ToTy>::doCast(
1623 Ctx);
1624 }
1625 };
1626
1627 template <typename ToTy>
1628 struct CastInfo<ToTy, const ::clang::extractapi::RecordContext *>
1629 : public ConstStrippingForwardingCast<
1630 ToTy, const ::clang::extractapi::RecordContext *,
1631 CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {};
1632
1633 } // namespace llvm
1634
1635 #endif // LLVM_CLANG_EXTRACTAPI_API_H
1636