Skip to content

Commit 0551ad0

Browse files
committed
[lldb] Initialize a shared, blank SwiftASTContext in Objective-C frames
The result of an Objective-C expression can be a Swift ValueObject. This means that `po foo` in Objective-C may run a Swift expression to print the object description of the result of the Objective-C expression `foo`. That expression has very few dependencies: ``` Swift._DebuggerSupport.stringForPrintObject(Swift.unsafeBitCast(0x001234, to: AnyObject.self)) ``` To avoid scanning potentially incompatible compiler flags and/or doing implicit imports in anotherwise explicitly built project, this patch ensures that one SwiftASTContext per triple is created, with no other contextual information. This makes `po` in ObjC much faster and reliable, the downside of this is that ```expr -l Swift -- import ModuleName``` will only work reliably for SDK modules outside of Swift frames. rdar://153332037
1 parent 771130a commit 0551ad0

File tree

14 files changed

+83
-129
lines changed

14 files changed

+83
-129
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,17 +2707,18 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
27072707

27082708
CompileUnit *cu = sc.comp_unit;
27092709
const char *key = TypeSystemSwiftTypeRef::DeriveKeyFor(sc);
2710+
bool swift_context = cu && cu->GetLanguage() == eLanguageTypeSwift;
27102711
std::string m_description;
27112712
{
27122713
StreamString ss;
27132714
ss << "SwiftASTContext";
27142715
if (for_expressions)
27152716
ss << "ForExpressions";
27162717
ss << "(module: " << '"' << key << "\", " << "cu: " << '"';
2717-
if (cu)
2718+
if (cu && swift_context)
27182719
ss << cu->GetPrimaryFile().GetFilename();
27192720
else
2720-
ss << "null";
2721+
ss << "*";
27212722
ss << '"' << ')';
27222723
m_description = ss.GetString();
27232724
}
@@ -2797,7 +2798,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
27972798
ModuleList module_module;
27982799
if (!target_sp)
27992800
module_module.Append(module_sp);
2800-
ModuleList &modules = target_sp ? target_sp->GetImages() : module_module;
2801+
ModuleList &modules =
2802+
(target_sp && swift_context) ? target_sp->GetImages() : module_module;
28012803
const size_t num_images = modules.GetSize();
28022804

28032805
// Set the SDK path prior to doing search paths. Otherwise when we
@@ -3133,7 +3135,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
31333135
}
31343136
}
31353137
};
3136-
scan_module(module_sp, 0);
3138+
if (swift_context)
3139+
scan_module(module_sp, 0);
31373140
for (size_t mi = 0; mi != num_images; ++mi) {
31383141
auto image_sp = modules.GetModuleAtIndex(mi);
31393142
if (!visited_modules.count(image_sp.get()))

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,15 +2072,14 @@ ConstString TypeSystemSwiftTypeRef::GetSwiftModuleFor(const SymbolContext &sc) {
20722072
}
20732073

20742074
const char *TypeSystemSwiftTypeRef::DeriveKeyFor(const SymbolContext &sc) {
2075-
if (sc.function)
2075+
if (sc.comp_unit && sc.comp_unit->GetLanguage() == eLanguageTypeSwift)
20762076
if (ConstString name = GetSwiftModuleFor(sc))
20772077
return name.GetCString();
20782078

2079-
if (sc.module_sp) {
2080-
if (sc.module_sp->GetFileSpec())
2081-
return sc.module_sp->GetFileSpec().GetFilename().GetCString();
2082-
return sc.module_sp->GetObjectName().GetCString();
2083-
}
2079+
// Otherwise create a catch-all context per unique triple.
2080+
if (sc.module_sp)
2081+
return ConstString(sc.module_sp->GetArchitecture().GetTriple().str()).AsCString();
2082+
20842083
return nullptr;
20852084
}
20862085

@@ -2563,6 +2562,9 @@ template <> bool Equivalent<CompilerType>(CompilerType l, CompilerType r) {
25632562
ConstString rhs = r.GetMangledTypeName();
25642563
if (lhs == ConstString("$sSiD") && rhs == ConstString("$sSuD"))
25652564
return true;
2565+
if (lhs.GetStringRef() == "$sSPySo0023unnamedstruct_hEEEdhdEaVGSgD" &&
2566+
rhs.GetStringRef() == "$ss13OpaquePointerVSgD")
2567+
return true;
25662568
// Ignore missing sugar.
25672569
swift::Demangle::Demangler dem;
25682570
auto l_node = GetDemangledType(dem, lhs.GetStringRef());
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@import Foundation;
2+
@interface Base : NSObject
3+
@end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Foundation
2+
import Base
3+
4+
private class Bar : Base {
5+
}
6+
7+
extension Bar {
8+
override var debugDescription : String { "Hello from Swift" }
9+
}
10+
11+
@objc public class Foo : NSObject {
12+
@objc public func getBase() -> Base? {
13+
return Bar()
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
OBJC_SOURCES := main.m
2+
CFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) -I. -I$(BUILDDIR)
3+
4+
SWIFT_SOURCES := Foo.swift
5+
SWIFTFLAGS_EXTRAS = -Xcc -I$(SRCDIR) -emit-objc-header-path Foo.h -parse-as-library
6+
7+
all: Foo.swift.o $(EXE)
8+
9+
include Makefile.rules
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
class TestSwiftPOObjC(TestBase):
7+
#NO_DEBUG_INFO_TESTCASE = True
8+
@skipUnlessDarwin
9+
@swiftTest
10+
def test(self):
11+
"""Test running po on a Swift object from Objective-C. This
12+
should initialize a generic SwiftASTContext with no parsing of
13+
Swift modules happening"""
14+
self.build()
15+
16+
lldbutil.run_to_source_breakpoint(
17+
self, "break here", lldb.SBFileSpec('main.m'))
18+
19+
log = self.getBuildArtifact("types.log")
20+
self.expect('log enable lldb types -f "%s"' % log)
21+
self.expect("expr -O -- base", substrs=["Hello from Swift"])
22+
self.filecheck('platform shell cat "%s"' % log, __file__)
23+
### -cc1 should be round-tripped so there is no more `-cc1` in the extra args. Look for `-triple` which is a cc1 flag.
24+
# CHECK-NOT: parsed module "a"
25+
# CHECK: SwiftASTContextForExpressions(module: "{{.*-.*-.*}}", cu: "*")::LogConfiguration()
26+
self.expect("expr -- base", substrs=["a.Bar"])
27+
self.expect("expr -- *base", substrs=["a.Bar"])
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import Foundation;
2+
@import Base;
3+
#import "Foo.h"
4+
5+
@implementation Base
6+
@end
7+
8+
int main(int argc, char **argv) {
9+
Foo *foo = [[Foo alloc] init];
10+
Base *base = [foo getBase];
11+
return 0; // break here
12+
13+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module Base { header "Base.h" }

lldb/test/API/lang/swift/unit-tests/Info.plist

Lines changed: 0 additions & 8 deletions
This file was deleted.

lldb/test/API/lang/swift/unit-tests/Makefile

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)