[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
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 9418ed7..bac7e02 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -19,43 +19,49 @@
 
 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 @@
   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 @@
   }
 
   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 84c1134..0d6dacb 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -23,13 +23,19 @@
   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 @@
 
   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 @@
     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 @@
   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 04ed329..1b2069d 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -34,6 +34,11 @@
     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 @@
   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 64e3a3c..1ad1d80 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -334,11 +334,16 @@
                            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);