More work to enable more exhaustive testing of the indexing API.

Next step: Add actual some test cases:-)


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82636 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index d0c1ea5..37f2d86 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -28,6 +28,21 @@
 
 namespace {
 
+static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE) 
+{
+  NamedDecl *D = DRE->getDecl();
+  if (isa<VarDecl>(D))
+    return CXCursor_VarRef;
+  else if (isa<FunctionDecl>(D))
+    return CXCursor_FunctionRef;
+  else if (isa<EnumConstantDecl>(D))
+    return CXCursor_EnumConstantRef;
+  else 
+    return CXCursor_NotImplemented;
+}
+
+#if 0
+// Will be useful one day.
 class CRefVisitor : public StmtVisitor<CRefVisitor> {
   CXDecl CDecl;
   CXDeclIterator Callback;
@@ -48,13 +63,7 @@
       Visit(*C);
   }
   void VisitDeclRefExpr(DeclRefExpr *Node) {
-    NamedDecl *D = Node->getDecl();
-    if (isa<VarDecl>(D))
-      Call(CXCursor_VarRef, Node);
-    else if (isa<FunctionDecl>(D))
-      Call(CXCursor_FunctionRef, Node);
-    else if (isa<EnumConstantDecl>(D))
-      Call(CXCursor_EnumConstantRef, Node);
+    Call(TranslateDeclRefExpr(Node), Node);
   }
   void VisitMemberExpr(MemberExpr *Node) {
     Call(CXCursor_MemberRef, Node);
@@ -66,6 +75,7 @@
     Call(CXCursor_ObjCIvarRef, Node);
   }
 };
+#endif
 
 // Translation Unit Visitor.
 class TUVisitor : public DeclVisitor<TUVisitor> {
@@ -208,9 +218,12 @@
   void VisitFunctionDecl(FunctionDecl *ND) {
     if (ND->isThisDeclarationADefinition()) {
       VisitDeclContext(dyn_cast<DeclContext>(ND));
-      
+#if 0
+      // Not currently needed.
+      CompoundStmt *Body = dyn_cast<CompoundStmt>(ND->getBody());
       CRefVisitor RVisit(CDecl, Callback, CData);
-      RVisit.Visit(ND->getBody());
+      RVisit.Visit(Body);
+#endif
     }
   }
   void VisitObjCMethodDecl(ObjCMethodDecl *ND) {
@@ -476,7 +489,18 @@
   ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc);
   
   Decl *Dcl = ALoc.getDecl();
-  if (Dcl) {  
+  Stmt *Stm = ALoc.getStmt();
+  if (Dcl) {
+    if (Stm) {
+      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Stm)) {
+        CXCursor C = { TranslateDeclRefExpr(DRE), Dcl, Stm };
+        return C;
+      } else if (ObjCMessageExpr *MExp = dyn_cast<ObjCMessageExpr>(Stm)) {
+        CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp };
+        return C;
+      }
+      // Fall through...treat as a decl, not a ref.
+    }
     CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
     return C;
   }
@@ -613,4 +637,27 @@
   return SourceMgr.getBufferName(SLoc);
 }
 
+void clang_getDefinitionSpellingAndExtent(CXCursor C, 
+                                          const char **startBuf,
+                                          const char **endBuf,
+                                          unsigned *startLine,
+                                          unsigned *startColumn,
+                                          unsigned *endLine,
+                                          unsigned *endColumn) 
+{
+  assert(C.decl && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
+  
+  SourceManager &SM = FD->getASTContext().getSourceManager();
+  *startBuf = SM.getCharacterData(Body->getLBracLoc());
+  *endBuf = SM.getCharacterData(Body->getRBracLoc());
+  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
+  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
+  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
+  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
+}
+
+
 } // end extern "C"