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/LLVM.h"
25#include "clang/Basic/Module.h"
32#include "llvm/ADT/SmallString.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/Casting.h"
35#include <type_traits>
36
37namespace clang {
38namespace extractapi {
39namespace impl {
40
41template <typename Derived>
43protected:
45 : Context(Context), API(API) {}
46
47public:
48 const APISet &getAPI() const { return API; }
49
51
53
55
57
59
61
63
66
69
71
74
77
79
81
83
85
87
89
91
93
95
97
99
102
105
107
108 bool
110
113
115
117
119
121
123
124 bool shouldDeclBeIncluded(const Decl *Decl) const;
125
127
128protected:
129 /// Collect API information for the enum constants and associate with the
130 /// parent enum.
132 const EnumDecl::enumerator_range Constants);
133
134 /// Collect API information for the Objective-C methods and associate with the
135 /// parent container.
137 const ObjCContainerDecl::method_range Methods);
138
140 const ObjCContainerDecl::prop_range Properties);
141
143 ObjCContainerRecord *Container,
144 const llvm::iterator_range<
146 Ivars);
147
150
153
154 StringRef getTypedefName(const TagDecl *Decl) {
155 if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
156 return TypedefDecl->getName();
157
158 return {};
159 }
160
161 bool isInSystemHeader(const Decl *D) {
162 return Context.getSourceManager().isInSystemHeader(D->getLocation());
163 }
164
165private:
166 Derived &getDerivedExtractAPIVisitor() {
167 return *static_cast<Derived *>(this);
168 }
169
170protected:
172 // FIXME: store AccessSpecifier given by inheritance
174 for (const auto &BaseSpecifier : Decl->bases()) {
175 // skip classes not inherited as public
176 if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
177 continue;
178 SymbolReference BaseClass;
179 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
180 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
181 if (auto *TTPTD = BaseSpecifier.getType()
182 ->getAs<TemplateTypeParmType>()
183 ->getDecl()) {
185 index::generateUSRForDecl(TTPTD, USR);
186 BaseClass.USR = API.copyString(USR);
187 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
188 }
189 } else {
191 *BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl());
192 }
193 Bases.emplace_back(BaseClass);
194 }
195 return Bases;
196 }
197
199 if (Decl->isUnion())
200 return APIRecord::RK_Union;
201 if (Decl->isStruct())
203
205 }
206
207 StringRef getOwningModuleName(const Decl &D) {
208 if (auto *OwningModule = D.getImportedOwningModule())
209 return OwningModule->Name;
210
211 return {};
212 }
213
215 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
216
217 if (!Context || isa<TranslationUnitDecl>(Context))
218 return {};
219
221 }
222
226
228 if (Record)
229 return SymbolReference(Record);
230
231 StringRef Name;
232 if (auto *ND = dyn_cast<NamedDecl>(&D))
233 Name = ND->getName();
234
236 }
237
239 return D.getName().empty() && getTypedefName(&D).empty() &&
240 D.isEmbeddedInDeclarator();
241 }
242
244 RecordContext *NewRecordContext) {
245 if (!NewRecordContext)
246 return;
247 auto *Tag = D.getType()->getAsTagDecl();
248 SmallString<128> TagUSR;
250 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
251 API.findRecordForUSR(TagUSR))) {
252 if (Record->IsEmbeddedInVarDeclarator)
253 NewRecordContext->stealRecordChain(*Record);
254 }
255 }
256};
257
258template <typename Derived>
260 // skip function parameters.
261 if (isa<ParmVarDecl>(Decl))
262 return true;
263
264 // Skip non-global variables in records (struct/union/class) but not static
265 // members.
266 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
267 return true;
268
269 // Skip local variables inside function or method.
271 return true;
272
273 // If this is a template but not specialization or instantiation, skip.
275 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
276 return true;
277
278 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
279 return true;
280
281 // Collect symbol information.
282 StringRef Name = Decl->getName();
286 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
287 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
288 DocComment Comment;
289 if (auto *RawComment =
290 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
291 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
292 Context.getDiagnostics());
293
294 // Build declaration fragments and sub-heading for the variable.
297 DeclarationFragments SubHeading =
299 if (Decl->isStaticDataMember()) {
301 API.createRecord<StaticFieldRecord>(
302 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
304 SubHeading, Access, isInSystemHeader(Decl));
305 } else {
306 // Add the global variable record to the API set.
307 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
308 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
310 SubHeading, isInSystemHeader(Decl));
311
312 // If this global variable has a non typedef'd anonymous tag type let's
313 // pretend the type's child records are under us in the hierarchy.
314 maybeMergeWithAnonymousTag(*Decl, NewRecord);
315 }
316
317 return true;
318}
319
320template <typename Derived>
322 const FunctionDecl *Decl) {
323 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
324 // Skip member function in class templates.
325 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
326 return true;
327
328 // Skip methods in records.
329 for (const auto &P : Context.getParents(*Method)) {
330 if (P.template get<CXXRecordDecl>())
331 return true;
332 }
333
334 // Skip ConstructorDecl and DestructorDecl.
335 if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
336 return true;
337 }
338
339 // Skip templated functions that aren't processed here.
340 switch (Decl->getTemplatedKind()) {
344 break;
348 return true;
349 }
350
351 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
352 return true;
353
354 // Collect symbol information.
355 StringRef Name = Decl->getName();
359 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
360 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
361 DocComment Comment;
362 if (auto *RawComment =
363 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
364 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
365 Context.getDiagnostics());
366
367 // Build declaration fragments, sub-heading, and signature of the function.
368 DeclarationFragments SubHeading =
370 FunctionSignature Signature =
372 if (Decl->getTemplateSpecializationInfo())
374 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
378 SubHeading, Signature, isInSystemHeader(Decl));
379 else
380 // Add the function record to the API set.
381 API.createRecord<GlobalFunctionRecord>(
382 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
385 Signature, isInSystemHeader(Decl));
386 return true;
387}
388
389template <typename Derived>
391 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
392 return true;
393
397 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
398 DocComment Comment;
399 if (auto *RawComment =
400 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
401 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
402 Context.getDiagnostics());
403
404 // Build declaration fragments and sub-heading for the enum.
407 DeclarationFragments SubHeading =
409
410 // Collect symbol information.
411 SymbolReference ParentContainer;
412
413 if (Decl->hasNameForLinkage()) {
414 StringRef Name = Decl->getName();
415 if (Name.empty())
416 Name = getTypedefName(Decl);
417
418 auto *ER = API.createRecord<EnumRecord>(
419 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
421 SubHeading, isInSystemHeader(Decl), false);
422 ParentContainer = SymbolReference(ER);
423 } else {
424 // If this an anonymous enum then the parent scope of the constants is the
425 // top level namespace.
426 ParentContainer = {};
427 }
428
429 // Now collect information about the enumerators in this enum.
430 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
431 Decl->enumerators());
432
433 return true;
434}
435
436template <typename Derived>
438 const FunctionDecl *Decl) {
439 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
440 return true;
441}
442
443template <typename Derived>
445 const RecordDecl *Decl) {
446 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
447 return true;
448}
449
450template <typename Derived>
452 const CXXRecordDecl *Decl) {
453 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
454 return true;
455}
456
457template <typename Derived>
459 const CXXMethodDecl *Decl) {
460 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
461 return true;
462}
463
464template <typename Derived>
467 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
468 return true;
469}
470
471template <typename Derived>
475 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
476 Decl);
477 return true;
478}
479
480template <typename Derived>
482 const VarTemplateDecl *Decl) {
483 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
484 return true;
485}
486
487template <typename Derived>
490 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
491 return true;
492}
493
494template <typename Derived>
498 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
499 return true;
500}
501
502template <typename Derived>
504 const FunctionTemplateDecl *Decl) {
505 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
506 return true;
507}
508
509template <typename Derived>
511 const NamespaceDecl *Decl) {
512 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
513 return true;
514}
515
516template <typename Derived>
518 const NamespaceDecl *Decl) {
519 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
520 return true;
521 if (Decl->isAnonymousNamespace())
522 return true;
523 StringRef Name = Decl->getName();
526 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
528 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
529 DocComment Comment;
530 if (auto *RawComment =
531 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
532 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
533 Context.getDiagnostics());
534
535 // Build declaration fragments and sub-heading for the struct.
538 DeclarationFragments SubHeading =
540 API.createRecord<NamespaceRecord>(
541 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
543 SubHeading, isInSystemHeader(Decl));
544
545 return true;
546}
547
548template <typename Derived>
550 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
551 return true;
552
553 // Collect symbol information.
554 StringRef Name = Decl->getName();
555 if (Name.empty())
556 Name = getTypedefName(Decl);
557
561 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
562 DocComment Comment;
563 if (auto *RawComment =
564 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
565 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
566 Context.getDiagnostics());
567
568 // Build declaration fragments and sub-heading for the struct.
571 DeclarationFragments SubHeading =
573
574 if (Decl->isUnion())
575 API.createRecord<UnionRecord>(
576 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
578 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
579 else
580 API.createRecord<StructRecord>(
581 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
583 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
584
585 return true;
586}
587
588template <typename Derived>
590 const CXXRecordDecl *Decl) {
591 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
592 Decl->isImplicit())
593 return true;
594
595 StringRef Name = Decl->getName();
596 if (Name.empty())
597 Name = getTypedefName(Decl);
598
602 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
603 DocComment Comment;
604 if (auto *RawComment =
605 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
606 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
607 Context.getDiagnostics());
610 DeclarationFragments SubHeading =
612
614
616 if (Decl->getDescribedClassTemplate()) {
617 // Inject template fragments before class fragments.
618 Declaration.prepend(
620 Decl->getDescribedClassTemplate()));
621 Record = API.createRecord<ClassTemplateRecord>(
622 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
624 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
625 isInSystemHeader(Decl));
626 } else {
627 Record = API.createRecord<CXXClassRecord>(
628 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
630 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
631 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
632 }
633
634 Record->KindForDisplay = getKindForDisplay(Decl);
635 Record->Bases = getBases(Decl);
636
637 return true;
638}
639
640template <typename Derived>
642 const CXXMethodDecl *Decl) {
643 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
644 Decl->isImplicit())
645 return true;
646
647 if (isa<CXXConversionDecl>(Decl))
648 return true;
649 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
650 return true;
651
655 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
656 DocComment Comment;
657 if (auto *RawComment =
658 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
659 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
660 Context.getDiagnostics());
661 DeclarationFragments SubHeading =
665
667 Decl->getDescribedFunctionTemplate()) {
668 API.createRecord<CXXMethodTemplateRecord>(
669 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
675 Template(TemplateDecl), isInSystemHeader(Decl));
676 } else if (Decl->getTemplateSpecializationInfo())
678 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
682 SubHeading, Signature, Access, isInSystemHeader(Decl));
683 else if (Decl->isOverloadedOperator())
684 API.createRecord<CXXInstanceMethodRecord>(
685 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
688 SubHeading, Signature, Access, isInSystemHeader(Decl));
689 else if (Decl->isStatic())
690 API.createRecord<CXXStaticMethodRecord>(
691 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
694 Signature, Access, isInSystemHeader(Decl));
695 else
696 API.createRecord<CXXInstanceMethodRecord>(
697 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
700 Signature, Access, isInSystemHeader(Decl));
701
702 return true;
703}
704
705template <typename Derived>
707 const CXXConstructorDecl *Decl) {
708 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
709 Decl->isImplicit())
710 return true;
711
712 auto Name = Decl->getNameAsString();
716 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
717 DocComment Comment;
718 if (auto *RawComment =
719 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
720 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
721 Context.getDiagnostics());
722
723 // Build declaration fragments, sub-heading, and signature for the method.
726 DeclarationFragments SubHeading =
728 FunctionSignature Signature =
731
732 API.createRecord<CXXConstructorRecord>(
733 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
735 Signature, Access, isInSystemHeader(Decl));
736 return true;
737}
738
739template <typename Derived>
741 const CXXDestructorDecl *Decl) {
742 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
743 Decl->isImplicit())
744 return true;
745
746 auto Name = Decl->getNameAsString();
750 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
751 DocComment Comment;
752 if (auto *RawComment =
753 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
754 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
755 Context.getDiagnostics());
756
757 // Build declaration fragments, sub-heading, and signature for the method.
760 DeclarationFragments SubHeading =
762 FunctionSignature Signature =
765 API.createRecord<CXXDestructorRecord>(
766 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
768 Signature, Access, isInSystemHeader(Decl));
769 return true;
770}
771
772template <typename Derived>
774 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
775 return true;
776
777 StringRef Name = Decl->getName();
781 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
782 DocComment Comment;
783 if (auto *RawComment =
784 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
785 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
786 Context.getDiagnostics());
789 DeclarationFragments SubHeading =
791 API.createRecord<ConceptRecord>(
792 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
794 Template(Decl), isInSystemHeader(Decl));
795 return true;
796}
797
798template <typename Derived>
801 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
802 return true;
803
804 StringRef Name = Decl->getName();
808 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
809 DocComment Comment;
810 if (auto *RawComment =
811 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
812 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
813 Context.getDiagnostics());
816 Decl);
817 DeclarationFragments SubHeading =
819
820 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
821 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
824 isInSystemHeader(Decl));
825
826 CTSR->Bases = getBases(Decl);
827
828 return true;
829}
830
831template <typename Derived>
835 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
836 return true;
837
838 StringRef Name = Decl->getName();
842 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
843 DocComment Comment;
844 if (auto *RawComment =
845 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
846 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
847 Context.getDiagnostics());
850 DeclarationFragments SubHeading =
852 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
853 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
856 isInSystemHeader(Decl));
857
858 CTPSR->KindForDisplay = getKindForDisplay(Decl);
859 CTPSR->Bases = getBases(Decl);
860
861 return true;
862}
863
864template <typename Derived>
866 const VarTemplateDecl *Decl) {
867 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
868 return true;
869
870 // Collect symbol information.
871 StringRef Name = Decl->getName();
875 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
876 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
877 DocComment Comment;
878 if (auto *RawComment =
879 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
880 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
881 Context.getDiagnostics());
882
883 // Build declaration fragments and sub-heading for the variable.
887 Decl))
889 Decl->getTemplatedDecl()));
890 // Inject template fragments before var fragments.
891 DeclarationFragments SubHeading =
893
894 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
895 API.createRecord<CXXFieldTemplateRecord>(
896 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
899 Template(Decl), isInSystemHeader(Decl));
900 else
901 API.createRecord<GlobalVariableTemplateRecord>(
902 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
904 SubHeading, Template(Decl), isInSystemHeader(Decl));
905 return true;
906}
907
908template <typename Derived>
911 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
912 return true;
913
914 // Collect symbol information.
915 StringRef Name = Decl->getName();
919 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
920 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
921 DocComment Comment;
922 if (auto *RawComment =
923 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
924 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
925 Context.getDiagnostics());
926
927 // Build declaration fragments and sub-heading for the variable.
930 Decl);
931 DeclarationFragments SubHeading =
934 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
936 SubHeading, isInSystemHeader(Decl));
937 return true;
938}
939
940template <typename Derived>
943 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
944 return true;
945
946 // Collect symbol information.
947 StringRef Name = Decl->getName();
951 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
952 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
953 DocComment Comment;
954 if (auto *RawComment =
955 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
956 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
957 Context.getDiagnostics());
958
959 // Build declaration fragments and sub-heading for the variable.
962 DeclarationFragments SubHeading =
965 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
967 SubHeading, Template(Decl), isInSystemHeader(Decl));
968 return true;
969}
970
971template <typename Derived>
973 const FunctionTemplateDecl *Decl) {
974 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
975 return true;
976 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
977 return true;
978
979 // Collect symbol information.
980 StringRef Name = Decl->getName();
984 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
985 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
986 DocComment Comment;
987 if (auto *RawComment =
988 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
989 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
990 Context.getDiagnostics());
991
992 DeclarationFragments SubHeading =
994 FunctionSignature Signature =
996 Decl->getTemplatedDecl());
997 API.createRecord<GlobalFunctionTemplateRecord>(
998 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1001 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1002
1003 return true;
1004}
1005
1006template <typename Derived>
1008 const ObjCInterfaceDecl *Decl) {
1009 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1010 return true;
1011
1012 // Collect symbol information.
1013 StringRef Name = Decl->getName();
1014 SmallString<128> USR;
1017 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1018 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1019 DocComment Comment;
1020 if (auto *RawComment =
1021 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1022 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1023 Context.getDiagnostics());
1024
1025 // Build declaration fragments and sub-heading for the interface.
1028 DeclarationFragments SubHeading =
1030
1031 // Collect super class information.
1032 SymbolReference SuperClass;
1033 if (const auto *SuperClassDecl = Decl->getSuperClass())
1034 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1035
1036 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1037 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1039 SubHeading, SuperClass, isInSystemHeader(Decl));
1040
1041 // Record all methods (selectors). This doesn't include automatically
1042 // synthesized property methods.
1043 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1044 Decl->methods());
1045 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1046 Decl->properties());
1047 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1048 Decl->ivars());
1049 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1050 Decl->protocols());
1051
1052 return true;
1053}
1054
1055template <typename Derived>
1057 const ObjCProtocolDecl *Decl) {
1058 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1059 return true;
1060
1061 // Collect symbol information.
1062 StringRef Name = Decl->getName();
1063 SmallString<128> USR;
1066 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1067 DocComment Comment;
1068 if (auto *RawComment =
1069 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1070 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1071 Context.getDiagnostics());
1072
1073 // Build declaration fragments and sub-heading for the protocol.
1076 DeclarationFragments SubHeading =
1078
1079 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1080 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1081 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1082 isInSystemHeader(Decl));
1083
1084 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1085 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1086 Decl->properties());
1087 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1088 Decl->protocols());
1089
1090 return true;
1091}
1092
1093template <typename Derived>
1095 const TypedefNameDecl *Decl) {
1096 // Skip ObjC Type Parameter for now.
1097 if (isa<ObjCTypeParamDecl>(Decl))
1098 return true;
1099
1101 return true;
1102
1103 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1104 return true;
1105
1106 StringRef Name = Decl->getName();
1107
1108 // If the underlying type was defined as part of the typedef modify it's
1109 // fragments directly and pretend the typedef doesn't exist.
1110 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1112 Decl->getName() == TagDecl->getName()) {
1113 SmallString<128> TagUSR;
1115 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1116 DeclarationFragments LeadingFragments;
1117 LeadingFragments.append("typedef",
1119 LeadingFragments.appendSpace();
1120 Record->Declaration.removeTrailingSemicolon()
1121 .prepend(std::move(LeadingFragments))
1124 .appendSemicolon();
1125
1126 return true;
1127 }
1128 }
1129 }
1130
1132 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1133 SmallString<128> USR;
1135 DocComment Comment;
1136 if (auto *RawComment =
1137 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1138 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1139 Context.getDiagnostics());
1140
1141 QualType Type = Decl->getUnderlyingType();
1142 SymbolReference SymRef =
1144 API);
1145
1146 API.createRecord<TypedefRecord>(
1147 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1151 isInSystemHeader(Decl));
1152
1153 return true;
1154}
1155
1156template <typename Derived>
1158 const ObjCCategoryDecl *Decl) {
1159 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1160 return true;
1161
1162 StringRef Name = Decl->getName();
1163 SmallString<128> USR;
1166 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1167 DocComment Comment;
1168 if (auto *RawComment =
1169 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1170 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1171 Context.getDiagnostics());
1172 // Build declaration fragments and sub-heading for the category.
1175 DeclarationFragments SubHeading =
1177
1178 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1179 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1180
1181 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1182 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1183 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1184 Interface, isInSystemHeader(Decl));
1185
1186 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1187 Decl->methods());
1188 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1189 Decl->properties());
1190 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1191 Decl->ivars());
1192 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1193 Decl->protocols());
1194
1195 return true;
1196}
1197
1198/// Collect API information for the enum constants and associate with the
1199/// parent enum.
1200template <typename Derived>
1202 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1203 for (const auto *Constant : Constants) {
1204 // Collect symbol information.
1205 StringRef Name = Constant->getName();
1206 SmallString<128> USR;
1207 index::generateUSRForDecl(Constant, USR);
1209 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1210 DocComment Comment;
1211 if (auto *RawComment =
1212 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1213 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1214 Context.getDiagnostics());
1215
1216 // Build declaration fragments and sub-heading for the enum constant.
1219 DeclarationFragments SubHeading =
1221
1222 API.createRecord<EnumConstantRecord>(
1223 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1224 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1225 }
1226}
1227
1228template <typename Derived>
1230 // ObjCIvars are handled separately
1231 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1232 return true;
1233
1234 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1235 return true;
1236
1237 // Collect symbol information.
1238 StringRef Name = Decl->getName();
1239 SmallString<128> USR;
1242 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1243 DocComment Comment;
1244 if (auto *RawComment =
1245 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1246 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1247 Context.getDiagnostics());
1248
1249 // Build declaration fragments and sub-heading for the struct field.
1252 DeclarationFragments SubHeading =
1254
1255 RecordContext *NewRecord = nullptr;
1256 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1258
1259 NewRecord = API.createRecord<CXXFieldRecord>(
1260 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1262 SubHeading, Access, isInSystemHeader(Decl));
1263 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1264 if (RD->isUnion())
1265 NewRecord = API.createRecord<UnionFieldRecord>(
1266 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1268 SubHeading, isInSystemHeader(Decl));
1269 else
1270 NewRecord = API.createRecord<StructFieldRecord>(
1271 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1273 SubHeading, isInSystemHeader(Decl));
1274 }
1275
1276 // If this field has a non typedef'd anonymous tag type let's pretend the
1277 // type's child records are under us in the hierarchy.
1278 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1279
1280 return true;
1281}
1282
1283template <typename Derived>
1285 const CXXConversionDecl *Decl) {
1286 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1287 Decl->isImplicit())
1288 return true;
1289
1290 auto Name = Decl->getNameAsString();
1291 SmallString<128> USR;
1294 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1295 DocComment Comment;
1296 if (auto *RawComment =
1297 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1298 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1299 Context.getDiagnostics());
1300
1301 // Build declaration fragments, sub-heading, and signature for the method.
1304 DeclarationFragments SubHeading =
1306 FunctionSignature Signature =
1309
1310 if (Decl->isStatic())
1311 API.createRecord<CXXStaticMethodRecord>(
1312 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1314 SubHeading, Signature, Access, isInSystemHeader(Decl));
1315 else
1316 API.createRecord<CXXInstanceMethodRecord>(
1317 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1319 SubHeading, Signature, Access, isInSystemHeader(Decl));
1320
1321 return true;
1322}
1323
1324/// Collect API information for the Objective-C methods and associate with the
1325/// parent container.
1326template <typename Derived>
1328 ObjCContainerRecord *Container,
1329 const ObjCContainerDecl::method_range Methods) {
1330 for (const auto *Method : Methods) {
1331 // Don't record selectors for properties.
1332 if (Method->isPropertyAccessor())
1333 continue;
1334
1335 auto Name = Method->getSelector().getAsString();
1336 SmallString<128> USR;
1337 index::generateUSRForDecl(Method, USR);
1339 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1340 DocComment Comment;
1341 if (auto *RawComment =
1342 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1343 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1344 Context.getDiagnostics());
1345
1346 // Build declaration fragments, sub-heading, and signature for the method.
1349 DeclarationFragments SubHeading =
1351 FunctionSignature Signature =
1353
1354 if (Method->isInstanceMethod())
1355 API.createRecord<ObjCInstanceMethodRecord>(
1356 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1358 SubHeading, Signature, isInSystemHeader(Method));
1359 else
1360 API.createRecord<ObjCClassMethodRecord>(
1361 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1363 SubHeading, Signature, isInSystemHeader(Method));
1364 }
1365}
1366
1367template <typename Derived>
1369 ObjCContainerRecord *Container,
1370 const ObjCContainerDecl::prop_range Properties) {
1371 for (const auto *Property : Properties) {
1372 StringRef Name = Property->getName();
1373 SmallString<128> USR;
1376 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1377 DocComment Comment;
1378 if (auto *RawComment =
1379 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1380 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1381 Context.getDiagnostics());
1382
1383 // Build declaration fragments and sub-heading for the property.
1386 DeclarationFragments SubHeading =
1388
1389 auto GetterName = Property->getGetterName().getAsString();
1390 auto SetterName = Property->getSetterName().getAsString();
1391
1392 // Get the attributes for property.
1393 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1394 if (Property->getPropertyAttributes() &
1396 Attributes |= ObjCPropertyRecord::ReadOnly;
1397
1398 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1399 API.createRecord<ObjCClassPropertyRecord>(
1400 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1402 SubHeading,
1403 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1404 GetterName, SetterName, Property->isOptional(),
1405 isInSystemHeader(Property));
1406 else
1407 API.createRecord<ObjCInstancePropertyRecord>(
1408 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1410 SubHeading,
1411 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1412 GetterName, SetterName, Property->isOptional(),
1413 isInSystemHeader(Property));
1414 }
1415}
1416
1417template <typename Derived>
1419 ObjCContainerRecord *Container,
1420 const llvm::iterator_range<
1422 Ivars) {
1423 for (const auto *Ivar : Ivars) {
1424 StringRef Name = Ivar->getName();
1425 SmallString<128> USR;
1426 index::generateUSRForDecl(Ivar, USR);
1427
1429 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1430 DocComment Comment;
1431 if (auto *RawComment =
1432 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1433 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1434 Context.getDiagnostics());
1435
1436 // Build declaration fragments and sub-heading for the instance variable.
1439 DeclarationFragments SubHeading =
1441
1442 API.createRecord<ObjCInstanceVariableRecord>(
1443 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1445 SubHeading, isInSystemHeader(Ivar));
1446 }
1447}
1448
1449template <typename Derived>
1451 ObjCContainerRecord *Container,
1453 for (const auto *Protocol : Protocols)
1454 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1455}
1456
1457} // namespace impl
1458
1459/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1460/// information.
1461template <typename Derived = void>
1463 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1464 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1465 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1466 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1467
1468public:
1470
1471 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1473 if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
1474 return Comment;
1475
1476 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1477 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1478 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1479 TagTypeDecl->isCompleteDefinition())
1480 return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
1481 }
1482
1483 return nullptr;
1484 }
1485};
1486
1487} // namespace extractapi
1488} // namespace clang
1489
1490#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
const Decl * D
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.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
SourceLocation Loc
Definition: SemaObjC.cpp:758
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:186
SourceManager & getSourceManager()
Definition: ASTContext.h:717
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:295
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
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:2335
bool isRecord() const
Definition: DeclBase.h:2135
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2048
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
SourceLocation getLocation() const
Definition: DeclBase.h:445
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition: DeclBase.h:928
DeclContext * getDeclContext()
Definition: DeclBase.h:454
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1908
Represents an enum.
Definition: Decl.h:3879
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:4010
Represents a member of a struct/union/class.
Definition: Decl.h:3069
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:957
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:2326
llvm::iterator_range< specific_decl_iterator< ObjCMethodDecl > > method_range
Definition: DeclObjC.h:1013
llvm::iterator_range< specific_decl_iterator< ObjCPropertyDecl > > prop_range
Definition: DeclObjC.h:964
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
llvm::iterator_range< protocol_iterator > protocol_range
Definition: DeclObjC.h:1356
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition: Type.h:942
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:4180
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:3596
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:3723
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3699
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:6170
The base class of the type hierarchy.
Definition: Type.h:1826
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3546
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3444
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:1400
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:112
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:99
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:88
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:313
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:61
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)
APIRecord::RecordKind getKindForDisplay(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)
void recordEnumConstants(SymbolReference Container, const EnumDecl::enumerator_range Constants)
Collect API information for the enum constants and associate with the parent enum.
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)
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 KindForDisplay
Definition: API.h:269
RecordKind
Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
Definition: API.h:194
SmallVector< SymbolReference > Bases
Definition: API.h:1172
This holds information associated with enum constants.
Definition: API.h:588
This holds information associated with enums.
Definition: API.h:633
This holds information associated with global functions.
Definition: API.h:405
This holds information associated with global functions.
Definition: API.h:486
This holds information associated with Objective-C categories.
Definition: API.h:1276
The base representation of an Objective-C container record.
Definition: API.h:1152
This holds information associated with Objective-C instance variables.
Definition: API.h:1052
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:1309
AttributeKind
The attributes associated with an Objective-C property.
Definition: API.h:977
This holds information associated with Objective-C protocols.
Definition: API.h:1333
StringRef Source
The source project/module/product of the referred symbol.
Definition: API.h:169
This holds information associated with typedefs.
Definition: API.h:1377
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.