forked from OSchip/llvm-project
[LLDB] Fix printing a static bool struct member when using "image lookup -t"
Fixes #58135 Somehow lldb was able to print the member on its own but when we try to print the whole type found by "image lookup -t" lldb would crash. This is because we'd encoded the initial value of the member as an integer. Which isn't the end of the world because bool is integral for C++. However, clang has a special AST node to handle literal bool and it expected us to use that instead. This adds a new codepath to handle static bool which uses cxxBoolLiteralExpr and we get the member printed as you'd expect. For testing I added a struct with just the bool because trying to print all of "A" crashes as well. Presumably because one of the other member's types isn't handled properly either. So for now I just added the bool case, we can merge it with A later. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D135169
This commit is contained in:
parent
7b442b07f2
commit
02c1c93948
|
@ -121,6 +121,8 @@ public:
|
|||
|
||||
bool IsIntegerOrEnumerationType(bool &is_signed) const;
|
||||
|
||||
bool IsBooleanType() const;
|
||||
|
||||
bool IsPolymorphicClass() const;
|
||||
|
||||
/// \param target_type Can pass nullptr.
|
||||
|
|
|
@ -178,6 +178,8 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool IsBooleanType(lldb::opaque_compiler_type_t type) = 0;
|
||||
|
||||
virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0;
|
||||
|
||||
virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
|
||||
|
|
|
@ -2720,6 +2720,7 @@ void DWARFASTParserClang::ParseSingleMember(
|
|||
// TODO: Support float/double static members as well.
|
||||
if (!attrs.const_value_form || !ct.IsIntegerOrEnumerationType(unused))
|
||||
return;
|
||||
|
||||
llvm::Expected<llvm::APInt> const_value_or_err =
|
||||
ExtractIntFromFormValue(ct, *attrs.const_value_form);
|
||||
if (!const_value_or_err) {
|
||||
|
@ -2728,7 +2729,13 @@ void DWARFASTParserClang::ParseSingleMember(
|
|||
v->getQualifiedNameAsString());
|
||||
return;
|
||||
}
|
||||
TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
|
||||
|
||||
if (ct.IsBooleanType())
|
||||
TypeSystemClang::SetBoolInitializerForVariable(
|
||||
v, !const_value_or_err->isZero());
|
||||
else
|
||||
TypeSystemClang::SetIntegerInitializerForVariable(v,
|
||||
*const_value_or_err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3224,6 +3224,20 @@ bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TypeSystemClang::IsBooleanType(lldb::opaque_compiler_type_t type) {
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
clang::QualType qual_type(GetCanonicalQualType(type));
|
||||
const clang::BuiltinType *builtin_type =
|
||||
llvm::dyn_cast<clang::BuiltinType>(qual_type->getCanonicalTypeInternal());
|
||||
|
||||
if (!builtin_type)
|
||||
return false;
|
||||
|
||||
return builtin_type->isBooleanType();
|
||||
}
|
||||
|
||||
bool TypeSystemClang::IsEnumerationType(lldb::opaque_compiler_type_t type,
|
||||
bool &is_signed) {
|
||||
if (type) {
|
||||
|
@ -7574,6 +7588,18 @@ clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
|
|||
return var_decl;
|
||||
}
|
||||
|
||||
void TypeSystemClang::SetBoolInitializerForVariable(VarDecl *var, bool value) {
|
||||
assert(!var->hasInit() && "variable already initialized");
|
||||
|
||||
QualType qt = var->getType();
|
||||
assert(qt->isSpecificBuiltinType(BuiltinType::Bool) &&
|
||||
"only boolean supported");
|
||||
|
||||
clang::ASTContext &ast = var->getASTContext();
|
||||
var->setInit(CXXBoolLiteralExpr::Create(ast, value, qt.getUnqualifiedType(),
|
||||
SourceLocation()));
|
||||
}
|
||||
|
||||
void TypeSystemClang::SetIntegerInitializerForVariable(
|
||||
VarDecl *var, const llvm::APInt &init_value) {
|
||||
assert(!var->hasInit() && "variable already initialized");
|
||||
|
|
|
@ -592,6 +592,8 @@ public:
|
|||
bool IsEnumerationType(lldb::opaque_compiler_type_t type,
|
||||
bool &is_signed) override;
|
||||
|
||||
bool IsBooleanType(lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
static bool IsObjCClassType(const CompilerType &type);
|
||||
|
@ -860,6 +862,8 @@ public:
|
|||
static void SetIntegerInitializerForVariable(clang::VarDecl *var,
|
||||
const llvm::APInt &init_value);
|
||||
|
||||
static void SetBoolInitializerForVariable(clang::VarDecl *var, bool value);
|
||||
|
||||
/// Initializes a variable with a floating point value.
|
||||
/// \param var The variable to initialize. Must not already have an
|
||||
/// initializer and must have a floating point type.
|
||||
|
|
|
@ -154,6 +154,12 @@ bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
|
|||
return IsIntegerType(is_signed) || IsEnumerationType(is_signed);
|
||||
}
|
||||
|
||||
bool CompilerType::IsBooleanType() const {
|
||||
if (IsValid())
|
||||
return m_type_system->IsBooleanType(m_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
|
||||
if (IsValid()) {
|
||||
return m_type_system->IsPointerType(m_type, pointee_type);
|
||||
|
|
|
@ -32,6 +32,11 @@ class TestCase(TestBase):
|
|||
# Test a bool member.
|
||||
self.expect_expr("A::bool_val", result_value="true")
|
||||
|
||||
# Test a bool member when printing the struct it is a member of.
|
||||
# TODO: replace this with printing struct A, once doing so doesn't crash lldb.
|
||||
self.expect("image lookup -t StaticBoolStruct",
|
||||
substrs=["static const bool value = false;"])
|
||||
|
||||
# Test that minimum and maximum values for each data type are right.
|
||||
self.expect_expr("A::char_max == char_max", result_value="true")
|
||||
self.expect_expr("A::uchar_max == uchar_max", result_value="true")
|
||||
|
|
|
@ -79,8 +79,13 @@ struct ClassWithEnumAlias {
|
|||
ScopedEnum::scoped_enum_case1;
|
||||
};
|
||||
|
||||
struct StaticBoolStruct {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
int main() {
|
||||
A a;
|
||||
StaticBoolStruct sbs;
|
||||
|
||||
auto char_max = A::char_max;
|
||||
auto uchar_max = A::uchar_max;
|
||||
|
|
Loading…
Reference in New Issue