[lldb] Don't crash when printing static enum members with bool as underlying type
authorArthur Eubanks <aeubanks@google.com>
Sun, 30 Oct 2022 19:42:40 +0000 (12:42 -0700)
committerArthur Eubanks <aeubanks@google.com>
Tue, 1 Nov 2022 16:28:54 +0000 (09:28 -0700)
Undoes a lot of the code added in D135169 to piggyback off of the enum logic in `TypeSystemClang::SetIntegerInitializerForVariable()`.

Fixes #58383.

Reviewed By: DavidSpickett

Differential Revision: https://reviews.llvm.org/D137045

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

index ef9f283..1ad9d6a 100644 (file)
@@ -121,8 +121,6 @@ public:
 
   bool IsIntegerOrEnumerationType(bool &is_signed) const;
 
-  bool IsBooleanType() const;
-
   bool IsPolymorphicClass() const;
 
   /// \param target_type    Can pass nullptr.
index 93959f4..fd31b13 100644 (file)
@@ -178,8 +178,6 @@ 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,
index 6e76203..037e118 100644 (file)
@@ -2820,12 +2820,7 @@ void DWARFASTParserClang::ParseSingleMember(
         return;
       }
 
-      if (ct.IsBooleanType())
-        TypeSystemClang::SetBoolInitializerForVariable(
-            v, !const_value_or_err->isZero());
-      else
-        TypeSystemClang::SetIntegerInitializerForVariable(v,
-                                                          *const_value_or_err);
+      TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
     }
     return;
   }
index 4fa3c65..5175ad8 100644 (file)
@@ -3226,20 +3226,6 @@ 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) {
@@ -7593,18 +7579,6 @@ 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");
@@ -7619,8 +7593,15 @@ void TypeSystemClang::SetIntegerInitializerForVariable(
     const EnumDecl *enum_decl = enum_type->getDecl();
     qt = enum_decl->getIntegerType();
   }
-  var->setInit(IntegerLiteral::Create(ast, init_value, qt.getUnqualifiedType(),
-                                      SourceLocation()));
+  // Bools are handled separately because the clang AST printer handles bools
+  // separately from other integral types.
+  if (qt->isSpecificBuiltinType(BuiltinType::Bool)) {
+    var->setInit(CXXBoolLiteralExpr::Create(
+        ast, !init_value.isZero(), qt.getUnqualifiedType(), SourceLocation()));
+  } else {
+    var->setInit(IntegerLiteral::Create(
+        ast, init_value, qt.getUnqualifiedType(), SourceLocation()));
+  }
 }
 
 void TypeSystemClang::SetFloatingInitializerForVariable(
index 291bb5d..a56c5f2 100644 (file)
@@ -592,8 +592,6 @@ 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);
@@ -863,8 +861,6 @@ 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.
index 1b02895..1bf2e7d 100644 (file)
@@ -154,12 +154,6 @@ 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);
index ed7cd25..7fccbf8 100644 (file)
@@ -57,6 +57,8 @@ class TestCase(TestBase):
 
         # Test an unscoped enum.
         self.expect_expr("A::enum_val", result_value="enum_case2")
+        # Test an unscoped enum with bool as the underlying type.
+        self.expect_expr("A::enum_bool_val", result_value="enum_bool_case2")
 
         # Test a scoped enum.
         self.expect_expr("A::scoped_enum_val", result_value="scoped_enum_case2")
index 4cd4933..4128a4d 100644 (file)
@@ -5,6 +5,11 @@ enum Enum {
   enum_case2 = 2,
 };
 
+enum EnumBool : bool {
+  enum_bool_case1 = false,
+  enum_bool_case2 = true,
+};
+
 enum class ScopedEnum {
   scoped_enum_case1 = 1,
   scoped_enum_case2 = 2,
@@ -51,6 +56,7 @@ struct A {
   const static auto wchar_min = std::numeric_limits<wchar_t>::min();
 
   const static Enum enum_val = enum_case2;
+  const static EnumBool enum_bool_val = enum_bool_case2;
   const static ScopedEnum scoped_enum_val = ScopedEnum::scoped_enum_case2;
   const static ScopedEnum not_enumerator_scoped_enum_val = static_cast<ScopedEnum>(5);
   const static ScopedEnum not_enumerator_scoped_enum_val_2 =