aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-12-13 18:47:41 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-12-13 18:47:41 +0000
commite422e45a6a89d450b8eca10f671b49874e87617a (patch)
treebe55d8a6c74db604e5d83cb474c96ceeefe39274
parentc2be04eaec94e20fc825fb98b713112d9d82562f (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.h5
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--test/Index/index-refs.cpp37
-rw-r--r--tools/libclang/IndexBody.cpp46
-rw-r--r--tools/libclang/IndexDecl.cpp28
-rw-r--r--tools/libclang/IndexTypeSourceInfo.cpp46
-rw-r--r--tools/libclang/IndexingContext.h9
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);