Skip to content

Get SwiftASTContextForExpression's SDK path straight from debug info. #3879

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ class TargetProperties : public Properties {

llvm::StringRef GetSwiftExtraClangFlags() const;

bool GetSwiftCreateModuleContextsInParallel() const;

bool GetSwiftReadMetadataFromFileCache() const;

bool GetSwiftUseReflectionSymbols() const;
Expand Down
83 changes: 33 additions & 50 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,35 @@ static llvm::Optional<StringRef> GetDSYMBundle(Module &module) {
return dsym;
}

/// Force parsing of the CUs to extract the SDK info.
static std::string GetSDKPathFromDebugInfo(std::string m_description,
Module &module) {
XcodeSDK sdk;
bool found_public_sdk = false;
bool found_internal_sdk = false;
if (SymbolFile *sym_file = module.GetSymbolFile())
for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i)
if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i))
if (cu_sp->GetLanguage() == lldb::eLanguageTypeSwift) {
auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);
sdk.Merge(cu_sdk);
bool is_internal_sdk = cu_sdk.IsAppleInternalSDK();
found_public_sdk |= !is_internal_sdk;
found_internal_sdk |= is_internal_sdk;
}

if (found_public_sdk && found_internal_sdk)
HEALTH_LOG_PRINTF("Unsupported mixing of public and internal SDKs in "
"'%s'. Mixed use of SDKs indicates use of different "
"toolchains, which is not supported.",
module.GetFileSpec().GetFilename().GetCString());

std::string sdk_path = HostInfo::GetXcodeSDKPath(sdk).str();
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Host SDK path for sdk %s is %s.",
sdk.GetString().str().c_str(), sdk_path.c_str());
return sdk_path;
}

/// Detect whether a Swift module was "imported" by DWARFImporter.
/// All this *really* means is that it couldn't be loaded through any
/// other mechanism.
Expand Down Expand Up @@ -1759,30 +1788,7 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Serialized SDK path is %s.",
serialized_sdk_path.str().c_str());

// Force parsing of the CUs to extract the SDK info.
XcodeSDK sdk;
bool found_public_sdk = false;
bool found_internal_sdk = false;
if (SymbolFile *sym_file = module.GetSymbolFile())
for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i)
if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i))
if (cu_sp->GetLanguage() == lldb::eLanguageTypeSwift) {
auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);
sdk.Merge(cu_sdk);
bool is_internal_sdk = cu_sdk.IsAppleInternalSDK();
found_public_sdk |= !is_internal_sdk;
found_internal_sdk |= is_internal_sdk;
}

if (found_public_sdk && found_internal_sdk)
HEALTH_LOG_PRINTF("Unsupported mixing of public and internal SDKs in "
"'%s'. Mixed use of SDKs indicates use of different "
"toolchains, which is not supported.",
module.GetFileSpec().GetFilename().GetCString());

std::string sdk_path = HostInfo::GetXcodeSDKPath(sdk).str();
LOG_PRINTF(LIBLLDB_LOG_TYPES, "Host SDK path for sdk %s is %s.",
sdk.GetString().str().c_str(), sdk_path.c_str());
std::string sdk_path = GetSDKPathFromDebugInfo(m_description, module);
if (FileSystem::Instance().Exists(sdk_path)) {
// Note that this is not final. InitializeSearchPathOptions()
// will set the SDK path based on the triple if this fails.
Expand Down Expand Up @@ -2130,42 +2136,19 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(lldb::LanguageType language,
handled_sdk_path = true;
}

auto warmup_astcontexts = [&]() {
if (target.GetSwiftCreateModuleContextsInParallel()) {
// The first call to GetTypeSystemForLanguage() on a module will
// trigger the import (and thus most likely the rebuild) of all
// the Clang modules that were imported in this module. This can
// be a lot of work (potentially ten seconds per module), but it
// can be performed in parallel.
llvm::ThreadPool pool(llvm::hardware_concurrency());
for (size_t mi = 0; mi != num_images; ++mi) {
auto module_sp = target.GetImages().GetModuleAtIndex(mi);
pool.async([=] {
GetModuleSwiftASTContext(*module_sp);
});
}
pool.wait();
}
};

if (!handled_sdk_path) {
warmup_astcontexts();
for (size_t mi = 0; mi != num_images; ++mi) {
ModuleSP module_sp = target.GetImages().GetModuleAtIndex(mi);
if (!HasSwiftModules(*module_sp))
continue;

SwiftASTContext *module_swift_ast = GetModuleSwiftASTContext(*module_sp);
if (!module_swift_ast || module_swift_ast->HasFatalErrors() ||
!module_swift_ast->GetClangImporter())
continue;
std::string sdk_path = GetSDKPathFromDebugInfo(m_description, *module_sp);

StringRef platform_sdk_path = module_swift_ast->GetPlatformSDKPath();
if (platform_sdk_path.empty())
if (sdk_path.empty())
continue;

handled_sdk_path = true;
swift_ast_sp->SetPlatformSDKPath(platform_sdk_path);
swift_ast_sp->SetPlatformSDKPath(sdk_path);
break;
}
}
Expand Down
12 changes: 0 additions & 12 deletions lldb/source/Target/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4146,18 +4146,6 @@ void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx,
true);
}

bool TargetProperties::GetSwiftCreateModuleContextsInParallel() const {
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
nullptr, false, ePropertyExperimental);
OptionValueProperties *exp_values =
exp_property->GetValue()->GetAsProperties();
if (exp_values)
return exp_values->GetPropertyAtIndexAsBoolean(
nullptr, ePropertySwiftCreateModuleContextsInParallel, true);
else
return true;
}

bool TargetProperties::GetSwiftReadMetadataFromFileCache() const {
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
nullptr, false, ePropertyExperimental);
Expand Down
3 changes: 0 additions & 3 deletions lldb/source/Target/TargetProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ let Definition = "target_experimental" in {
def InjectLocalVars : Property<"inject-local-vars", "Boolean">,
Global, DefaultTrue,
Desc<"If true, inject local variables explicitly into the expression text. This will fix symbol resolution when there are name collisions between ivars and local variables. But it can make expressions run much more slowly.">;
def SwiftCreateModuleContextsInParallel : Property<"swift-create-module-contexts-in-parallel", "Boolean">,
DefaultTrue,
Desc<"Create the per-module Swift AST contexts in parallel.">;
def SwiftReadMetadataFromFileCache: Property<"swift-read-metadata-from-file-cache", "Boolean">,
DefaultTrue,
Desc<"Read Swift reflection metadata from the file cache instead of the process when possible">;
Expand Down