Skip to content

Commit 1b3ee32

Browse files
[lldb] Apply available search paths from swift to clang importer
For explicit build that uses direct cc1 options (like swift caching), all search paths are dropped after dependency scanning. The clang modules from the explicit build are the only modules available for lldb, which should not be a problem if the context for expression evaluator in lldb matches the context for swift compiler. But there are currently, there are edge cases, like when lldb is constructing a type from generics from a different module, it might tries to import additional clang modules. Teach lldb to apply the swift search paths to clang importer, in case some implicit clang module build is required, to make the debugging process less disruptive. This cannot recover all the search paths (like clang specific ones that passes through -Xcc options), but lldb were already relying on the search paths from current module context can find the clang modules from a different context. This should make the behavior closer to implicit build before the lldb context and swift compiler context can match perfectly. rdar://138664252 (cherry picked from commit efb7606)
1 parent 325dd24 commit 1b3ee32

File tree

4 files changed

+90
-30
lines changed

4 files changed

+90
-30
lines changed

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

+71-25
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,23 @@ static void ConfigureResourceDirs(swift::CompilerInvocation &invocation,
10921092
invocation.setRuntimeResourcePath(resource_dir);
10931093
}
10941094

1095+
static void ConfigureModuleCachePath(SwiftASTContext &swift_ast_sp) {
1096+
std::string moduleCachePath =
1097+
swift_ast_sp.GetCompilerInvocation().getClangModuleCachePath().str();
1098+
if (!moduleCachePath.empty())
1099+
return;
1100+
1101+
// If the moduleCachePath is not configured, setup a default path location.
1102+
llvm::SmallString<0> path;
1103+
std::error_code ec =
1104+
llvm::sys::fs::createUniqueDirectory("ModuleCache", path);
1105+
if (!ec)
1106+
moduleCachePath = std::string(path);
1107+
else
1108+
moduleCachePath = "/tmp/lldb-ModuleCache";
1109+
swift_ast_sp.GetCompilerInvocation().setClangModuleCachePath(moduleCachePath);
1110+
}
1111+
10951112
static const char *getImportFailureString(swift::serialization::Status status) {
10961113
switch (status) {
10971114
case swift::serialization::Status::Valid:
@@ -1777,7 +1794,10 @@ static void applyOverrideOptions(std::vector<std::string> &args,
17771794
}
17781795

17791796
void SwiftASTContext::AddExtraClangArgs(
1780-
const std::vector<std::string> &ExtraArgs, StringRef overrideOpts) {
1797+
const std::vector<std::string> &ExtraArgs,
1798+
const std::vector<std::string> &module_search_paths,
1799+
const std::vector<std::pair<std::string, bool>> framework_search_paths,
1800+
StringRef overrideOpts) {
17811801
if (ExtraArgs.empty())
17821802
return;
17831803

@@ -1803,7 +1823,8 @@ void SwiftASTContext::AddExtraClangArgs(
18031823
if (importer_options.DirectClangCC1ModuleBuild) {
18041824
if (!fresh_invocation)
18051825
importer_options.ExtraArgs.clear();
1806-
AddExtraClangCC1Args(ExtraArgs, importer_options.ExtraArgs);
1826+
AddExtraClangCC1Args(ExtraArgs, module_search_paths, framework_search_paths,
1827+
importer_options.ExtraArgs);
18071828
applyOverrideOptions(importer_options.ExtraArgs, overrideOpts);
18081829
return;
18091830
}
@@ -1821,17 +1842,43 @@ void SwiftASTContext::AddExtraClangArgs(
18211842
}
18221843

18231844
void SwiftASTContext::AddExtraClangCC1Args(
1824-
const std::vector<std::string> &source, std::vector<std::string> &dest) {
1845+
const std::vector<std::string> &source,
1846+
const std::vector<std::string> &module_search_paths,
1847+
const std::vector<std::pair<std::string, bool>> framework_search_paths,
1848+
std::vector<std::string> &dest) {
18251849
clang::CompilerInvocation invocation;
1850+
std::vector<std::string> default_paths = {"/usr/include",
1851+
"/user/local/include"};
18261852
llvm::SmallVector<const char *> clangArgs;
1827-
clangArgs.reserve(source.size());
1853+
clangArgs.reserve(source.size() + module_search_paths.size() * 2 +
1854+
framework_search_paths.size() * 2 +
1855+
default_paths.size() * 2);
18281856
llvm::for_each(source, [&](const std::string &Arg) {
18291857
// Workaround for the extra driver argument embedded in the swiftmodule by
18301858
// some swift compiler version. It always starts with `--target=` and it is
18311859
// not a valid cc1 option.
18321860
if (!StringRef(Arg).starts_with("--target="))
18331861
clangArgs.push_back(Arg.c_str());
18341862
});
1863+
// Append some search paths from swift invocation so lldb can import
1864+
// additional clang modules when doing type reconstruction.
1865+
for (auto &path : module_search_paths) {
1866+
clangArgs.push_back("-I");
1867+
clangArgs.push_back(path.c_str());
1868+
}
1869+
for (auto &path : default_paths) {
1870+
llvm::SmallString<128> search_path(GetPlatformSDKPath());
1871+
llvm::sys::path::append(search_path, path);
1872+
path = std::string(search_path);
1873+
}
1874+
for (auto &path : default_paths) {
1875+
clangArgs.push_back("-I");
1876+
clangArgs.push_back(path.c_str());
1877+
}
1878+
for (auto &path : framework_search_paths) {
1879+
clangArgs.push_back("-F");
1880+
clangArgs.push_back(path.first.c_str());
1881+
}
18351882

18361883
std::string diags;
18371884
llvm::raw_string_ostream os(diags);
@@ -1858,6 +1905,12 @@ void SwiftASTContext::AddExtraClangCC1Args(
18581905
// Ignore CAS info inside modules when loading.
18591906
invocation.getFrontendOpts().ModuleLoadIgnoreCAS = true;
18601907

1908+
// Add options to allow clang importer to do implicit module build.
1909+
invocation.getLangOpts().ImplicitModules = true;
1910+
invocation.getHeaderSearchOpts().ImplicitModuleMaps = true;
1911+
invocation.getHeaderSearchOpts().ModuleCachePath =
1912+
GetCompilerInvocation().getClangModuleCachePath().str();
1913+
18611914
// Remove non-existing modules in a systematic way.
18621915
bool module_missing = false;
18631916
auto CheckFileExists = [&](const char *file) {
@@ -1897,7 +1950,7 @@ void SwiftASTContext::AddUserClangArgs(TargetProperties &props) {
18971950
std::vector<std::string> user_clang_flags;
18981951
for (const auto &arg : args.entries())
18991952
user_clang_flags.push_back(arg.ref().str());
1900-
AddExtraClangArgs(user_clang_flags);
1953+
AddExtraClangArgs(user_clang_flags, {}, {});
19011954
}
19021955

19031956
/// Turn relative paths in clang options into absolute paths based on
@@ -2470,6 +2523,7 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24702523
HostInfo::GetSwiftResourceDir(triple, swift_ast_sp->GetPlatformSDKPath());
24712524
ConfigureResourceDirs(swift_ast_sp->GetCompilerInvocation(), resource_dir,
24722525
triple);
2526+
ConfigureModuleCachePath(*swift_ast_sp);
24732527

24742528
swift_ast_sp->SetCompilerInvocationLLDBOverrides();
24752529

@@ -2493,7 +2547,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24932547

24942548
// Apply the working directory to all relative paths.
24952549
StringRef overrideOpts = target ? target->GetSwiftClangOverrideOptions() : "";
2496-
swift_ast_sp->AddExtraClangArgs(extra_clang_args, overrideOpts);
2550+
swift_ast_sp->AddExtraClangArgs(extra_clang_args, module_search_paths,
2551+
framework_search_paths, overrideOpts);
24972552
if (target)
24982553
swift_ast_sp->AddUserClangArgs(*target);
24992554
else
@@ -2929,6 +2984,7 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
29292984
triple, swift_ast_sp->GetPlatformSDKPath());
29302985
ConfigureResourceDirs(swift_ast_sp->GetCompilerInvocation(), resource_dir,
29312986
triple);
2987+
ConfigureModuleCachePath(*swift_ast_sp);
29322988

29332989
std::vector<swift::PluginSearchOption> plugin_search_options;
29342990
std::vector<std::string> module_search_paths;
@@ -2967,7 +3023,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
29673023
swift_ast_sp->AddDiagnostic(eSeverityError, error);
29683024
StringRef override_opts =
29693025
target_sp ? target_sp->GetSwiftClangOverrideOptions() : "";
2970-
swift_ast_sp->AddExtraClangArgs(extra_clang_args, override_opts);
3026+
swift_ast_sp->AddExtraClangArgs(extra_clang_args, module_search_paths,
3027+
framework_search_paths, override_opts);
29713028
}
29723029

29733030
// Now fold any extra options we were passed. This has to be done
@@ -3568,7 +3625,8 @@ ThreadSafeASTContext SwiftASTContext::GetASTContext() {
35683625
}
35693626

35703627
// Create the ClangImporter and determine the Clang module cache path.
3571-
std::string moduleCachePath = "";
3628+
std::string moduleCachePath =
3629+
GetCompilerInvocation().getClangModuleCachePath().str();
35723630
std::unique_ptr<swift::ClangImporter> clang_importer_ap;
35733631
auto &clang_importer_options = GetClangImporterOptions();
35743632
if (!m_ast_context_ap->SearchPathOpts.getSDKPath().empty() ||
@@ -3595,24 +3653,12 @@ ThreadSafeASTContext SwiftASTContext::GetASTContext() {
35953653
underlying_error.c_str());
35963654
}
35973655
}
3598-
if (clang_importer_ap)
3599-
moduleCachePath = swift::getModuleCachePathFromClang(
3656+
if (clang_importer_ap) {
3657+
auto clangModuleCache = swift::getModuleCachePathFromClang(
36003658
clang_importer_ap->getClangInstance());
3601-
}
3602-
}
3603-
3604-
if (moduleCachePath.empty()) {
3605-
moduleCachePath = GetClangModulesCacheProperty();
3606-
// Even though it is initialized to the default Clang location at startup a
3607-
// user could have overwritten it with an empty path.
3608-
if (moduleCachePath.empty()) {
3609-
llvm::SmallString<0> path;
3610-
std::error_code ec =
3611-
llvm::sys::fs::createUniqueDirectory("ModuleCache", path);
3612-
if (!ec)
3613-
moduleCachePath = std::string(path);
3614-
else
3615-
moduleCachePath = "/tmp/lldb-ModuleCache";
3659+
if (!clangModuleCache.empty())
3660+
moduleCachePath = clangModuleCache;
3661+
}
36163662
}
36173663
}
36183664
LOG_PRINTF(GetLog(LLDBLog::Types), "Using Clang module cache path: %s",

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

+11-4
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,17 @@ class SwiftASTContext : public TypeSystemSwift {
275275

276276
/// Add a list of Clang arguments to the ClangImporter options and
277277
/// apply the working directory to any relative paths.
278-
void AddExtraClangArgs(const std::vector<std::string> &ExtraArgs,
279-
llvm::StringRef overrideOpts = "");
280-
void AddExtraClangCC1Args(const std::vector<std::string>& source,
281-
std::vector<std::string>& dest);
278+
void AddExtraClangArgs(
279+
const std::vector<std::string> &ExtraArgs,
280+
const std::vector<std::string> &module_search_paths,
281+
const std::vector<std::pair<std::string, bool>> framework_search_paths,
282+
llvm::StringRef overrideOpts = "");
283+
284+
void AddExtraClangCC1Args(
285+
const std::vector<std::string> &source,
286+
const std::vector<std::string> &module_search_paths,
287+
const std::vector<std::pair<std::string, bool>> framework_search_paths,
288+
std::vector<std::string> &dest);
282289
static void AddExtraClangArgs(const std::vector<std::string>& source,
283290
std::vector<std::string>& dest);
284291
static std::string GetPluginServer(llvm::StringRef plugin_library_path);
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
SWIFT_SOURCES := main.swift
22
SWIFT_ENABLE_EXPLICIT_MODULES := YES
3-
SWIFTFLAGS_EXTRAS = -I$(SRCDIR) -cache-compile-job -cas-path $(BUILDDIR)/cas
3+
SWIFTFLAGS_EXTRAS = -I$(SRCDIR) -I/TEST_DIR -F/FRAMEWORK_DIR -cache-compile-job -cas-path $(BUILDDIR)/cas
44

55
include Makefile.rules

lldb/test/API/lang/swift/clangimporter/caching/TestSwiftClangImporterCaching.py

+7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ def test(self):
2828
self.filecheck('platform shell cat "%s"' % log, __file__)
2929
### -cc1 should be round-tripped so there is no more `-cc1` in the extra args. Look for `-triple` which is a cc1 flag.
3030
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- -triple
31+
### Check include paths in the module are forwards. The first argument is the source directory.
32+
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- -I
33+
# CHECK-NEXT: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() --
34+
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- -I
35+
# CHECK-NEXT: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- /TEST_DIR
36+
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- -F
37+
# CHECK-NEXT: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- /FRAMEWORK_DIR
3138
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration() -- -DADDED=1
3239
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift") Module import remark: loaded module 'ClangA'
3340
# CHECK-NOT: -cc1

0 commit comments

Comments
 (0)