[Lldb-commits] [lldb] 02c1c93 - [LLDB] Fix printing a static bool struct member when using "image lookup -t"
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 7 02:03:09 PDT 2022
Author: David Spickett
Date: 2022-10-07T09:02:59Z
New Revision: 02c1c939486f247dc80866477eaab193c634d1e2
URL: https://github.com/llvm/llvm-project/commit/02c1c939486f247dc80866477eaab193c634d1e2
DIFF: https://github.com/llvm/llvm-project/commit/02c1c939486f247dc80866477eaab193c634d1e2.diff
LOG: [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
Added:
Modified:
lldb/include/lldb/Symbol/CompilerType.h
lldb/include/lldb/Symbol/TypeSystem.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
lldb/source/Symbol/CompilerType.cpp
lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index aefd19d0a8595..f0443fceb28d0 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -121,6 +121,8 @@ class CompilerType {
bool IsIntegerOrEnumerationType(bool &is_signed) const;
+ bool IsBooleanType() const;
+
bool IsPolymorphicClass() const;
/// \param target_type Can pass nullptr.
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 57bdfa5b626ab..63f9495ad916d 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -178,6 +178,8 @@ class TypeSystem : public PluginInterface {
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,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 25f2a37cbab5d..988dc0236652a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -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;
}
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 4adf653b6c508..b2779d6dd10aa 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -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");
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 7c045fdf088c5..365fa720e0da5 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -592,6 +592,8 @@ class TypeSystemClang : public TypeSystem {
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 @@ class TypeSystemClang : public TypeSystem {
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.
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index bef456583687c..3a191644cc0d0 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -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);
diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
index 4f51d22a86850..0482007d48147 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/TestConstStaticIntegralMember.py
@@ -32,6 +32,11 @@ def test(self):
# 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")
diff --git a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
index 977e12295760a..d078076b99dc8 100644
--- a/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
+++ b/lldb/test/API/lang/cpp/const_static_integral_member/main.cpp
@@ -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;
More information about the lldb-commits
mailing list