clang 22.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:
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 if (!Decl->isCompleteDefinition()) {
177 return {};
178 }
179
180 // FIXME: store AccessSpecifier given by inheritance
182 for (const auto &BaseSpecifier : Decl->bases()) {
183 // skip classes not inherited as public
184 if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
185 continue;
186 if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
187 Bases.emplace_back(createSymbolReferenceForDecl(*BaseDecl));
188 } else {
189 SymbolReference BaseClass;
190 BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString(
192
193 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
194 if (auto *TTPTD = BaseSpecifier.getType()
195 ->getAs<TemplateTypeParmType>()
196 ->getDecl()) {
198 index::generateUSRForDecl(TTPTD, USR);
199 BaseClass.USR = API.copyString(USR);
200 BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
201 }
202 }
203 Bases.emplace_back(BaseClass);
204 }
205 }
206 return Bases;
207 }
208
210 if (Decl->isUnion())
211 return APIRecord::RK_Union;
212 if (Decl->isStruct())
214
216 }
217
218 StringRef getOwningModuleName(const Decl &D) {
219 if (auto *OwningModule = D.getImportedOwningModule())
220 return OwningModule->getTopLevelModule()->Name;
221
222 return {};
223 }
224
226 const auto *Context = cast_if_present<Decl>(D.getDeclContext());
227
229 return {};
230
232 }
233
237
238 APIRecord *Record = API.findRecordForUSR(USR);
239 if (Record)
240 return SymbolReference(Record);
241
242 StringRef Name;
243 if (auto *ND = dyn_cast<NamedDecl>(&D))
244 Name = ND->getName();
245
246 return API.createSymbolReference(Name, USR, getOwningModuleName(D));
247 }
248
250 return D.getName().empty() && getTypedefName(&D).empty() &&
252 }
253
255 RecordContext *NewRecordContext) {
256 if (!NewRecordContext)
257 return;
258 auto *Tag = D.getType()->getAsTagDecl();
259 if (!Tag) {
260 if (const auto *AT = D.getASTContext().getAsArrayType(D.getType())) {
261 Tag = AT->getElementType()->getAsTagDecl();
262 }
263 }
264 SmallString<128> TagUSR;
266 if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
267 API.findRecordForUSR(TagUSR))) {
268 if (Record->IsEmbeddedInVarDeclarator) {
269 NewRecordContext->stealRecordChain(*Record);
270 API.removeRecord(Record);
271 }
272 }
273 }
274};
275
276template <typename Derived>
278 // skip function parameters.
280 return true;
281
282 // Skip non-global variables in records (struct/union/class) but not static
283 // members.
284 if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
285 return true;
286
287 // Skip local variables inside function or method.
289 return true;
290
291 // If this is a template but not specialization or instantiation, skip.
293 Decl->getTemplateSpecializationKind() == TSK_Undeclared)
294 return true;
295
296 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
297 return true;
298
299 // Collect symbol information.
300 StringRef Name = Decl->getName();
303 PresumedLoc Loc =
304 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
305 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
306 DocComment Comment;
307 if (auto *RawComment =
308 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
309 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
310 Context.getDiagnostics());
311
312 // Build declaration fragments and sub-heading for the variable.
315 DeclarationFragments SubHeading =
317 if (Decl->isStaticDataMember()) {
319 API.createRecord<StaticFieldRecord>(
320 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
322 SubHeading, Access, isInSystemHeader(Decl));
323 } else {
324 // Add the global variable record to the API set.
325 auto *NewRecord = API.createRecord<GlobalVariableRecord>(
326 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
328 SubHeading, isInSystemHeader(Decl));
329
330 // If this global variable has a non typedef'd anonymous tag type let's
331 // pretend the type's child records are under us in the hierarchy.
332 maybeMergeWithAnonymousTag(*Decl, NewRecord);
333 }
334
335 return true;
336}
337
338template <typename Derived>
340 const FunctionDecl *Decl) {
341 if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
342 // Skip member function in class templates.
343 if (Method->getParent()->getDescribedClassTemplate() != nullptr)
344 return true;
345
346 // Skip methods in records.
347 for (const auto &P : Context.getParents(*Method)) {
348 if (P.template get<CXXRecordDecl>())
349 return true;
350 }
351
352 // Skip ConstructorDecl and DestructorDecl.
354 return true;
355 }
356
357 // Skip templated functions that aren't processed here.
358 switch (Decl->getTemplatedKind()) {
362 break;
366 return true;
367 }
368
369 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
370 return true;
371
372 // Collect symbol information.
373 auto Name = Decl->getNameAsString();
376 PresumedLoc Loc =
377 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
378 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
379 DocComment Comment;
380 if (auto *RawComment =
381 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
382 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
383 Context.getDiagnostics());
384
385 // Build declaration fragments, sub-heading, and signature of the function.
386 DeclarationFragments SubHeading =
388 FunctionSignature Signature =
390 if (Decl->getTemplateSpecializationInfo())
392 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
396 SubHeading, Signature, isInSystemHeader(Decl));
397 else
398 // Add the function record to the API set.
399 API.createRecord<GlobalFunctionRecord>(
400 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
403 Signature, isInSystemHeader(Decl));
404 return true;
405}
406
407template <typename Derived>
409 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
410 return true;
411
414 PresumedLoc Loc =
415 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
416 DocComment Comment;
417 if (auto *RawComment =
418 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
419 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
420 Context.getDiagnostics());
421
422 // Build declaration fragments and sub-heading for the enum.
425 DeclarationFragments SubHeading =
427
428 // Collect symbol information.
429 SymbolReference ParentContainer;
430
431 if (Decl->hasNameForLinkage()) {
432 StringRef Name = Decl->getName();
433 if (Name.empty())
434 Name = getTypedefName(Decl);
435
436 auto *ER = API.createRecord<EnumRecord>(
437 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
439 SubHeading, isInSystemHeader(Decl), false);
440 ParentContainer = SymbolReference(ER);
441 } else {
442 // If this an anonymous enum then the parent scope of the constants is the
443 // top level namespace.
444 ParentContainer = {};
445 }
446
447 // Now collect information about the enumerators in this enum.
448 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
449 Decl->enumerators());
450
451 return true;
452}
453
454template <typename Derived>
456 const FunctionDecl *Decl) {
457 getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
458 return true;
459}
460
461template <typename Derived>
463 const RecordDecl *Decl) {
464 getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
465 return true;
466}
467
468template <typename Derived>
470 const CXXRecordDecl *Decl) {
471 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
472 return true;
473}
474
475template <typename Derived>
477 const CXXMethodDecl *Decl) {
478 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
479 return true;
480}
481
482template <typename Derived>
485 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
486 return true;
487}
488
489template <typename Derived>
493 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
494 Decl);
495 return true;
496}
497
498template <typename Derived>
500 const VarTemplateDecl *Decl) {
501 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
502 return true;
503}
504
505template <typename Derived>
508 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
509 return true;
510}
511
512template <typename Derived>
516 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
517 return true;
518}
519
520template <typename Derived>
522 const FunctionTemplateDecl *Decl) {
523 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
524 return true;
525}
526
527template <typename Derived>
529 const NamespaceDecl *Decl) {
530 getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
531 return true;
532}
533
534template <typename Derived>
536 const NamespaceDecl *Decl) {
537 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
538 return true;
539 if (Decl->isAnonymousNamespace())
540 return true;
541 StringRef Name = Decl->getName();
544 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
545 PresumedLoc Loc =
546 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
547 DocComment Comment;
548 if (auto *RawComment =
549 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
550 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
551 Context.getDiagnostics());
552
553 // Build declaration fragments and sub-heading for the struct.
556 DeclarationFragments SubHeading =
558 API.createRecord<NamespaceRecord>(
559 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
561 SubHeading, isInSystemHeader(Decl));
562
563 return true;
564}
565
566template <typename Derived>
568 bool Ret = Base::TraverseRecordDecl(Decl);
569
570 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
573 API.removeRecord(USR);
574 }
575
576 return Ret;
577}
578
579template <typename Derived>
581 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
582 return true;
583
584 // Collect symbol information.
585 StringRef Name = Decl->getName();
586 if (Name.empty())
587 Name = getTypedefName(Decl);
588
591 PresumedLoc Loc =
592 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
593 DocComment Comment;
594 if (auto *RawComment =
595 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
596 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
597 Context.getDiagnostics());
598
599 // Build declaration fragments and sub-heading for the struct.
602 DeclarationFragments SubHeading =
604
605 if (Decl->isUnion())
606 API.createRecord<UnionRecord>(
607 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
610 else
611 API.createRecord<StructRecord>(
612 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
615
616 return true;
617}
618
619template <typename Derived>
622 bool Ret = Base::TraverseCXXRecordDecl(Decl);
623
624 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
627 API.removeRecord(USR);
628 }
629
630 return Ret;
631}
632
633template <typename Derived>
635 const CXXRecordDecl *Decl) {
636 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
637 Decl->isImplicit())
638 return true;
639
640 StringRef Name = Decl->getName();
641 if (Name.empty())
642 Name = getTypedefName(Decl);
643
646 PresumedLoc Loc =
647 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
648 DocComment Comment;
649 if (auto *RawComment =
650 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
651 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
652 Context.getDiagnostics());
655 DeclarationFragments SubHeading =
657
659
661 if (Decl->getDescribedClassTemplate()) {
662 // Inject template fragments before class fragments.
663 Declaration.prepend(
665 Decl->getDescribedClassTemplate()));
666 Record = API.createRecord<ClassTemplateRecord>(
667 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
669 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
671 } else {
672 Record = API.createRecord<CXXClassRecord>(
673 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
675 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
677 }
678
679 Record->KindForDisplay = getKindForDisplay(Decl);
680 Record->Bases = getBases(Decl);
681
682 return true;
683}
684
685template <typename Derived>
687 const CXXMethodDecl *Decl) {
688 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
689 Decl->isImplicit())
690 return true;
691
693 return true;
695 return true;
696
699 PresumedLoc Loc =
700 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
701 DocComment Comment;
702 if (auto *RawComment =
703 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
704 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
705 Context.getDiagnostics());
706 DeclarationFragments SubHeading =
710
712 Decl->getDescribedFunctionTemplate()) {
713 API.createRecord<CXXMethodTemplateRecord>(
714 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
721 } else if (Decl->getTemplateSpecializationInfo())
723 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
726 getFragmentsForFunctionTemplateSpecialization(Decl),
727 SubHeading, Signature, Access, isInSystemHeader(Decl));
728 else if (Decl->isOverloadedOperator())
729 API.createRecord<CXXInstanceMethodRecord>(
730 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
733 SubHeading, Signature, Access, isInSystemHeader(Decl));
734 else if (Decl->isStatic())
735 API.createRecord<CXXStaticMethodRecord>(
736 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
739 Signature, Access, isInSystemHeader(Decl));
740 else
741 API.createRecord<CXXInstanceMethodRecord>(
742 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
745 Signature, Access, isInSystemHeader(Decl));
746
747 return true;
748}
749
750template <typename Derived>
752 const CXXConstructorDecl *Decl) {
753 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
754 Decl->isImplicit())
755 return true;
756
757 auto Name = Decl->getNameAsString();
760 PresumedLoc Loc =
761 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
762 DocComment Comment;
763 if (auto *RawComment =
764 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
765 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
766 Context.getDiagnostics());
767
768 // Build declaration fragments, sub-heading, and signature for the method.
771 DeclarationFragments SubHeading =
773 FunctionSignature Signature =
776
777 API.createRecord<CXXConstructorRecord>(
778 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
780 Signature, Access, isInSystemHeader(Decl));
781 return true;
782}
783
784template <typename Derived>
786 const CXXDestructorDecl *Decl) {
787 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
788 Decl->isImplicit())
789 return true;
790
791 auto Name = Decl->getNameAsString();
794 PresumedLoc Loc =
795 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
796 DocComment Comment;
797 if (auto *RawComment =
798 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
799 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
800 Context.getDiagnostics());
801
802 // Build declaration fragments, sub-heading, and signature for the method.
805 DeclarationFragments SubHeading =
807 FunctionSignature Signature =
810 API.createRecord<CXXDestructorRecord>(
811 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
813 Signature, Access, isInSystemHeader(Decl));
814 return true;
815}
816
817template <typename Derived>
819 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
820 return true;
821
822 StringRef Name = Decl->getName();
825 PresumedLoc Loc =
826 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
827 DocComment Comment;
828 if (auto *RawComment =
829 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
830 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
831 Context.getDiagnostics());
834 DeclarationFragments SubHeading =
836 API.createRecord<ConceptRecord>(
837 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
840 return true;
841}
842
843template <typename Derived>
846 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
847 return true;
848
849 StringRef Name = Decl->getName();
852 PresumedLoc Loc =
853 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
854 DocComment Comment;
855 if (auto *RawComment =
856 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
857 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
858 Context.getDiagnostics());
861 Decl);
862 DeclarationFragments SubHeading =
864
865 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
866 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
870
871 CTSR->Bases = getBases(Decl);
872
873 return true;
874}
875
876template <typename Derived>
880 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
881 return true;
882
883 StringRef Name = Decl->getName();
886 PresumedLoc Loc =
887 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
888 DocComment Comment;
889 if (auto *RawComment =
890 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
891 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
892 Context.getDiagnostics());
895 DeclarationFragments SubHeading =
897 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
898 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
902
904 CTPSR->Bases = getBases(Decl);
905
906 return true;
907}
908
909template <typename Derived>
911 const VarTemplateDecl *Decl) {
912 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
913 return true;
914
915 // Collect symbol information.
916 StringRef Name = Decl->getName();
919 PresumedLoc Loc =
920 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
921 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
922 DocComment Comment;
923 if (auto *RawComment =
924 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
925 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
926 Context.getDiagnostics());
927
928 // Build declaration fragments and sub-heading for the variable.
932 Decl))
934 Decl->getTemplatedDecl()));
935 // Inject template fragments before var fragments.
936 DeclarationFragments SubHeading =
938
939 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
940 API.createRecord<CXXFieldTemplateRecord>(
941 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
945 else
946 API.createRecord<GlobalVariableTemplateRecord>(
947 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
949 SubHeading, Template(Decl), isInSystemHeader(Decl));
950 return true;
951}
952
953template <typename Derived>
956 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
957 return true;
958
959 // Collect symbol information.
960 StringRef Name = Decl->getName();
963 PresumedLoc Loc =
964 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
965 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
966 DocComment Comment;
967 if (auto *RawComment =
968 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
969 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
970 Context.getDiagnostics());
971
972 // Build declaration fragments and sub-heading for the variable.
975 Decl);
976 DeclarationFragments SubHeading =
979 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
981 SubHeading, isInSystemHeader(Decl));
982 return true;
983}
984
985template <typename Derived>
988 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
989 return true;
990
991 // Collect symbol information.
992 StringRef Name = Decl->getName();
995 PresumedLoc Loc =
996 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
997 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
998 DocComment Comment;
999 if (auto *RawComment =
1000 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1001 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1002 Context.getDiagnostics());
1003
1004 // Build declaration fragments and sub-heading for the variable.
1007 DeclarationFragments SubHeading =
1010 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1012 SubHeading, Template(Decl), isInSystemHeader(Decl));
1013 return true;
1014}
1015
1016template <typename Derived>
1018 const FunctionTemplateDecl *Decl) {
1019 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
1020 return true;
1021 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1022 return true;
1023
1024 // Collect symbol information.
1025 auto Name = Decl->getNameAsString();
1026 SmallString<128> USR;
1028 PresumedLoc Loc =
1029 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1030 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1031 DocComment Comment;
1032 if (auto *RawComment =
1033 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1034 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1035 Context.getDiagnostics());
1036
1037 DeclarationFragments SubHeading =
1039 FunctionSignature Signature =
1041 Decl->getTemplatedDecl());
1042 API.createRecord<GlobalFunctionTemplateRecord>(
1043 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1046 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1047
1048 return true;
1049}
1050
1051template <typename Derived>
1053 const ObjCInterfaceDecl *Decl) {
1054 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1055 return true;
1056
1057 // Collect symbol information.
1058 StringRef Name = Decl->getName();
1059 SmallString<128> USR;
1061 PresumedLoc Loc =
1062 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1063 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1064 DocComment Comment;
1065 if (auto *RawComment =
1066 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1067 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1068 Context.getDiagnostics());
1069
1070 // Build declaration fragments and sub-heading for the interface.
1073 DeclarationFragments SubHeading =
1075
1076 // Collect super class information.
1077 SymbolReference SuperClass;
1078 if (const auto *SuperClassDecl = Decl->getSuperClass())
1079 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1080
1081 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1082 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1084 SubHeading, SuperClass, isInSystemHeader(Decl));
1085
1086 // Record all methods (selectors). This doesn't include automatically
1087 // synthesized property methods.
1088 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1089 Decl->methods());
1090 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1091 Decl->properties());
1092 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1093 Decl->ivars());
1094 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1095 Decl->protocols());
1096
1097 return true;
1098}
1099
1100template <typename Derived>
1102 const ObjCProtocolDecl *Decl) {
1103 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1104 return true;
1105
1106 // Collect symbol information.
1107 StringRef Name = Decl->getName();
1108 SmallString<128> USR;
1110 PresumedLoc Loc =
1111 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1112 DocComment Comment;
1113 if (auto *RawComment =
1114 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1115 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1116 Context.getDiagnostics());
1117
1118 // Build declaration fragments and sub-heading for the protocol.
1121 DeclarationFragments SubHeading =
1123
1124 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1125 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1126 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1128
1129 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1130 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1131 Decl->properties());
1132 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1133 Decl->protocols());
1134
1135 return true;
1136}
1137
1138template <typename Derived>
1140 const TypedefNameDecl *Decl) {
1141 // Skip ObjC Type Parameter for now.
1143 return true;
1144
1146 return true;
1147
1148 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1149 return true;
1150
1151 StringRef Name = Decl->getName();
1152
1153 auto nameMatches = [&Name](TagDecl *TagDecl) {
1154 StringRef TagName = TagDecl->getName();
1155
1156 if (TagName == Name)
1157 return true;
1158
1159 // Also check whether the tag decl's name is the same as the typedef name
1160 // with prefixed underscores
1161 if (TagName.starts_with('_')) {
1162 StringRef StrippedName = TagName.ltrim('_');
1163
1164 if (StrippedName == Name)
1165 return true;
1166 }
1167
1168 return false;
1169 };
1170
1171 // If the underlying type was defined as part of the typedef modify it's
1172 // fragments directly and pretend the typedef doesn't exist.
1173 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1175 nameMatches(TagDecl)) {
1176 SmallString<128> TagUSR;
1178 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1179 DeclarationFragments LeadingFragments;
1180 LeadingFragments.append("typedef",
1182 LeadingFragments.appendSpace();
1183 Record->Declaration.removeTrailingSemicolon()
1184 .prepend(std::move(LeadingFragments))
1185 .append(" { ... } ", DeclarationFragments::FragmentKind::Text)
1187 .appendSemicolon();
1188
1189 // Replace the name and subheading in case it's underscored so we can
1190 // use the non-underscored version
1191 Record->Name = Name;
1193
1194 return true;
1195 }
1196 }
1197 }
1198
1199 PresumedLoc Loc =
1200 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1201 SmallString<128> USR;
1203 DocComment Comment;
1204 if (auto *RawComment =
1205 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1206 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1207 Context.getDiagnostics());
1208
1209 QualType Type = Decl->getUnderlyingType();
1210 SymbolReference SymRef =
1212 API);
1213
1214 API.createRecord<TypedefRecord>(
1215 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1220
1221 return true;
1222}
1223
1224template <typename Derived>
1226 const ObjCCategoryDecl *Decl) {
1227 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1228 return true;
1229
1230 StringRef Name = Decl->getName();
1231 SmallString<128> USR;
1233 PresumedLoc Loc =
1234 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1235 DocComment Comment;
1236 if (auto *RawComment =
1237 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1238 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1239 Context.getDiagnostics());
1240 // Build declaration fragments and sub-heading for the category.
1243 DeclarationFragments SubHeading =
1245
1246 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1248
1249 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1250 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1251 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1253
1254 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1255 Decl->methods());
1256 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1257 Decl->properties());
1258 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1259 Decl->ivars());
1260 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1261 Decl->protocols());
1262
1263 return true;
1264}
1265
1266/// Collect API information for the enum constants and associate with the
1267/// parent enum.
1268template <typename Derived>
1270 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1271 for (const auto *Constant : Constants) {
1272 // Collect symbol information.
1273 StringRef Name = Constant->getName();
1274 SmallString<128> USR;
1275 index::generateUSRForDecl(Constant, USR);
1276 PresumedLoc Loc =
1277 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1278 DocComment Comment;
1279 if (auto *RawComment =
1280 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1281 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1282 Context.getDiagnostics());
1283
1284 // Build declaration fragments and sub-heading for the enum constant.
1287 DeclarationFragments SubHeading =
1289
1290 API.createRecord<EnumConstantRecord>(
1291 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1292 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1293 }
1294}
1295
1296template <typename Derived>
1298 // ObjCIvars are handled separately
1300 return true;
1301
1302 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1303 return true;
1304
1305 // Collect symbol information.
1306 StringRef Name = Decl->getName();
1307 SmallString<128> USR;
1309 PresumedLoc Loc =
1310 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1311 DocComment Comment;
1312 if (auto *RawComment =
1313 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1314 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1315 Context.getDiagnostics());
1316
1317 // Build declaration fragments and sub-heading for the struct field.
1320 DeclarationFragments SubHeading =
1322
1323 RecordContext *NewRecord = nullptr;
1326
1327 NewRecord = API.createRecord<CXXFieldRecord>(
1328 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1330 SubHeading, Access, isInSystemHeader(Decl));
1331 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1332 if (RD->isUnion())
1333 NewRecord = API.createRecord<UnionFieldRecord>(
1334 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1336 SubHeading, isInSystemHeader(Decl));
1337 else
1338 NewRecord = API.createRecord<StructFieldRecord>(
1339 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1341 SubHeading, isInSystemHeader(Decl));
1342 }
1343
1344 // If this field has a non typedef'd anonymous tag type let's pretend the
1345 // type's child records are under us in the hierarchy.
1346 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1347
1348 return true;
1349}
1350
1351template <typename Derived>
1353 const CXXConversionDecl *Decl) {
1354 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1355 Decl->isImplicit())
1356 return true;
1357
1358 auto Name = Decl->getNameAsString();
1359 SmallString<128> USR;
1361 PresumedLoc Loc =
1362 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1363 DocComment Comment;
1364 if (auto *RawComment =
1365 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1366 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1367 Context.getDiagnostics());
1368
1369 // Build declaration fragments, sub-heading, and signature for the method.
1372 DeclarationFragments SubHeading =
1374 FunctionSignature Signature =
1377
1378 if (Decl->isStatic())
1379 API.createRecord<CXXStaticMethodRecord>(
1380 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1382 SubHeading, Signature, Access, isInSystemHeader(Decl));
1383 else
1384 API.createRecord<CXXInstanceMethodRecord>(
1385 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1387 SubHeading, Signature, Access, isInSystemHeader(Decl));
1388
1389 return true;
1390}
1391
1392/// Collect API information for the Objective-C methods and associate with the
1393/// parent container.
1394template <typename Derived>
1396 ObjCContainerRecord *Container,
1397 const ObjCContainerDecl::method_range Methods) {
1398 for (const auto *Method : Methods) {
1399 // Don't record selectors for properties.
1400 if (Method->isPropertyAccessor())
1401 continue;
1402
1403 auto Name = Method->getSelector().getAsString();
1404 SmallString<128> USR;
1406 PresumedLoc Loc =
1407 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1408 DocComment Comment;
1409 if (auto *RawComment =
1410 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1411 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1412 Context.getDiagnostics());
1413
1414 // Build declaration fragments, sub-heading, and signature for the method.
1417 DeclarationFragments SubHeading =
1419 FunctionSignature Signature =
1421
1422 if (Method->isInstanceMethod())
1423 API.createRecord<ObjCInstanceMethodRecord>(
1424 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1426 SubHeading, Signature, isInSystemHeader(Method));
1427 else
1428 API.createRecord<ObjCClassMethodRecord>(
1429 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1431 SubHeading, Signature, isInSystemHeader(Method));
1432 }
1433}
1434
1435template <typename Derived>
1437 ObjCContainerRecord *Container,
1438 const ObjCContainerDecl::prop_range Properties) {
1439 for (const auto *Property : Properties) {
1440 StringRef Name = Property->getName();
1441 SmallString<128> USR;
1443 PresumedLoc Loc =
1444 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1445 DocComment Comment;
1446 if (auto *RawComment =
1447 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1448 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1449 Context.getDiagnostics());
1450
1451 // Build declaration fragments and sub-heading for the property.
1454 DeclarationFragments SubHeading =
1456
1457 auto GetterName = Property->getGetterName().getAsString();
1458 auto SetterName = Property->getSetterName().getAsString();
1459
1460 // Get the attributes for property.
1461 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1462 if (Property->getPropertyAttributes() &
1464 Attributes |= ObjCPropertyRecord::ReadOnly;
1465
1466 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1467 API.createRecord<ObjCClassPropertyRecord>(
1470 SubHeading,
1471 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1472 GetterName, SetterName, Property->isOptional(),
1474 else
1475 API.createRecord<ObjCInstancePropertyRecord>(
1478 SubHeading,
1479 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1480 GetterName, SetterName, Property->isOptional(),
1482 }
1483}
1484
1485template <typename Derived>
1487 ObjCContainerRecord *Container,
1488 const llvm::iterator_range<
1490 Ivars) {
1491 for (const auto *Ivar : Ivars) {
1492 StringRef Name = Ivar->getName();
1493 SmallString<128> USR;
1494 index::generateUSRForDecl(Ivar, USR);
1495
1496 PresumedLoc Loc =
1497 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1498 DocComment Comment;
1499 if (auto *RawComment =
1500 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1501 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1502 Context.getDiagnostics());
1503
1504 // Build declaration fragments and sub-heading for the instance variable.
1507 DeclarationFragments SubHeading =
1509
1510 API.createRecord<ObjCInstanceVariableRecord>(
1511 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1513 SubHeading, isInSystemHeader(Ivar));
1514 }
1515}
1516
1517template <typename Derived>
1519 ObjCContainerRecord *Container,
1521 for (const auto *Protocol : Protocols)
1522 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1523}
1524
1525} // namespace impl
1526
1527/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1528/// information.
1529template <typename Derived = void>
1531 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1532 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1533 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1534 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1535
1536public:
1538
1539 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1540 const RawComment *fetchRawCommentForDecl(const Decl *D) const {
1541 if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
1542 return Comment;
1543
1544 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1545 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1546 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1547 TagTypeDecl->isCompleteDefinition())
1548 return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
1549 }
1550
1551 return nullptr;
1552 }
1553};
1554
1555} // namespace extractapi
1556} // namespace clang
1557
1558#endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
This file defines the APIRecord-based structs and the APISet class.
Defines the clang::ASTContext interface.
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.
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
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:790
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2943
Represents a C++ destructor within a class.
Definition DeclCXX.h:2869
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
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:2393
bool isRecord() const
Definition DeclBase.h:2189
Decl::Kind getDeclKind() const
Definition DeclBase.h:2102
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:593
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition DeclBase.h:812
SourceLocation getLocation() const
Definition DeclBase.h:439
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition DeclBase.h:949
DeclContext * getDeclContext()
Definition DeclBase.h:448
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:779
Information about one declarator, including the parsed type information and the identifier.
Definition DeclSpec.h:1874
Represents an enum.
Definition Decl.h:4004
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition Decl.h:4138
Represents a member of a struct/union/class.
Definition Decl.h:3157
Represents a function declaration or definition.
Definition Decl.h:1999
@ TK_FunctionTemplateSpecialization
Definition Decl.h:2015
@ TK_DependentFunctionTemplateSpecialization
Definition Decl.h:2018
Declaration of a template function.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:300
Represent a C++ namespace.
Definition Decl.h:591
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2329
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:1154
llvm::iterator_range< protocol_iterator > protocol_range
Definition DeclObjC.h:1357
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition TypeBase.h:937
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:4309
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3714
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:3833
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3809
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition Decl.h:3844
The base class of all kinds of template declarations (e.g., class, function, etc.).
The base class of the type hierarchy.
Definition TypeBase.h:1833
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Definition Type.h:65
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3664
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3559
QualType getType() const
Definition Decl.h:722
Represents a variable declaration or definition.
Definition Decl.h:925
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
A factory class to build DeclarationFragments for different kinds of Decl.
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.
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)
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)
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 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.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ AS_public
Definition Specifiers.h:124
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.
Definition TypeBase.h:911
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ 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.
Definition TypeBase.h:5868
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
SmallVector< SymbolReference > Protocols
Definition API.h:1180
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
This holds information associated with typedefs.
Definition API.h:1404
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.