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>
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 SmallString<128> TagUSR;
257 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
258 API.findRecordForUSR(TagUSR))) {
259 if (Record->IsEmbeddedInVarDeclarator) {
260 NewRecordContext->stealRecordChain(*Record);
262 }
263 }
264 }
265};
266
267template <typename Derived>
269 // skip function parameters.
270 if (isa<ParmVarDecl>(Decl))
271 return true;
272
273 // Skip non-global variables in records (struct/union/class) but not static
274 // members.
275 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
276 return true;
277
278 // Skip local variables inside function or method.
280 return true;
281
282 // If this is a template but not specialization or instantiation, skip.
284 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
285 return true;
286
287 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
288 return true;
289
290 // Collect symbol information.
291 StringRef Name = Decl->getName();
295 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
296 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
297 DocComment Comment;
298 if (auto *RawComment =
299 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
300 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
301 Context.getDiagnostics());
302
303 // Build declaration fragments and sub-heading for the variable.
306 DeclarationFragments SubHeading =
308 if (Decl->isStaticDataMember()) {
310 API.createRecord<StaticFieldRecord>(
311 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
313 SubHeading, Access, isInSystemHeader(Decl));
314 } else {
315 // Add the global variable record to the API set.
316 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
317 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
319 SubHeading, isInSystemHeader(Decl));
320
321 // If this global variable has a non typedef'd anonymous tag type let's
322 // pretend the type's child records are under us in the hierarchy.
323 maybeMergeWithAnonymousTag(*Decl, NewRecord);
324 }
325
326 return true;
327}
328
329template <typename Derived>
331 const FunctionDecl *Decl) {
332 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
333 // Skip member function in class templates.
334 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
335 return true;
336
337 // Skip methods in records.
338 for (const auto &P : Context.getParents(*Method)) {
339 if (P.template get<CXXRecordDecl>())
340 return true;
341 }
342
343 // Skip ConstructorDecl and DestructorDecl.
344 if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
345 return true;
346 }
347
348 // Skip templated functions that aren't processed here.
349 switch (Decl->getTemplatedKind()) {
353 break;
357 return true;
358 }
359
360 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
361 return true;
362
363 // Collect symbol information.
364 auto Name = Decl->getNameAsString();
368 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
369 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
370 DocComment Comment;
371 if (auto *RawComment =
372 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
373 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
374 Context.getDiagnostics());
375
376 // Build declaration fragments, sub-heading, and signature of the function.
377 DeclarationFragments SubHeading =
379 FunctionSignature Signature =
381 if (Decl->getTemplateSpecializationInfo())
383 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
387 SubHeading, Signature, isInSystemHeader(Decl));
388 else
389 // Add the function record to the API set.
390 API.createRecord<GlobalFunctionRecord>(
391 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
394 Signature, isInSystemHeader(Decl));
395 return true;
396}
397
398template <typename Derived>
400 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
401 return true;
402
406 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
407 DocComment Comment;
408 if (auto *RawComment =
409 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
410 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
411 Context.getDiagnostics());
412
413 // Build declaration fragments and sub-heading for the enum.
416 DeclarationFragments SubHeading =
418
419 // Collect symbol information.
420 SymbolReference ParentContainer;
421
422 if (Decl->hasNameForLinkage()) {
423 StringRef Name = Decl->getName();
424 if (Name.empty())
425 Name = getTypedefName(Decl);
426
427 auto *ER = API.createRecord<EnumRecord>(
428 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
430 SubHeading, isInSystemHeader(Decl), false);
431 ParentContainer = SymbolReference(ER);
432 } else {
433 // If this an anonymous enum then the parent scope of the constants is the
434 // top level namespace.
435 ParentContainer = {};
436 }
437
438 // Now collect information about the enumerators in this enum.
439 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
440 Decl->enumerators());
441
442 return true;
443}
444
445template <typename Derived>
447 const FunctionDecl *Decl) {
448 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
449 return true;
450}
451
452template <typename Derived>
454 const RecordDecl *Decl) {
455 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
456 return true;
457}
458
459template <typename Derived>
461 const CXXRecordDecl *Decl) {
462 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
463 return true;
464}
465
466template <typename Derived>
468 const CXXMethodDecl *Decl) {
469 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
470 return true;
471}
472
473template <typename Derived>
476 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
477 return true;
478}
479
480template <typename Derived>
484 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
485 Decl);
486 return true;
487}
488
489template <typename Derived>
491 const VarTemplateDecl *Decl) {
492 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
493 return true;
494}
495
496template <typename Derived>
499 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
500 return true;
501}
502
503template <typename Derived>
507 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
508 return true;
509}
510
511template <typename Derived>
513 const FunctionTemplateDecl *Decl) {
514 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
515 return true;
516}
517
518template <typename Derived>
520 const NamespaceDecl *Decl) {
521 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
522 return true;
523}
524
525template <typename Derived>
527 const NamespaceDecl *Decl) {
528 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
529 return true;
530 if (Decl->isAnonymousNamespace())
531 return true;
532 StringRef Name = Decl->getName();
535 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
537 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
538 DocComment Comment;
539 if (auto *RawComment =
540 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
541 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
542 Context.getDiagnostics());
543
544 // Build declaration fragments and sub-heading for the struct.
547 DeclarationFragments SubHeading =
549 API.createRecord<NamespaceRecord>(
550 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
552 SubHeading, isInSystemHeader(Decl));
553
554 return true;
555}
556
557template <typename Derived>
559 bool Ret = Base::TraverseRecordDecl(Decl);
560
561 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
564 API.removeRecord(USR);
565 }
566
567 return Ret;
568}
569
570template <typename Derived>
572 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
573 return true;
574
575 // Collect symbol information.
576 StringRef Name = Decl->getName();
577 if (Name.empty())
578 Name = getTypedefName(Decl);
579
583 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
584 DocComment Comment;
585 if (auto *RawComment =
586 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
587 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
588 Context.getDiagnostics());
589
590 // Build declaration fragments and sub-heading for the struct.
593 DeclarationFragments SubHeading =
595
596 if (Decl->isUnion())
597 API.createRecord<UnionRecord>(
598 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
600 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
601 else
602 API.createRecord<StructRecord>(
603 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
605 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
606
607 return true;
608}
609
610template <typename Derived>
613 bool Ret = Base::TraverseCXXRecordDecl(Decl);
614
615 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
618 API.removeRecord(USR);
619 }
620
621 return Ret;
622}
623
624template <typename Derived>
626 const CXXRecordDecl *Decl) {
627 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
628 Decl->isImplicit())
629 return true;
630
631 StringRef Name = Decl->getName();
632 if (Name.empty())
633 Name = getTypedefName(Decl);
634
638 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
639 DocComment Comment;
640 if (auto *RawComment =
641 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
642 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
643 Context.getDiagnostics());
646 DeclarationFragments SubHeading =
648
650
652 if (Decl->getDescribedClassTemplate()) {
653 // Inject template fragments before class fragments.
654 Declaration.prepend(
656 Decl->getDescribedClassTemplate()));
657 Record = API.createRecord<ClassTemplateRecord>(
658 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
660 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
661 isInSystemHeader(Decl));
662 } else {
663 Record = API.createRecord<CXXClassRecord>(
664 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
666 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
667 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
668 }
669
670 Record->KindForDisplay = getKindForDisplay(Decl);
671 Record->Bases = getBases(Decl);
672
673 return true;
674}
675
676template <typename Derived>
678 const CXXMethodDecl *Decl) {
679 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
680 Decl->isImplicit())
681 return true;
682
683 if (isa<CXXConversionDecl>(Decl))
684 return true;
685 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
686 return true;
687
691 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
692 DocComment Comment;
693 if (auto *RawComment =
694 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
695 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
696 Context.getDiagnostics());
697 DeclarationFragments SubHeading =
701
703 Decl->getDescribedFunctionTemplate()) {
704 API.createRecord<CXXMethodTemplateRecord>(
705 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
711 Template(TemplateDecl), isInSystemHeader(Decl));
712 } else if (Decl->getTemplateSpecializationInfo())
714 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
718 SubHeading, Signature, Access, isInSystemHeader(Decl));
719 else if (Decl->isOverloadedOperator())
720 API.createRecord<CXXInstanceMethodRecord>(
721 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
724 SubHeading, Signature, Access, isInSystemHeader(Decl));
725 else if (Decl->isStatic())
726 API.createRecord<CXXStaticMethodRecord>(
727 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
730 Signature, Access, isInSystemHeader(Decl));
731 else
732 API.createRecord<CXXInstanceMethodRecord>(
733 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
736 Signature, Access, isInSystemHeader(Decl));
737
738 return true;
739}
740
741template <typename Derived>
743 const CXXConstructorDecl *Decl) {
744 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
745 Decl->isImplicit())
746 return true;
747
748 auto Name = Decl->getNameAsString();
752 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
753 DocComment Comment;
754 if (auto *RawComment =
755 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
756 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
757 Context.getDiagnostics());
758
759 // Build declaration fragments, sub-heading, and signature for the method.
762 DeclarationFragments SubHeading =
764 FunctionSignature Signature =
767
768 API.createRecord<CXXConstructorRecord>(
769 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
771 Signature, Access, isInSystemHeader(Decl));
772 return true;
773}
774
775template <typename Derived>
777 const CXXDestructorDecl *Decl) {
778 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
779 Decl->isImplicit())
780 return true;
781
782 auto Name = Decl->getNameAsString();
786 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
787 DocComment Comment;
788 if (auto *RawComment =
789 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
790 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
791 Context.getDiagnostics());
792
793 // Build declaration fragments, sub-heading, and signature for the method.
796 DeclarationFragments SubHeading =
798 FunctionSignature Signature =
801 API.createRecord<CXXDestructorRecord>(
802 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
804 Signature, Access, isInSystemHeader(Decl));
805 return true;
806}
807
808template <typename Derived>
810 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
811 return true;
812
813 StringRef Name = Decl->getName();
817 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
818 DocComment Comment;
819 if (auto *RawComment =
820 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
821 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
822 Context.getDiagnostics());
825 DeclarationFragments SubHeading =
827 API.createRecord<ConceptRecord>(
828 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
830 Template(Decl), isInSystemHeader(Decl));
831 return true;
832}
833
834template <typename Derived>
837 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
838 return true;
839
840 StringRef Name = Decl->getName();
844 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
845 DocComment Comment;
846 if (auto *RawComment =
847 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
848 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
849 Context.getDiagnostics());
852 Decl);
853 DeclarationFragments SubHeading =
855
856 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
857 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
860 isInSystemHeader(Decl));
861
862 CTSR->Bases = getBases(Decl);
863
864 return true;
865}
866
867template <typename Derived>
871 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
872 return true;
873
874 StringRef Name = Decl->getName();
878 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
879 DocComment Comment;
880 if (auto *RawComment =
881 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
882 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
883 Context.getDiagnostics());
886 DeclarationFragments SubHeading =
888 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
889 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
892 isInSystemHeader(Decl));
893
894 CTPSR->KindForDisplay = getKindForDisplay(Decl);
895 CTPSR->Bases = getBases(Decl);
896
897 return true;
898}
899
900template <typename Derived>
902 const VarTemplateDecl *Decl) {
903 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
904 return true;
905
906 // Collect symbol information.
907 StringRef Name = Decl->getName();
911 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
912 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
913 DocComment Comment;
914 if (auto *RawComment =
915 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
916 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
917 Context.getDiagnostics());
918
919 // Build declaration fragments and sub-heading for the variable.
923 Decl))
925 Decl->getTemplatedDecl()));
926 // Inject template fragments before var fragments.
927 DeclarationFragments SubHeading =
929
930 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
931 API.createRecord<CXXFieldTemplateRecord>(
932 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
935 Template(Decl), isInSystemHeader(Decl));
936 else
937 API.createRecord<GlobalVariableTemplateRecord>(
938 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
940 SubHeading, Template(Decl), isInSystemHeader(Decl));
941 return true;
942}
943
944template <typename Derived>
947 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
948 return true;
949
950 // Collect symbol information.
951 StringRef Name = Decl->getName();
955 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
956 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
957 DocComment Comment;
958 if (auto *RawComment =
959 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
960 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
961 Context.getDiagnostics());
962
963 // Build declaration fragments and sub-heading for the variable.
966 Decl);
967 DeclarationFragments SubHeading =
970 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
972 SubHeading, isInSystemHeader(Decl));
973 return true;
974}
975
976template <typename Derived>
979 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
980 return true;
981
982 // Collect symbol information.
983 StringRef Name = Decl->getName();
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 // Build declaration fragments and sub-heading for the variable.
998 DeclarationFragments SubHeading =
1001 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1003 SubHeading, Template(Decl), isInSystemHeader(Decl));
1004 return true;
1005}
1006
1007template <typename Derived>
1009 const FunctionTemplateDecl *Decl) {
1010 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
1011 return true;
1012 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1013 return true;
1014
1015 // Collect symbol information.
1016 auto Name = Decl->getNameAsString();
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 DeclarationFragments SubHeading =
1030 FunctionSignature Signature =
1032 Decl->getTemplatedDecl());
1033 API.createRecord<GlobalFunctionTemplateRecord>(
1034 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1037 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1038
1039 return true;
1040}
1041
1042template <typename Derived>
1044 const ObjCInterfaceDecl *Decl) {
1045 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1046 return true;
1047
1048 // Collect symbol information.
1049 StringRef Name = Decl->getName();
1050 SmallString<128> USR;
1053 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1054 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1055 DocComment Comment;
1056 if (auto *RawComment =
1057 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1058 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1059 Context.getDiagnostics());
1060
1061 // Build declaration fragments and sub-heading for the interface.
1064 DeclarationFragments SubHeading =
1066
1067 // Collect super class information.
1068 SymbolReference SuperClass;
1069 if (const auto *SuperClassDecl = Decl->getSuperClass())
1070 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1071
1072 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1073 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1075 SubHeading, SuperClass, isInSystemHeader(Decl));
1076
1077 // Record all methods (selectors). This doesn't include automatically
1078 // synthesized property methods.
1079 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1080 Decl->methods());
1081 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1082 Decl->properties());
1083 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1084 Decl->ivars());
1085 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1086 Decl->protocols());
1087
1088 return true;
1089}
1090
1091template <typename Derived>
1093 const ObjCProtocolDecl *Decl) {
1094 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1095 return true;
1096
1097 // Collect symbol information.
1098 StringRef Name = Decl->getName();
1099 SmallString<128> USR;
1102 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1103 DocComment Comment;
1104 if (auto *RawComment =
1105 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1106 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1107 Context.getDiagnostics());
1108
1109 // Build declaration fragments and sub-heading for the protocol.
1112 DeclarationFragments SubHeading =
1114
1115 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1116 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1117 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1118 isInSystemHeader(Decl));
1119
1120 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1121 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1122 Decl->properties());
1123 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1124 Decl->protocols());
1125
1126 return true;
1127}
1128
1129template <typename Derived>
1131 const TypedefNameDecl *Decl) {
1132 // Skip ObjC Type Parameter for now.
1133 if (isa<ObjCTypeParamDecl>(Decl))
1134 return true;
1135
1137 return true;
1138
1139 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1140 return true;
1141
1142 StringRef Name = Decl->getName();
1143
1144 // If the underlying type was defined as part of the typedef modify it's
1145 // fragments directly and pretend the typedef doesn't exist.
1146 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1148 Decl->getName() == TagDecl->getName()) {
1149 SmallString<128> TagUSR;
1151 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1152 DeclarationFragments LeadingFragments;
1153 LeadingFragments.append("typedef",
1155 LeadingFragments.appendSpace();
1156 Record->Declaration.removeTrailingSemicolon()
1157 .prepend(std::move(LeadingFragments))
1160 .appendSemicolon();
1161
1162 return true;
1163 }
1164 }
1165 }
1166
1168 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1169 SmallString<128> USR;
1171 DocComment Comment;
1172 if (auto *RawComment =
1173 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1174 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1175 Context.getDiagnostics());
1176
1177 QualType Type = Decl->getUnderlyingType();
1178 SymbolReference SymRef =
1180 API);
1181
1182 API.createRecord<TypedefRecord>(
1183 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1187 isInSystemHeader(Decl));
1188
1189 return true;
1190}
1191
1192template <typename Derived>
1194 const ObjCCategoryDecl *Decl) {
1195 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1196 return true;
1197
1198 StringRef Name = Decl->getName();
1199 SmallString<128> USR;
1202 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1203 DocComment Comment;
1204 if (auto *RawComment =
1205 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1206 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1207 Context.getDiagnostics());
1208 // Build declaration fragments and sub-heading for the category.
1211 DeclarationFragments SubHeading =
1213
1214 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1215 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1216
1217 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1218 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1219 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1220 Interface, isInSystemHeader(Decl));
1221
1222 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1223 Decl->methods());
1224 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1225 Decl->properties());
1226 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1227 Decl->ivars());
1228 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1229 Decl->protocols());
1230
1231 return true;
1232}
1233
1234/// Collect API information for the enum constants and associate with the
1235/// parent enum.
1236template <typename Derived>
1238 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1239 for (const auto *Constant : Constants) {
1240 // Collect symbol information.
1241 StringRef Name = Constant->getName();
1242 SmallString<128> USR;
1243 index::generateUSRForDecl(Constant, USR);
1245 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1246 DocComment Comment;
1247 if (auto *RawComment =
1248 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1249 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1250 Context.getDiagnostics());
1251
1252 // Build declaration fragments and sub-heading for the enum constant.
1255 DeclarationFragments SubHeading =
1257
1258 API.createRecord<EnumConstantRecord>(
1259 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1260 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1261 }
1262}
1263
1264template <typename Derived>
1266 // ObjCIvars are handled separately
1267 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1268 return true;
1269
1270 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1271 return true;
1272
1273 // Collect symbol information.
1274 StringRef Name = Decl->getName();
1275 SmallString<128> USR;
1278 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1279 DocComment Comment;
1280 if (auto *RawComment =
1281 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1282 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1283 Context.getDiagnostics());
1284
1285 // Build declaration fragments and sub-heading for the struct field.
1288 DeclarationFragments SubHeading =
1290
1291 RecordContext *NewRecord = nullptr;
1292 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1294
1295 NewRecord = API.createRecord<CXXFieldRecord>(
1296 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1298 SubHeading, Access, isInSystemHeader(Decl));
1299 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1300 if (RD->isUnion())
1301 NewRecord = API.createRecord<UnionFieldRecord>(
1302 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1304 SubHeading, isInSystemHeader(Decl));
1305 else
1306 NewRecord = API.createRecord<StructFieldRecord>(
1307 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1309 SubHeading, isInSystemHeader(Decl));
1310 }
1311
1312 // If this field has a non typedef'd anonymous tag type let's pretend the
1313 // type's child records are under us in the hierarchy.
1314 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1315
1316 return true;
1317}
1318
1319template <typename Derived>
1321 const CXXConversionDecl *Decl) {
1322 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1323 Decl->isImplicit())
1324 return true;
1325
1326 auto Name = Decl->getNameAsString();
1327 SmallString<128> USR;
1330 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1331 DocComment Comment;
1332 if (auto *RawComment =
1333 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1334 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1335 Context.getDiagnostics());
1336
1337 // Build declaration fragments, sub-heading, and signature for the method.
1340 DeclarationFragments SubHeading =
1342 FunctionSignature Signature =
1345
1346 if (Decl->isStatic())
1347 API.createRecord<CXXStaticMethodRecord>(
1348 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1350 SubHeading, Signature, Access, isInSystemHeader(Decl));
1351 else
1352 API.createRecord<CXXInstanceMethodRecord>(
1353 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1355 SubHeading, Signature, Access, isInSystemHeader(Decl));
1356
1357 return true;
1358}
1359
1360/// Collect API information for the Objective-C methods and associate with the
1361/// parent container.
1362template <typename Derived>
1364 ObjCContainerRecord *Container,
1365 const ObjCContainerDecl::method_range Methods) {
1366 for (const auto *Method : Methods) {
1367 // Don't record selectors for properties.
1368 if (Method->isPropertyAccessor())
1369 continue;
1370
1371 auto Name = Method->getSelector().getAsString();
1372 SmallString<128> USR;
1373 index::generateUSRForDecl(Method, USR);
1375 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1376 DocComment Comment;
1377 if (auto *RawComment =
1378 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1379 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1380 Context.getDiagnostics());
1381
1382 // Build declaration fragments, sub-heading, and signature for the method.
1385 DeclarationFragments SubHeading =
1387 FunctionSignature Signature =
1389
1390 if (Method->isInstanceMethod())
1391 API.createRecord<ObjCInstanceMethodRecord>(
1392 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1394 SubHeading, Signature, isInSystemHeader(Method));
1395 else
1396 API.createRecord<ObjCClassMethodRecord>(
1397 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1399 SubHeading, Signature, isInSystemHeader(Method));
1400 }
1401}
1402
1403template <typename Derived>
1405 ObjCContainerRecord *Container,
1406 const ObjCContainerDecl::prop_range Properties) {
1407 for (const auto *Property : Properties) {
1408 StringRef Name = Property->getName();
1409 SmallString<128> USR;
1412 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1413 DocComment Comment;
1414 if (auto *RawComment =
1415 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1416 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1417 Context.getDiagnostics());
1418
1419 // Build declaration fragments and sub-heading for the property.
1422 DeclarationFragments SubHeading =
1424
1425 auto GetterName = Property->getGetterName().getAsString();
1426 auto SetterName = Property->getSetterName().getAsString();
1427
1428 // Get the attributes for property.
1429 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1430 if (Property->getPropertyAttributes() &
1432 Attributes |= ObjCPropertyRecord::ReadOnly;
1433
1434 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1435 API.createRecord<ObjCClassPropertyRecord>(
1436 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1438 SubHeading,
1439 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1440 GetterName, SetterName, Property->isOptional(),
1441 isInSystemHeader(Property));
1442 else
1443 API.createRecord<ObjCInstancePropertyRecord>(
1444 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1446 SubHeading,
1447 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1448 GetterName, SetterName, Property->isOptional(),
1449 isInSystemHeader(Property));
1450 }
1451}
1452
1453template <typename Derived>
1455 ObjCContainerRecord *Container,
1456 const llvm::iterator_range<
1458 Ivars) {
1459 for (const auto *Ivar : Ivars) {
1460 StringRef Name = Ivar->getName();
1461 SmallString<128> USR;
1462 index::generateUSRForDecl(Ivar, USR);
1463
1465 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1466 DocComment Comment;
1467 if (auto *RawComment =
1468 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1469 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1470 Context.getDiagnostics());
1471
1472 // Build declaration fragments and sub-heading for the instance variable.
1475 DeclarationFragments SubHeading =
1477
1478 API.createRecord<ObjCInstanceVariableRecord>(
1479 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1481 SubHeading, isInSystemHeader(Ivar));
1482 }
1483}
1484
1485template <typename Derived>
1487 ObjCContainerRecord *Container,
1489 for (const auto *Protocol : Protocols)
1490 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1491}
1492
1493} // namespace impl
1494
1495/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1496/// information.
1497template <typename Derived = void>
1499 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1500 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1501 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1502 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1503
1504public:
1506
1507 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1509 if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
1510 return Comment;
1511
1512 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1513 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1514 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1515 TagTypeDecl->isCompleteDefinition())
1516 return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
1517 }
1518
1519 return nullptr;
1520 }
1521};
1522
1523} // namespace extractapi
1524} // namespace clang
1525
1526#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:2553
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2880
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2817
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
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:2369
bool isRecord() const
Definition: DeclBase.h:2169
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2082
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:520
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:938
DeclContext * getDeclContext()
Definition: DeclBase.h:451
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:735
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1903
Represents an enum.
Definition: Decl.h:3847
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:3978
Represents a member of a struct/union/class.
Definition: Decl.h:3033
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:959
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:4148
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:3564
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:3691
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3667
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:6348
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:3514
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3413
Represents a variable declaration or definition.
Definition: Decl.h:882
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.