clang 20.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 if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
179 Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
180 } else {
181 SymbolReference BaseClass;
182 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
184
185 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
186 if (auto *TTPTD = BaseSpecifier.getType()
187 ->getAs<TemplateTypeParmType>()
188 ->getDecl()) {
190 index::generateUSRForDecl(TTPTD, USR);
191 BaseClass.USR = API.copyString(USR);
192 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
193 }
194 }
195 Bases.emplace_back(BaseClass);
196 }
197 }
198 return Bases;
199 }
200
202 if (Decl->isUnion())
203 return APIRecord::RK_Union;
204 if (Decl->isStruct())
206
208 }
209
210 StringRef getOwningModuleName(const Decl &D) {
211 if (auto *OwningModule = D.getImportedOwningModule())
212 return OwningModule->Name;
213
214 return {};
215 }
216
218 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
219
220 if (!Context || isa<TranslationUnitDecl>(Context))
221 return {};
222
224 }
225
229
231 if (Record)
232 return SymbolReference(Record);
233
234 StringRef Name;
235 if (auto *ND = dyn_cast<NamedDecl>(&D))
236 Name = ND->getName();
237
239 }
240
242 return D.getName().empty() && getTypedefName(&D).empty() &&
243 D.isEmbeddedInDeclarator();
244 }
245
247 RecordContext *NewRecordContext) {
248 if (!NewRecordContext)
249 return;
250 auto *Tag = D.getType()->getAsTagDecl();
251 SmallString<128> TagUSR;
253 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
254 API.findRecordForUSR(TagUSR))) {
255 if (Record->IsEmbeddedInVarDeclarator)
256 NewRecordContext->stealRecordChain(*Record);
257 }
258 }
259};
260
261template <typename Derived>
263 // skip function parameters.
264 if (isa<ParmVarDecl>(Decl))
265 return true;
266
267 // Skip non-global variables in records (struct/union/class) but not static
268 // members.
269 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
270 return true;
271
272 // Skip local variables inside function or method.
274 return true;
275
276 // If this is a template but not specialization or instantiation, skip.
278 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
279 return true;
280
281 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
282 return true;
283
284 // Collect symbol information.
285 StringRef Name = Decl->getName();
289 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
290 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
291 DocComment Comment;
292 if (auto *RawComment =
293 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
294 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
295 Context.getDiagnostics());
296
297 // Build declaration fragments and sub-heading for the variable.
300 DeclarationFragments SubHeading =
302 if (Decl->isStaticDataMember()) {
304 API.createRecord<StaticFieldRecord>(
305 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
307 SubHeading, Access, isInSystemHeader(Decl));
308 } else {
309 // Add the global variable record to the API set.
310 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
311 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
313 SubHeading, isInSystemHeader(Decl));
314
315 // If this global variable has a non typedef'd anonymous tag type let's
316 // pretend the type's child records are under us in the hierarchy.
317 maybeMergeWithAnonymousTag(*Decl, NewRecord);
318 }
319
320 return true;
321}
322
323template <typename Derived>
325 const FunctionDecl *Decl) {
326 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
327 // Skip member function in class templates.
328 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
329 return true;
330
331 // Skip methods in records.
332 for (const auto &P : Context.getParents(*Method)) {
333 if (P.template get<CXXRecordDecl>())
334 return true;
335 }
336
337 // Skip ConstructorDecl and DestructorDecl.
338 if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
339 return true;
340 }
341
342 // Skip templated functions that aren't processed here.
343 switch (Decl->getTemplatedKind()) {
347 break;
351 return true;
352 }
353
354 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
355 return true;
356
357 // Collect symbol information.
358 auto Name = Decl->getNameAsString();
362 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
363 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
364 DocComment Comment;
365 if (auto *RawComment =
366 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
367 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
368 Context.getDiagnostics());
369
370 // Build declaration fragments, sub-heading, and signature of the function.
371 DeclarationFragments SubHeading =
373 FunctionSignature Signature =
375 if (Decl->getTemplateSpecializationInfo())
377 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
381 SubHeading, Signature, isInSystemHeader(Decl));
382 else
383 // Add the function record to the API set.
384 API.createRecord<GlobalFunctionRecord>(
385 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
388 Signature, isInSystemHeader(Decl));
389 return true;
390}
391
392template <typename Derived>
394 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
395 return true;
396
400 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
401 DocComment Comment;
402 if (auto *RawComment =
403 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
404 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
405 Context.getDiagnostics());
406
407 // Build declaration fragments and sub-heading for the enum.
410 DeclarationFragments SubHeading =
412
413 // Collect symbol information.
414 SymbolReference ParentContainer;
415
416 if (Decl->hasNameForLinkage()) {
417 StringRef Name = Decl->getName();
418 if (Name.empty())
419 Name = getTypedefName(Decl);
420
421 auto *ER = API.createRecord<EnumRecord>(
422 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
424 SubHeading, isInSystemHeader(Decl), false);
425 ParentContainer = SymbolReference(ER);
426 } else {
427 // If this an anonymous enum then the parent scope of the constants is the
428 // top level namespace.
429 ParentContainer = {};
430 }
431
432 // Now collect information about the enumerators in this enum.
433 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
434 Decl->enumerators());
435
436 return true;
437}
438
439template <typename Derived>
441 const FunctionDecl *Decl) {
442 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
443 return true;
444}
445
446template <typename Derived>
448 const RecordDecl *Decl) {
449 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
450 return true;
451}
452
453template <typename Derived>
455 const CXXRecordDecl *Decl) {
456 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
457 return true;
458}
459
460template <typename Derived>
462 const CXXMethodDecl *Decl) {
463 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
464 return true;
465}
466
467template <typename Derived>
470 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
471 return true;
472}
473
474template <typename Derived>
478 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
479 Decl);
480 return true;
481}
482
483template <typename Derived>
485 const VarTemplateDecl *Decl) {
486 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
487 return true;
488}
489
490template <typename Derived>
493 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
494 return true;
495}
496
497template <typename Derived>
501 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
502 return true;
503}
504
505template <typename Derived>
507 const FunctionTemplateDecl *Decl) {
508 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
509 return true;
510}
511
512template <typename Derived>
514 const NamespaceDecl *Decl) {
515 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
516 return true;
517}
518
519template <typename Derived>
521 const NamespaceDecl *Decl) {
522 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
523 return true;
524 if (Decl->isAnonymousNamespace())
525 return true;
526 StringRef Name = Decl->getName();
529 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
531 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
532 DocComment Comment;
533 if (auto *RawComment =
534 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
535 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
536 Context.getDiagnostics());
537
538 // Build declaration fragments and sub-heading for the struct.
541 DeclarationFragments SubHeading =
543 API.createRecord<NamespaceRecord>(
544 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
546 SubHeading, isInSystemHeader(Decl));
547
548 return true;
549}
550
551template <typename Derived>
553 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
554 return true;
555
556 // Collect symbol information.
557 StringRef Name = Decl->getName();
558 if (Name.empty())
559 Name = getTypedefName(Decl);
560
564 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
565 DocComment Comment;
566 if (auto *RawComment =
567 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
568 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
569 Context.getDiagnostics());
570
571 // Build declaration fragments and sub-heading for the struct.
574 DeclarationFragments SubHeading =
576
577 if (Decl->isUnion())
578 API.createRecord<UnionRecord>(
579 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
581 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
582 else
583 API.createRecord<StructRecord>(
584 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
586 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
587
588 return true;
589}
590
591template <typename Derived>
593 const CXXRecordDecl *Decl) {
594 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
595 Decl->isImplicit())
596 return true;
597
598 StringRef Name = Decl->getName();
599 if (Name.empty())
600 Name = getTypedefName(Decl);
601
605 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
606 DocComment Comment;
607 if (auto *RawComment =
608 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
609 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
610 Context.getDiagnostics());
613 DeclarationFragments SubHeading =
615
617
619 if (Decl->getDescribedClassTemplate()) {
620 // Inject template fragments before class fragments.
621 Declaration.prepend(
623 Decl->getDescribedClassTemplate()));
624 Record = API.createRecord<ClassTemplateRecord>(
625 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
627 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
628 isInSystemHeader(Decl));
629 } else {
630 Record = API.createRecord<CXXClassRecord>(
631 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
633 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
634 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
635 }
636
637 Record->KindForDisplay = getKindForDisplay(Decl);
638 Record->Bases = getBases(Decl);
639
640 return true;
641}
642
643template <typename Derived>
645 const CXXMethodDecl *Decl) {
646 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
647 Decl->isImplicit())
648 return true;
649
650 if (isa<CXXConversionDecl>(Decl))
651 return true;
652 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
653 return true;
654
658 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
659 DocComment Comment;
660 if (auto *RawComment =
661 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
662 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
663 Context.getDiagnostics());
664 DeclarationFragments SubHeading =
668
670 Decl->getDescribedFunctionTemplate()) {
671 API.createRecord<CXXMethodTemplateRecord>(
672 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
678 Template(TemplateDecl), isInSystemHeader(Decl));
679 } else if (Decl->getTemplateSpecializationInfo())
681 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
685 SubHeading, Signature, Access, isInSystemHeader(Decl));
686 else if (Decl->isOverloadedOperator())
687 API.createRecord<CXXInstanceMethodRecord>(
688 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
691 SubHeading, Signature, Access, isInSystemHeader(Decl));
692 else if (Decl->isStatic())
693 API.createRecord<CXXStaticMethodRecord>(
694 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
697 Signature, Access, isInSystemHeader(Decl));
698 else
699 API.createRecord<CXXInstanceMethodRecord>(
700 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
703 Signature, Access, isInSystemHeader(Decl));
704
705 return true;
706}
707
708template <typename Derived>
710 const CXXConstructorDecl *Decl) {
711 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
712 Decl->isImplicit())
713 return true;
714
715 auto Name = Decl->getNameAsString();
719 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
720 DocComment Comment;
721 if (auto *RawComment =
722 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
723 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
724 Context.getDiagnostics());
725
726 // Build declaration fragments, sub-heading, and signature for the method.
729 DeclarationFragments SubHeading =
731 FunctionSignature Signature =
734
735 API.createRecord<CXXConstructorRecord>(
736 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
738 Signature, Access, isInSystemHeader(Decl));
739 return true;
740}
741
742template <typename Derived>
744 const CXXDestructorDecl *Decl) {
745 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
746 Decl->isImplicit())
747 return true;
748
749 auto Name = Decl->getNameAsString();
753 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
754 DocComment Comment;
755 if (auto *RawComment =
756 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
757 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
758 Context.getDiagnostics());
759
760 // Build declaration fragments, sub-heading, and signature for the method.
763 DeclarationFragments SubHeading =
765 FunctionSignature Signature =
768 API.createRecord<CXXDestructorRecord>(
769 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
771 Signature, Access, isInSystemHeader(Decl));
772 return true;
773}
774
775template <typename Derived>
777 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
778 return true;
779
780 StringRef Name = Decl->getName();
784 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
785 DocComment Comment;
786 if (auto *RawComment =
787 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
788 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
789 Context.getDiagnostics());
792 DeclarationFragments SubHeading =
794 API.createRecord<ConceptRecord>(
795 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
797 Template(Decl), isInSystemHeader(Decl));
798 return true;
799}
800
801template <typename Derived>
804 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
805 return true;
806
807 StringRef Name = Decl->getName();
811 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
812 DocComment Comment;
813 if (auto *RawComment =
814 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
815 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
816 Context.getDiagnostics());
819 Decl);
820 DeclarationFragments SubHeading =
822
823 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
824 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
827 isInSystemHeader(Decl));
828
829 CTSR->Bases = getBases(Decl);
830
831 return true;
832}
833
834template <typename Derived>
838 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
839 return true;
840
841 StringRef Name = Decl->getName();
845 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
846 DocComment Comment;
847 if (auto *RawComment =
848 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
849 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
850 Context.getDiagnostics());
853 DeclarationFragments SubHeading =
855 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
856 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
859 isInSystemHeader(Decl));
860
861 CTPSR->KindForDisplay = getKindForDisplay(Decl);
862 CTPSR->Bases = getBases(Decl);
863
864 return true;
865}
866
867template <typename Derived>
869 const VarTemplateDecl *Decl) {
870 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
871 return true;
872
873 // Collect symbol information.
874 StringRef Name = Decl->getName();
878 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
879 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
880 DocComment Comment;
881 if (auto *RawComment =
882 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
883 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
884 Context.getDiagnostics());
885
886 // Build declaration fragments and sub-heading for the variable.
890 Decl))
892 Decl->getTemplatedDecl()));
893 // Inject template fragments before var fragments.
894 DeclarationFragments SubHeading =
896
897 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
898 API.createRecord<CXXFieldTemplateRecord>(
899 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
902 Template(Decl), isInSystemHeader(Decl));
903 else
904 API.createRecord<GlobalVariableTemplateRecord>(
905 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
907 SubHeading, Template(Decl), isInSystemHeader(Decl));
908 return true;
909}
910
911template <typename Derived>
914 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
915 return true;
916
917 // Collect symbol information.
918 StringRef Name = Decl->getName();
922 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
923 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
924 DocComment Comment;
925 if (auto *RawComment =
926 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
927 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
928 Context.getDiagnostics());
929
930 // Build declaration fragments and sub-heading for the variable.
933 Decl);
934 DeclarationFragments SubHeading =
937 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
939 SubHeading, isInSystemHeader(Decl));
940 return true;
941}
942
943template <typename Derived>
946 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
947 return true;
948
949 // Collect symbol information.
950 StringRef Name = Decl->getName();
954 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
955 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
956 DocComment Comment;
957 if (auto *RawComment =
958 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
959 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
960 Context.getDiagnostics());
961
962 // Build declaration fragments and sub-heading for the variable.
965 DeclarationFragments SubHeading =
968 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
970 SubHeading, Template(Decl), isInSystemHeader(Decl));
971 return true;
972}
973
974template <typename Derived>
976 const FunctionTemplateDecl *Decl) {
977 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
978 return true;
979 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
980 return true;
981
982 // Collect symbol information.
983 auto Name = Decl->getNameAsString();
987 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
988 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
989 DocComment Comment;
990 if (auto *RawComment =
991 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
992 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
993 Context.getDiagnostics());
994
995 DeclarationFragments SubHeading =
997 FunctionSignature Signature =
999 Decl->getTemplatedDecl());
1000 API.createRecord<GlobalFunctionTemplateRecord>(
1001 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1004 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1005
1006 return true;
1007}
1008
1009template <typename Derived>
1011 const ObjCInterfaceDecl *Decl) {
1012 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1013 return true;
1014
1015 // Collect symbol information.
1016 StringRef Name = Decl->getName();
1017 SmallString<128> USR;
1020 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1021 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1022 DocComment Comment;
1023 if (auto *RawComment =
1024 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1025 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1026 Context.getDiagnostics());
1027
1028 // Build declaration fragments and sub-heading for the interface.
1031 DeclarationFragments SubHeading =
1033
1034 // Collect super class information.
1035 SymbolReference SuperClass;
1036 if (const auto *SuperClassDecl = Decl->getSuperClass())
1037 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1038
1039 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1040 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1042 SubHeading, SuperClass, isInSystemHeader(Decl));
1043
1044 // Record all methods (selectors). This doesn't include automatically
1045 // synthesized property methods.
1046 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1047 Decl->methods());
1048 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1049 Decl->properties());
1050 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1051 Decl->ivars());
1052 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1053 Decl->protocols());
1054
1055 return true;
1056}
1057
1058template <typename Derived>
1060 const ObjCProtocolDecl *Decl) {
1061 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1062 return true;
1063
1064 // Collect symbol information.
1065 StringRef Name = Decl->getName();
1066 SmallString<128> USR;
1069 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1070 DocComment Comment;
1071 if (auto *RawComment =
1072 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1073 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1074 Context.getDiagnostics());
1075
1076 // Build declaration fragments and sub-heading for the protocol.
1079 DeclarationFragments SubHeading =
1081
1082 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1083 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1084 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1085 isInSystemHeader(Decl));
1086
1087 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1088 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1089 Decl->properties());
1090 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1091 Decl->protocols());
1092
1093 return true;
1094}
1095
1096template <typename Derived>
1098 const TypedefNameDecl *Decl) {
1099 // Skip ObjC Type Parameter for now.
1100 if (isa<ObjCTypeParamDecl>(Decl))
1101 return true;
1102
1104 return true;
1105
1106 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1107 return true;
1108
1109 StringRef Name = Decl->getName();
1110
1111 // If the underlying type was defined as part of the typedef modify it's
1112 // fragments directly and pretend the typedef doesn't exist.
1113 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1115 Decl->getName() == TagDecl->getName()) {
1116 SmallString<128> TagUSR;
1118 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1119 DeclarationFragments LeadingFragments;
1120 LeadingFragments.append("typedef",
1122 LeadingFragments.appendSpace();
1123 Record->Declaration.removeTrailingSemicolon()
1124 .prepend(std::move(LeadingFragments))
1127 .appendSemicolon();
1128
1129 return true;
1130 }
1131 }
1132 }
1133
1135 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1136 SmallString<128> USR;
1138 DocComment Comment;
1139 if (auto *RawComment =
1140 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1141 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1142 Context.getDiagnostics());
1143
1144 QualType Type = Decl->getUnderlyingType();
1145 SymbolReference SymRef =
1147 API);
1148
1149 API.createRecord<TypedefRecord>(
1150 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1154 isInSystemHeader(Decl));
1155
1156 return true;
1157}
1158
1159template <typename Derived>
1161 const ObjCCategoryDecl *Decl) {
1162 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1163 return true;
1164
1165 StringRef Name = Decl->getName();
1166 SmallString<128> USR;
1169 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1170 DocComment Comment;
1171 if (auto *RawComment =
1172 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1173 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1174 Context.getDiagnostics());
1175 // Build declaration fragments and sub-heading for the category.
1178 DeclarationFragments SubHeading =
1180
1181 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1182 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1183
1184 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1185 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1186 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1187 Interface, isInSystemHeader(Decl));
1188
1189 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1190 Decl->methods());
1191 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1192 Decl->properties());
1193 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1194 Decl->ivars());
1195 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1196 Decl->protocols());
1197
1198 return true;
1199}
1200
1201/// Collect API information for the enum constants and associate with the
1202/// parent enum.
1203template <typename Derived>
1205 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1206 for (const auto *Constant : Constants) {
1207 // Collect symbol information.
1208 StringRef Name = Constant->getName();
1209 SmallString<128> USR;
1210 index::generateUSRForDecl(Constant, USR);
1212 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1213 DocComment Comment;
1214 if (auto *RawComment =
1215 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1216 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1217 Context.getDiagnostics());
1218
1219 // Build declaration fragments and sub-heading for the enum constant.
1222 DeclarationFragments SubHeading =
1224
1225 API.createRecord<EnumConstantRecord>(
1226 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1227 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1228 }
1229}
1230
1231template <typename Derived>
1233 // ObjCIvars are handled separately
1234 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1235 return true;
1236
1237 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1238 return true;
1239
1240 // Collect symbol information.
1241 StringRef Name = Decl->getName();
1242 SmallString<128> USR;
1245 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1246 DocComment Comment;
1247 if (auto *RawComment =
1248 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1249 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1250 Context.getDiagnostics());
1251
1252 // Build declaration fragments and sub-heading for the struct field.
1255 DeclarationFragments SubHeading =
1257
1258 RecordContext *NewRecord = nullptr;
1259 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1261
1262 NewRecord = API.createRecord<CXXFieldRecord>(
1263 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1265 SubHeading, Access, isInSystemHeader(Decl));
1266 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1267 if (RD->isUnion())
1268 NewRecord = API.createRecord<UnionFieldRecord>(
1269 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1271 SubHeading, isInSystemHeader(Decl));
1272 else
1273 NewRecord = API.createRecord<StructFieldRecord>(
1274 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1276 SubHeading, isInSystemHeader(Decl));
1277 }
1278
1279 // If this field has a non typedef'd anonymous tag type let's pretend the
1280 // type's child records are under us in the hierarchy.
1281 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1282
1283 return true;
1284}
1285
1286template <typename Derived>
1288 const CXXConversionDecl *Decl) {
1289 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1290 Decl->isImplicit())
1291 return true;
1292
1293 auto Name = Decl->getNameAsString();
1294 SmallString<128> USR;
1297 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1298 DocComment Comment;
1299 if (auto *RawComment =
1300 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1301 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1302 Context.getDiagnostics());
1303
1304 // Build declaration fragments, sub-heading, and signature for the method.
1307 DeclarationFragments SubHeading =
1309 FunctionSignature Signature =
1312
1313 if (Decl->isStatic())
1314 API.createRecord<CXXStaticMethodRecord>(
1315 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1317 SubHeading, Signature, Access, isInSystemHeader(Decl));
1318 else
1319 API.createRecord<CXXInstanceMethodRecord>(
1320 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1322 SubHeading, Signature, Access, isInSystemHeader(Decl));
1323
1324 return true;
1325}
1326
1327/// Collect API information for the Objective-C methods and associate with the
1328/// parent container.
1329template <typename Derived>
1331 ObjCContainerRecord *Container,
1332 const ObjCContainerDecl::method_range Methods) {
1333 for (const auto *Method : Methods) {
1334 // Don't record selectors for properties.
1335 if (Method->isPropertyAccessor())
1336 continue;
1337
1338 auto Name = Method->getSelector().getAsString();
1339 SmallString<128> USR;
1340 index::generateUSRForDecl(Method, USR);
1342 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1343 DocComment Comment;
1344 if (auto *RawComment =
1345 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1346 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1347 Context.getDiagnostics());
1348
1349 // Build declaration fragments, sub-heading, and signature for the method.
1352 DeclarationFragments SubHeading =
1354 FunctionSignature Signature =
1356
1357 if (Method->isInstanceMethod())
1358 API.createRecord<ObjCInstanceMethodRecord>(
1359 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1361 SubHeading, Signature, isInSystemHeader(Method));
1362 else
1363 API.createRecord<ObjCClassMethodRecord>(
1364 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1366 SubHeading, Signature, isInSystemHeader(Method));
1367 }
1368}
1369
1370template <typename Derived>
1372 ObjCContainerRecord *Container,
1373 const ObjCContainerDecl::prop_range Properties) {
1374 for (const auto *Property : Properties) {
1375 StringRef Name = Property->getName();
1376 SmallString<128> USR;
1379 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1380 DocComment Comment;
1381 if (auto *RawComment =
1382 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1383 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1384 Context.getDiagnostics());
1385
1386 // Build declaration fragments and sub-heading for the property.
1389 DeclarationFragments SubHeading =
1391
1392 auto GetterName = Property->getGetterName().getAsString();
1393 auto SetterName = Property->getSetterName().getAsString();
1394
1395 // Get the attributes for property.
1396 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1397 if (Property->getPropertyAttributes() &
1399 Attributes |= ObjCPropertyRecord::ReadOnly;
1400
1401 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1402 API.createRecord<ObjCClassPropertyRecord>(
1403 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1405 SubHeading,
1406 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1407 GetterName, SetterName, Property->isOptional(),
1408 isInSystemHeader(Property));
1409 else
1410 API.createRecord<ObjCInstancePropertyRecord>(
1411 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1413 SubHeading,
1414 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1415 GetterName, SetterName, Property->isOptional(),
1416 isInSystemHeader(Property));
1417 }
1418}
1419
1420template <typename Derived>
1422 ObjCContainerRecord *Container,
1423 const llvm::iterator_range<
1425 Ivars) {
1426 for (const auto *Ivar : Ivars) {
1427 StringRef Name = Ivar->getName();
1428 SmallString<128> USR;
1429 index::generateUSRForDecl(Ivar, USR);
1430
1432 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1433 DocComment Comment;
1434 if (auto *RawComment =
1435 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1436 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1437 Context.getDiagnostics());
1438
1439 // Build declaration fragments and sub-heading for the instance variable.
1442 DeclarationFragments SubHeading =
1444
1445 API.createRecord<ObjCInstanceVariableRecord>(
1446 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1448 SubHeading, isInSystemHeader(Ivar));
1449 }
1450}
1451
1452template <typename Derived>
1454 ObjCContainerRecord *Container,
1456 for (const auto *Protocol : Protocols)
1457 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1458}
1459
1460} // namespace impl
1461
1462/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1463/// information.
1464template <typename Derived = void>
1466 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1467 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1468 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1469 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1470
1471public:
1473
1474 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1476 if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
1477 return Comment;
1478
1479 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1480 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1481 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1482 TagTypeDecl->isCompleteDefinition())
1483 return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
1484 }
1485
1486 return nullptr;
1487 }
1488};
1489
1490} // namespace extractapi
1491} // namespace clang
1492
1493#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:720
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:712
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:2359
bool isRecord() const
Definition: DeclBase.h:2159
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2072
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:731
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1900
Represents an enum.
Definition: Decl.h:3840
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:3971
Represents a member of a struct/union/class.
Definition: Decl.h:3030
Represents a function declaration or definition.
Definition: Decl.h:1932
@ TK_MemberSpecialization
Definition: Decl.h:1944
@ TK_DependentNonTemplate
Definition: Decl.h:1953
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1948
@ TK_DependentFunctionTemplateSpecialization
Definition: Decl.h:1951
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:941
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:4141
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:3557
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:3684
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3660
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:6169
The base class of the type hierarchy.
Definition: Type.h:1829
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3507
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3405
Represents a variable declaration or definition.
Definition: Decl.h:879
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.