clang 19.0.0git
ExtractAPIVisitor.h
Go to the documentation of this file.
1//===- ExtractAPI/ExtractAPIVisitor.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 ExtractAPVisitor AST visitation interface.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
15#define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
16
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclObjC.h"
24#include "clang/Basic/Module.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/Support/Casting.h"
34#include <type_traits>
35
36namespace clang {
37namespace extractapi {
38namespace impl {
39
40template <typename Derived>
42protected:
44 : Context(Context), API(API) {}
45
46public:
47 const APISet &getAPI() const { return API; }
48
50
52
54
56
58
60
62
65
68
70
73
76
78
80
82
84
86
88
90
92
94
96
98
101
104
106
107 bool
109
112
114
116
118
120
122
123 bool shouldDeclBeIncluded(const Decl *Decl) const;
124
126
127protected:
128 /// Collect API information for the enum constants and associate with the
129 /// parent enum.
131 const EnumDecl::enumerator_range Constants);
132
133 /// Collect API information for the Objective-C methods and associate with the
134 /// parent container.
136 const ObjCContainerDecl::method_range Methods);
137
139 const ObjCContainerDecl::prop_range Properties);
140
142 ObjCContainerRecord *Container,
143 const llvm::iterator_range<
145 Ivars);
146
149
152
153 StringRef getTypedefName(const TagDecl *Decl) {
154 if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
155 return TypedefDecl->getName();
156
157 return {};
158 }
159
160 bool isInSystemHeader(const Decl *D) {
162 }
163
164private:
165 Derived &getDerivedExtractAPIVisitor() {
166 return *static_cast<Derived *>(this);
167 }
168
169protected:
171 // FIXME: store AccessSpecifier given by inheritance
173 for (const auto &BaseSpecifier : Decl->bases()) {
174 // skip classes not inherited as public
175 if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
176 continue;
177 SymbolReference BaseClass;
178 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
179 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
180 if (auto *TTPTD = BaseSpecifier.getType()
181 ->getAs<TemplateTypeParmType>()
182 ->getDecl()) {
184 index::generateUSRForDecl(TTPTD, USR);
185 BaseClass.USR = API.copyString(USR);
186 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
187 }
188 } else {
190 *BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl());
191 }
192 Bases.emplace_back(BaseClass);
193 }
194 return Bases;
195 }
196
197 StringRef getOwningModuleName(const Decl &D) {
198 if (auto *OwningModule = D.getImportedOwningModule())
199 return OwningModule->Name;
200
201 return {};
202 }
203
205 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
206
207 if (!Context || isa<TranslationUnitDecl>(Context))
208 return {};
209
211 }
212
216
218 if (Record)
219 return SymbolReference(Record);
220
221 StringRef Name;
222 if (auto *ND = dyn_cast<NamedDecl>(&D))
223 Name = ND->getName();
224
225 return API.createSymbolReference(Name, USR, getOwningModuleName(D));
226 }
227
229 return D.getName().empty() && getTypedefName(&D).empty() &&
231 }
232
234 RecordContext *NewRecordContext) {
235 if (!NewRecordContext)
236 return;
237 auto *Tag = D.getType()->getAsTagDecl();
238 SmallString<128> TagUSR;
240 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
241 API.findRecordForUSR(TagUSR))) {
242 if (Record->IsEmbeddedInVarDeclarator) {
243 NewRecordContext->stealRecordChain(*Record);
244 auto *NewRecord = cast<APIRecord>(NewRecordContext);
245 if (NewRecord->Comment.empty())
246 NewRecord->Comment = Record->Comment;
247 }
248 }
249 }
250};
251
252template <typename Derived>
254 // skip function parameters.
255 if (isa<ParmVarDecl>(Decl))
256 return true;
257
258 // Skip non-global variables in records (struct/union/class) but not static
259 // members.
260 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
261 return true;
262
263 // Skip local variables inside function or method.
265 return true;
266
267 // If this is a template but not specialization or instantiation, skip.
269 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
270 return true;
271
272 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
273 return true;
274
275 // Collect symbol information.
276 StringRef Name = Decl->getName();
279 PresumedLoc Loc =
280 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
281 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
282 DocComment Comment;
283 if (auto *RawComment =
284 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
285 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
286 Context.getDiagnostics());
287
288 // Build declaration fragments and sub-heading for the variable.
291 DeclarationFragments SubHeading =
293 if (Decl->isStaticDataMember()) {
295 API.createRecord<StaticFieldRecord>(
296 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
298 SubHeading, Access, isInSystemHeader(Decl));
299 } else {
300 // Add the global variable record to the API set.
301 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
302 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
304 SubHeading, isInSystemHeader(Decl));
305
306 // If this global variable has a non typedef'd anonymous tag type let's
307 // pretend the type's child records are under us in the hierarchy.
308 maybeMergeWithAnonymousTag(*Decl, NewRecord);
309 }
310
311 return true;
312}
313
314template <typename Derived>
316 const FunctionDecl *Decl) {
317 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
318 // Skip member function in class templates.
319 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
320 return true;
321
322 // Skip methods in records.
323 for (const auto &P : Context.getParents(*Method)) {
324 if (P.template get<CXXRecordDecl>())
325 return true;
326 }
327
328 // Skip ConstructorDecl and DestructorDecl.
329 if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
330 return true;
331 }
332
333 // Skip templated functions that aren't processed here.
334 switch (Decl->getTemplatedKind()) {
338 break;
342 return true;
343 }
344
345 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
346 return true;
347
348 // Collect symbol information.
349 StringRef Name = Decl->getName();
352 PresumedLoc Loc =
353 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
354 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
355 DocComment Comment;
356 if (auto *RawComment =
357 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
358 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
359 Context.getDiagnostics());
360
361 // Build declaration fragments, sub-heading, and signature of the function.
362 DeclarationFragments SubHeading =
364 FunctionSignature Signature =
366 if (Decl->getTemplateSpecializationInfo())
368 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
372 SubHeading, Signature, isInSystemHeader(Decl));
373 else
374 // Add the function record to the API set.
375 API.createRecord<GlobalFunctionRecord>(
376 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
379 Signature, isInSystemHeader(Decl));
380 return true;
381}
382
383template <typename Derived>
385 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
386 return true;
387
388 SmallString<128> QualifiedNameBuffer;
389 // Collect symbol information.
390 StringRef Name = Decl->getName();
391 if (Name.empty())
392 Name = getTypedefName(Decl);
393 if (Name.empty()) {
394 llvm::raw_svector_ostream OS(QualifiedNameBuffer);
395 Decl->printQualifiedName(OS);
396 Name = QualifiedNameBuffer;
397 }
398
401 PresumedLoc Loc =
402 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
403 DocComment Comment;
404 if (auto *RawComment =
405 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
406 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
407 Context.getDiagnostics());
408
409 // Build declaration fragments and sub-heading for the enum.
412 DeclarationFragments SubHeading =
414 auto *ER = API.createRecord<EnumRecord>(
415 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
417 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
418
419 // Now collect information about the enumerators in this enum.
420 getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
421
422 return true;
423}
424
425template <typename Derived>
427 const FunctionDecl *Decl) {
428 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
429 return true;
430}
431
432template <typename Derived>
434 const RecordDecl *Decl) {
435 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
436 return true;
437}
438
439template <typename Derived>
441 const CXXRecordDecl *Decl) {
442 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
443 return true;
444}
445
446template <typename Derived>
448 const CXXMethodDecl *Decl) {
449 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
450 return true;
451}
452
453template <typename Derived>
456 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
457 return true;
458}
459
460template <typename Derived>
464 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
465 Decl);
466 return true;
467}
468
469template <typename Derived>
471 const VarTemplateDecl *Decl) {
472 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
473 return true;
474}
475
476template <typename Derived>
479 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
480 return true;
481}
482
483template <typename Derived>
487 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
488 return true;
489}
490
491template <typename Derived>
493 const FunctionTemplateDecl *Decl) {
494 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
495 return true;
496}
497
498template <typename Derived>
500 const NamespaceDecl *Decl) {
501 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
502 return true;
503}
504
505template <typename Derived>
507 const NamespaceDecl *Decl) {
508 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
509 return true;
510 if (Decl->isAnonymousNamespace())
511 return true;
512 StringRef Name = Decl->getName();
515 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
516 PresumedLoc Loc =
517 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
518 DocComment Comment;
519 if (auto *RawComment =
520 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
521 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
522 Context.getDiagnostics());
523
524 // Build declaration fragments and sub-heading for the struct.
527 DeclarationFragments SubHeading =
529 API.createRecord<NamespaceRecord>(
530 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
532 SubHeading, isInSystemHeader(Decl));
533
534 return true;
535}
536
537template <typename Derived>
539 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
540 return true;
541
542 // Collect symbol information.
543 StringRef Name = Decl->getName();
544 if (Name.empty())
545 Name = getTypedefName(Decl);
546
549 PresumedLoc Loc =
550 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
551 DocComment Comment;
552 if (auto *RawComment =
553 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
554 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
555 Context.getDiagnostics());
556
557 // Build declaration fragments and sub-heading for the struct.
560 DeclarationFragments SubHeading =
562
563 if (Decl->isUnion())
564 API.createRecord<UnionRecord>(
565 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
567 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
568 else
569 API.createRecord<StructRecord>(
570 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
572 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
573
574 return true;
575}
576
577template <typename Derived>
579 const CXXRecordDecl *Decl) {
580 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
581 Decl->isImplicit())
582 return true;
583
584 StringRef Name = Decl->getName();
585 if (Name.empty())
586 Name = getTypedefName(Decl);
587
590 PresumedLoc Loc =
591 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
592 DocComment Comment;
593 if (auto *RawComment =
594 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
595 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
596 Context.getDiagnostics());
599 DeclarationFragments SubHeading =
601
603 if (Decl->isUnion())
605 else if (Decl->isStruct())
607 else
610
612 if (Decl->getDescribedClassTemplate()) {
613 // Inject template fragments before class fragments.
614 Declaration.prepend(
616 Decl->getDescribedClassTemplate()));
617 Record = API.createRecord<ClassTemplateRecord>(
618 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
620 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
621 isInSystemHeader(Decl));
622 } else
623 Record = API.createRecord<CXXClassRecord>(
624 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
626 SubHeading, Kind, Access, isInSystemHeader(Decl),
627 isEmbeddedInVarDeclarator(*Decl));
628
629 Record->Bases = getBases(Decl);
630
631 return true;
632}
633
634template <typename Derived>
636 const CXXMethodDecl *Decl) {
637 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
638 Decl->isImplicit())
639 return true;
640
641 if (isa<CXXConversionDecl>(Decl))
642 return true;
643 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
644 return true;
645
648 PresumedLoc Loc =
649 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
650 DocComment Comment;
651 if (auto *RawComment =
652 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
653 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
654 Context.getDiagnostics());
655 DeclarationFragments SubHeading =
659
661 Decl->getDescribedFunctionTemplate()) {
662 API.createRecord<CXXMethodTemplateRecord>(
663 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
669 Template(TemplateDecl), isInSystemHeader(Decl));
670 } else if (Decl->getTemplateSpecializationInfo())
672 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
676 SubHeading, Signature, Access, isInSystemHeader(Decl));
677 else if (Decl->isOverloadedOperator())
678 API.createRecord<CXXInstanceMethodRecord>(
679 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
682 SubHeading, Signature, Access, isInSystemHeader(Decl));
683 else if (Decl->isStatic())
684 API.createRecord<CXXStaticMethodRecord>(
685 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
688 Signature, Access, isInSystemHeader(Decl));
689 else
690 API.createRecord<CXXInstanceMethodRecord>(
691 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
694 Signature, Access, isInSystemHeader(Decl));
695
696 return true;
697}
698
699template <typename Derived>
701 const CXXConstructorDecl *Decl) {
702 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
703 Decl->isImplicit())
704 return true;
705
706 auto Name = Decl->getNameAsString();
709 PresumedLoc Loc =
710 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
711 DocComment Comment;
712 if (auto *RawComment =
713 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
714 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
715 Context.getDiagnostics());
716
717 // Build declaration fragments, sub-heading, and signature for the method.
720 DeclarationFragments SubHeading =
722 FunctionSignature Signature =
725
726 API.createRecord<CXXConstructorRecord>(
727 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
729 Signature, Access, isInSystemHeader(Decl));
730 return true;
731}
732
733template <typename Derived>
735 const CXXDestructorDecl *Decl) {
736 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
737 Decl->isImplicit())
738 return true;
739
740 auto Name = Decl->getNameAsString();
743 PresumedLoc Loc =
744 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
745 DocComment Comment;
746 if (auto *RawComment =
747 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
748 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
749 Context.getDiagnostics());
750
751 // Build declaration fragments, sub-heading, and signature for the method.
754 DeclarationFragments SubHeading =
756 FunctionSignature Signature =
759 API.createRecord<CXXDestructorRecord>(
760 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
762 Signature, Access, isInSystemHeader(Decl));
763 return true;
764}
765
766template <typename Derived>
768 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
769 return true;
770
771 StringRef Name = Decl->getName();
774 PresumedLoc Loc =
775 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
776 DocComment Comment;
777 if (auto *RawComment =
778 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
779 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
780 Context.getDiagnostics());
783 DeclarationFragments SubHeading =
785 API.createRecord<ConceptRecord>(
786 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
788 Template(Decl), isInSystemHeader(Decl));
789 return true;
790}
791
792template <typename Derived>
795 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
796 return true;
797
798 StringRef Name = Decl->getName();
801 PresumedLoc Loc =
802 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
803 DocComment Comment;
804 if (auto *RawComment =
805 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
806 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
807 Context.getDiagnostics());
810 Decl);
811 DeclarationFragments SubHeading =
813
814 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
815 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
818 isInSystemHeader(Decl));
819
820 CTSR->Bases = getBases(Decl);
821
822 return true;
823}
824
825template <typename Derived>
829 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
830 return true;
831
832 StringRef Name = Decl->getName();
835 PresumedLoc Loc =
836 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
837 DocComment Comment;
838 if (auto *RawComment =
839 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
840 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
841 Context.getDiagnostics());
844 DeclarationFragments SubHeading =
846 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
847 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
850 isInSystemHeader(Decl));
851
852 CTPSR->Bases = getBases(Decl);
853
854 return true;
855}
856
857template <typename Derived>
859 const VarTemplateDecl *Decl) {
860 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
861 return true;
862
863 // Collect symbol information.
864 StringRef Name = Decl->getName();
867 PresumedLoc Loc =
868 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
869 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
870 DocComment Comment;
871 if (auto *RawComment =
872 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
873 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
874 Context.getDiagnostics());
875
876 // Build declaration fragments and sub-heading for the variable.
880 Decl))
882 Decl->getTemplatedDecl()));
883 // Inject template fragments before var fragments.
884 DeclarationFragments SubHeading =
886
887 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
888 API.createRecord<CXXFieldTemplateRecord>(
889 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
892 Template(Decl), isInSystemHeader(Decl));
893 else
894 API.createRecord<GlobalVariableTemplateRecord>(
895 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
897 SubHeading, Template(Decl), isInSystemHeader(Decl));
898 return true;
899}
900
901template <typename Derived>
904 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
905 return true;
906
907 // Collect symbol information.
908 StringRef Name = Decl->getName();
911 PresumedLoc Loc =
912 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
913 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
914 DocComment Comment;
915 if (auto *RawComment =
916 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
917 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
918 Context.getDiagnostics());
919
920 // Build declaration fragments and sub-heading for the variable.
923 Decl);
924 DeclarationFragments SubHeading =
927 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
929 SubHeading, isInSystemHeader(Decl));
930 return true;
931}
932
933template <typename Derived>
936 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
937 return true;
938
939 // Collect symbol information.
940 StringRef Name = Decl->getName();
943 PresumedLoc Loc =
944 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
945 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
946 DocComment Comment;
947 if (auto *RawComment =
948 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
949 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
950 Context.getDiagnostics());
951
952 // Build declaration fragments and sub-heading for the variable.
955 DeclarationFragments SubHeading =
958 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
960 SubHeading, Template(Decl), isInSystemHeader(Decl));
961 return true;
962}
963
964template <typename Derived>
966 const FunctionTemplateDecl *Decl) {
967 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
968 return true;
969 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
970 return true;
971
972 // Collect symbol information.
973 StringRef Name = Decl->getName();
976 PresumedLoc Loc =
977 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
978 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
979 DocComment Comment;
980 if (auto *RawComment =
981 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
982 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
983 Context.getDiagnostics());
984
985 DeclarationFragments SubHeading =
987 FunctionSignature Signature =
989 Decl->getTemplatedDecl());
990 API.createRecord<GlobalFunctionTemplateRecord>(
991 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
994 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
995
996 return true;
997}
998
999template <typename Derived>
1001 const ObjCInterfaceDecl *Decl) {
1002 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1003 return true;
1004
1005 // Collect symbol information.
1006 StringRef Name = Decl->getName();
1007 SmallString<128> USR;
1009 PresumedLoc Loc =
1010 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1011 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1012 DocComment Comment;
1013 if (auto *RawComment =
1014 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1015 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1016 Context.getDiagnostics());
1017
1018 // Build declaration fragments and sub-heading for the interface.
1021 DeclarationFragments SubHeading =
1023
1024 // Collect super class information.
1025 SymbolReference SuperClass;
1026 if (const auto *SuperClassDecl = Decl->getSuperClass())
1027 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1028
1029 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1030 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1032 SubHeading, SuperClass, isInSystemHeader(Decl));
1033
1034 // Record all methods (selectors). This doesn't include automatically
1035 // synthesized property methods.
1036 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1037 Decl->methods());
1038 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1039 Decl->properties());
1040 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1041 Decl->ivars());
1042 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1043 Decl->protocols());
1044
1045 return true;
1046}
1047
1048template <typename Derived>
1050 const ObjCProtocolDecl *Decl) {
1051 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1052 return true;
1053
1054 // Collect symbol information.
1055 StringRef Name = Decl->getName();
1056 SmallString<128> USR;
1058 PresumedLoc Loc =
1059 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1060 DocComment Comment;
1061 if (auto *RawComment =
1062 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1063 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1064 Context.getDiagnostics());
1065
1066 // Build declaration fragments and sub-heading for the protocol.
1069 DeclarationFragments SubHeading =
1071
1072 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1073 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1074 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1075 isInSystemHeader(Decl));
1076
1077 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1078 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1079 Decl->properties());
1080 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1081 Decl->protocols());
1082
1083 return true;
1084}
1085
1086template <typename Derived>
1088 const TypedefNameDecl *Decl) {
1089 // Skip ObjC Type Parameter for now.
1090 if (isa<ObjCTypeParamDecl>(Decl))
1091 return true;
1092
1094 return true;
1095
1096 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1097 return true;
1098
1099 StringRef Name = Decl->getName();
1100
1101 // If the underlying type was defined as part of the typedef modify it's
1102 // fragments directly and pretend the typedef doesn't exist.
1103 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1105 Decl->getName() == TagDecl->getName()) {
1106 SmallString<128> TagUSR;
1108 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1109 DeclarationFragments LeadingFragments;
1110 LeadingFragments.append("typedef",
1112 LeadingFragments.appendSpace();
1113 Record->Declaration.removeTrailingSemicolon()
1114 .prepend(std::move(LeadingFragments))
1117 .appendSemicolon();
1118
1119 return true;
1120 }
1121 }
1122 }
1123
1124 PresumedLoc Loc =
1125 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1126 SmallString<128> USR;
1128 DocComment Comment;
1129 if (auto *RawComment =
1130 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1131 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1132 Context.getDiagnostics());
1133
1134 QualType Type = Decl->getUnderlyingType();
1135 SymbolReference SymRef =
1137 API);
1138
1139 API.createRecord<TypedefRecord>(
1140 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1144 isInSystemHeader(Decl));
1145
1146 return true;
1147}
1148
1149template <typename Derived>
1151 const ObjCCategoryDecl *Decl) {
1152 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1153 return true;
1154
1155 StringRef Name = Decl->getName();
1156 SmallString<128> USR;
1158 PresumedLoc Loc =
1159 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1160 DocComment Comment;
1161 if (auto *RawComment =
1162 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1163 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1164 Context.getDiagnostics());
1165 // Build declaration fragments and sub-heading for the category.
1168 DeclarationFragments SubHeading =
1170
1171 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1172 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1173
1174 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1175 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1176 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1177 Interface, isInSystemHeader(Decl));
1178
1179 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1180 Decl->methods());
1181 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1182 Decl->properties());
1183 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1184 Decl->ivars());
1185 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1186 Decl->protocols());
1187
1188 return true;
1189}
1190
1191/// Collect API information for the enum constants and associate with the
1192/// parent enum.
1193template <typename Derived>
1196 for (const auto *Constant : Constants) {
1197 // Collect symbol information.
1198 StringRef Name = Constant->getName();
1199 SmallString<128> USR;
1200 index::generateUSRForDecl(Constant, USR);
1201 PresumedLoc Loc =
1202 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1203 DocComment Comment;
1204 if (auto *RawComment =
1205 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1206 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1207 Context.getDiagnostics());
1208
1209 // Build declaration fragments and sub-heading for the enum constant.
1212 DeclarationFragments SubHeading =
1214
1215 API.createRecord<EnumConstantRecord>(
1216 USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
1218 SubHeading, isInSystemHeader(Constant));
1219 }
1220}
1221
1222template <typename Derived>
1224 // ObjCIvars are handled separately
1225 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1226 return true;
1227
1228 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1229 return true;
1230
1231 // Collect symbol information.
1232 StringRef Name = Decl->getName();
1233 SmallString<128> USR;
1235 PresumedLoc Loc =
1236 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1237 DocComment Comment;
1238 if (auto *RawComment =
1239 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1240 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1241 Context.getDiagnostics());
1242
1243 // Build declaration fragments and sub-heading for the struct field.
1246 DeclarationFragments SubHeading =
1248
1249 RecordContext *NewRecord = nullptr;
1250 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1252
1253 NewRecord = API.createRecord<CXXFieldRecord>(
1254 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1256 SubHeading, Access, isInSystemHeader(Decl));
1257 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1258 if (RD->isUnion())
1259 NewRecord = API.createRecord<UnionFieldRecord>(
1260 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1262 SubHeading, isInSystemHeader(Decl));
1263 else
1264 NewRecord = API.createRecord<StructFieldRecord>(
1265 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1267 SubHeading, isInSystemHeader(Decl));
1268 }
1269
1270 // If this field has a non typedef'd anonymous tag type let's pretend the
1271 // type's child records are under us in the hierarchy.
1272 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1273
1274 return true;
1275}
1276
1277template <typename Derived>
1279 const CXXConversionDecl *Decl) {
1280 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1281 Decl->isImplicit())
1282 return true;
1283
1284 auto Name = Decl->getNameAsString();
1285 SmallString<128> USR;
1287 PresumedLoc Loc =
1288 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1289 DocComment Comment;
1290 if (auto *RawComment =
1291 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1292 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1293 Context.getDiagnostics());
1294
1295 // Build declaration fragments, sub-heading, and signature for the method.
1298 DeclarationFragments SubHeading =
1300 FunctionSignature Signature =
1303
1304 if (Decl->isStatic())
1305 API.createRecord<CXXStaticMethodRecord>(
1306 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1308 SubHeading, Signature, Access, isInSystemHeader(Decl));
1309 else
1310 API.createRecord<CXXInstanceMethodRecord>(
1311 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1313 SubHeading, Signature, Access, isInSystemHeader(Decl));
1314
1315 return true;
1316}
1317
1318/// Collect API information for the Objective-C methods and associate with the
1319/// parent container.
1320template <typename Derived>
1322 ObjCContainerRecord *Container,
1323 const ObjCContainerDecl::method_range Methods) {
1324 for (const auto *Method : Methods) {
1325 // Don't record selectors for properties.
1326 if (Method->isPropertyAccessor())
1327 continue;
1328
1329 auto Name = Method->getSelector().getAsString();
1330 SmallString<128> USR;
1331 index::generateUSRForDecl(Method, USR);
1332 PresumedLoc Loc =
1333 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1334 DocComment Comment;
1335 if (auto *RawComment =
1336 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1337 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1338 Context.getDiagnostics());
1339
1340 // Build declaration fragments, sub-heading, and signature for the method.
1343 DeclarationFragments SubHeading =
1345 FunctionSignature Signature =
1347
1348 if (Method->isInstanceMethod())
1349 API.createRecord<ObjCInstanceMethodRecord>(
1350 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1352 SubHeading, Signature, isInSystemHeader(Method));
1353 else
1354 API.createRecord<ObjCClassMethodRecord>(
1355 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1357 SubHeading, Signature, isInSystemHeader(Method));
1358 }
1359}
1360
1361template <typename Derived>
1363 ObjCContainerRecord *Container,
1364 const ObjCContainerDecl::prop_range Properties) {
1365 for (const auto *Property : Properties) {
1366 StringRef Name = Property->getName();
1367 SmallString<128> USR;
1369 PresumedLoc Loc =
1370 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1371 DocComment Comment;
1372 if (auto *RawComment =
1373 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1374 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1375 Context.getDiagnostics());
1376
1377 // Build declaration fragments and sub-heading for the property.
1380 DeclarationFragments SubHeading =
1382
1383 auto GetterName = Property->getGetterName().getAsString();
1384 auto SetterName = Property->getSetterName().getAsString();
1385
1386 // Get the attributes for property.
1387 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1388 if (Property->getPropertyAttributes() &
1390 Attributes |= ObjCPropertyRecord::ReadOnly;
1391
1392 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1393 API.createRecord<ObjCClassPropertyRecord>(
1394 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1396 SubHeading,
1397 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1398 GetterName, SetterName, Property->isOptional(),
1399 isInSystemHeader(Property));
1400 else
1401 API.createRecord<ObjCInstancePropertyRecord>(
1402 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1404 SubHeading,
1405 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1406 GetterName, SetterName, Property->isOptional(),
1407 isInSystemHeader(Property));
1408 }
1409}
1410
1411template <typename Derived>
1413 ObjCContainerRecord *Container,
1414 const llvm::iterator_range<
1416 Ivars) {
1417 for (const auto *Ivar : Ivars) {
1418 StringRef Name = Ivar->getName();
1419 SmallString<128> USR;
1420 index::generateUSRForDecl(Ivar, USR);
1421
1422 PresumedLoc Loc =
1423 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1424 DocComment Comment;
1425 if (auto *RawComment =
1426 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1427 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1428 Context.getDiagnostics());
1429
1430 // Build declaration fragments and sub-heading for the instance variable.
1433 DeclarationFragments SubHeading =
1435
1436 API.createRecord<ObjCInstanceVariableRecord>(
1437 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1439 SubHeading, isInSystemHeader(Ivar));
1440 }
1441}
1442
1443template <typename Derived>
1445 ObjCContainerRecord *Container,
1447 for (const auto *Protocol : Protocols)
1448 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1449}
1450
1451} // namespace impl
1452
1453/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1454/// information.
1455template <typename Derived = void>
1457 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1458 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1459 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1460 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1461
1462public:
1464
1465 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1466 const RawComment *fetchRawCommentForDecl(const Decl *D) const {
1467 return this->Context.getRawCommentForDeclNoCache(D);
1468 }
1469};
1470
1471} // namespace extractapi
1472} // namespace clang
1473
1474#endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
This file defines the APIRecord-based structs and the APISet class.
Defines the clang::ASTContext interface.
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
This file defines the Declaration Fragments related classes.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
This file defines the UnderlyingTypeResolver which is a helper type for resolving the undelrying type...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
SourceManager & getSourceManager()
Definition: ASTContext.h:705
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
RawComment * getRawCommentForDeclNoCache(const Decl *D) const
Return the documentation comment attached to a given declaration, without looking into cache.
Definition: ASTContext.cpp:293
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2532
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2859
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2796
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2057
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Represents a class template specialization, which refers to a class template with a given set of temp...
Declaration of a C++20 concept.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2344
bool isRecord() const
Definition: DeclBase.h:2148
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2061
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:601
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:805
SourceLocation getLocation() const
Definition: DeclBase.h:447
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition: DeclBase.h:941
DeclContext * getDeclContext()
Definition: DeclBase.h:456
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
Represents an enum.
Definition: Decl.h:3868
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:3999
Represents a member of a struct/union/class.
Definition: Decl.h:3058
Represents a function declaration or definition.
Definition: Decl.h:1971
@ TK_MemberSpecialization
Definition: Decl.h:1983
@ TK_DependentNonTemplate
Definition: Decl.h:1992
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1987
@ TK_DependentFunctionTemplateSpecialization
Definition: Decl.h:1990
Declaration of a template function.
Definition: DeclTemplate.h:958
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
Represent a C++ namespace.
Definition: Decl.h:547
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2323
llvm::iterator_range< specific_decl_iterator< ObjCMethodDecl > > method_range
Definition: DeclObjC.h:1012
llvm::iterator_range< specific_decl_iterator< ObjCPropertyDecl > > prop_range
Definition: DeclObjC.h:963
Represents an ObjC class declaration.
Definition: DeclObjC.h:1152
llvm::iterator_range< protocol_iterator > protocol_range
Definition: DeclObjC.h:1354
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2079
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition: Type.h:738
std::vector< CommentLine > getFormattedLines(const SourceManager &SourceMgr, DiagnosticsEngine &Diags) const
Returns sanitized comment text as separated lines with locations in source, suitable for further proc...
Represents a struct/union/class.
Definition: Decl.h:4169
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3585
bool isEmbeddedInDeclarator() const
True if this tag declaration is "embedded" (i.e., defined or declared for the very first time) in the...
Definition: Decl.h:3712
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3688
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:5572
The base class of the type hierarchy.
Definition: Type.h:1607
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Definition: Type.cpp:1878
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3535
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3433
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
APISet holds the set of API records collected from given inputs.
Definition: API.h:1397
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:113
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:100
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:89
static DeclarationFragments getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *)
static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *)
static DeclarationFragments getFragmentsForEnumConstant(const EnumConstantDecl *)
Build DeclarationFragments for an enum constant declaration EnumConstantDecl.
static DeclarationFragments getFragmentsForObjCCategory(const ObjCCategoryDecl *)
Build DeclarationFragments for an Objective-C category declaration ObjCCategoryDecl.
static DeclarationFragments getFragmentsForTypedef(const TypedefNameDecl *Decl)
Build DeclarationFragments for a typedef TypedefNameDecl.
static DeclarationFragments getFragmentsForEnum(const EnumDecl *)
Build DeclarationFragments for an enum declaration EnumDecl.
static DeclarationFragments getFragmentsForConversionFunction(const CXXConversionDecl *)
static DeclarationFragments getFragmentsForClassTemplateSpecialization(const ClassTemplateSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCProtocol(const ObjCProtocolDecl *)
Build DeclarationFragments for an Objective-C protocol declaration ObjCProtocolDecl.
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *)
static DeclarationFragments getFragmentsForField(const FieldDecl *)
Build DeclarationFragments for a field declaration FieldDecl.
static DeclarationFragments getFragmentsForVar(const VarDecl *)
Build DeclarationFragments for a variable declaration VarDecl.
static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(const ClassTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *)
Build DeclarationFragments for an Objective-C method declaration ObjCMethodDecl.
static DeclarationFragments getFragmentsForFunction(const FunctionDecl *)
Build DeclarationFragments for a function declaration FunctionDecl.
static AccessControl getAccessControl(const Decl *Decl)
static DeclarationFragments getFragmentsForObjCProperty(const ObjCPropertyDecl *)
Build DeclarationFragments for an Objective-C property declaration ObjCPropertyDecl.
static DeclarationFragments getFragmentsForSpecialCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForNamespace(const NamespaceDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(const VarTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplateSpecialization(const VarTemplateSpecializationDecl *)
static FunctionSignature getFunctionSignature(const FunctionT *Function)
Build FunctionSignature for a function-like declaration FunctionT like FunctionDecl,...
static DeclarationFragments getSubHeading(const NamedDecl *)
Build sub-heading fragments for a NamedDecl.
static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *)
static DeclarationFragments getFragmentsForOverloadedOperator(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl)
static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *)
Build DeclarationFragments for a struct/union record declaration RecordDecl.
static DeclarationFragments getFragmentsForObjCInterface(const ObjCInterfaceDecl *)
Build DeclarationFragments for an Objective-C interface declaration ObjCInterfaceDecl.
DeclarationFragments is a vector of tagged important parts of a symbol's declaration.
DeclarationFragments & append(DeclarationFragments Other)
Append another DeclarationFragments to the end.
DeclarationFragments & appendSpace()
Append a text Fragment of a space character.
DeclarationFragments & prepend(DeclarationFragments Other)
Prepend another DeclarationFragments to the beginning.
DeclarationFragments & removeTrailingSemicolon()
Removes a trailing semicolon character if present.
DeclarationFragments & appendSemicolon()
Append a text Fragment of a semicolon character.
The RecursiveASTVisitor to traverse symbol declarations and collect API information.
const RawComment * fetchRawCommentForDecl(const Decl *D) const
ExtractAPIVisitor(ASTContext &Context, APISet &API)
bool shouldDeclBeIncluded(const Decl *D) const
Store function signature information with DeclarationFragments of the return type and parameters.
Base class used for specific record types that have children records this is analogous to the DeclCon...
Definition: API.h:310
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:62
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl)
bool WalkUpFromClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitFunctionDecl(const FunctionDecl *Decl)
bool VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
void maybeMergeWithAnonymousTag(const DeclaratorDecl &D, RecordContext *NewRecordContext)
bool VisitCXXMethodDecl(const CXXMethodDecl *Decl)
bool VisitVarTemplateDecl(const VarTemplateDecl *Decl)
bool WalkUpFromCXXMethodDecl(const CXXMethodDecl *Decl)
StringRef getTypedefName(const TagDecl *Decl)
void recordObjCInstanceVariables(ObjCContainerRecord *Container, const llvm::iterator_range< DeclContext::specific_decl_iterator< ObjCIvarDecl > > Ivars)
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl)
void recordObjCMethods(ObjCContainerRecord *Container, const ObjCContainerDecl::method_range Methods)
Collect API information for the Objective-C methods and associate with the parent container.
void recordObjCProperties(ObjCContainerRecord *Container, const ObjCContainerDecl::prop_range Properties)
bool WalkUpFromNamespaceDecl(const NamespaceDecl *Decl)
SymbolReference createHierarchyInformationForDecl(const Decl &D)
bool WalkUpFromRecordDecl(const RecordDecl *Decl)
bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl)
bool VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl)
const RawComment * fetchRawCommentForDecl(const Decl *Decl) const
bool VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool VisitTypedefNameDecl(const TypedefNameDecl *Decl)
void recordEnumConstants(EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants)
Collect API information for the enum constants and associate with the parent enum.
bool VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl)
SymbolReference createSymbolReferenceForDecl(const Decl &D)
bool WalkUpFromVarTemplateDecl(const VarTemplateDecl *Decl)
bool shouldDeclBeIncluded(const Decl *Decl) const
bool VisitNamespaceDecl(const NamespaceDecl *Decl)
bool WalkUpFromFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl)
bool WalkUpFromFunctionDecl(const FunctionDecl *Decl)
bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl)
void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols)
bool VisitCXXConversionDecl(const CXXConversionDecl *Decl)
SmallVector< SymbolReference > getBases(const CXXRecordDecl *Decl)
bool VisitConceptDecl(const ConceptDecl *Decl)
bool WalkUpFromVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool WalkUpFromClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
std::vector< RawComment::CommentLine > DocComment
DocComment is a vector of RawComment::CommentLine.
Definition: API.h:158
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
The JSON file list parser is used to communicate input to InstallAPI.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Definition: Linkage.h:24
@ Property
The type of a property.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ AS_public
Definition: Specifiers.h:121
static AvailabilityInfo createFromDecl(const Decl *Decl)
The base representation of an API record. Holds common symbol information.
Definition: API.h:192
RecordKind
Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
Definition: API.h:194
SmallVector< SymbolReference > Bases
Definition: API.h:1169
This holds information associated with enum constants.
Definition: API.h:585
This holds information associated with enums.
Definition: API.h:630
This holds information associated with global functions.
Definition: API.h:402
This holds information associated with global functions.
Definition: API.h:483
This holds information associated with Objective-C categories.
Definition: API.h:1273
The base representation of an Objective-C container record.
Definition: API.h:1149
This holds information associated with Objective-C instance variables.
Definition: API.h:1049
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:1306
AttributeKind
The attributes associated with an Objective-C property.
Definition: API.h:974
This holds information associated with Objective-C protocols.
Definition: API.h:1330
StringRef Source
The source project/module/product of the referred symbol.
Definition: API.h:169
This holds information associated with typedefs.
Definition: API.h:1374
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.