aprantl created this revision. aprantl added reviewers: friss, jingham. Herald added a subscriber: mgorny.
Inside Xcode and in Xcode toolchains LLDB is always in lockstep with the Swift compiler, so it can reuse its Clang resource directory. This allows LLDB and the Swift compiler to share the same Clang module cache. rdar://problem/40039633 https://reviews.llvm.org/D46736 Files: include/lldb/Host/macosx/HostInfoMacOSX.h source/Host/macosx/HostInfoMacOSX.mm unittests/Host/CMakeLists.txt unittests/Host/HostInfoTest.cpp
Index: unittests/Host/HostInfoTest.cpp =================================================================== --- unittests/Host/HostInfoTest.cpp +++ unittests/Host/HostInfoTest.cpp @@ -8,7 +8,9 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/HostInfo.h" +#include "lldb/Host/macosx/HostInfoMacOSX.h" #include "lldb/lldb-defines.h" +#include "TestingSupport/TestUtilities.h" #include "gtest/gtest.h" using namespace lldb_private; @@ -43,3 +45,41 @@ EXPECT_EQ(HostInfo::GetAugmentedArchSpec(LLDB_ARCH_DEFAULT).GetTriple(), HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple()); } + + +struct HostInfoMacOSXTest : public HostInfoMacOSX { + static std::string ComputeClangDir(std::string lldb_shlib_path, + bool verify = false) { + FileSpec clang_dir; + FileSpec lldb_shlib_spec(lldb_shlib_path, false); + ComputeClangDirectory(lldb_shlib_spec, clang_dir, verify); + return clang_dir.GetPath(); + } +}; + + +TEST_F(HostInfoTest, MacOSX) { + // This returns whatever the POSIX fallback returns. + std::string posix = "/usr/lib/liblldb.dylib"; + EXPECT_FALSE(HostInfoMacOSXTest::ComputeClangDir(posix).empty()); + + std::string xcode = + "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework"; + std::string xcode_clang = + "/Applications/Xcode.app/Contents/Developer/Toolchains/" + "XcodeDefault.xctoolchain/usr/lib/swift/clang"; + EXPECT_EQ(HostInfoMacOSXTest::ComputeClangDir(xcode), xcode_clang); + + std::string toolchain = + "/Applications/Xcode.app/Contents/Developer/Toolchains/" + "Swift-4.1-development-snapshot.xctoolchain/System/Library/" + "PrivateFrameworks/LLDB.framework"; + std::string toolchain_clang = + "/Applications/Xcode.app/Contents/Developer/Toolchains/" + "Swift-4.1-development-snapshot.xctoolchain/usr/lib/swift/clang"; + EXPECT_EQ(HostInfoMacOSXTest::ComputeClangDir(toolchain), toolchain_clang); + + // Test that a bogus path is detected. + EXPECT_NE(HostInfoMacOSXTest::ComputeClangDir(GetInputFilePath(xcode), true), + HostInfoMacOSXTest::ComputeClangDir(GetInputFilePath(xcode))); +} Index: unittests/Host/CMakeLists.txt =================================================================== --- unittests/Host/CMakeLists.txt +++ unittests/Host/CMakeLists.txt @@ -21,4 +21,5 @@ LINK_LIBS lldbCore lldbHost + lldbUtilityHelpers ) Index: source/Host/macosx/HostInfoMacOSX.mm =================================================================== --- source/Host/macosx/HostInfoMacOSX.mm +++ source/Host/macosx/HostInfoMacOSX.mm @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" // C++ Includes @@ -226,21 +227,67 @@ #endif } +static bool VerifyClangPath(const llvm::Twine &clang_path) { + if (llvm::sys::fs::is_directory(clang_path)) + return true; + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (log) + log->Printf("HostInfoMacOSX::ComputeClangDirectory(): " + "failed to stat clang resource directory at \"%s\"", + clang_path.str().c_str()); + return false; +} + bool HostInfoMacOSX::ComputeClangDirectory(FileSpec &file_spec) { FileSpec lldb_file_spec; if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) return false; + return ComputeClangDirectory(lldb_file_spec, file_spec, true); +} - std::string raw_path = lldb_file_spec.GetPath(); +bool HostInfoMacOSX::ComputeClangDirectory(FileSpec &lldb_shlib_spec, + FileSpec &file_spec, bool verify) { + std::string raw_path = lldb_shlib_spec.GetPath(); - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos == std::string::npos) + auto rev_it = llvm::sys::path::rbegin(raw_path); + auto r_end = llvm::sys::path::rend(raw_path); + + // Check for a Posix-style build of LLDB. + if (rev_it == r_end || *rev_it != "LLDB.framework") return HostInfoPosix::ComputeClangDirectory(file_spec); - - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); + + // Inside Xcode and in Xcode toolchains LLDB is always in lockstep + // with the Swift compiler, so it can reuse its Clang resource + // directory. This allows LLDB and the Swift compiler to share the + // same Clang module cache. + llvm::SmallString<256> clang_path; + const char *swift_clang_resource_dir = "usr/lib/swift/clang"; + ++rev_it; + if (rev_it != r_end && *rev_it == "SharedFrameworks") { + // This is the top-level LLDB in the Xcode.app bundle. + raw_path.resize(rev_it - r_end); + llvm::sys::path::append(clang_path, raw_path, + "Developer/Toolchains/XcodeDefault.xctoolchain", + swift_clang_resource_dir); + if (!verify || VerifyClangPath(clang_path)) { + file_spec.SetFile(clang_path.c_str(), true); + return true; + } + } else if (rev_it != r_end && *rev_it == "PrivateFrameworks" && + ++rev_it != r_end && ++rev_it != r_end) { + // This is LLDB inside an Xcode toolchain. + raw_path.resize(rev_it - r_end); + llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir); + if (!verify || VerifyClangPath(clang_path)) { + file_spec.SetFile(clang_path.c_str(), true); + return true; + } + } + + // Fall back to the Clang resource directory inside the framework. + raw_path.resize(rev_it - r_end); raw_path.append("/Resources/Clang"); - + file_spec.SetFile(raw_path.c_str(), true); return true; } Index: include/lldb/Host/macosx/HostInfoMacOSX.h =================================================================== --- include/lldb/Host/macosx/HostInfoMacOSX.h +++ include/lldb/Host/macosx/HostInfoMacOSX.h @@ -38,6 +38,8 @@ static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputePythonDirectory(FileSpec &file_spec); static bool ComputeClangDirectory(FileSpec &file_spec); + static bool ComputeClangDirectory(FileSpec &lldb_shlib_spec, + FileSpec &file_spec, bool verify); static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); static bool ComputeUserPluginsDirectory(FileSpec &file_spec); };
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits