14#ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
15#define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
32#include "llvm/ADT/SmallString.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/Casting.h"
41template <
typename Derived>
144 const llvm::iterator_range<
166 Derived &getDerivedExtractAPIVisitor() {
167 return *
static_cast<Derived *
>(
this);
172 if (!
Decl->isCompleteDefinition()) {
178 for (
const auto &BaseSpecifier :
Decl->bases()) {
182 if (
auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) {
186 BaseClass.
Name =
API.copyString(BaseSpecifier.getType().getAsString(
189 if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
190 if (
auto *TTPTD = BaseSpecifier.getType()
191 ->getAs<TemplateTypeParmType>()
195 BaseClass.USR =
API.copyString(USR);
199 Bases.emplace_back(BaseClass);
208 if (
Decl->isStruct())
216 return OwningModule->getTopLevelModule()->Name;
239 if (
auto *ND = dyn_cast<NamedDecl>(&D))
240 Name = ND->getName();
252 if (!NewRecordContext)
257 Tag = AT->getElementType()->getAsTagDecl();
262 if (
auto *
Record = llvm::dyn_cast_if_present<TagRecord>(
263 API.findRecordForUSR(TagUSR))) {
264 if (
Record->IsEmbeddedInVarDeclarator) {
272template <
typename Derived>
292 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
296 StringRef Name =
Decl->getName();
304 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
313 if (
Decl->isStaticDataMember()) {
334template <
typename Derived>
337 if (
const auto *
Method = dyn_cast<CXXMethodDecl>(
Decl)) {
339 if (
Method->getParent()->getDescribedClassTemplate() !=
nullptr)
344 if (P.template get<CXXRecordDecl>())
354 switch (
Decl->getTemplatedKind()) {
365 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
369 auto Name =
Decl->getNameAsString();
377 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
386 if (
Decl->getTemplateSpecializationInfo())
403template <
typename Derived>
405 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
414 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
427 if (
Decl->hasNameForLinkage()) {
428 StringRef Name =
Decl->getName();
440 ParentContainer = {};
444 getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
445 Decl->enumerators());
450template <
typename Derived>
453 getDerivedExtractAPIVisitor().VisitFunctionDecl(
Decl);
457template <
typename Derived>
460 getDerivedExtractAPIVisitor().VisitRecordDecl(
Decl);
464template <
typename Derived>
467 getDerivedExtractAPIVisitor().VisitCXXRecordDecl(
Decl);
471template <
typename Derived>
474 getDerivedExtractAPIVisitor().VisitCXXMethodDecl(
Decl);
478template <
typename Derived>
481 getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(
Decl);
485template <
typename Derived>
489 getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
494template <
typename Derived>
497 getDerivedExtractAPIVisitor().VisitVarTemplateDecl(
Decl);
501template <
typename Derived>
504 getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(
Decl);
508template <
typename Derived>
512 getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(
Decl);
516template <
typename Derived>
519 getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(
Decl);
523template <
typename Derived>
526 getDerivedExtractAPIVisitor().VisitNamespaceDecl(
Decl);
530template <
typename Derived>
533 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
535 if (
Decl->isAnonymousNamespace())
537 StringRef Name =
Decl->getName();
545 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
562template <
typename Derived>
564 bool Ret = Base::TraverseRecordDecl(
Decl);
569 API.removeRecord(USR);
575template <
typename Derived>
577 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
581 StringRef Name =
Decl->getName();
591 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
619template <
typename Derived>
622 bool Ret = Base::TraverseCXXRecordDecl(
Decl);
627 API.removeRecord(USR);
633template <
typename Derived>
636 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl) ||
640 StringRef Name =
Decl->getName();
650 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
661 if (
Decl->getDescribedClassTemplate()) {
665 Decl->getDescribedClassTemplate()));
669 SubHeading,
Template(
Decl->getDescribedClassTemplate()), Access,
685template <
typename Derived>
688 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl) ||
703 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
712 Decl->getDescribedFunctionTemplate()) {
721 }
else if (
Decl->getTemplateSpecializationInfo())
726 getFragmentsForFunctionTemplateSpecialization(
Decl),
728 else if (
Decl->isOverloadedOperator())
734 else if (
Decl->isStatic())
750template <
typename Derived>
753 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl) ||
757 auto Name =
Decl->getNameAsString();
764 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
784template <
typename Derived>
787 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl) ||
791 auto Name =
Decl->getNameAsString();
798 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
817template <
typename Derived>
819 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
822 StringRef Name =
Decl->getName();
829 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
843template <
typename Derived>
846 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
849 StringRef Name =
Decl->getName();
856 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
876template <
typename Derived>
880 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
883 StringRef Name =
Decl->getName();
890 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
909template <
typename Derived>
912 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
916 StringRef Name =
Decl->getName();
924 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
934 Decl->getTemplatedDecl()));
953template <
typename Derived>
956 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
960 StringRef Name =
Decl->getName();
968 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
985template <
typename Derived>
988 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
992 StringRef Name =
Decl->getName();
1000 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1016template <
typename Derived>
1021 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1025 auto Name =
Decl->getNameAsString();
1033 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1041 Decl->getTemplatedDecl());
1051template <
typename Derived>
1054 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1058 StringRef Name =
Decl->getName();
1066 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1078 if (
const auto *SuperClassDecl =
Decl->getSuperClass())
1088 getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1090 getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1091 Decl->properties());
1092 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1094 getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1100template <
typename Derived>
1103 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1107 StringRef Name =
Decl->getName();
1114 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1129 getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord,
Decl->methods());
1130 getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1131 Decl->properties());
1132 getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1138template <
typename Derived>
1148 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1151 StringRef Name =
Decl->getName();
1156 if (TagName == Name)
1161 if (TagName.starts_with(
'_')) {
1162 StringRef StrippedName = TagName.ltrim(
'_');
1164 if (StrippedName == Name)
1173 if (
auto *
TagDecl =
Decl->getUnderlyingType()->getAsTagDecl()) {
1178 if (
auto *
Record =
API.findRecordForUSR(TagUSR)) {
1180 LeadingFragments.
append(
"typedef",
1183 Record->Declaration.removeTrailingSemicolon()
1184 .prepend(std::move(LeadingFragments))
1205 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1224template <
typename Derived>
1227 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1230 StringRef Name =
Decl->getName();
1237 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1254 getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1256 getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1257 Decl->properties());
1258 getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1260 getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1268template <
typename Derived>
1271 for (
const auto *
Constant : Constants) {
1273 StringRef Name =
Constant->getName();
1280 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Constant))
1296template <
typename Derived>
1302 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl))
1306 StringRef Name =
Decl->getName();
1313 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1351template <
typename Derived>
1354 if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(
Decl) ||
1358 auto Name =
Decl->getNameAsString();
1365 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Decl))
1378 if (
Decl->isStatic())
1394template <
typename Derived>
1398 for (
const auto *
Method : Methods) {
1400 if (
Method->isPropertyAccessor())
1403 auto Name =
Method->getSelector().getAsString();
1407 Context.getSourceManager().getPresumedLoc(
Method->getLocation());
1410 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Method))
1422 if (
Method->isInstanceMethod())
1435template <
typename Derived>
1439 for (
const auto *
Property : Properties) {
1440 StringRef Name =
Property->getName();
1447 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(
Property))
1457 auto GetterName =
Property->getGetterName().getAsString();
1458 auto SetterName =
Property->getSetterName().getAsString();
1462 if (
Property->getPropertyAttributes() &
1472 GetterName, SetterName,
Property->isOptional(),
1480 GetterName, SetterName,
Property->isOptional(),
1485template <
typename Derived>
1488 const llvm::iterator_range<
1491 for (
const auto *Ivar : Ivars) {
1492 StringRef Name = Ivar->getName();
1497 Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1500 getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1517template <
typename Derived>
1521 for (
const auto *Protocol : Protocols)
1529template <
typename Derived =
void>
1532 std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1541 if (
const auto *Comment = this->
Context.getRawCommentNoCache(D))
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.getRawCommentNoCache(TagTypeDecl);
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
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 ...
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
Represents a C++ struct/union/class.
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,...
Decl::Kind getDeclKind() const
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
SourceLocation getLocation() const
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
Represents a ValueDecl that came out of a declarator.
Information about one declarator, including the parsed type information and the identifier.
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Represents a member of a struct/union/class.
Represents a function declaration or definition.
@ TK_MemberSpecialization
@ TK_DependentNonTemplate
@ TK_FunctionTemplateSpecialization
@ TK_DependentFunctionTemplateSpecialization
Declaration of a template function.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represent a C++ namespace.
ObjCCategoryDecl - Represents a category declaration.
llvm::iterator_range< specific_decl_iterator< ObjCMethodDecl > > method_range
llvm::iterator_range< specific_decl_iterator< ObjCPropertyDecl > > prop_range
Represents an ObjC class declaration.
llvm::iterator_range< protocol_iterator > protocol_range
Represents an Objective-C protocol declaration.
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Represents a struct/union/class.
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.
bool isEmbeddedInDeclarator() const
True if this tag declaration is "embedded" (i.e., defined or declared for the very first time) in the...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
The base class of all kinds of template declarations (e.g., class, function, etc.).
The base class of the type hierarchy.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Base class for declarations which introduce a typedef-name.
Represents a variable declaration or definition.
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Property
The type of a property.
@ Template
We are parsing a template declaration.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
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)