clang 19.0.0git
ExtractAPIVisitor.h
Go to the documentation of this file.
1//===- ExtractAPI/ExtractAPIVisitor.h ---------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the ExtractAPVisitor AST visitation interface.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
15#define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
16
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclObjC.h"
24#include "clang/Basic/Module.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/Support/Casting.h"
34#include <type_traits>
35
36namespace clang {
37namespace extractapi {
38namespace impl {
39
40template <typename Derived>
42protected:
44 : Context(Context), API(API) {}
45
46public:
47 const APISet &getAPI() const { return API; }
48
50
52
54
56
58
60
62
65
68
70
73
76
78
80
82
84
86
88
90
92
94
96
98
101
104
106
107 bool
109
112
114
116
118
120
122
123 bool shouldDeclBeIncluded(const Decl *Decl) const;
124
126
127protected:
128 /// Collect API information for the enum constants and associate with the
129 /// parent enum.
131 const EnumDecl::enumerator_range Constants);
132
133 /// Collect API information for the Objective-C methods and associate with the
134 /// parent container.
136 const ObjCContainerDecl::method_range Methods);
137
139 const ObjCContainerDecl::prop_range Properties);
140
142 ObjCContainerRecord *Container,
143 const llvm::iterator_range<
145 Ivars);
146
149
152
153 StringRef getTypedefName(const TagDecl *Decl) {
154 if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
155 return TypedefDecl->getName();
156
157 return {};
158 }
159
160 bool isInSystemHeader(const Decl *D) {
162 }
163
164private:
165 Derived &getDerivedExtractAPIVisitor() {
166 return *static_cast<Derived *>(this);
167 }
168
169protected:
171 // FIXME: store AccessSpecifier given by inheritance
173 for (const auto &BaseSpecifier : Decl->bases()) {
174 // skip classes not inherited as public
175 if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
176 continue;
177 SymbolReference BaseClass;
178 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
179 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
180 if (auto *TTPTD = BaseSpecifier.getType()
181 ->getAs<TemplateTypeParmType>()
182 ->getDecl()) {
184 index::generateUSRForDecl(TTPTD, USR);
185 BaseClass.USR = API.copyString(USR);
186 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
187 }
188 } else {
190 *BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl());
191 }
192 Bases.emplace_back(BaseClass);
193 }
194 return Bases;
195 }
196
198 if (Decl->isUnion())
199 return APIRecord::RK_Union;
200 if (Decl->isStruct())
202
204 }
205
206 StringRef getOwningModuleName(const Decl &D) {
207 if (auto *OwningModule = D.getImportedOwningModule())
208 return OwningModule->Name;
209
210 return {};
211 }
212
214 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
215
216 if (!Context || isa<TranslationUnitDecl>(Context))
217 return {};
218
220 }
221
225
227 if (Record)
228 return SymbolReference(Record);
229
230 StringRef Name;
231 if (auto *ND = dyn_cast<NamedDecl>(&D))
232 Name = ND->getName();
233
234 return API.createSymbolReference(Name, USR, getOwningModuleName(D));
235 }
236
238 return D.getName().empty() && getTypedefName(&D).empty() &&
240 }
241
243 RecordContext *NewRecordContext) {
244 if (!NewRecordContext)
245 return;
246 auto *Tag = D.getType()->getAsTagDecl();
247 SmallString<128> TagUSR;
249 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
250 API.findRecordForUSR(TagUSR))) {
251 if (Record->IsEmbeddedInVarDeclarator) {
252 NewRecordContext->stealRecordChain(*Record);
253 auto *NewRecord = cast<APIRecord>(NewRecordContext);
254 if (NewRecord->Comment.empty())
255 NewRecord->Comment = Record->Comment;
256 }
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 StringRef Name = Decl->getName();
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
397 SmallString<128> QualifiedNameBuffer;
398 // Collect symbol information.
399 StringRef Name = Decl->getName();
400 if (Name.empty())
401 Name = getTypedefName(Decl);
402 if (Name.empty()) {
403 llvm::raw_svector_ostream OS(QualifiedNameBuffer);
404 Decl->printQualifiedName(OS);
405 Name = QualifiedNameBuffer;
406 }
407
411 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
412 DocComment Comment;
413 if (auto *RawComment =
414 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
415 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
416 Context.getDiagnostics());
417
418 // Build declaration fragments and sub-heading for the enum.
421 DeclarationFragments SubHeading =
423 auto *ER = API.createRecord<EnumRecord>(
424 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
426 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
427
428 // Now collect information about the enumerators in this enum.
429 getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
430
431 return true;
432}
433
434template <typename Derived>
436 const FunctionDecl *Decl) {
437 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
438 return true;
439}
440
441template <typename Derived>
443 const RecordDecl *Decl) {
444 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
445 return true;
446}
447
448template <typename Derived>
450 const CXXRecordDecl *Decl) {
451 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
452 return true;
453}
454
455template <typename Derived>
457 const CXXMethodDecl *Decl) {
458 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
459 return true;
460}
461
462template <typename Derived>
465 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
466 return true;
467}
468
469template <typename Derived>
473 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
474 Decl);
475 return true;
476}
477
478template <typename Derived>
480 const VarTemplateDecl *Decl) {
481 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
482 return true;
483}
484
485template <typename Derived>
488 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
489 return true;
490}
491
492template <typename Derived>
496 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
497 return true;
498}
499
500template <typename Derived>
502 const FunctionTemplateDecl *Decl) {
503 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
504 return true;
505}
506
507template <typename Derived>
509 const NamespaceDecl *Decl) {
510 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
511 return true;
512}
513
514template <typename Derived>
516 const NamespaceDecl *Decl) {
517 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
518 return true;
519 if (Decl->isAnonymousNamespace())
520 return true;
521 StringRef Name = Decl->getName();
524 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
526 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
527 DocComment Comment;
528 if (auto *RawComment =
529 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
530 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
531 Context.getDiagnostics());
532
533 // Build declaration fragments and sub-heading for the struct.
536 DeclarationFragments SubHeading =
538 API.createRecord<NamespaceRecord>(
539 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
541 SubHeading, isInSystemHeader(Decl));
542
543 return true;
544}
545
546template <typename Derived>
548 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
549 return true;
550
551 // Collect symbol information.
552 StringRef Name = Decl->getName();
553 if (Name.empty())
554 Name = getTypedefName(Decl);
555
559 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
560 DocComment Comment;
561 if (auto *RawComment =
562 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
563 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
564 Context.getDiagnostics());
565
566 // Build declaration fragments and sub-heading for the struct.
569 DeclarationFragments SubHeading =
571
572 if (Decl->isUnion())
573 API.createRecord<UnionRecord>(
574 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
576 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
577 else
578 API.createRecord<StructRecord>(
579 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
581 SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
582
583 return true;
584}
585
586template <typename Derived>
588 const CXXRecordDecl *Decl) {
589 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
590 Decl->isImplicit())
591 return true;
592
593 StringRef Name = Decl->getName();
594 if (Name.empty())
595 Name = getTypedefName(Decl);
596
600 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
601 DocComment Comment;
602 if (auto *RawComment =
603 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
604 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
605 Context.getDiagnostics());
608 DeclarationFragments SubHeading =
610
612
614 if (Decl->getDescribedClassTemplate()) {
615 // Inject template fragments before class fragments.
616 Declaration.prepend(
618 Decl->getDescribedClassTemplate()));
619 Record = API.createRecord<ClassTemplateRecord>(
620 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
622 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
623 isInSystemHeader(Decl));
624 } else {
625 Record = API.createRecord<CXXClassRecord>(
626 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
628 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
629 isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
630 }
631
632 Record->KindForDisplay = getKindForDisplay(Decl);
633 Record->Bases = getBases(Decl);
634
635 return true;
636}
637
638template <typename Derived>
640 const CXXMethodDecl *Decl) {
641 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
642 Decl->isImplicit())
643 return true;
644
645 if (isa<CXXConversionDecl>(Decl))
646 return true;
647 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
648 return true;
649
653 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
654 DocComment Comment;
655 if (auto *RawComment =
656 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
657 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
658 Context.getDiagnostics());
659 DeclarationFragments SubHeading =
663
665 Decl->getDescribedFunctionTemplate()) {
666 API.createRecord<CXXMethodTemplateRecord>(
667 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
673 Template(TemplateDecl), isInSystemHeader(Decl));
674 } else if (Decl->getTemplateSpecializationInfo())
676 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
680 SubHeading, Signature, Access, isInSystemHeader(Decl));
681 else if (Decl->isOverloadedOperator())
682 API.createRecord<CXXInstanceMethodRecord>(
683 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
686 SubHeading, Signature, Access, isInSystemHeader(Decl));
687 else if (Decl->isStatic())
688 API.createRecord<CXXStaticMethodRecord>(
689 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
692 Signature, Access, isInSystemHeader(Decl));
693 else
694 API.createRecord<CXXInstanceMethodRecord>(
695 USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
698 Signature, Access, isInSystemHeader(Decl));
699
700 return true;
701}
702
703template <typename Derived>
705 const CXXConstructorDecl *Decl) {
706 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
707 Decl->isImplicit())
708 return true;
709
710 auto Name = Decl->getNameAsString();
714 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
715 DocComment Comment;
716 if (auto *RawComment =
717 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
718 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
719 Context.getDiagnostics());
720
721 // Build declaration fragments, sub-heading, and signature for the method.
724 DeclarationFragments SubHeading =
726 FunctionSignature Signature =
729
730 API.createRecord<CXXConstructorRecord>(
731 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
733 Signature, Access, isInSystemHeader(Decl));
734 return true;
735}
736
737template <typename Derived>
739 const CXXDestructorDecl *Decl) {
740 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
741 Decl->isImplicit())
742 return true;
743
744 auto Name = Decl->getNameAsString();
748 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
749 DocComment Comment;
750 if (auto *RawComment =
751 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
752 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
753 Context.getDiagnostics());
754
755 // Build declaration fragments, sub-heading, and signature for the method.
758 DeclarationFragments SubHeading =
760 FunctionSignature Signature =
763 API.createRecord<CXXDestructorRecord>(
764 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
766 Signature, Access, isInSystemHeader(Decl));
767 return true;
768}
769
770template <typename Derived>
772 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
773 return true;
774
775 StringRef Name = Decl->getName();
779 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
780 DocComment Comment;
781 if (auto *RawComment =
782 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
783 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
784 Context.getDiagnostics());
787 DeclarationFragments SubHeading =
789 API.createRecord<ConceptRecord>(
790 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
792 Template(Decl), isInSystemHeader(Decl));
793 return true;
794}
795
796template <typename Derived>
799 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
800 return true;
801
802 StringRef Name = Decl->getName();
806 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
807 DocComment Comment;
808 if (auto *RawComment =
809 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
810 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
811 Context.getDiagnostics());
814 Decl);
815 DeclarationFragments SubHeading =
817
818 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
819 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
822 isInSystemHeader(Decl));
823
824 CTSR->Bases = getBases(Decl);
825
826 return true;
827}
828
829template <typename Derived>
833 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
834 return true;
835
836 StringRef Name = Decl->getName();
840 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
841 DocComment Comment;
842 if (auto *RawComment =
843 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
844 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
845 Context.getDiagnostics());
848 DeclarationFragments SubHeading =
850 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
851 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
854 isInSystemHeader(Decl));
855
856 CTPSR->KindForDisplay = getKindForDisplay(Decl);
857 CTPSR->Bases = getBases(Decl);
858
859 return true;
860}
861
862template <typename Derived>
864 const VarTemplateDecl *Decl) {
865 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
866 return true;
867
868 // Collect symbol information.
869 StringRef Name = Decl->getName();
873 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
874 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
875 DocComment Comment;
876 if (auto *RawComment =
877 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
878 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
879 Context.getDiagnostics());
880
881 // Build declaration fragments and sub-heading for the variable.
885 Decl))
887 Decl->getTemplatedDecl()));
888 // Inject template fragments before var fragments.
889 DeclarationFragments SubHeading =
891
892 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
893 API.createRecord<CXXFieldTemplateRecord>(
894 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
897 Template(Decl), isInSystemHeader(Decl));
898 else
899 API.createRecord<GlobalVariableTemplateRecord>(
900 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
902 SubHeading, Template(Decl), isInSystemHeader(Decl));
903 return true;
904}
905
906template <typename Derived>
909 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
910 return true;
911
912 // Collect symbol information.
913 StringRef Name = Decl->getName();
917 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
918 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
919 DocComment Comment;
920 if (auto *RawComment =
921 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
922 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
923 Context.getDiagnostics());
924
925 // Build declaration fragments and sub-heading for the variable.
928 Decl);
929 DeclarationFragments SubHeading =
932 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
934 SubHeading, isInSystemHeader(Decl));
935 return true;
936}
937
938template <typename Derived>
941 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
942 return true;
943
944 // Collect symbol information.
945 StringRef Name = Decl->getName();
949 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
950 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
951 DocComment Comment;
952 if (auto *RawComment =
953 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
954 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
955 Context.getDiagnostics());
956
957 // Build declaration fragments and sub-heading for the variable.
960 DeclarationFragments SubHeading =
963 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
965 SubHeading, Template(Decl), isInSystemHeader(Decl));
966 return true;
967}
968
969template <typename Derived>
971 const FunctionTemplateDecl *Decl) {
972 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
973 return true;
974 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
975 return true;
976
977 // Collect symbol information.
978 StringRef Name = Decl->getName();
982 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
983 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
984 DocComment Comment;
985 if (auto *RawComment =
986 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
987 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
988 Context.getDiagnostics());
989
990 DeclarationFragments SubHeading =
992 FunctionSignature Signature =
994 Decl->getTemplatedDecl());
995 API.createRecord<GlobalFunctionTemplateRecord>(
996 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
999 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1000
1001 return true;
1002}
1003
1004template <typename Derived>
1006 const ObjCInterfaceDecl *Decl) {
1007 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1008 return true;
1009
1010 // Collect symbol information.
1011 StringRef Name = Decl->getName();
1012 SmallString<128> USR;
1015 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1016 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1017 DocComment Comment;
1018 if (auto *RawComment =
1019 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1020 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1021 Context.getDiagnostics());
1022
1023 // Build declaration fragments and sub-heading for the interface.
1026 DeclarationFragments SubHeading =
1028
1029 // Collect super class information.
1030 SymbolReference SuperClass;
1031 if (const auto *SuperClassDecl = Decl->getSuperClass())
1032 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1033
1034 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1035 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1037 SubHeading, SuperClass, isInSystemHeader(Decl));
1038
1039 // Record all methods (selectors). This doesn't include automatically
1040 // synthesized property methods.
1041 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1042 Decl->methods());
1043 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1044 Decl->properties());
1045 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1046 Decl->ivars());
1047 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1048 Decl->protocols());
1049
1050 return true;
1051}
1052
1053template <typename Derived>
1055 const ObjCProtocolDecl *Decl) {
1056 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1057 return true;
1058
1059 // Collect symbol information.
1060 StringRef Name = Decl->getName();
1061 SmallString<128> USR;
1064 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1065 DocComment Comment;
1066 if (auto *RawComment =
1067 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1068 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1069 Context.getDiagnostics());
1070
1071 // Build declaration fragments and sub-heading for the protocol.
1074 DeclarationFragments SubHeading =
1076
1077 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1078 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1079 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1080 isInSystemHeader(Decl));
1081
1082 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1083 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1084 Decl->properties());
1085 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1086 Decl->protocols());
1087
1088 return true;
1089}
1090
1091template <typename Derived>
1093 const TypedefNameDecl *Decl) {
1094 // Skip ObjC Type Parameter for now.
1095 if (isa<ObjCTypeParamDecl>(Decl))
1096 return true;
1097
1099 return true;
1100
1101 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1102 return true;
1103
1104 StringRef Name = Decl->getName();
1105
1106 // If the underlying type was defined as part of the typedef modify it's
1107 // fragments directly and pretend the typedef doesn't exist.
1108 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1110 Decl->getName() == TagDecl->getName()) {
1111 SmallString<128> TagUSR;
1113 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1114 DeclarationFragments LeadingFragments;
1115 LeadingFragments.append("typedef",
1117 LeadingFragments.appendSpace();
1118 Record->Declaration.removeTrailingSemicolon()
1119 .prepend(std::move(LeadingFragments))
1122 .appendSemicolon();
1123
1124 return true;
1125 }
1126 }
1127 }
1128
1130 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1131 SmallString<128> USR;
1133 DocComment Comment;
1134 if (auto *RawComment =
1135 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1136 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1137 Context.getDiagnostics());
1138
1139 QualType Type = Decl->getUnderlyingType();
1140 SymbolReference SymRef =
1142 API);
1143
1144 API.createRecord<TypedefRecord>(
1145 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1149 isInSystemHeader(Decl));
1150
1151 return true;
1152}
1153
1154template <typename Derived>
1156 const ObjCCategoryDecl *Decl) {
1157 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1158 return true;
1159
1160 StringRef Name = Decl->getName();
1161 SmallString<128> USR;
1164 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1165 DocComment Comment;
1166 if (auto *RawComment =
1167 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1168 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1169 Context.getDiagnostics());
1170 // Build declaration fragments and sub-heading for the category.
1173 DeclarationFragments SubHeading =
1175
1176 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1177 SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1178
1179 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1180 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1181 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1182 Interface, isInSystemHeader(Decl));
1183
1184 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1185 Decl->methods());
1186 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1187 Decl->properties());
1188 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1189 Decl->ivars());
1190 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1191 Decl->protocols());
1192
1193 return true;
1194}
1195
1196/// Collect API information for the enum constants and associate with the
1197/// parent enum.
1198template <typename Derived>
1201 for (const auto *Constant : Constants) {
1202 // Collect symbol information.
1203 StringRef Name = Constant->getName();
1204 SmallString<128> USR;
1205 index::generateUSRForDecl(Constant, USR);
1207 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1208 DocComment Comment;
1209 if (auto *RawComment =
1210 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1211 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1212 Context.getDiagnostics());
1213
1214 // Build declaration fragments and sub-heading for the enum constant.
1217 DeclarationFragments SubHeading =
1219
1220 API.createRecord<EnumConstantRecord>(
1221 USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
1223 SubHeading, isInSystemHeader(Constant));
1224 }
1225}
1226
1227template <typename Derived>
1229 // ObjCIvars are handled separately
1230 if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1231 return true;
1232
1233 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1234 return true;
1235
1236 // Collect symbol information.
1237 StringRef Name = Decl->getName();
1238 SmallString<128> USR;
1241 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1242 DocComment Comment;
1243 if (auto *RawComment =
1244 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1245 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1246 Context.getDiagnostics());
1247
1248 // Build declaration fragments and sub-heading for the struct field.
1251 DeclarationFragments SubHeading =
1253
1254 RecordContext *NewRecord = nullptr;
1255 if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1257
1258 NewRecord = API.createRecord<CXXFieldRecord>(
1259 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1261 SubHeading, Access, isInSystemHeader(Decl));
1262 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1263 if (RD->isUnion())
1264 NewRecord = API.createRecord<UnionFieldRecord>(
1265 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1267 SubHeading, isInSystemHeader(Decl));
1268 else
1269 NewRecord = API.createRecord<StructFieldRecord>(
1270 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1272 SubHeading, isInSystemHeader(Decl));
1273 }
1274
1275 // If this field has a non typedef'd anonymous tag type let's pretend the
1276 // type's child records are under us in the hierarchy.
1277 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1278
1279 return true;
1280}
1281
1282template <typename Derived>
1284 const CXXConversionDecl *Decl) {
1285 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1286 Decl->isImplicit())
1287 return true;
1288
1289 auto Name = Decl->getNameAsString();
1290 SmallString<128> USR;
1293 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1294 DocComment Comment;
1295 if (auto *RawComment =
1296 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1297 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1298 Context.getDiagnostics());
1299
1300 // Build declaration fragments, sub-heading, and signature for the method.
1303 DeclarationFragments SubHeading =
1305 FunctionSignature Signature =
1308
1309 if (Decl->isStatic())
1310 API.createRecord<CXXStaticMethodRecord>(
1311 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1313 SubHeading, Signature, Access, isInSystemHeader(Decl));
1314 else
1315 API.createRecord<CXXInstanceMethodRecord>(
1316 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1318 SubHeading, Signature, Access, isInSystemHeader(Decl));
1319
1320 return true;
1321}
1322
1323/// Collect API information for the Objective-C methods and associate with the
1324/// parent container.
1325template <typename Derived>
1327 ObjCContainerRecord *Container,
1328 const ObjCContainerDecl::method_range Methods) {
1329 for (const auto *Method : Methods) {
1330 // Don't record selectors for properties.
1331 if (Method->isPropertyAccessor())
1332 continue;
1333
1334 auto Name = Method->getSelector().getAsString();
1335 SmallString<128> USR;
1336 index::generateUSRForDecl(Method, USR);
1338 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1339 DocComment Comment;
1340 if (auto *RawComment =
1341 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1342 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1343 Context.getDiagnostics());
1344
1345 // Build declaration fragments, sub-heading, and signature for the method.
1348 DeclarationFragments SubHeading =
1350 FunctionSignature Signature =
1352
1353 if (Method->isInstanceMethod())
1354 API.createRecord<ObjCInstanceMethodRecord>(
1355 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1357 SubHeading, Signature, isInSystemHeader(Method));
1358 else
1359 API.createRecord<ObjCClassMethodRecord>(
1360 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1362 SubHeading, Signature, isInSystemHeader(Method));
1363 }
1364}
1365
1366template <typename Derived>
1368 ObjCContainerRecord *Container,
1369 const ObjCContainerDecl::prop_range Properties) {
1370 for (const auto *Property : Properties) {
1371 StringRef Name = Property->getName();
1372 SmallString<128> USR;
1375 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1376 DocComment Comment;
1377 if (auto *RawComment =
1378 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1379 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1380 Context.getDiagnostics());
1381
1382 // Build declaration fragments and sub-heading for the property.
1385 DeclarationFragments SubHeading =
1387
1388 auto GetterName = Property->getGetterName().getAsString();
1389 auto SetterName = Property->getSetterName().getAsString();
1390
1391 // Get the attributes for property.
1392 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1393 if (Property->getPropertyAttributes() &
1395 Attributes |= ObjCPropertyRecord::ReadOnly;
1396
1397 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1398 API.createRecord<ObjCClassPropertyRecord>(
1399 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1401 SubHeading,
1402 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1403 GetterName, SetterName, Property->isOptional(),
1404 isInSystemHeader(Property));
1405 else
1406 API.createRecord<ObjCInstancePropertyRecord>(
1407 USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1409 SubHeading,
1410 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1411 GetterName, SetterName, Property->isOptional(),
1412 isInSystemHeader(Property));
1413 }
1414}
1415
1416template <typename Derived>
1418 ObjCContainerRecord *Container,
1419 const llvm::iterator_range<
1421 Ivars) {
1422 for (const auto *Ivar : Ivars) {
1423 StringRef Name = Ivar->getName();
1424 SmallString<128> USR;
1425 index::generateUSRForDecl(Ivar, USR);
1426
1428 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1429 DocComment Comment;
1430 if (auto *RawComment =
1431 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1432 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1433 Context.getDiagnostics());
1434
1435 // Build declaration fragments and sub-heading for the instance variable.
1438 DeclarationFragments SubHeading =
1440
1441 API.createRecord<ObjCInstanceVariableRecord>(
1442 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1444 SubHeading, isInSystemHeader(Ivar));
1445 }
1446}
1447
1448template <typename Derived>
1450 ObjCContainerRecord *Container,
1452 for (const auto *Protocol : Protocols)
1453 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1454}
1455
1456} // namespace impl
1457
1458/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1459/// information.
1460template <typename Derived = void>
1462 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1463 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1464 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1465 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1466
1467public:
1469
1470 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1471 const RawComment *fetchRawCommentForDecl(const Decl *D) const {
1472 return this->Context.getRawCommentForDeclNoCache(D);
1473 }
1474};
1475
1476} // namespace extractapi
1477} // namespace clang
1478
1479#endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
This file defines the APIRecord-based structs and the APISet class.
Defines the clang::ASTContext interface.
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
This file defines the Declaration Fragments related classes.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
This file defines the UnderlyingTypeResolver which is a helper type for resolving the undelrying type...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
SourceManager & getSourceManager()
Definition: ASTContext.h:705
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
RawComment * getRawCommentForDeclNoCache(const Decl *D) const
Return the documentation comment attached to a given declaration, without looking into cache.
Definition: ASTContext.cpp:293
Represents a C++ constructor within a class.
Definition: DeclCXX.h: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:2342
bool isRecord() const
Definition: DeclBase.h:2146
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2059
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:803
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:939
DeclContext * getDeclContext()
Definition: DeclBase.h:454
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
Represents an enum.
Definition: Decl.h:3867
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:3998
Represents a member of a struct/union/class.
Definition: Decl.h:3057
Represents a function declaration or definition.
Definition: Decl.h:1971
@ TK_MemberSpecialization
Definition: Decl.h:1983
@ TK_DependentNonTemplate
Definition: Decl.h:1992
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1987
@ TK_DependentFunctionTemplateSpecialization
Definition: Decl.h:1990
Declaration of a template function.
Definition: DeclTemplate.h:957
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
Represent a C++ namespace.
Definition: Decl.h:547
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2326
llvm::iterator_range< specific_decl_iterator< ObjCMethodDecl > > method_range
Definition: DeclObjC.h:1013
llvm::iterator_range< specific_decl_iterator< ObjCPropertyDecl > > prop_range
Definition: DeclObjC.h:964
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
llvm::iterator_range< protocol_iterator > protocol_range
Definition: DeclObjC.h:1356
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition: Type.h:940
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:4168
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:3584
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:3711
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3687
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:5782
The base class of the type hierarchy.
Definition: Type.h:1813
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Definition: Type.cpp:1879
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3534
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3432
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
APISet holds the set of API records collected from given inputs.
Definition: API.h:1400
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:113
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:100
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:89
static DeclarationFragments getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *)
static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *)
static DeclarationFragments getFragmentsForEnumConstant(const EnumConstantDecl *)
Build DeclarationFragments for an enum constant declaration EnumConstantDecl.
static DeclarationFragments getFragmentsForObjCCategory(const ObjCCategoryDecl *)
Build DeclarationFragments for an Objective-C category declaration ObjCCategoryDecl.
static DeclarationFragments getFragmentsForTypedef(const TypedefNameDecl *Decl)
Build DeclarationFragments for a typedef TypedefNameDecl.
static DeclarationFragments getFragmentsForEnum(const EnumDecl *)
Build DeclarationFragments for an enum declaration EnumDecl.
static DeclarationFragments getFragmentsForConversionFunction(const CXXConversionDecl *)
static DeclarationFragments getFragmentsForClassTemplateSpecialization(const ClassTemplateSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCProtocol(const ObjCProtocolDecl *)
Build DeclarationFragments for an Objective-C protocol declaration ObjCProtocolDecl.
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *)
static DeclarationFragments getFragmentsForField(const FieldDecl *)
Build DeclarationFragments for a field declaration FieldDecl.
static DeclarationFragments getFragmentsForVar(const VarDecl *)
Build DeclarationFragments for a variable declaration VarDecl.
static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(const ClassTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *)
Build DeclarationFragments for an Objective-C method declaration ObjCMethodDecl.
static DeclarationFragments getFragmentsForFunction(const FunctionDecl *)
Build DeclarationFragments for a function declaration FunctionDecl.
static AccessControl getAccessControl(const Decl *Decl)
static DeclarationFragments getFragmentsForObjCProperty(const ObjCPropertyDecl *)
Build DeclarationFragments for an Objective-C property declaration ObjCPropertyDecl.
static DeclarationFragments getFragmentsForSpecialCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForNamespace(const NamespaceDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(const VarTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplateSpecialization(const VarTemplateSpecializationDecl *)
static FunctionSignature getFunctionSignature(const FunctionT *Function)
Build FunctionSignature for a function-like declaration FunctionT like FunctionDecl,...
static DeclarationFragments getSubHeading(const NamedDecl *)
Build sub-heading fragments for a NamedDecl.
static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *)
static DeclarationFragments getFragmentsForOverloadedOperator(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl)
static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *)
Build DeclarationFragments for a struct/union record declaration RecordDecl.
static DeclarationFragments getFragmentsForObjCInterface(const ObjCInterfaceDecl *)
Build DeclarationFragments for an Objective-C interface declaration ObjCInterfaceDecl.
DeclarationFragments is a vector of tagged important parts of a symbol's declaration.
DeclarationFragments & append(DeclarationFragments Other)
Append another DeclarationFragments to the end.
DeclarationFragments & appendSpace()
Append a text Fragment of a space character.
DeclarationFragments & prepend(DeclarationFragments Other)
Prepend another DeclarationFragments to the beginning.
DeclarationFragments & removeTrailingSemicolon()
Removes a trailing semicolon character if present.
DeclarationFragments & appendSemicolon()
Append a text Fragment of a semicolon character.
The RecursiveASTVisitor to traverse symbol declarations and collect API information.
const RawComment * fetchRawCommentForDecl(const Decl *D) const
ExtractAPIVisitor(ASTContext &Context, APISet &API)
bool shouldDeclBeIncluded(const Decl *D) const
Store function signature information with DeclarationFragments of the return type and parameters.
Base class used for specific record types that have children records this is analogous to the DeclCon...
Definition: API.h:313
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:62
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl)
bool WalkUpFromClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitFunctionDecl(const FunctionDecl *Decl)
bool VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
void maybeMergeWithAnonymousTag(const DeclaratorDecl &D, RecordContext *NewRecordContext)
bool VisitCXXMethodDecl(const CXXMethodDecl *Decl)
bool VisitVarTemplateDecl(const VarTemplateDecl *Decl)
bool WalkUpFromCXXMethodDecl(const CXXMethodDecl *Decl)
StringRef getTypedefName(const TagDecl *Decl)
void recordObjCInstanceVariables(ObjCContainerRecord *Container, const llvm::iterator_range< DeclContext::specific_decl_iterator< ObjCIvarDecl > > Ivars)
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl)
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)
bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl)
bool VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl)
const RawComment * fetchRawCommentForDecl(const Decl *Decl) const
bool VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool VisitTypedefNameDecl(const TypedefNameDecl *Decl)
void recordEnumConstants(EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants)
Collect API information for the enum constants and associate with the parent enum.
bool VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl)
SymbolReference createSymbolReferenceForDecl(const Decl &D)
bool WalkUpFromVarTemplateDecl(const VarTemplateDecl *Decl)
bool shouldDeclBeIncluded(const Decl *Decl) const
bool VisitNamespaceDecl(const NamespaceDecl *Decl)
bool WalkUpFromFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl)
bool WalkUpFromFunctionDecl(const FunctionDecl *Decl)
bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl)
void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols)
bool VisitCXXConversionDecl(const CXXConversionDecl *Decl)
SmallVector< SymbolReference > getBases(const CXXRecordDecl *Decl)
bool VisitConceptDecl(const ConceptDecl *Decl)
bool WalkUpFromVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool WalkUpFromClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
std::vector< RawComment::CommentLine > DocComment
DocComment is a vector of RawComment::CommentLine.
Definition: API.h:158
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
The JSON file list parser is used to communicate input to InstallAPI.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Definition: Linkage.h:24
@ Property
The type of a property.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ AS_public
Definition: Specifiers.h:121
static AvailabilityInfo createFromDecl(const Decl *Decl)
The base representation of an API record. Holds common symbol information.
Definition: API.h:192
RecordKind 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.