Skip to content

Commit 471bfae

Browse files
Merge pull request #8480 from adrian-prantl/121758809
Clear the Clang type cache when new modules are loaded / Create non-null typerefs in field descriptors for Clang types
2 parents f86065d + 6d6646f commit 471bfae

12 files changed

+178
-41
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/ReflectionContext.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class TargetReflectionContext : public ReflectionContextInterface {
132132
const swift::reflection::TypeRef *type_ref =
133133
GetTypeRefOrNull(dem, node, descriptor_finder);
134134
if (!type_ref)
135-
LLDB_LOG(GetLog(LLDBLog::Types), "Could not find typeref for type: {0}",
135+
LLDB_LOG(GetLog(LLDBLog::Types), "Could not find typeref for type {0}",
136136
mangled_type_name);
137137
return type_ref;
138138
}
@@ -197,8 +197,9 @@ class TargetReflectionContext : public ReflectionContextInterface {
197197
std::stringstream ss;
198198
type_ref->dump(ss);
199199
LLDB_LOG(log,
200-
"[TargetReflectionContext::getTypeInfo] Getting "
201-
"type info for typeref:\n{0}", ss.str());
200+
"[TargetReflectionContext[{0:x}]::getTypeInfo] Getting type "
201+
"info for typeref {1}",
202+
provider ? provider->getId() : 0, ss.str());
202203
}
203204

204205
auto type_info = m_reflection_ctx.getTypeInfo(type_ref, provider);
@@ -207,7 +208,7 @@ class TargetReflectionContext : public ReflectionContextInterface {
207208
type_ref->dump(ss);
208209
LLDB_LOG(log,
209210
"[TargetReflectionContext::getTypeInfo] Could not get "
210-
"type info for typeref:\n{0}",
211+
"type info for typeref {0}",
211212
ss.str());
212213
}
213214

@@ -216,8 +217,8 @@ class TargetReflectionContext : public ReflectionContextInterface {
216217
type_info->dump(ss);
217218
LLDB_LOG(log,
218219
"[TargetReflectionContext::getTypeInfo] Found "
219-
"type info:\n{0}",
220-
ss.str());
220+
"type info {0}",
221+
ss.str());
221222
}
222223
return type_info;
223224
}

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
353353
ExecutionContext exe_ctx;
354354
process.CalculateExecutionContext(exe_ctx);
355355
auto *exe_scope = exe_ctx.GetBestExecutionContextScope();
356+
TypeSystemSwiftTypeRef &typesystem = *m_reader->get();
356357
// Build a TypeInfo for the Clang type.
357358
auto size = clang_type.GetByteSize(exe_scope);
358359
auto bit_align = clang_type.GetTypeBitAlign(exe_scope);
@@ -372,11 +373,14 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
372373
"[LLDBTypeInfoProvider] bitfield support is not yet implemented");
373374
continue;
374375
}
376+
CompilerType swift_type =
377+
typesystem.ConvertClangTypeToSwiftType(field_type);
378+
auto *typeref = m_runtime.GetTypeRef(swift_type, &typesystem);
375379
swift::reflection::FieldInfo field_info = {
376-
name, (unsigned)bit_offset_ptr / 8, 0, nullptr,
380+
name, (unsigned)bit_offset_ptr / 8, 0, typeref,
377381
*GetOrCreateTypeInfo(field_type)};
378382
fields.push_back(field_info);
379-
}
383+
}
380384
}
381385
return m_runtime.emplaceClangTypeInfo(clang_type, size, bit_align, fields);
382386
}

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ class SwiftLanguageRuntimeImpl {
197197

198198
bool IsABIStable();
199199

200+
/// Use the reflection context to build a TypeRef object.
201+
const swift::reflection::TypeRef *
202+
GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder);
203+
200204
void DumpTyperef(CompilerType type, TypeSystemSwiftTypeRef *module_holder,
201205
Stream *s);
202206

@@ -212,10 +216,6 @@ class SwiftLanguageRuntimeImpl {
212216
SwiftLanguageRuntime::ForEachGenericParameter(node, callback);
213217
}
214218

215-
/// Use the reflection context to build a TypeRef object.
216-
const swift::reflection::TypeRef *
217-
GetTypeRef(CompilerType type, TypeSystemSwiftTypeRef *module_holder);
218-
219219
/// If \p instance points to a Swift object, retrieve its
220220
/// RecordTypeInfo and pass it to the callback \p fn. Repeat the
221221
/// process with all superclasses. If \p fn returns \p true, early

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

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#include <algorithm>
4848
#include <sstream>
49+
#include <type_traits>
4950

5051
using namespace lldb;
5152
using namespace lldb_private;
@@ -190,7 +191,6 @@ GetMangledName(swift::Demangle::Demangler &dem,
190191
return mangleNode(global);
191192
}
192193

193-
/// Find a Clang type by name in the modules in \p module_holder.
194194
TypeSP TypeSystemSwiftTypeRef::LookupClangType(StringRef name_ref) {
195195
llvm::SmallVector<CompilerContext, 2> decl_context;
196196
// Make up a decl context for non-nested types.
@@ -199,45 +199,65 @@ TypeSP TypeSystemSwiftTypeRef::LookupClangType(StringRef name_ref) {
199199
return LookupClangType(name_ref, decl_context);
200200
}
201201

202-
/// Find a Clang type by name in the modules in \p module_holder.
203-
TypeSP TypeSystemSwiftTypeRef::LookupClangType(
204-
StringRef name_ref, llvm::ArrayRef<CompilerContext> decl_context) {
205-
202+
/// Look up one Clang type in a module.
203+
static TypeSP LookupClangType(Module &m,
204+
llvm::ArrayRef<CompilerContext> decl_context) {
206205
TypeQuery query(decl_context, TypeQueryOptions::e_find_one |
207206
TypeQueryOptions::e_module_search);
208207
query.SetLanguages(TypeSystemClang::GetSupportedLanguagesForTypes());
208+
TypeResults results;
209+
m.FindTypes(query, results);
210+
return results.GetFirstType();
211+
}
209212

210-
auto lookup = [&](Module &M) -> TypeSP {
211-
TypeResults results;
212-
M.FindTypes(query, results);
213-
return results.GetFirstType();
214-
};
213+
TypeSP TypeSystemSwiftTypeRef::LookupClangType(
214+
StringRef name_ref, llvm::ArrayRef<CompilerContext> decl_context,
215+
ExecutionContext *exe_ctx) {
216+
Module *m = GetModule();
217+
if (!m)
218+
return {};
219+
return ::LookupClangType(const_cast<Module &>(*m), decl_context);
220+
}
215221

222+
TypeSP TypeSystemSwiftTypeRefForExpressions::LookupClangType(
223+
StringRef name_ref, llvm::ArrayRef<CompilerContext> decl_context,
224+
ExecutionContext *exe_ctx) {
216225
// Check the cache first. Negative results are also cached.
217226
TypeSP result;
218227
ConstString name(name_ref);
219228
if (m_clang_type_cache.Lookup(name.AsCString(), result))
220229
return result;
221230

222-
if (auto *M = GetModule()) {
223-
TypeSP result = lookup(*M);
224-
// Cache it.
225-
m_clang_type_cache.Insert(name.AsCString(), result);
226-
return result;
227-
}
228-
229231
TargetSP target_sp = GetTargetWP().lock();
230232
if (!target_sp)
231233
return {};
232-
target_sp->GetImages().ForEach([&](const ModuleSP &module) -> bool {
234+
235+
ModuleSP cur_module;
236+
if (exe_ctx)
237+
if (StackFrame *frame = exe_ctx->GetFramePtr())
238+
cur_module =
239+
frame->GetSymbolContext(lldb::eSymbolContextModule).module_sp;
240+
241+
auto lookup = [&](const ModuleSP &m) -> bool {
242+
// Already visited this.
243+
if (m == cur_module)
244+
return true;
245+
233246
// Don't recursively call into LookupClangTypes() to avoid filling
234247
// hundreds of image caches with negative results.
235-
result = lookup(const_cast<Module &>(*module));
248+
result = ::LookupClangType(const_cast<Module &>(*m), decl_context);
236249
// Cache it in the expression context.
237250
if (result)
238251
m_clang_type_cache.Insert(name.AsCString(), result);
239252
return !result;
240-
});
253+
};
254+
255+
// Visit the current module first as a performance optimization heuristic.
256+
if (cur_module)
257+
if (!lookup(cur_module))
258+
return result;
259+
260+
target_sp->GetImages().ForEach(lookup);
241261
return result;
242262
}
243263

@@ -331,6 +351,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
331351
return optional;
332352
}
333353
}
354+
if (clang_type.IsAnonymousType())
355+
return nullptr;
334356
llvm::StringRef clang_name = clang_type.GetTypeName().GetStringRef();
335357
#define MAP_TYPE(C_TYPE_NAME, C_TYPE_KIND, C_TYPE_BITWIDTH, SWIFT_MODULE_NAME, \
336358
SWIFT_TYPE_NAME, CAN_BE_MISSING, C_NAME_MAPPING) \
@@ -383,6 +405,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
383405
auto *tuple = dem.createNode(Node::Kind::Tuple);
384406
NodePointer element_type = GetClangTypeNode(
385407
{clang_type.GetTypeSystem(), elem_type.getAsOpaquePtr()}, dem);
408+
if (!element_type)
409+
return nullptr;
386410
for (unsigned i = 0; i < size; ++i) {
387411
NodePointer tuple_element = dem.createNode(Node::Kind::TupleElement);
388412
NodePointer type = dem.createNode(Node::Kind::Type);
@@ -414,6 +438,8 @@ TypeSystemSwiftTypeRef::GetClangTypeNode(CompilerType clang_type,
414438
break;
415439

416440
NodePointer element_type_node = GetClangTypeNode(element_type, dem);
441+
if (!element_type_node)
442+
return nullptr;
417443
llvm::SmallVector<NodePointer, 1> elements({element_type_node});
418444
return CreateBoundGenericStruct("SIMD" + std::to_string(size),
419445
swift::STDLIB_NAME, elements, dem);
@@ -819,8 +845,12 @@ TypeSystemSwiftTypeRef::GetCanonicalNode(swift::Demangle::Demangler &dem,
819845
case Node::Kind::BoundGenericTypeAlias:
820846
case Node::Kind::TypeAlias: {
821847
auto node_clangtype = ResolveTypeAlias(dem, node);
822-
if (CompilerType clang_type = node_clangtype.second)
823-
return GetClangTypeNode(clang_type, dem);
848+
if (CompilerType clang_type = node_clangtype.second) {
849+
if (auto result = GetClangTypeNode(clang_type, dem))
850+
return result;
851+
else
852+
return node;
853+
}
824854
if (node_clangtype.first)
825855
return node_clangtype.first;
826856
return node;
@@ -1491,6 +1521,7 @@ void TypeSystemSwiftTypeRef::NotifyAllTypeSystems(
14911521
void TypeSystemSwiftTypeRefForExpressions::ModulesDidLoad(
14921522
ModuleList &module_list) {
14931523
++m_generation;
1524+
m_clang_type_cache.Clear();
14941525
NotifyAllTypeSystems([&](TypeSystemSP ts_sp) {
14951526
if (auto swift_ast_ctx =
14961527
llvm::dyn_cast_or_null<SwiftASTContextForExpressions>(ts_sp.get()))
@@ -3180,8 +3211,11 @@ TypeSystemSwiftTypeRef::GetClangTypeTypeNode(swift::Demangle::Demangler &dem,
31803211
assert(clang_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>() &&
31813212
"expected a clang type");
31823213
using namespace swift::Demangle;
3214+
NodePointer node = GetClangTypeNode(clang_type, dem);
3215+
if (!node)
3216+
return nullptr;
31833217
NodePointer type = dem.createNode(Node::Kind::Type);
3184-
type->addChild(GetClangTypeNode(clang_type, dem), dem);
3218+
type->addChild(node, dem);
31853219
return type;
31863220
}
31873221

@@ -3358,6 +3392,8 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
33583392
swift::Demangle::Demangler dem;
33593393
swift::Demangle::NodePointer node =
33603394
GetClangTypeTypeNode(dem, clang_child_type);
3395+
if (!node)
3396+
return {};
33613397
switch (node->getChild(0)->getKind()) {
33623398
case swift::Demangle::Node::Kind::Class:
33633399
prefix = "ObjectiveC.";
@@ -3440,6 +3476,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
34403476
ast_child_name = suffix.str();
34413477
assert((llvm::StringRef(child_name).contains('.') ||
34423478
llvm::StringRef(ast_child_name).contains('.') ||
3479+
llvm::StringRef(ast_child_name).starts_with("_") ||
34433480
Equivalent(child_name, ast_child_name)));
34443481
assert(ast_language_flags ||
34453482
(Equivalent(std::optional<uint64_t>(child_byte_size),
@@ -4457,6 +4494,8 @@ TypeSystemSwiftTypeRef::GetTypedefedType(opaque_compiler_type_t type) {
44574494
} else {
44584495
NodePointer clang_node =
44594496
GetClangTypeNode(std::get<CompilerType>(pair), dem);
4497+
if (!clang_node)
4498+
return {};
44604499
type_node->addChild(clang_node, dem);
44614500
}
44624501
return RemangleAsType(dem, type_node);

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,11 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
383383
lldb::TypeSP LookupClangType(llvm::StringRef name_ref);
384384

385385
/// Search the debug info for a Clang type with the specified name and decl
386-
/// context, and cache the result.
387-
lldb::TypeSP LookupClangType(llvm::StringRef name_ref,
388-
llvm::ArrayRef<CompilerContext> decl_context);
386+
/// context.
387+
virtual lldb::TypeSP
388+
LookupClangType(llvm::StringRef name_ref,
389+
llvm::ArrayRef<CompilerContext> decl_context,
390+
ExecutionContext *exe_ctx = nullptr);
389391

390392
/// Attempts to convert a Clang type into a Swift type.
391393
/// For example, int is converted to Int32.
@@ -397,6 +399,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
397399

398400
/// Lookup a type in the debug info.
399401
lldb::TypeSP FindTypeInModule(lldb::opaque_compiler_type_t type);
402+
400403
protected:
401404
/// Helper that creates an AST type from \p type.
402405
void *ReconstructType(lldb::opaque_compiler_type_t type,
@@ -491,8 +494,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
491494

492495
/// All lldb::Type pointers produced by DWARFASTParser Swift go here.
493496
ThreadSafeDenseMap<const char *, lldb::TypeSP> m_swift_type_map;
494-
/// Map ConstString Clang type identifiers to Clang types.
495-
ThreadSafeDenseMap<const char *, lldb::TypeSP> m_clang_type_cache;
496497
};
497498

498499
/// This one owns a SwiftASTContextForExpressions.
@@ -535,8 +536,15 @@ class TypeSystemSwiftTypeRefForExpressions : public TypeSystemSwiftTypeRef {
535536
/// Forwards to SwiftASTContext.
536537
PersistentExpressionState *GetPersistentExpressionState() override;
537538
Status PerformCompileUnitImports(const SymbolContext &sc);
538-
/// Returns how often ModulesDidLoad was called/
539+
/// Returns how often ModulesDidLoad was called.
539540
unsigned GetGeneration() const { return m_generation; }
541+
/// Performs a target-wide search.
542+
/// \param exe_ctx is a hint for where to look first.
543+
lldb::TypeSP
544+
LookupClangType(llvm::StringRef name_ref,
545+
llvm::ArrayRef<CompilerContext> decl_context,
546+
ExecutionContext *exe_ctx) override;
547+
540548

541549
friend class SwiftASTContextForExpressions;
542550
protected:
@@ -553,6 +561,8 @@ class TypeSystemSwiftTypeRefForExpressions : public TypeSystemSwiftTypeRef {
553561
/// Perform all the implicit imports for the current frame.
554562
mutable std::unique_ptr<SymbolContext> m_initial_symbol_context_up;
555563
std::unique_ptr<SwiftPersistentExpressionState> m_persistent_state_up;
564+
/// Map ConstString Clang type identifiers to Clang types.
565+
ThreadSafeDenseMap<const char *, lldb::TypeSP> m_clang_type_cache;
556566
};
557567

558568
} // namespace lldb_private
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct FromClang {
2+
int x;
3+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct FromClang {
2+
int x;
3+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This Makefile recursively calls itself, hence the ?=.
2+
EXE ?= a.out
3+
SWIFT_SOURCES ?= loader.swift
4+
SWIFT_BRIDGING_HEADER ?= ClangHeader.h
5+
SWIFT_PRECOMPILE_BRIDGING_HEADER ?= NO
6+
SWIFTFLAGS_EXTRAS ?= -enable-bare-slash-regex
7+
8+
all: dylib $(EXE)
9+
10+
include Makefile.rules
11+
12+
.PHONY: dylib
13+
dylib:
14+
$(MAKE) MAKE_DSYM=$(MAKE_DSYM) CC=$(CC) SWIFTC=$(SWIFTC) \
15+
ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
16+
VPATH=$(SRCDIR) -I $(SRCDIR) \
17+
-f $(SRCDIR)/Makefile \
18+
DYLIB_FILENAME=dylib.dylib \
19+
DYLIB_SWIFT_SOURCES=dylib.swift \
20+
DYLIB_NAME=dylib \
21+
DYLIB_ONLY=YES \
22+
SWIFTFLAGS_EXTRAS="-Xcc -I$(SRCDIR)" \
23+
SWIFT_SOURCES= \
24+
SWIFT_BRIDGING_HEADER= \
25+
LD_EXTRAS="-lSwiftCore -Xlinker -exported_symbol -Xlinker _f" \
26+
dylib.dylib
27+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from lldbsuite.test.lldbtest import *
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbutil as lldbutil
4+
5+
class TestSwiftLateSwiftDylibClangDeps(TestBase):
6+
@skipUnlessDarwin
7+
@swiftTest
8+
@skipIfDarwinEmbedded
9+
def test(self):
10+
"""Test that the reflection metadata cache is invalidated
11+
when new DWARF debug info is available"""
12+
self.build()
13+
target, process, _, _ = lldbutil.run_to_source_breakpoint(
14+
self, "break here", lldb.SBFileSpec("loader.swift"))
15+
16+
# Initialize SwiftASTContext before loading the dylib.
17+
self.runCmd("setting set symbols.swift-enable-ast-context false")
18+
self.expect("v fromClang",
19+
substrs=["missing debug info", "FromClang"])
20+
21+
bkpt = target.BreakpointCreateByLocation(
22+
lldb.SBFileSpec('dylib.swift'), 5)
23+
threads = lldbutil.continue_to_breakpoint(process, bkpt)
24+
25+
self.expect("v x", substrs=['42'])
26+
self.expect("frame select 1")
27+
self.expect("v fromClang", substrs=['23'])

0 commit comments

Comments
 (0)