Author: adrian Date: Fri May 11 10:54:09 2018 New Revision: 332111 URL: http://llvm.org/viewvc/llvm-project?rev=332111&view=rev Log: HostInfoMacOSX: Share the clang resource directory with Swift.
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 Differential Revision: https://reviews.llvm.org/D46736 Modified: lldb/trunk/include/lldb/Host/macosx/HostInfoMacOSX.h lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm lldb/trunk/unittests/Host/CMakeLists.txt lldb/trunk/unittests/Host/HostInfoTest.cpp Modified: lldb/trunk/include/lldb/Host/macosx/HostInfoMacOSX.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/macosx/HostInfoMacOSX.h?rev=332111&r1=332110&r2=332111&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/macosx/HostInfoMacOSX.h (original) +++ lldb/trunk/include/lldb/Host/macosx/HostInfoMacOSX.h Fri May 11 10:54:09 2018 @@ -38,6 +38,8 @@ protected: 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); }; Modified: lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm?rev=332111&r1=332110&r2=332111&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm (original) +++ lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm Fri May 11 10:54:09 2018 @@ -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 @@ bool HostInfoMacOSX::ComputePythonDirect #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; + } + } else { + raw_path.resize(rev_it - r_end); + } + + // Fall back to the Clang resource directory inside the framework. raw_path.append("/Resources/Clang"); - file_spec.SetFile(raw_path.c_str(), true); return true; } Modified: lldb/trunk/unittests/Host/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/CMakeLists.txt?rev=332111&r1=332110&r2=332111&view=diff ============================================================================== --- lldb/trunk/unittests/Host/CMakeLists.txt (original) +++ lldb/trunk/unittests/Host/CMakeLists.txt Fri May 11 10:54:09 2018 @@ -22,4 +22,5 @@ add_lldb_unittest(HostTests LINK_LIBS lldbCore lldbHost + lldbUtilityHelpers ) Modified: lldb/trunk/unittests/Host/HostInfoTest.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/HostInfoTest.cpp?rev=332111&r1=332110&r2=332111&view=diff ============================================================================== --- lldb/trunk/unittests/Host/HostInfoTest.cpp (original) +++ lldb/trunk/unittests/Host/HostInfoTest.cpp Fri May 11 10:54:09 2018 @@ -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 @@ TEST_F(HostInfoTest, GetAugmentedArchSpe 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))); +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits