14 using namespace clang;
15 using namespace index;
17 #define TRY_DECL(D,CALL_EXPR) \
19 if (!IndexCtx.shouldIndex(D)) return true; \
24 #define TRY_TO(CALL_EXPR) \
32 class IndexingDeclVisitor :
public ConstDeclVisitor<IndexingDeclVisitor, bool> {
37 : IndexCtx(indexCtx) { }
41 bool VisitDecl(
const Decl *D) {
61 IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
64 IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
73 if (
const NamedDecl *TTD = TD->getTemplatedDecl())
84 bool isIBType =
false) {
85 if (!Parent) Parent = D;
91 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
94 if (
const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
95 auto *DC = Parm->getDeclContext();
96 if (
auto *FD = dyn_cast<FunctionDecl>(DC)) {
97 if (FD->isThisDeclarationADefinition())
98 IndexCtx.handleDecl(Parm);
99 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
100 if (MD->isThisDeclarationADefinition())
101 IndexCtx.handleDecl(Parm);
103 IndexCtx.handleDecl(Parm);
105 }
else if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
106 if (FD->isThisDeclarationADefinition()) {
107 for (
auto PI : FD->parameters()) {
108 IndexCtx.handleDecl(PI);
114 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
115 if (FD->isThisDeclarationADefinition()) {
116 for (
const auto *PV : FD->parameters()) {
117 if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
118 !PV->hasUnparsedDefaultArg())
119 IndexCtx.indexBody(PV->getDefaultArg(), D);
132 for(
auto overridden: Overriden) {
149 if (AssociatedProp) {
152 AssociatedProp->getGetterNameLoc():
153 AssociatedProp->getSetterNameLoc();
163 }
else if (AttrLoc.
isValid()) {
164 IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->
getDeclContext()),
168 TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
170 bool hasIBActionAndFirst = D->
hasAttr<IBActionAttr>();
172 handleDeclarator(
I, D, hasIBActionAndFirst);
173 hasIBActionAndFirst =
false;
179 IndexCtx.indexBody(Body, D, D);
192 gatherTemplatePseudoOverrides(
const NamedDecl *D,
194 if (!IndexCtx.getLangOpts().CPlusPlus)
203 if (
const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
205 bool TypeOverride = isa<TypeDecl>(D);
207 if (
const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
208 ND = CTD->getTemplatedDecl();
209 if (ND->isImplicit())
213 if (ND->getKind() != D->
getKind())
215 }
else if (!isa<TypeDecl>(ND))
217 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
218 const auto *DFD = cast<FunctionDecl>(D);
220 if (FD->getStorageClass() != DFD->getStorageClass() ||
221 FD->getNumParams() != DFD->getNumParams())
224 Relations.emplace_back(
233 if (
auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
234 if (CXXMD->isVirtual())
236 for (
auto I = CXXMD->begin_overridden_methods(),
237 E = CXXMD->end_overridden_methods();
I !=
E; ++
I) {
241 gatherTemplatePseudoOverrides(D, Relations);
245 Base->getTemplatedDecl()));
247 TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
251 IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
252 Ctor->getParent(), Ctor->getDeclContext());
255 for (
const auto *Init : Ctor->inits()) {
256 if (Init->isWritten()) {
257 IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
258 if (
const FieldDecl *Member = Init->getAnyMember())
259 IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
261 IndexCtx.indexBody(Init->getInit(), D, D);
265 if (
auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
266 IndexCtx.handleReference(Dtor->getParent(),
267 TypeNameInfo->getTypeLoc().getLocStart(),
268 Dtor->getParent(), Dtor->getDeclContext());
274 for (
const auto &Arg : TemplateArgInfo->arguments())
281 IndexCtx.indexBody(Body, D, D);
287 bool VisitVarDecl(
const VarDecl *D) {
289 gatherTemplatePseudoOverrides(D, Relations);
292 IndexCtx.indexBody(D->
getInit(), D);
297 for (
const auto *Binding : D->
bindings())
298 TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
299 return Base::VisitDecompositionDecl(D);
302 bool VisitFieldDecl(
const FieldDecl *D) {
304 gatherTemplatePseudoOverrides(D, Relations);
319 TRY_DECL(D, IndexCtx.handleDecl(D));
330 TRY_DECL(D, IndexCtx.handleDecl(D));
338 gatherTemplatePseudoOverrides(D, Relations);
345 bool VisitTagDecl(
const TagDecl *D) {
350 gatherTemplatePseudoOverrides(D, Relations);
351 IndexCtx.indexTagDecl(D, Relations);
355 gatherTemplatePseudoOverrides(D, Relations);
356 return IndexCtx.handleReference(D, D->
getLocation(), Parent,
369 I = ProtList.
begin(),
E = ProtList.
end();
I !=
E; ++
I, ++LI) {
375 TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
383 TRY_DECL(D, IndexCtx.handleDecl(D));
386 bool hasSuperTypedef =
false;
388 if (
auto *TT = TInfo->getType()->getAs<
TypedefType>()) {
389 if (
auto *TD = TT->getDecl()) {
390 hasSuperTypedef =
true;
391 TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
399 TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
404 TRY_TO(IndexCtx.indexDeclContext(D));
406 return IndexCtx.handleReference(D, D->
getLocation(),
nullptr,
414 TRY_DECL(D, IndexCtx.handleDecl(D));
417 TRY_TO(IndexCtx.indexDeclContext(D));
419 return IndexCtx.handleReference(D, D->
getLocation(),
nullptr,
431 IndexCtx.handleDecl(Class);
433 TRY_DECL(D, IndexCtx.handleDecl(D));
439 if (
I->getLocation().isInvalid())
440 IndexCtx.indexDecl(
I);
442 for (
const auto *
I : D->
decls()) {
443 if (!isa<ObjCPropertyImplDecl>(
I) ||
444 cast<ObjCPropertyImplDecl>(
I)->getLocation().isValid())
445 IndexCtx.indexDecl(
I);
452 if (!IndexCtx.shouldIndex(D))
462 if (!CategoryLoc.isValid())
463 CategoryLoc = D->getLocation();
464 TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
465 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
467 TRY_TO(IndexCtx.indexDeclContext(D));
482 TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
483 IndexCtx.indexDeclContext(D);
500 handleObjCMethod(MD, D);
503 handleObjCMethod(MD, D);
504 TRY_DECL(D, IndexCtx.handleDecl(D));
505 if (IBOutletCollectionAttr *attr = D->
getAttr<IBOutletCollectionAttr>())
506 IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
521 if (Loc.isInvalid()) {
522 Loc = Container->getLocation();
525 TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
534 if (MD->isPropertyAccessor() &&
535 !hasUserDefined(MD, Container))
536 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
539 if (MD->isPropertyAccessor() &&
540 !hasUserDefined(MD, Container))
541 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
544 if (IvarD->getSynthesize()) {
554 IvarLoc = Container->getLocation();
559 TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
569 TRY_DECL(D, IndexCtx.handleDecl(D));
570 IndexCtx.indexDeclContext(D);
575 TRY_DECL(D, IndexCtx.handleDecl(D));
582 bool VisitUsingDecl(
const UsingDecl *D) {
589 IndexCtx.handleReference(
I->getUnderlyingDecl(), D->
getLocation(), Parent,
610 bool VisitClassTemplateSpecializationDecl(
const
617 const Decl *SpecializationOf =
618 Template.is<ClassTemplateDecl *>()
619 ? (
Decl *)Template.get<ClassTemplateDecl *>()
621 if (!D->isThisDeclarationADefinition())
622 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
623 IndexCtx.indexTagDecl(
627 IndexCtx.indexTypeSourceInfo(TSI,
nullptr,
628 D->getLexicalDeclContext());
632 static
bool shouldIndexTemplateParameterDefaultValue(const
NamedDecl *D) {
637 if (
const auto *FD = dyn_cast<FunctionDecl>(D))
638 return FD->getCanonicalDecl() == FD;
639 else if (
const auto *TD = dyn_cast<TagDecl>(D))
640 return TD->getCanonicalDecl() == TD;
641 else if (
const auto *VD = dyn_cast<VarDecl>(D))
642 return VD->getCanonicalDecl() == VD;
652 shouldIndexTemplateParameterDefaultValue(Parent)) {
655 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
656 if (TTP->hasDefaultArgument())
657 IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
658 }
else if (
const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
659 if (NTTP->hasDefaultArgument())
660 IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
661 }
else if (
const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
662 if (TTPD->hasDefaultArgument())
663 handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
685 IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->
getDeclContext()));
691 return IndexCtx.importedModule(D);
704 bool IndexingContext::indexDecl(
const Decl *D) {
705 if (D->
isImplicit() && shouldIgnoreIfImplicit(D))
711 IndexingDeclVisitor Visitor(*
this);
712 bool ShouldContinue = Visitor.Visit(D);
716 if (!Visitor.Handled && isa<DeclContext>(D))
723 for (
const auto *
I : DC->
decls())
733 if (isa<ObjCMethodDecl>(D))
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Represents a relation to another symbol for a symbol occurrence.
ObjCInterfaceDecl * getClassInterface()
bool isBitField() const
Determines whether this field is a bitfield.
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
Stmt - This represents one statement.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
#define TRY_DECL(D, CALL_EXPR)
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
const Expr * getInitExpr() const
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
The template argument is an expression, and we've not resolved it to one of the other forms yet...
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Decl - This represents one declaration (or definition), e.g.
bool indexTopLevelDecl(const Decl *D)
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const Expr * getInit() const
NamespaceDecl - Represent a C++ namespace.
A container of type source information.
Represents a C++ constructor within a class.
Expr * getInClassInitializer() const
getInClassInitializer - Get the C++11 in-class initializer for this member, or null if one has not be...
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
TRY_TO(TraverseType(T->getPointeeType()))
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TypeSourceInfo * getSuperClassTInfo() const
ObjCMethodDecl - Represents an instance or class method declaration.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Stores a list of template parameters for a TemplateDecl and its derived classes.
unsigned param_size() const
ParmVarDecl - Represents a parameter to a function.
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
TypeSourceInfo * getTypeSourceInfo() const
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Kind getPropertyImplementation() const
ObjCProtocolList::iterator protocol_iterator
return(__x >> __y)|(__x<< (32-__y))
Represents a class template specialization, which refers to a class template with a given set of temp...
SourceLocation getSelectorStartLoc() const
SymbolRole
Set of roles that are attributed to symbol occurrences.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition() - Return true if this declaration is a completion definition of the ty...
Represents a C++ using-declaration.
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
ObjCContainerDecl - Represents a container for method declarations.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
NamedDecl * getNominatedNamespaceAsWritten()
NestedNameSpecifierLoc getTemplateQualifierLoc() const
bool indexDecl(const Decl *D)
Represents an Objective-C protocol declaration.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
SourceLocation getTemplateNameLoc() const
ArrayRef< BindingDecl * > bindings() const
Represents an ObjC class declaration.
propimpl_range property_impls() const
detail::InMemoryDirectory::const_iterator I
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Represents a ValueDecl that came out of a declarator.
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getBitWidth() const
bool indexDeclContext(const DeclContext *DC)
Represents a C++ destructor within a class.
ArgKind getKind() const
Return the kind of stored template argument.
DeclContext * getDeclContext()
bool indexDeclGroupRef(DeclGroupRef DG)
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
static bool isTemplateImplicitInstantiation(const Decl *D)
bool isInstanceMethod() const
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
shadow_range shadows() const
TypeSourceInfo * getTypeSourceInfo() const
TypeSourceInfo * getReturnTypeSourceInfo() const
ObjCCategoryDecl * getCategoryDecl() const
ArrayRef< ParmVarDecl * > parameters() const
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
TagDecl - Represents the declaration of a struct/union/class/enum.
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
bool getSynthesize() const
ObjCCategoryDecl - Represents a category declaration.
const ObjCInterfaceDecl * getClassInterface() const
bool isPropertyAccessor() const
Represents one property declaration in an Objective-C interface.
loc_iterator loc_begin() const
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Represents a C++11 static_assert declaration.
SourceLocation getCategoryNameLoc() const
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Base class for declarations which introduce a typedef-name.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
const ObjCProtocolList & getReferencedProtocols() const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
The base class of all kinds of template declarations (e.g., class, function, etc.).
The template argument is a pack expansion of a template name that was provided for a template templat...
bool isFreeStanding() const
A decomposition declaration.
SourceLocation getPropertyIvarDeclLoc() const
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Selector getSelector() const
detail::InMemoryDirectory::const_iterator E
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
ObjCMethodDecl * getGetterMethodDecl() const
Location wrapper for a TemplateArgument.
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
ObjCMethodDecl * getSetterMethodDecl() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
A list of Objective-C protocols, along with the source locations at which they were referenced...
const ObjCProtocolList & getReferencedProtocols() const
The template argument is a type.
TemplateArgumentLocInfo getLocInfo() const
ObjCPropertyDecl * getPropertyDecl() const
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Represents a C++ struct/union/class.
The template argument is a template name that was provided for a template template parameter...
ObjCIvarDecl - Represents an ObjC instance variable.
Location information for a TemplateArgument.
Declaration of a class template.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
ObjCInterfaceDecl * getSuperClass() const
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
An instance of this class represents the declaration of a property member.
SourceLocation getLocation() const
NamedDecl - This represents a decl with a name.
Represents a C++ namespace alias.
Represents C++ using-directive.
TypeSourceInfo * getTypeSourceInfo() const
A simple visitor class that helps create declaration visitors.
const TemplateArgument & getArgument() const
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
bool hasInClassInitializer() const
hasInClassInitializer - Determine whether this member has a C++11 in-class initializer.