Skip to content

Commit

Permalink
[lldb] Elimintate SwiftASTContext from enum handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adrian-prantl committed Jan 18, 2025
1 parent be14764 commit 21c0612
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 54 deletions.
54 changes: 20 additions & 34 deletions lldb/source/Plugins/Language/Swift/SwiftOptionSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,43 +149,35 @@ std::string lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
return sstr.GetString().str();
}

static bool ReadValueIfAny(ValueObject &valobj, llvm::APInt &value) {
ValueObjectSP most_qualified_sp(valobj.GetQualifiedRepresentationIfAvailable(
lldb::eDynamicDontRunTarget, true));

bool success;
value = llvm::APInt(64, most_qualified_sp->GetValueAsUnsigned(0, &success));
return success;
}

static ValueObjectSP GetRawValue(ValueObject *valobj) {
if (!valobj)
return nullptr;

static ConstString g_rawValue("rawValue");

auto rawValue_sp = valobj->GetChildMemberWithName(g_rawValue, true);

return rawValue_sp;
}

bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
FormatObject(ValueObject *valobj, std::string &dest,
const TypeSummaryOptions &options) {
auto rawValue_sp = GetRawValue(valobj);
if (!rawValue_sp)
return false;
StreamString ss;
DataExtractor data;
Status error;

llvm::APInt value;
if (!ReadValueIfAny(*rawValue_sp, value))
if (!valobj)
return false;
valobj->GetData(data, error);
if (error.Fail())
return false;

{
ExecutionContext exe_ctx = valobj->GetExecutionContextRef().Lock(false);
ExecutionContext exe_ctx(valobj->GetExecutionContextRef());
StreamString case_s;
if (valobj->GetCompilerType().DumpTypeValue(
&case_s, lldb::eFormatEnum, data, 0, data.GetByteSize(), 0, 0,
exe_ctx.GetBestExecutionContextScope(), false)) {
ss << '.' << case_s.GetData();
dest.assign(ss.GetData());
return true;
}
FillCasesIfNeeded(&exe_ctx);
}

StreamString ss;
offset_t data_offset = 0;
int64_t value = data.GetMaxS64(&data_offset, data.GetByteSize());

bool first_match = true;
bool any_match = false;

Expand Down Expand Up @@ -246,11 +238,5 @@ bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::

bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
DoesPrintChildren(ValueObject *valobj) const {
auto rawValue_sp = GetRawValue(valobj);
if (!rawValue_sp)
return false;

llvm::APInt value;
// only show children if you couldn't read the value of rawValue
return (false == ReadValueIfAny(*rawValue_sp, value));
return false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ llvm::Expected<std::string> SwiftLanguageRuntime::GetEnumCaseName(
return eti->getCases()[case_index].Name;

// TODO: uncomment this after fixing projection for every type: rdar://138424904
// LogUnimplementedTypeKind(__FUNCTION__, type);
LogUnimplementedTypeKind(__FUNCTION__, type);
return llvm::createStringError("unimplemented enum kind");
}

Expand Down
57 changes: 38 additions & 19 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ class ClangNameImporter {
return imported_name.getBaseName().userFacingName().str();
}

template <typename IntTy>
llvm::StringRef ProjectEnumCase(const clang::EnumDecl *decl, IntTy val) {
for (const auto *enumerator : decl->enumerators())
if (enumerator->getInitVal() == val)
return m_clang_importer->getEnumConstantName(enumerator).str();
return {};
}

private:
swift::CompilerInvocation m_compiler_invocation;
swift::SourceManager m_source_manager;
Expand Down Expand Up @@ -4643,18 +4651,41 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
// In some instances, a swift `structure` wraps an objc enum. The enum
// case needs to be handled, but structs are no-ops.
auto resolved = ResolveTypeAlias(dem, node, true);
auto clang_type = std::get<CompilerType>(resolved);
if (!clang_type)
return false;
auto resolved_type = std::get<CompilerType>(resolved);
if (!resolved_type)
return false;

bool is_signed;
if (!clang_type.IsEnumerationType(is_signed))
if (!resolved_type.IsEnumerationType(is_signed))
// The type is a clang struct, not an enum.
return false;

// The type is an enum imported from clang. Try Swift type metadata first,
// and failing that fallback to the AST.
LLVM_FALLTHROUGH;
if (!resolved_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>())
return false;

// The type is an enum imported from clang.
auto qual_type = ClangUtil::GetQualType(resolved_type);
auto *enum_type =
llvm::dyn_cast_or_null<clang::EnumType>(qual_type.getTypePtrOrNull());
if (!enum_type)
return false;
auto *importer = GetNameImporter();
if (!importer)
return false;
if (!data_byte_size)
return false;
StringRef case_name;
if (is_signed) {
uint64_t val = data.GetMaxU64(&data_offset, data_byte_size);
case_name = importer->ProjectEnumCase(enum_type->getDecl(), val);
} else {
int64_t val = data.GetMaxS64(&data_offset, data_byte_size);
case_name = importer->ProjectEnumCase(enum_type->getDecl(), val);
}
if (case_name.empty())
return false;
s << case_name;
return true;
}
case Node::Kind::Enum:
case Node::Kind::BoundGenericEnum: {
Expand All @@ -4674,18 +4705,6 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
error = toString(case_name.takeError());
}

// No result available from the runtime, fallback to the AST. This occurs
// for some Clang imported enums.
if (auto swift_ast_context =
GetSwiftASTContext(GetSymbolContext(exe_scope))) {
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
if (swift_ast_context->DumpTypeValue(
ReconstructType(type, &exe_ctx), s, format, data, data_offset,
data_byte_size, bitfield_bit_size, bitfield_bit_offset,
exe_scope, is_base_class))
return true;
}
s << error;
return false;
}
Expand Down

0 comments on commit 21c0612

Please sign in to comment.