From 59d94d98ca79b29b54294de8d717b98c8df8fdb1 Mon Sep 17 00:00:00 2001 From: Todd Fiala Date: Thu, 21 Jul 2016 12:53:39 -0600 Subject: [PATCH] educate Linux LLDB how to find the resource dir Non-Apple platforms would fail to find the Swift resource dir when running LLDB from the build dir. This issue was not present when running LLDB from the install dir. This change makes one more fallback attempt to synthesize the Swift resource dir by doing what would be a valid regex-based manipulation of the LLDB lib path for a build-script-driven style build. That style build is the prevailing build style for everywhere except for the Xcode-driven LLDB build. This change also restores running the LLDB Swift REPL tests on Linux that run from the build layout. Fixes: bugs.swift.org/SR-1300 bugs.swift.org/SR-2136 --- packages/Python/lldbsuite/test/lldbrepl.py | 1 - source/Symbol/SwiftASTContext.cpp | 126 +++++++++++++++++++-- source/Target/SwiftLanguageRuntime.cpp | 2 +- 3 files changed, 118 insertions(+), 11 deletions(-) diff --git a/packages/Python/lldbsuite/test/lldbrepl.py b/packages/Python/lldbsuite/test/lldbrepl.py index 840799a57d40..19844e07457c 100644 --- a/packages/Python/lldbsuite/test/lldbrepl.py +++ b/packages/Python/lldbsuite/test/lldbrepl.py @@ -27,7 +27,6 @@ class REPLTest(PExpectTest): @swiftTest @no_debug_info_test - @skipIfLinux # https://bugs.swift.org/browse/SR-1300 def testREPL(self): # setup the regexp for the prompt self.prompt = re.compile('\\d+>') diff --git a/source/Symbol/SwiftASTContext.cpp b/source/Symbol/SwiftASTContext.cpp index 6553370cd010..81609dddee88 100644 --- a/source/Symbol/SwiftASTContext.cpp +++ b/source/Symbol/SwiftASTContext.cpp @@ -15,6 +15,7 @@ // C++ Includes #include // std::once #include +#include #include #include "clang/Basic/TargetInfo.h" @@ -2646,76 +2647,183 @@ GetResourceDir () static ConstString g_cached_resource_dir; static std::once_flag g_once_flag; std::call_once(g_once_flag, [](){ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + // First, check if there's something in our bundle - { FileSpec swift_dir_spec; - if (HostInfo::GetLLDBPath (ePathTypeSwiftDir, swift_dir_spec)) { - // We can't just check for the Swift directory, because that always exists. We have to look for "clang" inside that. - + if (log) + log->Printf("%s: trying ePathTypeSwiftDir: %s", + __FUNCTION__, + swift_dir_spec.GetCString()); + // We can't just check for the Swift directory, because that + // always exists. We have to look for "clang" inside that. FileSpec swift_clang_dir_spec = swift_dir_spec; swift_clang_dir_spec.AppendPathComponent("clang"); if (swift_clang_dir_spec.IsDirectory()) { - g_cached_resource_dir = ConstString(swift_dir_spec.GetPath()); + g_cached_resource_dir = + ConstString(swift_dir_spec.GetPath()); + if (log) + log->Printf("%s: found Swift resource dir via " + "ePathTypeSwiftDir': %s", + __FUNCTION__, + g_cached_resource_dir.AsCString()); return; } } } - // Nothing in our bundle. Are we in a toolchain that has its own Swift compiler resource dir? + // Nothing in our bundle. Are we in a toolchain that has its own Swift + // compiler resource dir? { std::string xcode_toolchain_path = GetCurrentToolchainPath(); + if (log) + log->Printf("%s: trying toolchain path: %s", + __FUNCTION__, + xcode_toolchain_path.c_str()); if (!xcode_toolchain_path.empty()) { xcode_toolchain_path.append("usr/lib/swift"); + if (log) + log->Printf("%s: trying toolchain-based lib path: %s", + __FUNCTION__, + xcode_toolchain_path.c_str()); if (FileSpec(xcode_toolchain_path, false).IsDirectory()) { g_cached_resource_dir = ConstString(xcode_toolchain_path); + if (log) + log->Printf("%s: found Swift resource dir via " + "toolchain path + 'usr/lib/swift': %s", + __FUNCTION__, + g_cached_resource_dir.AsCString()); return; } } } - // We're not in a toolchain that has one. Use the Xcode default toolchain. + // We're not in a toolchain that has one. Use the Xcode default + // toolchain. { std::string xcode_contents_path = GetXcodeContentsPath(); + if (log) + log->Printf("%s: trying Xcode path: %s", + __FUNCTION__, + xcode_contents_path.c_str()); if (!xcode_contents_path.empty()) { - xcode_contents_path.append("Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift"); + xcode_contents_path.append("Developer/Toolchains/" + "XcodeDefault.xctoolchain" + "/usr/lib/swift"); + if (log) + log->Printf("%s: trying Xcode-based lib path: %s", + __FUNCTION__, + xcode_contents_path.c_str()); if (FileSpec(xcode_contents_path, false).IsDirectory()) { g_cached_resource_dir = ConstString(xcode_contents_path); + if (log) + log->Printf("%s: found Swift resource dir via " + "Xcode contents path + default toolchain " + "relative dir: %s", + __FUNCTION__, + g_cached_resource_dir.AsCString()); return; } } } - // We're not in Xcode. We must be in the command-line tools. + // We're not in Xcode. We might be in the command-line tools. { std::string cl_tools_path = GetCurrentCLToolsPath(); + if (log) + log->Printf("%s: trying command-line tools path: %s", + __FUNCTION__, + cl_tools_path.c_str()); if (!cl_tools_path.empty()) { cl_tools_path.append("usr/lib/swift"); + if (log) + log->Printf("%s: trying command-line tools-based lib " + "path: %s", + __FUNCTION__, + cl_tools_path.c_str()); if (FileSpec(cl_tools_path, false).IsDirectory()) { g_cached_resource_dir = ConstString(cl_tools_path); + if (log) + log->Printf("%s: found Swift resource dir via " + "command-line tools path + " + "usr/lib/swift: %s", + __FUNCTION__, + g_cached_resource_dir.AsCString()); return; } } } + + // For non-Apple platforms, we might be in the build-dir configuration + // rather than the install-dir configuration. If that is the case, we + // have to look for a Swift build-dir that is sibling to the lldb + // build dir. + { + FileSpec swift_dir_spec; + if (HostInfo::GetLLDBPath (ePathTypeSwiftDir, swift_dir_spec)) + { + // Let's try to regex this. + // We're looking for /some/path/lldb-{os}-{arch}, and want to + // build the following: + // /some/path/swift-{os}-{arch}/lib/swift/{os}/{arch} + // In a match, these are the following assignments for + // backrefs: + // $1 - first part of path before swift build dir + // $2 - the host OS path separator character + // $3 - all the stuff that should come after changing + // lldb to swift for the lib dir. + auto match_regex = + std::regex("^(.+([/\\\\]))lldb-(.+)$"); + auto replace_format = "$1swift-$3"; + auto build_tree_resource_dir + = std::regex_replace(swift_dir_spec.GetCString(), + match_regex, replace_format); + if (log) + log->Printf("%s: trying ePathTypeSwiftDir regex-based " + "build dir: %s", + __FUNCTION__, + build_tree_resource_dir.c_str()); + FileSpec swift_resource_dir_spec( + build_tree_resource_dir.c_str(), false); + if (swift_resource_dir_spec.IsDirectory()) + { + g_cached_resource_dir = + ConstString(swift_resource_dir_spec.GetPath()); + if (log) + log->Printf("%s: found Swift resource dir via " + "ePathTypeSwiftDir + inferred build-tree " + "dir: %s", __FUNCTION__, + g_cached_resource_dir.AsCString()); + return; + } + } + } + + + // We failed to find a reasonable Swift resource dir. + if (log) + log->Printf("%s: failed to find a Swift resource dir", + __FUNCTION__); }); return g_cached_resource_dir; diff --git a/source/Target/SwiftLanguageRuntime.cpp b/source/Target/SwiftLanguageRuntime.cpp index 0f4cdd54660e..b442303f0daa 100644 --- a/source/Target/SwiftLanguageRuntime.cpp +++ b/source/Target/SwiftLanguageRuntime.cpp @@ -1318,7 +1318,7 @@ SwiftLanguageRuntime::MemberVariableOffsetResolver::ResolveOffset (ValueObject * if (result) { if (log) - log->Printf("[MemberVariableOffsetResolver] offset discovered = %llu", (uint64_t)result.getValue()); + log->Printf("[MemberVariableOffsetResolver] offset discovered = %" PRIu64, (uint64_t)result.getValue()); m_offsets.emplace(ivar_name.AsCString(), result.getValue()); return result.getValue(); }