diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-13 18:47:41 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-13 18:47:41 +0000 |
commit | e422e45a6a89d450b8eca10f671b49874e87617a (patch) | |
tree | be55d8a6c74db604e5d83cb474c96ceeefe39274 | |
parent | c2be04eaec94e20fc825fb98b713112d9d82562f (diff) |
[libclang] Indexing API: Fix indexing of missed references.
rdar://10567864&10567916
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146497 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 5 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 2 | ||||
-rw-r--r-- | test/Index/index-refs.cpp | 37 | ||||
-rw-r--r-- | tools/libclang/IndexBody.cpp | 46 | ||||
-rw-r--r-- | tools/libclang/IndexDecl.cpp | 28 | ||||
-rw-r--r-- | tools/libclang/IndexTypeSourceInfo.cpp | 46 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 9 |
7 files changed, 142 insertions, 31 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 65e98ade51..8b0aed17a6 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -4311,11 +4311,12 @@ typedef struct { * \endcode * * The parent of reference of type 'Foo' is the variable 'var'. - * parentEntity will be null for references inside statement bodies. + * For references inside statement bodies of functions/methods, + * the parentEntity will be the function/method. */ const CXIdxEntityInfo *parentEntity; /** - * \brief Container context of the reference. + * \brief Lexical container context of the reference. */ const CXIdxContainerInfo *container; } CXIdxEntityRefInfo; diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index cca85ac865..2bc85a569e 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1566,6 +1566,8 @@ DEF_TRAVERSE_DECL(FieldDecl, { TRY_TO(TraverseDeclaratorHelper(D)); if (D->isBitField()) TRY_TO(TraverseStmt(D->getBitWidth())); + else if (D->hasInClassInitializer()) + TRY_TO(TraverseStmt(D->getInClassInitializer())); }) DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, { diff --git a/test/Index/index-refs.cpp b/test/Index/index-refs.cpp new file mode 100644 index 0000000000..0b3c0bc423 --- /dev/null +++ b/test/Index/index-refs.cpp @@ -0,0 +1,37 @@ + +namespace NS { + extern int gx; + typedef int MyInt; +} + +enum { + EnumVal = 1 +}; + +NS::MyInt NS::gx = EnumVal; + +void foo() { + NS::MyInt x; +} + +enum { + SecondVal = EnumVal +}; + +// RUN: c-index-test -index-file %s | FileCheck %s +// CHECK: [indexDeclaration]: kind: namespace | name: NS +// CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx +// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt +// CHECK-NEXT: [indexDeclaration]: kind: enum +// CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: EnumVal +// CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx +// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS +// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: MyInt +// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS +// CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal +// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo +// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS +// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: MyInt +// CHECK-NEXT: [indexDeclaration]: kind: enum +// CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: SecondVal +// CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp index 9418ed7bb1..bac7e02514 100644 --- a/tools/libclang/IndexBody.cpp +++ b/tools/libclang/IndexBody.cpp @@ -19,43 +19,49 @@ namespace { class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> { IndexingContext &IndexCtx; + const NamedDecl *Parent; const DeclContext *ParentDC; bool InPseudoObject; typedef RecursiveASTVisitor<BodyIndexer> base; public: - BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC) - : IndexCtx(indexCtx), ParentDC(DC), InPseudoObject(false) { } + BodyIndexer(IndexingContext &indexCtx, + const NamedDecl *Parent, const DeclContext *DC) + : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC), + InPseudoObject(false) { } bool shouldWalkTypesOfTypeLocs() const { return false; } bool TraverseTypeLoc(TypeLoc TL) { - IndexCtx.indexTypeLoc(TL, 0, ParentDC); + IndexCtx.indexTypeLoc(TL, Parent, ParentDC); return true; } bool VisitDeclRefExpr(DeclRefExpr *E) { - IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E); + IndexCtx.handleReference(E->getDecl(), E->getLocation(), + Parent, ParentDC, E); return true; } bool VisitMemberExpr(MemberExpr *E) { - IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 0, ParentDC, - E); + IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), + Parent, ParentDC, E); return true; } bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { - IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E); + IndexCtx.handleReference(E->getDecl(), E->getLocation(), + Parent, ParentDC, E); return true; } bool VisitObjCMessageExpr(ObjCMessageExpr *E) { if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) - IndexCtx.indexTypeSourceInfo(Cls, 0, ParentDC); + IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC); if (ObjCMethodDecl *MD = E->getMethodDecl()) - IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 0, ParentDC, E, + IndexCtx.handleReference(MD, E->getSelectorStartLoc(), + Parent, ParentDC, E, InPseudoObject ? CXIdxEntityRef_Implicit : CXIdxEntityRef_Direct); return true; @@ -64,14 +70,14 @@ public: bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { if (E->isImplicitProperty()) { if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter()) - IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E, + IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, CXIdxEntityRef_Implicit); if (ObjCMethodDecl *MD = E->getImplicitPropertySetter()) - IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E, + IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, CXIdxEntityRef_Implicit); } else { - IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 0, - ParentDC, E); + IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), + Parent, ParentDC, E); } return true; } @@ -82,14 +88,20 @@ public: } bool VisitCXXConstructExpr(CXXConstructExpr *E) { - IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 0, - ParentDC, E); + IndexCtx.handleReference(E->getConstructor(), E->getLocation(), + Parent, ParentDC, E); return true; } }; } // anonymous namespace -void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) { - BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S)); +void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent, + const DeclContext *DC) { + if (!S) + return; + + if (DC == 0) + DC = Parent->getLexicalDeclContext(); + BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S)); } diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp index 84c1134501..0d6dacb775 100644 --- a/tools/libclang/IndexDecl.cpp +++ b/tools/libclang/IndexDecl.cpp @@ -23,13 +23,19 @@ public: explicit IndexingDeclVisitor(IndexingContext &indexCtx) : IndexCtx(indexCtx) { } + void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) { + if (!Parent) Parent = D; + IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent); + IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent); + } + bool VisitFunctionDecl(FunctionDecl *D) { IndexCtx.handleFunction(D); - IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); + handleDeclarator(D); if (D->isThisDeclarationADefinition()) { const Stmt *Body = D->getBody(); if (Body) { - IndexCtx.indexBody(Body, D); + IndexCtx.indexBody(Body, D, D); } } return true; @@ -37,18 +43,24 @@ public: bool VisitVarDecl(VarDecl *D) { IndexCtx.handleVar(D); - IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); + handleDeclarator(D); + IndexCtx.indexBody(D->getInit(), D); return true; } bool VisitFieldDecl(FieldDecl *D) { IndexCtx.handleField(D); - IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); + handleDeclarator(D); + if (D->isBitField()) + IndexCtx.indexBody(D->getBitWidth(), D); + else if (D->hasInClassInitializer()) + IndexCtx.indexBody(D->getInClassInitializer(), D); return true; } bool VisitEnumConstantDecl(EnumConstantDecl *D) { IndexCtx.handleEnumerator(D); + IndexCtx.indexBody(D->getInitExpr(), D); return true; } @@ -147,12 +159,12 @@ public: IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) - IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D); + handleDeclarator(*I, D); if (D->isThisDeclarationADefinition()) { const Stmt *Body = D->getBody(); if (Body) { - IndexCtx.indexBody(Body, D); + IndexCtx.indexBody(Body, D, D); } } return true; @@ -205,11 +217,11 @@ public: bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { IndexCtx.handleFunctionTemplate(D); FunctionDecl *FD = D->getTemplatedDecl(); - IndexCtx.indexTypeSourceInfo(FD->getTypeSourceInfo(), D); + handleDeclarator(FD, D); if (FD->isThisDeclarationADefinition()) { const Stmt *Body = FD->getBody(); if (Body) { - IndexCtx.indexBody(Body, FD); + IndexCtx.indexBody(Body, D, FD); } } return true; diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp index 04ed329f3b..1b2069d30d 100644 --- a/tools/libclang/IndexTypeSourceInfo.cpp +++ b/tools/libclang/IndexTypeSourceInfo.cpp @@ -34,6 +34,11 @@ public: return true; } + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { + IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC); + return true; + } + bool VisitTagTypeLoc(TagTypeLoc TL) { TagDecl *D = TL.getDecl(); if (D->getParentFunctionOrMethod()) @@ -75,17 +80,54 @@ void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo, if (!TInfo || TInfo->getTypeLoc().isNull()) return; - if (DC == 0) - DC = Parent->getDeclContext(); indexTypeLoc(TInfo->getTypeLoc(), Parent, DC); } void IndexingContext::indexTypeLoc(TypeLoc TL, const NamedDecl *Parent, const DeclContext *DC) { + if (TL.isNull()) + return; + + if (DC == 0) + DC = Parent->getLexicalDeclContext(); TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL); } +void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, + const NamedDecl *Parent, + const DeclContext *DC) { + if (!NNS) + return; + + if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) + indexNestedNameSpecifierLoc(Prefix, Parent, DC); + + if (DC == 0) + DC = Parent->getLexicalDeclContext(); + SourceLocation Loc = NNS.getSourceRange().getBegin(); + + switch (NNS.getNestedNameSpecifier()->getKind()) { + case NestedNameSpecifier::Identifier: + case NestedNameSpecifier::Global: + break; + + case NestedNameSpecifier::Namespace: + handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(), + Loc, Parent, DC); + break; + case NestedNameSpecifier::NamespaceAlias: + handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), + Loc, Parent, DC); + break; + + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + indexTypeLoc(NNS.getTypeLoc(), Parent, DC); + break; + } +} + void IndexingContext::indexTagDecl(const TagDecl *D) { if (handleTagDecl(D)) { if (D->isThisDeclarationADefinition()) diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index 64e3a3c5d4..1ad1d809ee 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -334,11 +334,16 @@ public: const DeclContext *DC = 0); void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent, - const DeclContext *DC); + const DeclContext *DC = 0); + + void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, + const NamedDecl *Parent, + const DeclContext *DC = 0); void indexDeclContext(const DeclContext *DC); - void indexBody(const Stmt *S, const DeclContext *DC); + void indexBody(const Stmt *S, const NamedDecl *Parent, + const DeclContext *DC = 0); void handleDiagnosticSet(CXDiagnosticSet CXDiagSet); |