Add clang_getDeclLine and clang_getDeclColumn
Fix clang_getCursorDecl to do the right thing for expr refs
Fixup test file to accommodate new output (which includes the line/column for the referenced decl)


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82798 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 37f2d86..74b3cfd 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -354,6 +354,22 @@
     return "";
 }
 
+unsigned clang_getDeclLine(CXDecl AnonDecl)
+{
+  assert(AnonDecl && "Passed null CXDecl");
+  NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
+  SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
+  return SourceMgr.getSpellingLineNumber(ND->getLocation());
+}
+
+unsigned clang_getDeclColumn(CXDecl AnonDecl)
+{
+  assert(AnonDecl && "Passed null CXDecl");
+  NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
+  SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
+  return SourceMgr.getSpellingLineNumber(ND->getLocation());
+}
+
 const char *clang_getCursorSpelling(CXCursor C)
 {
   assert(C.decl && "CXCursor has null decl");
@@ -542,9 +558,36 @@
   return C.kind;
 }
 
+static Decl *getDeclFromExpr(Stmt *E) {
+  if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+    return RefExpr->getDecl();
+  if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return ME->getMemberDecl();
+  if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+    return RE->getDecl();
+
+  if (CallExpr *CE = dyn_cast<CallExpr>(E))
+    return getDeclFromExpr(CE->getCallee());
+  if (CastExpr *CE = dyn_cast<CastExpr>(E))
+    return getDeclFromExpr(CE->getSubExpr());
+  if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
+    return OME->getMethodDecl();
+
+  return 0;
+}
+
 CXDecl clang_getCursorDecl(CXCursor C) 
 {
-  return C.decl;
+  if (clang_isDeclaration(C.kind))
+    return C.decl;
+    
+  if (clang_isReference(C.kind)) {
+    if (C.stmt)
+      return getDeclFromExpr(static_cast<Stmt *>(C.stmt));
+    else
+      return C.decl;
+  }
+  return 0;
 }
 
 static SourceLocation getLocationFromCursor(CXCursor C,