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