Add support for 'CXFile' (<rdar://problem/7303360>).

- 4 new functions (clang_getCursorSourceFile, clang_getDeclSourceFile, clang_getFileName, clang_getFileTime).

- Should remove clang_getDeclSource() and clang_getCursorSource(). For now, just put 'deprecate' comment in header. 

- Also changed CXX style comment to C style (to eliminate warning).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85238 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index cbc1df9..0d41edb 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -16,11 +16,13 @@
 #ifndef CLANG_C_INDEX_H
 #define CLANG_C_INDEX_H
 
+#include <sys/stat.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-// MSVC DLL import/export.
+/* MSVC DLL import/export. */
 #ifdef _MSC_VER
   #ifdef _CINDEX_LIB_
     #define CINDEX_LINKAGE __declspec(dllexport)
@@ -44,6 +46,7 @@
 
 typedef void *CXTranslationUnit;  /* A translation unit instance. */
 
+typedef void *CXFile;    /* A source file */
 typedef void *CXDecl;    /* A specific declaration within a translation unit. */
 typedef void *CXStmt;    /* A specific statement within a function/method */
 
@@ -241,6 +244,12 @@
 CINDEX_LINKAGE void clang_loadDeclaration(CXDecl, CXDeclIterator, CXClientData);
 
 /*
+ * CXFile Operations.
+ */
+const char *clang_getFileName(CXFile SFile);
+time_t clang_getFileTime(CXFile SFile);
+
+/*
  * CXEntity Operations.
  */
 CINDEX_LINKAGE const char *clang_getDeclarationName(CXEntity);
@@ -254,7 +263,8 @@
 CINDEX_LINKAGE const char *clang_getDeclSpelling(CXDecl);
 CINDEX_LINKAGE unsigned clang_getDeclLine(CXDecl);
 CINDEX_LINKAGE unsigned clang_getDeclColumn(CXDecl);
-CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl);
+CINDEX_LINKAGE const char *clang_getDeclSource(CXDecl); /* deprecate */
+CINDEX_LINKAGE CXFile clang_getDeclSourceFile(CXDecl);
 
 /*
  * CXCursor Operations.
@@ -289,8 +299,9 @@
 
 CINDEX_LINKAGE unsigned clang_getCursorLine(CXCursor);
 CINDEX_LINKAGE unsigned clang_getCursorColumn(CXCursor);
-CINDEX_LINKAGE const char *clang_getCursorSource(CXCursor);
 CINDEX_LINKAGE const char *clang_getCursorSpelling(CXCursor);
+CINDEX_LINKAGE const char *clang_getCursorSource(CXCursor); /* deprecate */
+CINDEX_LINKAGE CXFile clang_getCursorSourceFile(CXCursor);
 
 /* for debug/testing */
 CINDEX_LINKAGE const char *clang_getCursorKindSpelling(enum CXCursorKind Kind); 
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index f044f89..5ffa6d7 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -571,9 +571,40 @@
 const char *clang_getDeclSource(CXDecl AnonDecl) 
 {
   assert(AnonDecl && "Passed null CXDecl");
+  FileEntry *FEnt = static_cast<FileEntry *>(clang_getDeclSourceFile(AnonDecl));
+  assert (FEnt && "Cannot find FileEntry for Decl");
+  return clang_getFileName(FEnt);
+}
+
+static const FileEntry *getFileEntryFromSourceLocation(SourceManager &SMgr,
+                                                       SourceLocation SLoc) 
+{
+  FileID FID;
+  if (SLoc.isFileID())
+    FID = SMgr.getFileID(SLoc);
+  else
+    FID = SMgr.getDecomposedSpellingLoc(SLoc).first;
+  return SMgr.getFileEntryForID(FID);
+}
+
+CXFile clang_getDeclSourceFile(CXDecl AnonDecl) 
+{
+  assert(AnonDecl && "Passed null CXDecl");
   NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
   SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
-  return SourceMgr.getBufferName(ND->getLocation());
+  return (void *)getFileEntryFromSourceLocation(SourceMgr, ND->getLocation());
+}
+
+const char *clang_getFileName(CXFile SFile) {
+  assert(SFile && "Passed null CXFile");
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return FEnt->getName();
+}
+
+time_t clang_getFileTime(CXFile SFile) {
+  assert(SFile && "Passed null CXFile");
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return FEnt->getModificationTime();
 }
 
 const char *clang_getCursorSpelling(CXCursor C)
@@ -930,6 +961,16 @@
   return Buffer->getBufferIdentifier();
 }
 
+CXFile clang_getCursorSourceFile(CXCursor C)
+{
+  assert(C.decl && "CXCursor has null decl");
+  NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
+  SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
+  
+  return (void *)getFileEntryFromSourceLocation(SourceMgr,
+                                        getLocationFromCursor(C,SourceMgr, ND));
+}
+
 void clang_getDefinitionSpellingAndExtent(CXCursor C, 
                                           const char **startBuf,
                                           const char **endBuf,
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
index e9d44a0..b726aa0 100644
--- a/tools/CIndex/CIndex.exports
+++ b/tools/CIndex/CIndex.exports
@@ -30,3 +30,7 @@
 _clang_getCursorKindSpelling
 _clang_getDefinitionSpellingAndExtent
 _clang_getTranslationUnitSpelling
+_clang_getCursorSourceFile
+_clang_getDeclSourceFile
+_clang_getFileName
+_clang_getFileTime