Skip to content

Commit efb7606

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
1 parent 9c2a1f2 commit efb7606

File tree

4 files changed

+90
-30
lines changed

4 files changed

+90
-30
lines changed

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

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,23 @@ static void ConfigureResourceDirs(swift::CompilerInvocation &invocation,
10931093
invocation.setRuntimeResourcePath(resource_dir);
10941094
}
10951095

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

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

@@ -1804,7 +1824,8 @@ void SwiftASTContext::AddExtraClangArgs(
18041824
if (importer_options.DirectClangCC1ModuleBuild) {
18051825
if (!fresh_invocation)
18061826
importer_options.ExtraArgs.clear();
1807-
AddExtraClangCC1Args(ExtraArgs, importer_options.ExtraArgs);
1827+
AddExtraClangCC1Args(ExtraArgs, module_search_paths, framework_search_paths,
1828+
importer_options.ExtraArgs);
18081829
applyOverrideOptions(importer_options.ExtraArgs, overrideOpts);
18091830
return;
18101831
}
@@ -1822,17 +1843,43 @@ void SwiftASTContext::AddExtraClangArgs(
18221843
}
18231844

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

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

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

19041957
/// Turn relative paths in clang options into absolute paths based on
@@ -2471,6 +2524,7 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24712524
HostInfo::GetSwiftResourceDir(triple, swift_ast_sp->GetPlatformSDKPath());
24722525
ConfigureResourceDirs(swift_ast_sp->GetCompilerInvocation(), resource_dir,
24732526
triple);
2527+
ConfigureModuleCachePath(*swift_ast_sp);
24742528

24752529
swift_ast_sp->SetCompilerInvocationLLDBOverrides();
24762530

@@ -2494,7 +2548,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24942548

24952549
// Apply the working directory to all relative paths.
24962550
StringRef overrideOpts = target ? target->GetSwiftClangOverrideOptions() : "";
2497-
swift_ast_sp->AddExtraClangArgs(extra_clang_args, overrideOpts);
2551+
swift_ast_sp->AddExtraClangArgs(extra_clang_args, module_search_paths,
2552+
framework_search_paths, overrideOpts);
24982553
if (target)
24992554
swift_ast_sp->AddUserClangArgs(*target);
25002555
else
@@ -2930,6 +2985,7 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
29302985
triple, swift_ast_sp->GetPlatformSDKPath());
29312986
ConfigureResourceDirs(swift_ast_sp->GetCompilerInvocation(), resource_dir,
29322987
triple);
2988+
ConfigureModuleCachePath(*swift_ast_sp);
29332989

29342990
std::vector<swift::PluginSearchOption> plugin_search_options;
29352991
std::vector<std::string> module_search_paths;
@@ -2968,7 +3024,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
29683024
swift_ast_sp->AddDiagnostic(eSeverityError, error);
29693025
StringRef override_opts =
29703026
target_sp ? target_sp->GetSwiftClangOverrideOptions() : "";
2971-
swift_ast_sp->AddExtraClangArgs(extra_clang_args, override_opts);
3027+
swift_ast_sp->AddExtraClangArgs(extra_clang_args, module_search_paths,
3028+
framework_search_paths, override_opts);
29723029
}
29733030

29743031
// Now fold any extra options we were passed. This has to be done
@@ -3572,7 +3629,8 @@ ThreadSafeASTContext SwiftASTContext::GetASTContext() {
35723629
}
35733630

35743631
// Create the ClangImporter and determine the Clang module cache path.
3575-
std::string moduleCachePath = "";
3632+
std::string moduleCachePath =
3633+
GetCompilerInvocation().getClangModuleCachePath().str();
35763634
std::unique_ptr<swift::ClangImporter> clang_importer_ap;
35773635
auto &clang_importer_options = GetClangImporterOptions();
35783636
if (!m_ast_context_ap->SearchPathOpts.getSDKPath().empty() ||
@@ -3599,24 +3657,12 @@ ThreadSafeASTContext SwiftASTContext::GetASTContext() {
35993657
underlying_error.c_str());
36003658
}
36013659
}
3602-
if (clang_importer_ap)
3603-
moduleCachePath = swift::getModuleCachePathFromClang(
3660+
if (clang_importer_ap) {
3661+
auto clangModuleCache = swift::getModuleCachePathFromClang(
36043662
clang_importer_ap->getClangInstance());
3605-
}
3606-
}
3607-
3608-
if (moduleCachePath.empty()) {
3609-
moduleCachePath = GetClangModulesCacheProperty();
3610-
// Even though it is initialized to the default Clang location at startup a
3611-
// user could have overwritten it with an empty path.
3612-
if (moduleCachePath.empty()) {
3613-
llvm::SmallString<0> path;
3614-
std::error_code ec =
3615-
llvm::sys::fs::createUniqueDirectory("ModuleCache", path);
3616-
if (!ec)
3617-
moduleCachePath = std::string(path);
3618-
else
3619-
moduleCachePath = "/tmp/lldb-ModuleCache";
3663+
if (!clangModuleCache.empty())
3664+
moduleCachePath = clangModuleCache;
3665+
}
36203666
}
36213667
}
36223668
LOG_PRINTF(GetLog(LLDBLog::Types), "Using Clang module cache path: %s",

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

Lines changed: 11 additions & 4 deletions
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);
Lines changed: 1 addition & 1 deletion
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

Lines changed: 7 additions & 0 deletions
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)