Skip to content

Commit 3358d3e

Browse files
Merge pull request #4083 from adrian-prantl/89836973-framework-paths
Partially revert 70d2ba0.
2 parents ea171fe + cc20c75 commit 3358d3e

File tree

11 files changed

+142
-2
lines changed

11 files changed

+142
-2
lines changed

lldb/include/lldb/Target/Target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ class TargetProperties : public Properties {
169169

170170
llvm::StringRef GetSwiftExtraClangFlags() const;
171171

172+
bool GetSwiftCreateModuleContextsInParallel() const;
173+
172174
bool GetSwiftReadMetadataFromFileCache() const;
173175

174176
bool GetSwiftUseReflectionSymbols() const;

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

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,14 +2078,45 @@ ProcessModule(ModuleSP module_sp, std::string m_description,
20782078
module_search_paths.insert(module_search_paths.end(),
20792079
opts.getImportSearchPaths().begin(),
20802080
opts.getImportSearchPaths().end());
2081-
for (const auto &fwsp : opts.getFrameworkSearchPaths())
2082-
framework_search_paths.push_back({fwsp.Path, fwsp.IsSystem});
20832081
auto &clang_opts = invocation.getClangImporterOptions().ExtraArgs;
20842082
for (const std::string &arg : clang_opts) {
20852083
extra_clang_args.push_back(arg);
20862084
LOG_VERBOSE_PRINTF(GetLog(LLDBLog::Types), "adding Clang argument \"%s\".",
20872085
arg.c_str());
20882086
}
2087+
// FIXME: Unfortunately this:
2088+
//
2089+
// for (const auto &fwsp : opts.getFrameworkSearchPaths())
2090+
// framework_search_paths.push_back({fwsp.Path, fwsp.IsSystem});
2091+
//
2092+
// is insufficient, as ClangImporter can discover more framework
2093+
// search paths on the fly. Once a better solution is found,
2094+
// warmup_contexts can be retired (again).
2095+
{
2096+
SymbolFile *sym_file = module_sp->GetSymbolFile();
2097+
if (!sym_file)
2098+
return;
2099+
Status sym_file_error;
2100+
auto type_system_or_err =
2101+
sym_file->GetTypeSystemForLanguage(lldb::eLanguageTypeSwift);
2102+
if (!type_system_or_err) {
2103+
llvm::consumeError(type_system_or_err.takeError());
2104+
return;
2105+
}
2106+
auto ts = llvm::dyn_cast_or_null<TypeSystemSwift>(&*type_system_or_err);
2107+
if (!ts)
2108+
return;
2109+
2110+
SwiftASTContext *ast_context = ts->GetSwiftASTContext();
2111+
if (ast_context && !ast_context->HasErrors()) {
2112+
if (use_all_compiler_flags ||
2113+
target.GetExecutableModulePointer() == module_sp.get()) {
2114+
const auto &opts = ast_context->GetSearchPathOptions();
2115+
for (const auto &fwsp : opts.getFrameworkSearchPaths())
2116+
framework_search_paths.push_back({fwsp.Path, fwsp.IsSystem});
2117+
}
2118+
}
2119+
}
20892120
}
20902121

20912122
lldb::TypeSystemSP SwiftASTContext::CreateInstance(
@@ -2145,7 +2176,26 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
21452176
handled_sdk_path = true;
21462177
}
21472178

2179+
auto warmup_astcontexts = [&]() {
2180+
if (target.GetSwiftCreateModuleContextsInParallel()) {
2181+
// The first call to GetTypeSystemForLanguage() on a module will
2182+
// trigger the import (and thus most likely the rebuild) of all
2183+
// the Clang modules that were imported in this module. This can
2184+
// be a lot of work (potentially ten seconds per module), but it
2185+
// can be performed in parallel.
2186+
llvm::ThreadPool pool(llvm::hardware_concurrency());
2187+
for (size_t mi = 0; mi != num_images; ++mi) {
2188+
auto module_sp = target.GetImages().GetModuleAtIndex(mi);
2189+
pool.async([=] {
2190+
GetModuleSwiftASTContext(*module_sp);
2191+
});
2192+
}
2193+
pool.wait();
2194+
}
2195+
};
2196+
21482197
if (!handled_sdk_path) {
2198+
warmup_astcontexts();
21492199
for (size_t mi = 0; mi != num_images; ++mi) {
21502200
ModuleSP module_sp = target.GetImages().GetModuleAtIndex(mi);
21512201
if (!HasSwiftModules(*module_sp))

lldb/source/Target/Target.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4163,6 +4163,18 @@ void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx,
41634163
true);
41644164
}
41654165

4166+
bool TargetProperties::GetSwiftCreateModuleContextsInParallel() const {
4167+
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
4168+
nullptr, false, ePropertyExperimental);
4169+
OptionValueProperties *exp_values =
4170+
exp_property->GetValue()->GetAsProperties();
4171+
if (exp_values)
4172+
return exp_values->GetPropertyAtIndexAsBoolean(
4173+
nullptr, ePropertySwiftCreateModuleContextsInParallel, true);
4174+
else
4175+
return true;
4176+
}
4177+
41664178
bool TargetProperties::GetSwiftReadMetadataFromFileCache() const {
41674179
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
41684180
nullptr, false, ePropertyExperimental);

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ let Definition = "target_experimental" in {
44
def InjectLocalVars : Property<"inject-local-vars", "Boolean">,
55
Global, DefaultTrue,
66
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.">;
7+
def SwiftCreateModuleContextsInParallel : Property<"swift-create-module-contexts-in-parallel", "Boolean">,
8+
DefaultTrue,
9+
Desc<"Create the per-module Swift AST contexts in parallel.">;
710
def SwiftReadMetadataFromFileCache: Property<"swift-read-metadata-from-file-cache", "Boolean">,
811
DefaultTrue,
912
Desc<"Read Swift reflection metadata from the file cache instead of the process when possible">;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@_implementationOnly import Discovered
2+
public class D {
3+
public init() { member = Invisible() }
4+
private let member : Invisible
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
struct Invisible {};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "Discovered.h"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
SWIFT_SOURCES := main.swift
2+
3+
SWIFTFLAGS_EXTRAS = -F $(BUILDDIR) -framework Direct -Xlinker -rpath -Xlinker $(BUILDDIR)
4+
5+
all: Direct.framework $(EXE)
6+
7+
include Makefile.rules
8+
9+
Discovered.framework: Discovered.h
10+
$(MAKE) -f $(MAKEFILE_RULES) \
11+
DYLIB_ONLY=YES \
12+
DYLIB_NAME=Discovered \
13+
DYLIB_OBJC_SOURCES=Discovered.m \
14+
FRAMEWORK_HEADERS=$(SRCDIR)/Discovered.h \
15+
FRAMEWORK_MODULES=$(SRCDIR)/module.modulemap \
16+
FRAMEWORK=Discovered
17+
18+
Direct.framework: $(SRCDIR)/Direct.swift.in Discovered.framework
19+
mkdir -p $(BUILDDIR)/secret_path
20+
cp $< $(BUILDDIR)/Direct.swift
21+
mv Discovered.framework $(BUILDDIR)/secret_path
22+
$(MAKE) -f $(MAKEFILE_RULES) \
23+
DYLIB_NAME=Direct \
24+
DYLIB_SWIFT_SOURCES=Direct.swift \
25+
DYLIB_MODULENAME=Direct \
26+
FRAMEWORK=Direct \
27+
SWIFTFLAGS_EXTRAS=-F$(BUILDDIR)/secret_path
28+
rm -f $(BUILDDIR)/Direct.swiftmodule $(BUILDDIR)/Direct.swiftinterface $(BUILDDIR)/Direct.swift
29+
ln -s $(BUILDDIR)/Direct.framework/Direct $(BUILDDIR)/Direct # FIXME
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import os
6+
import unittest2
7+
8+
9+
class TestSwiftSystemFramework(lldbtest.TestBase):
10+
11+
NO_DEBUG_INFO_TESTCASE = True
12+
mydir = lldbtest.TestBase.compute_mydir(__file__)
13+
14+
@swiftTest
15+
@skipIf(oslist=no_match(["macosx"]))
16+
def test_system_framework(self):
17+
"""Test the discovery of framework search paths from framework dependencies."""
18+
self.build()
19+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
20+
self, 'break here', lldb.SBFileSpec('main.swift'))
21+
22+
log = self.getBuildArtifact("types.log")
23+
self.runCmd('log enable lldb types -f "%s"' % log)
24+
self.expect("expression -- 0")
25+
pos = 0
26+
import io
27+
with open(log, "r", encoding='utf-8') as logfile:
28+
for line in logfile:
29+
if "SwiftASTContextForExpressions::LogConfiguration()" in line and \
30+
"/secret_path" in line:
31+
pos += 1
32+
self.assertEqual(pos, 1, "framework search path discovery is broken")
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Direct
2+
let d = D()
3+
print("break here")
4+
print(d)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
framework module Discovered { header "Discovered.h" }

0 commit comments

Comments
 (0)