clang 21.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>
44
45protected:
47 : Context(Context), API(API) {}
48
49public:
50 const APISet &getAPI() const { return API; }
51
53
55
57
59
61
63
65
68
71
73
76
79
81
83
85
88
91
93
95
97
99
101
103
106
109
111
112 bool
114
117
119
121
123
125
127
128 bool shouldDeclBeIncluded(const Decl *Decl) const;
129
131
132protected:
133 /// Collect API information for the enum constants and associate with the
134 /// parent enum.
136 const EnumDecl::enumerator_range Constants);
137
138 /// Collect API information for the Objective-C methods and associate with the
139 /// parent container.
141 const ObjCContainerDecl::method_range Methods);
142
144 const ObjCContainerDecl::prop_range Properties);
145
147 ObjCContainerRecord *Container,
148 const llvm::iterator_range<
150 Ivars);
151
154
157
158 StringRef getTypedefName(const TagDecl *Decl) {
159 if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
160 return TypedefDecl->getName();
161
162 return {};
163 }
164
165 bool isInSystemHeader(const Decl *D) {
166 return Context.getSourceManager().isInSystemHeader(D->getLocation());
167 }
168
169private:
170 Derived &getDerivedExtractAPIVisitor() {
171 return *static_cast<Derived *>(this);
172 }
173
174protected:
176 // FIXME: store AccessSpecifier given by inheritance
178 for (const auto &BaseSpecifier : Decl->bases()) {
179 // skip classes not inherited as public
180 if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
181 continue;
182 if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
183 Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
184 } else {
185 SymbolReference BaseClass;
186 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
188
189 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
190 if (auto *TTPTD = BaseSpecifier.getType()
191 ->getAs<TemplateTypeParmType>()
192 ->getDecl()) {
194 index::generateUSRForDecl(TTPTD, USR);
195 BaseClass.USR = API.copyString(USR);
196 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
197 }
198 }
199 Bases.emplace_back(BaseClass);
200 }
201 }
202 return Bases;
203 }
204
206 if (Decl->isUnion())
207 return APIRecord::RK_Union;
208 if (Decl->isStruct())
210
212 }
213
214 StringRef getOwningModuleName(const Decl &D) {
215 if (auto *OwningModule = D.getImportedOwningModule())
216 return OwningModule->getTopLevelModule()->Name;
217
218 return {};
219 }
220
222 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
223
224 if (!Context || isa<TranslationUnitDecl>(Context))
225 return {};
226
228 }
229
233
235 if (Record)
236 return SymbolReference(Record);
237
238 StringRef Name;
239 if (auto *ND = dyn_cast<NamedDecl>(&D))
240 Name = ND->getName();
241
243 }
244
246 return D.getName().empty() && getTypedefName(&D).empty() &&
247 D.isEmbeddedInDeclarator() && !D.isFreeStanding();
248 }
249
251 RecordContext *NewRecordContext) {
252 if (!NewRecordContext)
253 return;
254 auto *Tag = D.getType()->getAsTagDecl();
255 if (!Tag) {
256 if (const auto *AT = D.getASTContext().getAsArrayType(D.getType())) {
257 Tag = AT->getElementType()->getAsTagDecl();
258 }
259 }
260 SmallString<128> TagUSR;
262 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
263 API.findRecordForUSR(TagUSR))) {
264 if (Record->IsEmbeddedInVarDeclarator) {
265 NewRecordContext->stealRecordChain(*Record);
267 }
268 }
269 }
270};
271
272template <typename Derived>
274 // skip function parameters.
275 if (isa<ParmVarDecl>(Decl))
276 return true;
277
278 // Skip non-global variables in records (struct/union/class) but not static
279 // members.
280 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
281 return true;
282
283 // Skip local variables inside function or method.
285 return true;
286
287 // If this is a template but not specialization or instantiation, skip.
289 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
290 return true;
291
292 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
293 return true;
294
295 // Collect symbol information.
296 StringRef Name = Decl->getName();
300 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
301 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
302 DocComment Comment;
303 if (auto *RawComment =
304 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
305 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
306 Context.getDiagnostics());
307
308 // Build declaration fragments and sub-heading for the variable.
311 DeclarationFragments SubHeading =
313 if (Decl->isStaticDataMember()) {
315 API.createRecord<StaticFieldRecord>(
316 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
318 SubHeading, Access, isInSystemHeader(Decl));
319 } else {
320 // Add the global variable record to the API set.
321 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
322 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
324 SubHeading, isInSystemHeader(Decl));
325
326 // If this global variable has a non typedef'd anonymous tag type let's
327 // pretend the type's child records are under us in the hierarchy.
328 maybeMergeWithAnonymousTag(*Decl, NewRecord);
329 }
330
331 return true;
332}
333
334template <typename Derived>
336 const FunctionDecl *Decl) {
337 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
338 // Skip member function in class templates.
339 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
340 return true;
341
342 // Skip methods in records.
343 for (const auto &P : Context.getParents(*Method)) {
344 if (P.template get<CXXRecordDecl>())
345 return true;
346 }
347
348 // Skip ConstructorDecl and DestructorDecl.
349 if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
350 return true;
351 }
352
353 // Skip templated functions that aren't processed here.
354 switch (Decl->getTemplatedKind()) {
358 break;
362 return true;
363 }
364
365 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
366 return true;
367
368 // Collect symbol information.
369 auto Name = Decl->getNameAsString();
373 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
374 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
375 DocComment Comment;
376 if (auto *RawComment =
377 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
378 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
379 Context.getDiagnostics());
380
381 // Build declaration fragments, sub-heading, and signature of the function.
382 DeclarationFragments SubHeading =
384 FunctionSignature Signature =
386 if (Decl->getTemplateSpecializationInfo())
388 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
392 SubHeading, Signature, isInSystemHeader(Decl));
393 else
394 // Add the function record to the API set.
395 API.createRecord<GlobalFunctionRecord>(
396 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
399 Signature, isInSystemHeader(Decl));
400 return true;
401}
402
403template <typename Derived>
405 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
406 return true;
407
411 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
412 DocComment Comment;
413 if (auto *RawComment =
414 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
415 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
416 Context.getDiagnostics());
417
418 // Build declaration fragments and sub-heading for the enum.
421 DeclarationFragments SubHeading =
423
424 // Collect symbol information.
425 SymbolReference ParentContainer;
426
427 if (Decl->hasNameForLinkage()) {
428 StringRef Name = Decl->getName();
429 if (Name.empty())
430 Name = getTypedefName(Decl);
431
432 auto *ER = API.createRecord<EnumRecord>(
433 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
435 SubHeading, isInSystemHeader(Decl), false);
436 ParentContainer = SymbolReference(ER);
437 } else {
438 // If this an anonymous enum then the parent scope of the constants is the
439 // top level namespace.
440 ParentContainer = {};
441 }
442
443 // Now collect information about the enumerators in this enum.
444 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
445 Decl->enumerators());
446
447 return true;
448}
449
450template <typename Derived>
452 const FunctionDecl *Decl) {
453 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
454 return true;
455}
456
457template <typename Derived>
459 const RecordDecl *Decl) {
460 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
461 return true;
462}
463
464template <typename Derived>
466 const CXXRecordDecl *Decl) {
467 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
468 return true;
469}
470
471template <typename Derived>
473 const CXXMethodDecl *Decl) {
474 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
475 return true;
476}
477
478template <typename Derived>
481 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
482 return true;
483}
484
485template <typename Derived>
489 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
490 Decl);
491 return true;
492}
493
494template <typename Derived>
496 const VarTemplateDecl *Decl) {
497 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
498 return true;
499}
500
501template <typename Derived>
504 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
505 return true;
506}
507
508template <typename Derived>
512 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
513 return true;
514}
515
516template <typename Derived>
518 const FunctionTemplateDecl *Decl) {
519 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
520 return true;
521}
522
523template <typename Derived>
525 const NamespaceDecl *Decl) {
526 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
527 return true;
528}
529
530template <typename Derived>
532 const NamespaceDecl *Decl) {
533 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
534 return true;
535 if (Decl->isAnonymousNamespace())
536 return true;
537 StringRef Name = Decl->getName();
540 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
542 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
543 DocComment Comment;
544 if (auto *RawComment =
545 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
546 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
547 Context.getDiagnostics());
548
549 // Build declaration fragments and sub-heading for the struct.
552 DeclarationFragments SubHeading =
554 API.createRecord<NamespaceRecord>(
555 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
557 SubHeading, isInSystemHeader(Decl));
558
559 return true;
560}
561
562template <typename Derived>
564 bool Ret = Base::TraverseRecordDecl(Decl);
565
566 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
569 API.removeRecord(USR);
570 }
571
572 return Ret;
573}
574
575template <typename Derived>
577 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
578 return true;
579
580 // Collect symbol information.
581 StringRef Name = Decl->getName();
582 if (Name.empty())
583 Name = getTypedefName(Decl);
584
588 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
589 DocComment Comment;
590 if (auto *RawComment =
591 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
592 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
593 Context.getDiagnostics());
594
595 // Build declaration fragments and sub-heading for the struct.
598 DeclarationFragments SubHeading =
600
601 if (Decl->isUnion())
602 API.createRecord<UnionRecord>(
603 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
605 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
606 else
607 API.createRecord<StructRecord>(
608 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
610 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
611
612 return true;
613}
614
615template <typename Derived>
618 bool Ret = Base::TraverseCXXRecordDecl(Decl);
619
620 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
623 API.removeRecord(USR);
624 }
625
626 return Ret;
627}
628
629template <typename Derived>
631 const CXXRecordDecl *Decl) {
632 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
633 Decl->isImplicit())
634 return true;
635
636 StringRef Name = Decl->getName();
637 if (Name.empty())
638 Name = getTypedefName(Decl);
639
643 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
644 DocComment Comment;
645 if (auto *RawComment =
646 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
647 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
648 Context.getDiagnostics());
651 DeclarationFragments SubHeading =
653
655
657 if (Decl->getDescribedClassTemplate()) {
658 // Inject template fragments before class fragments.
659 Declaration.prepend(
661 Decl->getDescribedClassTemplate()));
662 Record = API.createRecord<ClassTemplateRecord>(
663 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
665 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
666 isInSystemHeader(Decl));
667 } else {
668 Record = API.createRecord<CXXClassRecord>(
669 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
671 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
672 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
673 }
674
675 Record->KindForDisplay = getKindForDisplay(Decl);
676 Record->Bases = getBases(Decl);
677
678 return true;
679}
680
681template <typename Derived>
683 const CXXMethodDecl *Decl) {
684 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
685 Decl->isImplicit())
686 return true;
687
688 if (isa<CXXConversionDecl>(Decl))
689 return true;
690 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
691 return true;
692
696 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
697 DocComment Comment;
698 if (auto *RawComment =
699 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
700 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
701 Context.getDiagnostics());
702 DeclarationFragments SubHeading =
706
708 Decl->getDescribedFunctionTemplate()) {
709 API.createRecord<CXXMethodTemplateRecord>(
710 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
716 Template(TemplateDecl), isInSystemHeader(Decl));
717 } else if (Decl->getTemplateSpecializationInfo())
719 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
723 SubHeading, Signature, Access, isInSystemHeader(Decl));
724 else if (Decl->isOverloadedOperator())
725 API.createRecord<CXXInstanceMethodRecord>(
726 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
729 SubHeading, Signature, Access, isInSystemHeader(Decl));
730 else if (Decl->isStatic())
731 API.createRecord<CXXStaticMethodRecord>(
732 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
735 Signature, Access, isInSystemHeader(Decl));
736 else
737 API.createRecord<CXXInstanceMethodRecord>(
738 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
741 Signature, Access, isInSystemHeader(Decl));
742
743 return true;
744}
745
746template <typename Derived>
748 const CXXConstructorDecl *Decl) {
749 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
750 Decl->isImplicit())
751 return true;
752
753 auto Name = Decl->getNameAsString();
757 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
758 DocComment Comment;
759 if (auto *RawComment =
760 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
761 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
762 Context.getDiagnostics());
763
764 // Build declaration fragments, sub-heading, and signature for the method.
767 DeclarationFragments SubHeading =
769 FunctionSignature Signature =
772
773 API.createRecord<CXXConstructorRecord>(
774 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
776 Signature, Access, isInSystemHeader(Decl));
777 return true;
778}
779
780template <typename Derived>
782 const CXXDestructorDecl *Decl) {
783 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
784 Decl->isImplicit())
785 return true;
786
787 auto Name = Decl->getNameAsString();
791 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
792 DocComment Comment;
793 if (auto *RawComment =
794 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
795 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
796 Context.getDiagnostics());
797
798 // Build declaration fragments, sub-heading, and signature for the method.
801 DeclarationFragments SubHeading =
803 FunctionSignature Signature =
806 API.createRecord<CXXDestructorRecord>(
807 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
809 Signature, Access, isInSystemHeader(Decl));
810 return true;
811}
812
813template <typename Derived>
815 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
816 return true;
817
818 StringRef Name = Decl->getName();
822 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
823 DocComment Comment;
824 if (auto *RawComment =
825 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
826 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
827 Context.getDiagnostics());
830 DeclarationFragments SubHeading =
832 API.createRecord<ConceptRecord>(
833 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
835 Template(Decl), isInSystemHeader(Decl));
836 return true;
837}
838
839template <typename Derived>
842 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
843 return true;
844
845 StringRef Name = Decl->getName();
849 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
850 DocComment Comment;
851 if (auto *RawComment =
852 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
853 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
854 Context.getDiagnostics());
857 Decl);
858 DeclarationFragments SubHeading =
860
861 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
862 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
865 isInSystemHeader(Decl));
866
867 CTSR->Bases = getBases(Decl);
868
869 return true;
870}
871
872template <typename Derived>
876 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
877 return true;
878
879 StringRef Name = Decl->getName();
883 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
884 DocComment Comment;
885 if (auto *RawComment =
886 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
887 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
888 Context.getDiagnostics());
891 DeclarationFragments SubHeading =
893 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
894 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
897 isInSystemHeader(Decl));
898
899 CTPSR->KindForDisplay = getKindForDisplay(Decl);
900 CTPSR->Bases = getBases(Decl);
901
902 return true;
903}
904
905template <typename Derived>
907 const VarTemplateDecl *Decl) {
908 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
909 return true;
910
911 // Collect symbol information.
912 StringRef Name = Decl->getName();
916 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
917 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
918 DocComment Comment;
919 if (auto *RawComment =
920 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
921 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
922 Context.getDiagnostics());
923
924 // Build declaration fragments and sub-heading for the variable.
928 Decl))
930 Decl->getTemplatedDecl()));
931 // Inject template fragments before var fragments.
932 DeclarationFragments SubHeading =
934
935 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
936 API.createRecord<CXXFieldTemplateRecord>(
937 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
940 Template(Decl), isInSystemHeader(Decl));
941 else
942 API.createRecord<GlobalVariableTemplateRecord>(
943 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
945 SubHeading, Template(Decl), isInSystemHeader(Decl));
946 return true;
947}
948
949template <typename Derived>
952 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
953 return true;
954
955 // Collect symbol information.
956 StringRef Name = Decl->getName();
960 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
961 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
962 DocComment Comment;
963 if (auto *RawComment =
964 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
965 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
966 Context.getDiagnostics());
967
968 // Build declaration fragments and sub-heading for the variable.
971 Decl);
972 DeclarationFragments SubHeading =
975 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
977 SubHeading, isInSystemHeader(Decl));
978 return true;
979}
980
981template <typename Derived>
984 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
985 return true;
986
987 // Collect symbol information.
988 StringRef Name = Decl->getName();
992 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
993 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
994 DocComment Comment;
995 if (auto *RawComment =
996 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
997 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
998 Context.getDiagnostics());
999
1000 // Build declaration fragments and sub-heading for the variable.
1003 DeclarationFragments SubHeading =
1006 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1008 SubHeading, Template(Decl), isInSystemHeader(Decl));
1009 return true;
1010}
1011
1012template <typename Derived>
1014 const FunctionTemplateDecl *Decl) {
1015 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
1016 return true;
1017 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1018 return true;
1019
1020 // Collect symbol information.
1021 auto Name = Decl->getNameAsString();
1022 SmallString<128> USR;
1025 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1026 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1027 DocComment Comment;
1028 if (auto *RawComment =
1029 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1030 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1031 Context.getDiagnostics());
1032
1033 DeclarationFragments SubHeading =
1035 FunctionSignature Signature =
1037 Decl->getTemplatedDecl());
1038 API.createRecord<GlobalFunctionTemplateRecord>(
1039 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1042 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1043
1044 return true;
1045}
1046
1047template <typename Derived>
1049 const ObjCInterfaceDecl *Decl) {
1050 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1051 return true;
1052
1053 // Collect symbol information.
1054 StringRef Name = Decl->getName();
1055 SmallString<128> USR;
1058 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1059 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
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 interface.
1069 DeclarationFragments SubHeading =
1071
1072 // Collect super class information.
1073 SymbolReference SuperClass;
1074 if (const auto *SuperClassDecl = Decl->getSuperClass())
1075 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1076
1077 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1078 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1080 SubHeading, SuperClass, isInSystemHeader(Decl));
1081
1082 // Record all methods (selectors). This doesn't include automatically
1083 // synthesized property methods.
1084 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1085 Decl->methods());
1086 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1087 Decl->properties());
1088 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1089 Decl->ivars());
1090 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1091 Decl->protocols());
1092
1093 return true;
1094}
1095
1096template <typename Derived>
1098 const ObjCProtocolDecl *Decl) {
1099 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1100 return true;
1101
1102 // Collect symbol information.
1103 StringRef Name = Decl->getName();
1104 SmallString<128> USR;
1107 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1108 DocComment Comment;
1109 if (auto *RawComment =
1110 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1111 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1112 Context.getDiagnostics());
1113
1114 // Build declaration fragments and sub-heading for the protocol.
1117 DeclarationFragments SubHeading =
1119
1120 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1121 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1122 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1123 isInSystemHeader(Decl));
1124
1125 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1126 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1127 Decl->properties());
1128 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1129 Decl->protocols());
1130
1131 return true;
1132}
1133
1134template <typename Derived>
1136 const TypedefNameDecl *Decl) {
1137 // Skip ObjC Type Parameter for now.
1138 if (isa<ObjCTypeParamDecl>(Decl))
1139 return true;
1140
1142 return true;
1143
1144 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1145 return true;
1146
1147 StringRef Name = Decl->getName();
1148
1149 // If the underlying type was defined as part of the typedef modify it's
1150 // fragments directly and pretend the typedef doesn't exist.
1151 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1153 Decl->getName() == TagDecl->getName()) {
1154 SmallString<128> TagUSR;
1156 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1157 DeclarationFragments LeadingFragments;
1158 LeadingFragments.append("typedef",
1160 LeadingFragments.appendSpace();
1161 Record->Declaration.removeTrailingSemicolon()
1162 .prepend(std::move(LeadingFragments))
1165 .appendSemicolon();
1166
1167 return true;
1168 }
1169 }
1170 }
1171
1173 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1174 SmallString<128> USR;
1176 DocComment Comment;
1177 if (auto *RawComment =
1178 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1179 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1180 Context.getDiagnostics());
1181
1182 QualType Type = Decl->getUnderlyingType();
1183 SymbolReference SymRef =
1185 API);
1186
1187 API.createRecord<TypedefRecord>(
1188 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1192 isInSystemHeader(Decl));
1193
1194 return true;
1195}
1196
1197template <typename Derived>
1199 const ObjCCategoryDecl *Decl) {
1200 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1201 return true;
1202
1203 StringRef Name = Decl->getName();
1204 SmallString<128> USR;
1207 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1208 DocComment Comment;
1209 if (auto *RawComment =
1210 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1211 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1212 Context.getDiagnostics());
1213 // Build declaration fragments and sub-heading for the category.
1216 DeclarationFragments SubHeading =
1218
1219 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1220 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1221
1222 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1223 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1224 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1225 Interface, isInSystemHeader(Decl));
1226
1227 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1228 Decl->methods());
1229 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1230 Decl->properties());
1231 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1232 Decl->ivars());
1233 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1234 Decl->protocols());
1235
1236 return true;
1237}
1238
1239/// Collect API information for the enum constants and associate with the
1240/// parent enum.
1241template <typename Derived>
1243 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1244 for (const auto *Constant : Constants) {
1245 // Collect symbol information.
1246 StringRef Name = Constant->getName();
1247 SmallString<128> USR;
1248 index::generateUSRForDecl(Constant, USR);
1250 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1251 DocComment Comment;
1252 if (auto *RawComment =
1253 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1254 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1255 Context.getDiagnostics());
1256
1257 // Build declaration fragments and sub-heading for the enum constant.
1260 DeclarationFragments SubHeading =
1262
1263 API.createRecord<EnumConstantRecord>(
1264 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1265 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1266 }
1267}
1268
1269template <typename Derived>
1271 // ObjCIvars are handled separately
1272 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1273 return true;
1274
1275 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1276 return true;
1277
1278 // Collect symbol information.
1279 StringRef Name = Decl->getName();
1280 SmallString<128> USR;
1283 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1284 DocComment Comment;
1285 if (auto *RawComment =
1286 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1287 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1288 Context.getDiagnostics());
1289
1290 // Build declaration fragments and sub-heading for the struct field.
1293 DeclarationFragments SubHeading =
1295
1296 RecordContext *NewRecord = nullptr;
1297 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1299
1300 NewRecord = API.createRecord<CXXFieldRecord>(
1301 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1303 SubHeading, Access, isInSystemHeader(Decl));
1304 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1305 if (RD->isUnion())
1306 NewRecord = API.createRecord<UnionFieldRecord>(
1307 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1309 SubHeading, isInSystemHeader(Decl));
1310 else
1311 NewRecord = API.createRecord<StructFieldRecord>(
1312 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1314 SubHeading, isInSystemHeader(Decl));
1315 }
1316
1317 // If this field has a non typedef'd anonymous tag type let's pretend the
1318 // type's child records are under us in the hierarchy.
1319 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1320
1321 return true;
1322}
1323
1324template <typename Derived>
1326 const CXXConversionDecl *Decl) {
1327 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1328 Decl->isImplicit())
1329 return true;
1330
1331 auto Name = Decl->getNameAsString();
1332 SmallString<128> USR;
1335 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1336 DocComment Comment;
1337 if (auto *RawComment =
1338 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1339 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1340 Context.getDiagnostics());
1341
1342 // Build declaration fragments, sub-heading, and signature for the method.
1345 DeclarationFragments SubHeading =
1347 FunctionSignature Signature =
1350
1351 if (Decl->isStatic())
1352 API.createRecord<CXXStaticMethodRecord>(
1353 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1355 SubHeading, Signature, Access, isInSystemHeader(Decl));
1356 else
1357 API.createRecord<CXXInstanceMethodRecord>(
1358 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1360 SubHeading, Signature, Access, isInSystemHeader(Decl));
1361
1362 return true;
1363}
1364
1365/// Collect API information for the Objective-C methods and associate with the
1366/// parent container.
1367template <typename Derived>
1369 ObjCContainerRecord *Container,
1370 const ObjCContainerDecl::method_range Methods) {
1371 for (const auto *Method : Methods) {
1372 // Don't record selectors for properties.
1373 if (Method->isPropertyAccessor())
1374 continue;
1375
1376 auto Name = Method->getSelector().getAsString();
1377 SmallString<128> USR;
1378 index::generateUSRForDecl(Method, USR);
1380 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1381 DocComment Comment;
1382 if (auto *RawComment =
1383 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1384 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1385 Context.getDiagnostics());
1386
1387 // Build declaration fragments, sub-heading, and signature for the method.
1390 DeclarationFragments SubHeading =
1392 FunctionSignature Signature =
1394
1395 if (Method->isInstanceMethod())
1396 API.createRecord<ObjCInstanceMethodRecord>(
1397 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1399 SubHeading, Signature, isInSystemHeader(Method));
1400 else
1401 API.createRecord<ObjCClassMethodRecord>(
1402 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1404 SubHeading, Signature, isInSystemHeader(Method));
1405 }
1406}
1407
1408template <typename Derived>
1410 ObjCContainerRecord *Container,
1411 const ObjCContainerDecl::prop_range Properties) {
1412 for (const auto *Property : Properties) {
1413 StringRef Name = Property->getName();
1414 SmallString<128> USR;
1417 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1418 DocComment Comment;
1419 if (auto *RawComment =
1420 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1421 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1422 Context.getDiagnostics());
1423
1424 // Build declaration fragments and sub-heading for the property.
1427 DeclarationFragments SubHeading =
1429
1430 auto GetterName = Property->getGetterName().getAsString();
1431 auto SetterName = Property->getSetterName().getAsString();
1432
1433 // Get the attributes for property.
1434 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1435 if (Property->getPropertyAttributes() &
1437 Attributes |= ObjCPropertyRecord::ReadOnly;
1438
1439 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1440 API.createRecord<ObjCClassPropertyRecord>(
1441 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1443 SubHeading,
1444 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1445 GetterName, SetterName, Property->isOptional(),
1446 isInSystemHeader(Property));
1447 else
1448 API.createRecord<ObjCInstancePropertyRecord>(
1449 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1451 SubHeading,
1452 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1453 GetterName, SetterName, Property->isOptional(),
1454 isInSystemHeader(Property));
1455 }
1456}
1457
1458template <typename Derived>
1460 ObjCContainerRecord *Container,
1461 const llvm::iterator_range<
1463 Ivars) {
1464 for (const auto *Ivar : Ivars) {
1465 StringRef Name = Ivar->getName();
1466 SmallString<128> USR;
1467 index::generateUSRForDecl(Ivar, USR);
1468
1470 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1471 DocComment Comment;
1472 if (auto *RawComment =
1473 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1474 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1475 Context.getDiagnostics());
1476
1477 // Build declaration fragments and sub-heading for the instance variable.
1480 DeclarationFragments SubHeading =
1482
1483 API.createRecord<ObjCInstanceVariableRecord>(
1484 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1486 SubHeading, isInSystemHeader(Ivar));
1487 }
1488}
1489
1490template <typename Derived>
1492 ObjCContainerRecord *Container,
1494 for (const auto *Protocol : Protocols)
1495 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1496}
1497
1498} // namespace impl
1499
1500/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1501/// information.
1502template <typename Derived = void>
1504 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1505 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1506 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1507 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1508
1509public:
1511
1512 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1514 if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
1515 return Comment;
1516
1517 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1518 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1519 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1520 TagTypeDecl->isCompleteDefinition())
1521 return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
1522 }
1523
1524 return nullptr;
1525 }
1526};
1527
1528} // namespace extractapi
1529} // namespace clang
1530
1531#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:759
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:188
SourceManager & getSourceManager()
Definition: ASTContext.h:741
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:733
RawComment * getRawCommentForDeclNoCache(const Decl *D) const
Return the documentation comment attached to a given declaration, without looking into cache.
Definition: ASTContext.cpp:313
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2592
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2924
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2856
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2117
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:2386
bool isRecord() const
Definition: DeclBase.h:2186
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2099
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:528
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:596
SourceLocation getLocation() const
Definition: DeclBase.h:442
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition: DeclBase.h:942
DeclContext * getDeclContext()
Definition: DeclBase.h:451
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:739
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1904
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:3040
Represents a function declaration or definition.
Definition: Decl.h:1935
@ TK_MemberSpecialization
Definition: Decl.h:1947
@ TK_DependentNonTemplate
Definition: Decl.h:1956
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1951
@ TK_DependentFunctionTemplateSpecialization
Definition: Decl.h:1954
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:280
Represent a C++ namespace.
Definition: Decl.h:551
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2328
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:2083
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition: Type.h:929
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:398
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:6354
The base class of the type hierarchy.
Definition: Type.h:1828
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:3434
Represents a variable declaration or definition.
Definition: Decl.h:886
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:1427
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:134
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:121
void removeRecord(StringRef USR)
Definition: API.cpp:139
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:110
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:306
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:59
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:151
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:191
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ AS_public
Definition: Specifiers.h:124
static AvailabilityInfo createFromDecl(const Decl *Decl)
The base representation of an API record. Holds common symbol information.
Definition: API.h:185
RecordKind KindForDisplay
Definition: API.h:262
RecordKind
Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
Definition: API.h:187
SmallVector< SymbolReference > Bases
Definition: API.h:1199
This holds information associated with enum constants.
Definition: API.h:583
This holds information associated with enums.
Definition: API.h:645
This holds information associated with global functions.
Definition: API.h:400
This holds information associated with global functions.
Definition: API.h:481
This holds information associated with Objective-C categories.
Definition: API.h:1303
The base representation of an Objective-C container record.
Definition: API.h:1179
This holds information associated with Objective-C instance variables.
Definition: API.h:1079
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:1336
AttributeKind
The attributes associated with an Objective-C property.
Definition: API.h:1004
This holds information associated with Objective-C protocols.
Definition: API.h:1360
StringRef Source
The source project/module/product of the referred symbol.
Definition: API.h:162
This holds information associated with typedefs.
Definition: API.h:1404
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.