clang 24.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
606 if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
608
609 if (Decl->isUnion())
610 API.createRecord<UnionRecord>(
611 USR, Name, createHierarchyInformationForDecl(*Decl), Loc, Availability,
612 Comment, Declaration, SubHeading, isInSystemHeader(Decl),
614 else
615 API.createRecord<StructRecord>(
616 USR, Name, createHierarchyInformationForDecl(*Decl), Loc, Availability,
617 Comment, Declaration, SubHeading, isInSystemHeader(Decl),
619
620 return true;
621}
622
623template <typename Derived>
626 bool Ret = Base::TraverseCXXRecordDecl(Decl);
627
628 if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
631 API.removeRecord(USR);
632 }
633
634 return Ret;
635}
636
637template <typename Derived>
639 const CXXRecordDecl *Decl) {
640 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
641 Decl->isImplicit())
642 return true;
643
644 StringRef Name = Decl->getName();
645 if (Name.empty())
646 Name = getTypedefName(Decl);
647
650 PresumedLoc Loc =
651 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
652 DocComment Comment;
653 if (auto *RawComment =
654 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
655 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
656 Context.getDiagnostics());
659 DeclarationFragments SubHeading =
661
663
665 if (Decl->getDescribedClassTemplate()) {
666 // Inject template fragments before class fragments.
667 Declaration.prepend(
669 Decl->getDescribedClassTemplate()));
670 Record = API.createRecord<ClassTemplateRecord>(
671 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
673 SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
675 } else {
676 Record = API.createRecord<CXXClassRecord>(
677 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
679 SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
681 }
682
683 Record->KindForDisplay = getKindForDisplay(Decl);
684 Record->Bases = getBases(Decl);
685
686 return true;
687}
688
689template <typename Derived>
691 const CXXMethodDecl *Decl) {
692 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
693 Decl->isImplicit())
694 return true;
695
697 return true;
699 return true;
700
703 PresumedLoc Loc =
704 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
705 DocComment Comment;
706 if (auto *RawComment =
707 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
708 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
709 Context.getDiagnostics());
710 DeclarationFragments SubHeading =
714
716 Decl->getDescribedFunctionTemplate()) {
717 API.createRecord<CXXMethodTemplateRecord>(
718 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
725 } else if (Decl->getTemplateSpecializationInfo())
727 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
730 getFragmentsForFunctionTemplateSpecialization(Decl),
731 SubHeading, Signature, Access, isInSystemHeader(Decl));
732 else if (Decl->isOverloadedOperator())
733 API.createRecord<CXXInstanceMethodRecord>(
734 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
737 SubHeading, Signature, Access, isInSystemHeader(Decl));
738 else if (Decl->isStatic())
739 API.createRecord<CXXStaticMethodRecord>(
740 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
743 Signature, Access, isInSystemHeader(Decl));
744 else
745 API.createRecord<CXXInstanceMethodRecord>(
746 USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
749 Signature, Access, isInSystemHeader(Decl));
750
751 return true;
752}
753
754template <typename Derived>
756 const CXXConstructorDecl *Decl) {
757 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
758 Decl->isImplicit())
759 return true;
760
761 auto Name = Decl->getNameAsString();
764 PresumedLoc Loc =
765 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
766 DocComment Comment;
767 if (auto *RawComment =
768 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
769 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
770 Context.getDiagnostics());
771
772 // Build declaration fragments, sub-heading, and signature for the method.
775 DeclarationFragments SubHeading =
777 FunctionSignature Signature =
780
781 API.createRecord<CXXConstructorRecord>(
782 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
784 Signature, Access, isInSystemHeader(Decl));
785 return true;
786}
787
788template <typename Derived>
790 const CXXDestructorDecl *Decl) {
791 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
792 Decl->isImplicit())
793 return true;
794
795 auto Name = Decl->getNameAsString();
798 PresumedLoc Loc =
799 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
800 DocComment Comment;
801 if (auto *RawComment =
802 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
803 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
804 Context.getDiagnostics());
805
806 // Build declaration fragments, sub-heading, and signature for the method.
809 DeclarationFragments SubHeading =
811 FunctionSignature Signature =
814 API.createRecord<CXXDestructorRecord>(
815 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
817 Signature, Access, isInSystemHeader(Decl));
818 return true;
819}
820
821template <typename Derived>
823 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
824 return true;
825
826 StringRef Name = Decl->getName();
829 PresumedLoc Loc =
830 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
831 DocComment Comment;
832 if (auto *RawComment =
833 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
834 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
835 Context.getDiagnostics());
838 DeclarationFragments SubHeading =
840 API.createRecord<ConceptRecord>(
841 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
844 return true;
845}
846
847template <typename Derived>
850 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
851 return true;
852
853 StringRef Name = Decl->getName();
856 PresumedLoc Loc =
857 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
858 DocComment Comment;
859 if (auto *RawComment =
860 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
861 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
862 Context.getDiagnostics());
865 Decl);
866 DeclarationFragments SubHeading =
868
869 auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
870 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
874
875 CTSR->Bases = getBases(Decl);
876
877 return true;
878}
879
880template <typename Derived>
884 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
885 return true;
886
887 StringRef Name = Decl->getName();
890 PresumedLoc Loc =
891 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
892 DocComment Comment;
893 if (auto *RawComment =
894 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
895 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
896 Context.getDiagnostics());
899 DeclarationFragments SubHeading =
901 auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
902 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
906
908 CTPSR->Bases = getBases(Decl);
909
910 return true;
911}
912
913template <typename Derived>
915 const VarTemplateDecl *Decl) {
916 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
917 return true;
918
919 // Collect symbol information.
920 StringRef Name = Decl->getName();
923 PresumedLoc Loc =
924 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
925 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
926 DocComment Comment;
927 if (auto *RawComment =
928 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
929 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
930 Context.getDiagnostics());
931
932 // Build declaration fragments and sub-heading for the variable.
936 Decl))
938 Decl->getTemplatedDecl()));
939 // Inject template fragments before var fragments.
940 DeclarationFragments SubHeading =
942
943 if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
944 API.createRecord<CXXFieldTemplateRecord>(
945 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
949 else
950 API.createRecord<GlobalVariableTemplateRecord>(
951 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
953 SubHeading, Template(Decl), isInSystemHeader(Decl));
954 return true;
955}
956
957template <typename Derived>
960 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
961 return true;
962
963 // Collect symbol information.
964 StringRef Name = Decl->getName();
967 PresumedLoc Loc =
968 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
969 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
970 DocComment Comment;
971 if (auto *RawComment =
972 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
973 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
974 Context.getDiagnostics());
975
976 // Build declaration fragments and sub-heading for the variable.
979 Decl);
980 DeclarationFragments SubHeading =
983 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
985 SubHeading, isInSystemHeader(Decl));
986 return true;
987}
988
989template <typename Derived>
992 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
993 return true;
994
995 // Collect symbol information.
996 StringRef Name = Decl->getName();
999 PresumedLoc Loc =
1000 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1001 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1002 DocComment Comment;
1003 if (auto *RawComment =
1004 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1005 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1006 Context.getDiagnostics());
1007
1008 // Build declaration fragments and sub-heading for the variable.
1011 DeclarationFragments SubHeading =
1014 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1016 SubHeading, Template(Decl), isInSystemHeader(Decl));
1017 return true;
1018}
1019
1020template <typename Derived>
1022 const FunctionTemplateDecl *Decl) {
1023 if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
1024 return true;
1025 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1026 return true;
1027
1028 // Collect symbol information.
1029 auto Name = Decl->getNameAsString();
1030 SmallString<128> USR;
1032 PresumedLoc Loc =
1033 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1034 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1035 DocComment Comment;
1036 if (auto *RawComment =
1037 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1038 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1039 Context.getDiagnostics());
1040
1041 DeclarationFragments SubHeading =
1043 FunctionSignature Signature =
1045 Decl->getTemplatedDecl());
1046 API.createRecord<GlobalFunctionTemplateRecord>(
1047 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1050 SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1051
1052 return true;
1053}
1054
1055template <typename Derived>
1057 const ObjCInterfaceDecl *Decl) {
1058 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1059 return true;
1060
1061 // Collect symbol information.
1062 StringRef Name = Decl->getName();
1063 SmallString<128> USR;
1065 PresumedLoc Loc =
1066 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1067 LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1068 DocComment Comment;
1069 if (auto *RawComment =
1070 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1071 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1072 Context.getDiagnostics());
1073
1074 // Build declaration fragments and sub-heading for the interface.
1077 DeclarationFragments SubHeading =
1079
1080 // Collect super class information.
1081 SymbolReference SuperClass;
1082 if (const auto *SuperClassDecl = Decl->getSuperClass())
1083 SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1084
1085 auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1086 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1088 SubHeading, SuperClass, isInSystemHeader(Decl));
1089
1090 // Record all methods (selectors). This doesn't include automatically
1091 // synthesized property methods.
1092 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1093 Decl->methods());
1094 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1095 Decl->properties());
1096 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1097 Decl->ivars());
1098 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1099 Decl->protocols());
1100
1101 return true;
1102}
1103
1104template <typename Derived>
1106 const ObjCProtocolDecl *Decl) {
1107 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1108 return true;
1109
1110 // Collect symbol information.
1111 StringRef Name = Decl->getName();
1112 SmallString<128> USR;
1114 PresumedLoc Loc =
1115 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1116 DocComment Comment;
1117 if (auto *RawComment =
1118 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1119 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1120 Context.getDiagnostics());
1121
1122 // Build declaration fragments and sub-heading for the protocol.
1125 DeclarationFragments SubHeading =
1127
1128 auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1129 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1130 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1132
1133 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1134 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1135 Decl->properties());
1136 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1137 Decl->protocols());
1138
1139 return true;
1140}
1141
1142template <typename Derived>
1144 const TypedefNameDecl *Decl) {
1145 // Skip ObjC Type Parameter for now.
1147 return true;
1148
1150 return true;
1151
1152 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1153 return true;
1154
1155 StringRef Name = Decl->getName();
1156
1157 auto nameMatches = [&Name](TagDecl *TagDecl) {
1158 StringRef TagName = TagDecl->getName();
1159
1160 if (TagName == Name)
1161 return true;
1162
1163 // Also check whether the tag decl's name is the same as the typedef name
1164 // with prefixed underscores
1165 if (TagName.starts_with('_')) {
1166 StringRef StrippedName = TagName.ltrim('_');
1167
1168 if (StrippedName == Name)
1169 return true;
1170 }
1171
1172 return false;
1173 };
1174
1175 // If the underlying type was defined as part of the typedef modify it's
1176 // fragments directly and pretend the typedef doesn't exist.
1177 if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1179 nameMatches(TagDecl)) {
1180 SmallString<128> TagUSR;
1182 if (auto *Record = API.findRecordForUSR(TagUSR)) {
1183 DeclarationFragments LeadingFragments;
1184 LeadingFragments.append("typedef",
1186 LeadingFragments.appendSpace();
1187 Record->Declaration.removeTrailingSemicolon()
1188 .prepend(std::move(LeadingFragments))
1189 .append(" { ... } ", DeclarationFragments::FragmentKind::Text)
1191 .appendSemicolon();
1192
1193 // Replace the name and subheading in case it's underscored so we can
1194 // use the non-underscored version
1195 Record->Name = Name;
1197
1198 return true;
1199 }
1200 }
1201 }
1202
1203 PresumedLoc Loc =
1204 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1205 SmallString<128> USR;
1207 DocComment Comment;
1208 if (auto *RawComment =
1209 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1210 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1211 Context.getDiagnostics());
1212
1213 QualType Type = Decl->getUnderlyingType();
1214 SymbolReference SymRef =
1216 API);
1217
1218 API.createRecord<TypedefRecord>(
1219 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1224
1225 return true;
1226}
1227
1228template <typename Derived>
1230 const ObjCCategoryDecl *Decl) {
1231 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1232 return true;
1233
1234 StringRef Name = Decl->getName();
1235 SmallString<128> USR;
1237 PresumedLoc Loc =
1238 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1239 DocComment Comment;
1240 if (auto *RawComment =
1241 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1242 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1243 Context.getDiagnostics());
1244 // Build declaration fragments and sub-heading for the category.
1247 DeclarationFragments SubHeading =
1249
1250 const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1252
1253 auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1254 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1255 AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1257
1258 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1259 Decl->methods());
1260 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1261 Decl->properties());
1262 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1263 Decl->ivars());
1264 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1265 Decl->protocols());
1266
1267 return true;
1268}
1269
1270/// Collect API information for the enum constants and associate with the
1271/// parent enum.
1272template <typename Derived>
1274 SymbolReference Container, const EnumDecl::enumerator_range Constants) {
1275 for (const auto *Constant : Constants) {
1276 // Collect symbol information.
1277 StringRef Name = Constant->getName();
1278 SmallString<128> USR;
1280 PresumedLoc Loc =
1281 Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1282 DocComment Comment;
1283 if (auto *RawComment =
1284 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1285 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1286 Context.getDiagnostics());
1287
1288 // Build declaration fragments and sub-heading for the enum constant.
1291 DeclarationFragments SubHeading =
1293
1294 API.createRecord<EnumConstantRecord>(
1295 USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
1296 Comment, Declaration, SubHeading, isInSystemHeader(Constant));
1297 }
1298}
1299
1300template <typename Derived>
1302 // ObjCIvars are handled separately
1304 return true;
1305
1306 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1307 return true;
1308
1309 // Collect symbol information.
1310 StringRef Name = Decl->getName();
1311 SmallString<128> USR;
1313 PresumedLoc Loc =
1314 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1315 DocComment Comment;
1316 if (auto *RawComment =
1317 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1318 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1319 Context.getDiagnostics());
1320
1321 // Build declaration fragments and sub-heading for the struct field.
1324 DeclarationFragments SubHeading =
1326
1327 RecordContext *NewRecord = nullptr;
1330
1331 NewRecord = API.createRecord<CXXFieldRecord>(
1332 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1334 SubHeading, Access, isInSystemHeader(Decl));
1335 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1336 if (RD->isUnion())
1337 NewRecord = API.createRecord<UnionFieldRecord>(
1338 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1340 SubHeading, isInSystemHeader(Decl));
1341 else
1342 NewRecord = API.createRecord<StructFieldRecord>(
1343 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1345 SubHeading, isInSystemHeader(Decl));
1346 }
1347
1348 // If this field has a non typedef'd anonymous tag type let's pretend the
1349 // type's child records are under us in the hierarchy.
1350 maybeMergeWithAnonymousTag(*Decl, NewRecord);
1351
1352 return true;
1353}
1354
1355template <typename Derived>
1357 const CXXConversionDecl *Decl) {
1358 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1359 Decl->isImplicit())
1360 return true;
1361
1362 auto Name = Decl->getNameAsString();
1363 SmallString<128> USR;
1365 PresumedLoc Loc =
1366 Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1367 DocComment Comment;
1368 if (auto *RawComment =
1369 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1370 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1371 Context.getDiagnostics());
1372
1373 // Build declaration fragments, sub-heading, and signature for the method.
1376 DeclarationFragments SubHeading =
1378 FunctionSignature Signature =
1381
1382 if (Decl->isStatic())
1383 API.createRecord<CXXStaticMethodRecord>(
1384 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1386 SubHeading, Signature, Access, isInSystemHeader(Decl));
1387 else
1388 API.createRecord<CXXInstanceMethodRecord>(
1389 USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1391 SubHeading, Signature, Access, isInSystemHeader(Decl));
1392
1393 return true;
1394}
1395
1396/// Collect API information for the Objective-C methods and associate with the
1397/// parent container.
1398template <typename Derived>
1400 ObjCContainerRecord *Container,
1401 const ObjCContainerDecl::method_range Methods) {
1402 for (const auto *Method : Methods) {
1403 // Don't record selectors for properties.
1404 if (Method->isPropertyAccessor())
1405 continue;
1406
1407 auto Name = Method->getSelector().getAsString();
1408 SmallString<128> USR;
1410 PresumedLoc Loc =
1411 Context.getSourceManager().getPresumedLoc(Method->getLocation());
1412 DocComment Comment;
1413 if (auto *RawComment =
1414 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1415 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1416 Context.getDiagnostics());
1417
1418 // Build declaration fragments, sub-heading, and signature for the method.
1421 DeclarationFragments SubHeading =
1423 FunctionSignature Signature =
1425
1426 if (Method->isInstanceMethod())
1427 API.createRecord<ObjCInstanceMethodRecord>(
1428 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1430 SubHeading, Signature, isInSystemHeader(Method));
1431 else
1432 API.createRecord<ObjCClassMethodRecord>(
1433 USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1435 SubHeading, Signature, isInSystemHeader(Method));
1436 }
1437}
1438
1439template <typename Derived>
1441 ObjCContainerRecord *Container,
1442 const ObjCContainerDecl::prop_range Properties) {
1443 for (const auto *Property : Properties) {
1444 StringRef Name = Property->getName();
1445 SmallString<128> USR;
1447 PresumedLoc Loc =
1448 Context.getSourceManager().getPresumedLoc(Property->getLocation());
1449 DocComment Comment;
1450 if (auto *RawComment =
1451 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1452 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1453 Context.getDiagnostics());
1454
1455 // Build declaration fragments and sub-heading for the property.
1458 DeclarationFragments SubHeading =
1460
1461 auto GetterName = Property->getGetterName().getAsString();
1462 auto SetterName = Property->getSetterName().getAsString();
1463
1464 // Get the attributes for property.
1465 unsigned Attributes = ObjCPropertyRecord::NoAttr;
1466 if (Property->getPropertyAttributes() &
1468 Attributes |= ObjCPropertyRecord::ReadOnly;
1469
1470 if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1471 API.createRecord<ObjCClassPropertyRecord>(
1474 SubHeading,
1475 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1476 GetterName, SetterName, Property->isOptional(),
1478 else
1479 API.createRecord<ObjCInstancePropertyRecord>(
1482 SubHeading,
1483 static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1484 GetterName, SetterName, Property->isOptional(),
1486 }
1487}
1488
1489template <typename Derived>
1491 ObjCContainerRecord *Container,
1492 const llvm::iterator_range<
1494 Ivars) {
1495 for (const auto *Ivar : Ivars) {
1496 StringRef Name = Ivar->getName();
1497 SmallString<128> USR;
1498 index::generateUSRForDecl(Ivar, USR);
1499
1500 PresumedLoc Loc =
1501 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1502 DocComment Comment;
1503 if (auto *RawComment =
1504 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1505 Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1506 Context.getDiagnostics());
1507
1508 // Build declaration fragments and sub-heading for the instance variable.
1511 DeclarationFragments SubHeading =
1513
1514 API.createRecord<ObjCInstanceVariableRecord>(
1515 USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1517 SubHeading, isInSystemHeader(Ivar));
1518 }
1519}
1520
1521template <typename Derived>
1523 ObjCContainerRecord *Container,
1525 for (const auto *Protocol : Protocols)
1526 Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1527}
1528
1529} // namespace impl
1530
1531/// The RecursiveASTVisitor to traverse symbol declarations and collect API
1532/// information.
1533template <typename Derived = void>
1535 : public impl::ExtractAPIVisitorBase<std::conditional_t<
1536 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1537 using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1538 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1539
1540public:
1542
1543 bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1544 const RawComment *fetchRawCommentForDecl(const Decl *D) const {
1545 if (const auto *Comment = this->Context.getRawCommentNoCache(D))
1546 return Comment;
1547
1548 if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
1549 const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
1550 if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
1551 TagTypeDecl->isCompleteDefinition())
1552 return this->Context.getRawCommentNoCache(TagTypeDecl);
1553 }
1554
1555 return nullptr;
1556 }
1557};
1558
1559} // namespace extractapi
1560} // namespace clang
1561
1562#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:223
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:861
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a C++ constructor within a class.
Definition DeclCXX.h:2633
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2968
Represents a C++ destructor within a class.
Definition DeclCXX.h:2898
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2145
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:2423
bool isRecord() const
Definition DeclBase.h:2206
Decl::Kind getDeclKind() const
Definition DeclBase.h:2119
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition DeclBase.h:824
SourceLocation getLocation() const
Definition DeclBase.h:447
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition DeclBase.h:966
DeclContext * getDeclContext()
Definition DeclBase.h:456
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
Information about one declarator, including the parsed type information and the identifier.
Definition DeclSpec.h:2001
Represents an enum.
Definition Decl.h:4055
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition Decl.h:4198
Represents a member of a struct/union/class.
Definition Decl.h:3204
Represents a function declaration or definition.
Definition Decl.h:2029
@ TK_FunctionTemplateSpecialization
Definition Decl.h:2045
@ TK_DependentFunctionTemplateSpecialization
Definition Decl.h:2048
Declaration of a template function.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
Represent a C++ namespace.
Definition Decl.h:592
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:4369
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:3761
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:3886
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3862
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition Decl.h:3897
The base class of all kinds of template declarations (e.g., class, function, etc.).
The base class of the type hierarchy.
Definition TypeBase.h:1875
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:63
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3711
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3606
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
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:1428
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:125
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:192
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5975
Storage of availability attributes for a declaration.
void mergeWith(AvailabilityInfo Other)
Augments the existing information with additional constraints provided by Other.
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:1405
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.