]> granicus.if.org Git - clang/commitdiff
[libclang] Add clang_File_tryGetRealPathName
authorFangrui Song <maskray@google.com>
Sat, 7 Apr 2018 20:50:35 +0000 (20:50 +0000)
committerFangrui Song <maskray@google.com>
Sat, 7 Apr 2018 20:50:35 +0000 (20:50 +0000)
Summary:
clang_getFileName() may return a path relative to WorkingDir.
On Arch Linux, during clang_indexTranslationUnit(), clang_getFileName() on
CXIdxIncludedIncludedFileInfo::file may return
"/../lib64/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../include/c++/7.3.0/string",
for `#include <string>`.

I presume WorkingDir is somehow changed to /usr/lib or /usr/include and
clang_getFileName() returns a path relative to WorkingDir.

clang_File_tryGetRealPathName() returns "/usr/include/c++/7.3.0/string"
which is more useful for the indexer in this case.

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D42893

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@329515 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang-c/Index.h
tools/libclang/CIndex.cpp
tools/libclang/libclang.exports
unittests/libclang/LibclangTest.cpp

index cc43b6a535990e93b18f6ffabe8ade2abad11887..e8dcfdf035049d767db010397a183724f3b2255c 100644 (file)
@@ -424,6 +424,13 @@ CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu,
  */
 CINDEX_LINKAGE int clang_File_isEqual(CXFile file1, CXFile file2);
 
+/**
+ * \brief Returns the real path name of \c file.
+ *
+ * An empty string may be returned. Use \c clang_getFileName() in that case.
+ */
+CINDEX_LINKAGE CXString clang_File_tryGetRealPathName(CXFile file);
+
 /**
  * @}
  */
index 743057182962b3d884f56439a7ed14ffb0ff995a..480e00eb962b25d3405739e6def9ec119bfee909 100644 (file)
@@ -4249,6 +4249,14 @@ int clang_File_isEqual(CXFile file1, CXFile file2) {
   return FEnt1->getUniqueID() == FEnt2->getUniqueID();
 }
 
+CXString clang_File_tryGetRealPathName(CXFile SFile) {
+  if (!SFile)
+    return cxstring::createNull();
+
+  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
+  return cxstring::createRef(FEnt->tryGetRealPathName());
+}
+
 //===----------------------------------------------------------------------===//
 // CXCursor Operations.
 //===----------------------------------------------------------------------===//
index 67e4b4334b7eb52434453e38c48a0f88b30e2a80..222598dcd94e14923d6cb9968f9174fc948c812a 100644 (file)
@@ -46,6 +46,7 @@ clang_Cursor_isVariadic
 clang_Cursor_getModule
 clang_Cursor_getStorageClass
 clang_File_isEqual
+clang_File_tryGetRealPathName
 clang_Module_getASTFile
 clang_Module_getParent
 clang_Module_getName
index c44095d5428378fd7d614ce5ed4c3dba0ab3ce85..17a506762f1f4b82f78c32b9209f9b08b6b29e9c 100644 (file)
@@ -482,6 +482,21 @@ public:
   }
 };
 
+TEST_F(LibclangReparseTest, FileName) {
+  std::string CppName = "main.cpp";
+  WriteFile(CppName, "int main() {}");
+  ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
+                                       nullptr, 0, TUFlags);
+  CXFile cxf = clang_getFile(ClangTU, CppName.c_str());
+
+  CXString cxname = clang_getFileName(cxf);
+  ASSERT_TRUE(strstr(clang_getCString(cxname), CppName.c_str()));
+  clang_disposeString(cxname);
+
+  cxname = clang_File_tryGetRealPathName(cxf);
+  ASSERT_TRUE(strstr(clang_getCString(cxname), CppName.c_str()));
+  clang_disposeString(cxname);
+}
 
 TEST_F(LibclangReparseTest, Reparse) {
   const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";