Skip to content

Commit 48f0651

Browse files
Merge pull request swiftlang#9857 from adrian-prantl/typeref-enums
[lldb] Eliminate SwiftASTContext from enum handling
2 parents e17653f + e5b0f31 commit 48f0651

File tree

5 files changed

+93
-102
lines changed

5 files changed

+93
-102
lines changed

lldb/source/Plugins/Language/Swift/SwiftOptionSet.cpp

Lines changed: 23 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "SwiftOptionSet.h"
1414

1515
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
16-
#include "Plugins/TypeSystem/Swift/SwiftASTContext.h"
16+
#include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
1717
#include "lldb/Symbol/CompilerType.h"
1818
#include "lldb/Utility/LLDBLog.h"
1919
#include "lldb/Utility/Log.h"
@@ -70,7 +70,7 @@ bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
7070
lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
7171
SwiftOptionSetSummaryProvider(CompilerType clang_type)
7272
: TypeSummaryImpl(TypeSummaryImpl::Kind::eInternal,
73-
TypeSummaryImpl::Flags()),
73+
TypeSummaryImpl::Flags().SetDontShowValue(true)),
7474
m_type(clang_type), m_cases() {}
7575

7676
void lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
@@ -90,29 +90,8 @@ void lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
9090
// information.
9191
auto ts = m_type.GetTypeSystem();
9292
TypeSystemSwift *tss = nullptr;
93-
std::shared_ptr<SwiftASTContext> swift_ast_ctx;
94-
if (auto trts =
95-
ts.dyn_cast_or_null<TypeSystemSwiftTypeRef>()) {
93+
if (auto trts = ts.dyn_cast_or_null<TypeSystemSwiftTypeRef>())
9694
tss = trts.get();
97-
CompilerType ast_type = trts->ReconstructType(m_type, exe_ctx);
98-
swift_ast_ctx =
99-
ast_type.GetTypeSystem().dyn_cast_or_null<SwiftASTContext>();
100-
if (swift_ast_ctx) {
101-
auto ast_decl_ts = GetAsEnumDecl(ast_type);
102-
if (ast_decl_ts.first) {
103-
tss = swift_ast_ctx.get();
104-
enum_decl = ast_decl_ts.first;
105-
m_type = ast_type;
106-
} else {
107-
LLDB_LOG(GetLog(LLDBLog::DataFormatters),
108-
"Cannot get Clang type for {0}",
109-
m_type.GetMangledTypeName());
110-
}
111-
} else {
112-
LLDB_LOG(GetLog(LLDBLog::DataFormatters), "Cannot reconstruct {0}",
113-
m_type.GetMangledTypeName());
114-
}
115-
}
11695
if (!tss) {
11796
LLDB_LOG(GetLog(LLDBLog::DataFormatters), "No typesystem");
11897
return;
@@ -149,43 +128,35 @@ std::string lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
149128
return sstr.GetString().str();
150129
}
151130

152-
static bool ReadValueIfAny(ValueObject &valobj, llvm::APInt &value) {
153-
ValueObjectSP most_qualified_sp(valobj.GetQualifiedRepresentationIfAvailable(
154-
lldb::eDynamicDontRunTarget, true));
155-
156-
bool success;
157-
value = llvm::APInt(64, most_qualified_sp->GetValueAsUnsigned(0, &success));
158-
return success;
159-
}
160-
161-
static ValueObjectSP GetRawValue(ValueObject *valobj) {
162-
if (!valobj)
163-
return nullptr;
164-
165-
static ConstString g_rawValue("rawValue");
166-
167-
auto rawValue_sp = valobj->GetChildMemberWithName(g_rawValue, true);
168-
169-
return rawValue_sp;
170-
}
171-
172131
bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
173132
FormatObject(ValueObject *valobj, std::string &dest,
174133
const TypeSummaryOptions &options) {
175-
auto rawValue_sp = GetRawValue(valobj);
176-
if (!rawValue_sp)
177-
return false;
134+
StreamString ss;
135+
DataExtractor data;
136+
Status error;
178137

179-
llvm::APInt value;
180-
if (!ReadValueIfAny(*rawValue_sp, value))
138+
if (!valobj)
139+
return false;
140+
valobj->GetData(data, error);
141+
if (error.Fail())
181142
return false;
182143

183144
{
184-
ExecutionContext exe_ctx = valobj->GetExecutionContextRef().Lock(false);
145+
ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
146+
StreamString case_s;
147+
if (valobj->GetCompilerType().DumpTypeValue(
148+
&case_s, lldb::eFormatEnum, data, 0, data.GetByteSize(), 0, 0,
149+
exe_ctx.GetBestExecutionContextScope(), false)) {
150+
ss << '.' << case_s.GetData();
151+
dest.assign(ss.GetData());
152+
return true;
153+
}
185154
FillCasesIfNeeded(&exe_ctx);
186155
}
187156

188-
StreamString ss;
157+
offset_t data_offset = 0;
158+
int64_t value = data.GetMaxS64(&data_offset, data.GetByteSize());
159+
189160
bool first_match = true;
190161
bool any_match = false;
191162

@@ -246,11 +217,5 @@ bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
246217

247218
bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
248219
DoesPrintChildren(ValueObject *valobj) const {
249-
auto rawValue_sp = GetRawValue(valobj);
250-
if (!rawValue_sp)
251-
return false;
252-
253-
llvm::APInt value;
254-
// only show children if you couldn't read the value of rawValue
255-
return (false == ReadValueIfAny(*rawValue_sp, value));
220+
return false;
256221
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ llvm::Expected<std::string> SwiftLanguageRuntime::GetEnumCaseName(
997997
return eti->getCases()[case_index].Name;
998998

999999
// TODO: uncomment this after fixing projection for every type: rdar://138424904
1000-
// LogUnimplementedTypeKind(__FUNCTION__, type);
1000+
LogUnimplementedTypeKind(__FUNCTION__, type);
10011001
return llvm::createStringError("unimplemented enum kind");
10021002
}
10031003

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8469,15 +8469,9 @@ bool SwiftASTContext::DumpTypeValue(
84698469
SwiftEnumDescriptor *cached_enum_info = GetCachedEnumInfo(type);
84708470
if (cached_enum_info) {
84718471
auto enum_elem_info = cached_enum_info->GetElementFromData(data, true);
8472-
if (enum_elem_info)
8473-
s.Printf("%s", enum_elem_info->name.GetCString());
8474-
else {
8475-
lldb::offset_t ptr = 0;
8476-
if (data.GetByteSize())
8477-
s.Printf("<invalid> (0x%" PRIx8 ")", data.GetU8(&ptr));
8478-
else
8479-
s.Printf("<empty>");
8480-
}
8472+
if (!enum_elem_info)
8473+
return false;
8474+
s.Printf("%s", enum_elem_info->name.GetCString());
84818475
return true;
84828476
} else
84838477
s.Printf("<unknown type>");

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

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ class ClangNameImporter {
9292
return imported_name.getBaseName().userFacingName().str();
9393
}
9494

95+
template <typename IntTy>
96+
llvm::StringRef ProjectEnumCase(const clang::EnumDecl *decl, IntTy val) {
97+
for (const auto *enumerator : decl->enumerators()) {
98+
llvm::APSInt case_val = enumerator->getInitVal();
99+
if ((case_val.isSigned() &&
100+
llvm::APSInt::isSameValue(case_val, llvm::APSInt::get(val))) ||
101+
(case_val.isUnsigned() &&
102+
llvm::APSInt::isSameValue(case_val, llvm::APSInt::getUnsigned(val))))
103+
return m_clang_importer->getEnumConstantName(enumerator).str();
104+
}
105+
return {};
106+
}
107+
95108
private:
96109
swift::CompilerInvocation m_compiler_invocation;
97110
swift::SourceManager m_source_manager;
@@ -2638,7 +2651,8 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
26382651
return result; \
26392652
} while (0)
26402653

2641-
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
2654+
#define VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, COMPARISON, EXE_CTX, \
2655+
ARGS) \
26422656
do { \
26432657
auto result = IMPL(); \
26442658
if (!ModuleList::GetGlobalModuleListProperties() \
@@ -2658,7 +2672,7 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
26582672
return result; \
26592673
bool equivalent = \
26602674
!ReconstructType(TYPE) /* missing .swiftmodule */ || \
2661-
(Equivalent( \
2675+
(COMPARISON( \
26622676
result, \
26632677
GetSwiftASTContext(GetSymbolContext(&_exe_ctx))->REFERENCE ARGS)); \
26642678
if (!equivalent) \
@@ -2668,6 +2682,9 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
26682682
return result; \
26692683
} while (0)
26702684

2685+
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
2686+
VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, Equivalent, EXE_CTX, ARGS)
2687+
26712688
#define VALIDATE_AND_RETURN_EXPECTED(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
26722689
do { \
26732690
auto result = IMPL(); \
@@ -2707,7 +2724,10 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
27072724
#else
27082725
#define VALIDATE_AND_RETURN_STATIC(IMPL, REFERENCE) \
27092726
return IMPL()
2710-
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) return IMPL();
2727+
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, COMPARISON, EXE_CTX, ARGS) \
2728+
return IMPL();
2729+
#define VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
2730+
return IMPL();
27112731
#define VALIDATE_AND_RETURN_EXPECTED(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
27122732
return IMPL();
27132733
#endif
@@ -4731,18 +4751,41 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
47314751
// In some instances, a swift `structure` wraps an objc enum. The enum
47324752
// case needs to be handled, but structs are no-ops.
47334753
auto resolved = ResolveTypeAlias(dem, node, flavor, true);
4734-
auto clang_type = std::get<CompilerType>(resolved);
4735-
if (!clang_type)
4754+
auto resolved_type = std::get<CompilerType>(resolved);
4755+
if (!resolved_type)
47364756
return false;
47374757

47384758
bool is_signed;
4739-
if (!clang_type.IsEnumerationType(is_signed))
4759+
if (!resolved_type.IsEnumerationType(is_signed))
47404760
// The type is a clang struct, not an enum.
47414761
return false;
47424762

4743-
// The type is an enum imported from clang. Try Swift type metadata first,
4744-
// and failing that fallback to the AST.
4745-
LLVM_FALLTHROUGH;
4763+
if (!resolved_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>())
4764+
return false;
4765+
4766+
// The type is an enum imported from clang.
4767+
auto qual_type = ClangUtil::GetQualType(resolved_type);
4768+
auto *enum_type =
4769+
llvm::dyn_cast_or_null<clang::EnumType>(qual_type.getTypePtrOrNull());
4770+
if (!enum_type)
4771+
return false;
4772+
auto *importer = GetNameImporter();
4773+
if (!importer)
4774+
return false;
4775+
if (!data_byte_size)
4776+
return false;
4777+
StringRef case_name;
4778+
if (is_signed) {
4779+
int64_t val = data.GetMaxS64(&data_offset, data_byte_size);
4780+
case_name = importer->ProjectEnumCase(enum_type->getDecl(), val);
4781+
} else {
4782+
uint64_t val = data.GetMaxU64(&data_offset, data_byte_size);
4783+
case_name = importer->ProjectEnumCase(enum_type->getDecl(), val);
4784+
}
4785+
if (case_name.empty())
4786+
return false;
4787+
s << case_name;
4788+
return true;
47464789
}
47474790
case Node::Kind::Enum:
47484791
case Node::Kind::BoundGenericEnum: {
@@ -4762,18 +4805,6 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
47624805
error = toString(case_name.takeError());
47634806
}
47644807

4765-
// No result available from the runtime, fallback to the AST. This occurs
4766-
// for some Clang imported enums.
4767-
if (auto swift_ast_context =
4768-
GetSwiftASTContext(GetSymbolContext(exe_scope))) {
4769-
ExecutionContext exe_ctx;
4770-
exe_scope->CalculateExecutionContext(exe_ctx);
4771-
if (swift_ast_context->DumpTypeValue(
4772-
ReconstructType(type, &exe_ctx), s, format, data, data_offset,
4773-
data_byte_size, bitfield_bit_size, bitfield_bit_offset,
4774-
exe_scope, is_base_class))
4775-
return true;
4776-
}
47774808
s << error;
47784809
return false;
47794810
}
@@ -4825,17 +4856,21 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
48254856
ConstString(((StreamString *)&s)->GetString())) &&
48264857
"TypeSystemSwiftTypeRef diverges from SwiftASTContext");
48274858
});
4828-
4829-
// SwiftASTContext fails here, details explained in RemoteASTImport.test
4830-
if (StringRef(AsMangledName(type)) == "$s15RemoteASTImport14FromMainModuleCD")
4831-
return impl();
4832-
48334859
#endif
48344860

4835-
VALIDATE_AND_RETURN(impl, DumpTypeValue, type, exe_scope,
4836-
(ReconstructType(type, exe_scope), ast_s, format, data,
4837-
data_offset, data_byte_size, bitfield_bit_size,
4838-
bitfield_bit_offset, exe_scope, is_base_class));
4861+
auto better_or_equal = [](bool a, bool b) -> bool {
4862+
if (a || a == b)
4863+
return true;
4864+
4865+
llvm::dbgs() << "TypeSystemSwiftTypeRef: " << a << " SwiftASTContext: " << b
4866+
<< "\n";
4867+
return false;
4868+
};
4869+
VALIDATE_AND_RETURN_CUSTOM(
4870+
impl, DumpTypeValue, type, better_or_equal, exe_scope,
4871+
(ReconstructType(type, exe_scope), ast_s, format, data, data_offset,
4872+
data_byte_size, bitfield_bit_size, bitfield_bit_offset, exe_scope,
4873+
is_base_class));
48394874
}
48404875

48414876
bool TypeSystemSwiftTypeRef::IsPointerOrReferenceType(

lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,4 @@
1313
from lldbsuite.test.decorators import *
1414

1515
lldbinline.MakeInlineTest(__file__, globals(),
16-
decorators=[swiftTest,skipUnlessDarwin,
17-
expectedFailureAll(bugnumber="rdar://60396797",
18-
setting=('symbols.use-swift-clangimporter', 'false'))
19-
])
16+
decorators=[swiftTest,skipUnlessDarwin])

0 commit comments

Comments
 (0)