]> granicus.if.org Git - clang/commitdiff
Make clang/test/Index/pch-from-libclang.c pass in more places
authorNico Weber <nicolasweber@gmx.de>
Thu, 31 Jan 2019 22:15:32 +0000 (22:15 +0000)
committerNico Weber <nicolasweber@gmx.de>
Thu, 31 Jan 2019 22:15:32 +0000 (22:15 +0000)
- fixes the test on macOS with LLVM_ENABLE_PIC=OFF
- together with D57343, gets the test to pass on Windows
- makes it run everywhere (it seems to just pass on Linux)

The main change is to pull out the resource directory computation into a
function shared by all 3 places that do it. In CIndexer.cpp, this now works no
matter if libclang is in lib/ or bin/ or statically linked to a binary in bin/.

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

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

include/clang/Driver/Driver.h
lib/Driver/Driver.cpp
lib/Frontend/CompilerInvocation.cpp
test/Index/pch-from-libclang.c
tools/libclang/CIndexer.cpp

index 0551230dad616d7fa688ff9602e322f1dddc464b..03e6458a5e5d5197830e89afd1743d884ec21b17 100644 (file)
@@ -277,6 +277,12 @@ private:
                               SmallString<128> &CrashDiagDir);
 
 public:
+
+  /// Takes the path to a binary that's either in bin/ or lib/ and returns
+  /// the path to clang's resource directory.
+  static std::string GetResourcesPath(StringRef BinaryPath,
+                                      StringRef CustomResourceDir = "");
+
   Driver(StringRef ClangExecutable, StringRef TargetTriple,
          DiagnosticsEngine &Diags,
          IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
index e93d3e05775436a657a7291b4514a27c98a48870..0a89e2c45e197f258c582d36c6fa659963f670dc 100644 (file)
@@ -89,6 +89,33 @@ using namespace clang::driver;
 using namespace clang;
 using namespace llvm::opt;
 
+// static
+std::string Driver::GetResourcesPath(StringRef BinaryPath,
+                                     StringRef CustomResourceDir) {
+  // Since the resource directory is embedded in the module hash, it's important
+  // that all places that need it call this function, so that they get the
+  // exact same string ("a/../b/" and "b/" get different hashes, for example).
+
+  // Dir is bin/ or lib/, depending on where BinaryPath is.
+  std::string Dir = llvm::sys::path::parent_path(BinaryPath);
+
+  SmallString<128> P(Dir);
+  if (CustomResourceDir != "") {
+    llvm::sys::path::append(P, CustomResourceDir);
+  } else {
+    // On Windows, libclang.dll is in bin/.
+    // On non-Windows, libclang.so/.dylib is in lib/.
+    // With a static-library build of libclang, LibClangPath will contain the
+    // path of the embedding binary, which for LLVM binaries will be in bin/.
+    // ../lib gets us to lib/ in both cases.
+    P = llvm::sys::path::parent_path(Dir);
+    llvm::sys::path::append(P, Twine("lib") + CLANG_LIBDIR_SUFFIX, "clang",
+                            CLANG_VERSION_STRING);
+  }
+
+  return P.str();
+}
+
 Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
                DiagnosticsEngine &Diags,
                IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
@@ -119,17 +146,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
 #endif
 
   // Compute the path to the resource directory.
-  StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
-  SmallString<128> P(Dir);
-  if (ClangResourceDir != "") {
-    llvm::sys::path::append(P, ClangResourceDir);
-  } else {
-    StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX);
-    P = llvm::sys::path::parent_path(Dir);
-    llvm::sys::path::append(P, Twine("lib") + ClangLibdirSuffix, "clang",
-                            CLANG_VERSION_STRING);
-  }
-  ResourceDir = P.str();
+  ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
 }
 
 void Driver::ParseDriverMode(StringRef ProgramName,
index dbc29e24aee36294d93179d6c58f0a12107ae438..05cce3c909412e1241bf0766afd24c48b5f4857b 100644 (file)
@@ -26,6 +26,7 @@
 #include "clang/Basic/Visibility.h"
 #include "clang/Basic/XRayInstr.h"
 #include "clang/Config/config.h"
+#include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/CommandLineSourceLoc.h"
@@ -1893,18 +1894,7 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
                                                  void *MainAddr) {
   std::string ClangExecutable =
       llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
-  StringRef Dir = llvm::sys::path::parent_path(ClangExecutable);
-
-  // Compute the path to the resource directory.
-  StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
-  SmallString<128> P(Dir);
-  if (ClangResourceDir != "")
-    llvm::sys::path::append(P, ClangResourceDir);
-  else
-    llvm::sys::path::append(P, "..", Twine("lib") + CLANG_LIBDIR_SUFFIX,
-                            "clang", CLANG_VERSION_STRING);
-
-  return P.str();
+  return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
 }
 
 static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
index 349fcac01ecadf9ec43c27bb565474c7ae1c1297..e71b61cddc319923328adf96c88d60ae7070c3f8 100644 (file)
@@ -1,7 +1,11 @@
 // Check that clang can use a PCH created from libclang.
 
-// FIXME: Non-darwin bots fail. Would need investigation using -module-file-info to see what is the difference in modules generated from libclang vs the compiler invocation, in those systems.
-// REQUIRES: system-darwin
+// This test doesn't use -fdisable-module-hash and hence requires that
+// CompilerInvocation::getModuleHash() computes exactly the same hash
+// for c-index-test and clang, which in turn requires that the both use
+// exactly the same resource-dir, even without calling realpath() on it:
+// - a/../b/ and b/ are not considered the same
+// - on Windows, c:\ and C:\ (only different in case) are not the same
 
 // RUN: %clang_cc1 -fsyntax-only %s -verify
 // RUN: c-index-test -write-pch %t.h.pch %s -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin
index 28ec7abb37ae69148cc798c3367c7df73a4ed0b1..03907884ac1a548264860e1957deace183075c94 100644 (file)
@@ -14,6 +14,7 @@
 #include "CXString.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Version.h"
+#include "clang/Driver/Driver.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/MD5.h"
@@ -62,7 +63,7 @@ const std::string &CIndexer::getClangResourcesPath() {
 #endif
 #endif
 
-  LibClangPath += llvm::sys::path::parent_path(path);
+  LibClangPath += path;
 #else
   // This silly cast below avoids a C++ warning.
   Dl_info info;
@@ -70,13 +71,11 @@ const std::string &CIndexer::getClangResourcesPath() {
     llvm_unreachable("Call to dladdr() failed");
 
   // We now have the CIndex directory, locate clang relative to it.
-  LibClangPath += llvm::sys::path::parent_path(info.dli_fname);
+  LibClangPath += info.dli_fname;
 #endif
 
-  llvm::sys::path::append(LibClangPath, "clang", CLANG_VERSION_STRING);
-
   // Cache our result.
-  ResourcesPath = LibClangPath.str();
+  ResourcesPath = driver::Driver::GetResourcesPath(LibClangPath);
   return ResourcesPath;
 }