Skip to content

Commit

Permalink
[lldb] Elimintate SwiftASTContext from enum handling
Browse files Browse the repository at this point in the history
rdar://115078610
  • Loading branch information
adrian-prantl committed Jan 29, 2025
1 parent 1d8bf9d commit d95fa3b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 66 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 @@ -977,7 +977,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
97 changes: 66 additions & 31 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ 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()) {
llvm::APSInt case_val = enumerator->getInitVal();
if ((case_val.isSigned() &&
llvm::APSInt::isSameValue(case_val, llvm::APSInt::get(val))) ||
(case_val.isUnsigned() &&
llvm::APSInt::isSameValue(case_val, llvm::APSInt::getUnsigned(val))))
return m_clang_importer->getEnumConstantName(enumerator).str();
}
return {};
}

private:
swift::CompilerInvocation m_compiler_invocation;
swift::SourceManager m_source_manager;
Expand Down Expand Up @@ -2620,7 +2633,8 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
return result; \
} while (0)

#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
#define VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, COMPARISON, EXE_CTX, \
ARGS) \
do { \
auto result = IMPL(); \
if (!ModuleList::GetGlobalModuleListProperties() \
Expand All @@ -2640,7 +2654,7 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
return result; \
bool equivalent = \
!ReconstructType(TYPE) /* missing .swiftmodule */ || \
(Equivalent( \
(COMPARISON( \
result, \
GetSwiftASTContext(GetSymbolContext(&_exe_ctx))->REFERENCE ARGS)); \
if (!equivalent) \
Expand All @@ -2650,6 +2664,9 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
return result; \
} while (0)

#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, Equivalent, EXE_CTX, ARGS)

#define VALIDATE_AND_RETURN_EXPECTED(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
do { \
auto result = IMPL(); \
Expand Down Expand Up @@ -2689,7 +2706,10 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
#else
#define VALIDATE_AND_RETURN_STATIC(IMPL, REFERENCE) \
return IMPL()
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) return IMPL();
#define VALIDATE_AND_RETURN(IMPL, REFERENCE, TYPE, COMPARISON, EXE_CTX, ARGS) \
return IMPL();
#define VALIDATE_AND_RETURN_CUSTOM(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
return IMPL();
#define VALIDATE_AND_RETURN_EXPECTED(IMPL, REFERENCE, TYPE, EXE_CTX, ARGS) \
return IMPL();
#endif
Expand Down Expand Up @@ -4724,18 +4744,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, flavor, 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) {
int64_t val = data.GetMaxS64(&data_offset, data_byte_size);
case_name = importer->ProjectEnumCase(enum_type->getDecl(), val);
} else {
uint64_t val = data.GetMaxU64(&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 @@ -4755,18 +4798,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 Expand Up @@ -4818,17 +4849,21 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
ConstString(((StreamString *)&s)->GetString())) &&
"TypeSystemSwiftTypeRef diverges from SwiftASTContext");
});

// SwiftASTContext fails here, details explained in RemoteASTImport.test
if (StringRef(AsMangledName(type)) == "$s15RemoteASTImport14FromMainModuleCD")
return impl();

#endif

VALIDATE_AND_RETURN(impl, DumpTypeValue, type, exe_scope,
(ReconstructType(type, exe_scope), ast_s, format, data,
data_offset, data_byte_size, bitfield_bit_size,
bitfield_bit_offset, exe_scope, is_base_class));
auto better_or_equal = [](bool a, bool b) -> bool {
if (a || a == b)
return true;

llvm::dbgs() << "TypeSystemSwiftTypeRef: " << a << " SwiftASTContext: " << b
<< "\n";
return false;
};
VALIDATE_AND_RETURN_CUSTOM(
impl, DumpTypeValue, type, better_or_equal, exe_scope,
(ReconstructType(type, exe_scope), ast_s, format, data, data_offset,
data_byte_size, bitfield_bit_size, bitfield_bit_offset, exe_scope,
is_base_class));
}

bool TypeSystemSwiftTypeRef::IsPointerOrReferenceType(
Expand Down

0 comments on commit d95fa3b

Please sign in to comment.