[lldb] Refactor and test TypeSystemClang::GetEnumerationIntegerType
authorRaphael Isemann <teemperor@gmail.com>
Tue, 18 Feb 2020 08:10:16 +0000 (09:10 +0100)
committerRaphael Isemann <teemperor@gmail.com>
Tue, 18 Feb 2020 08:52:49 +0000 (09:52 +0100)
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
lldb/unittests/Symbol/TestTypeSystemClang.cpp

index 5b3ea88..02f4816 100644 (file)
@@ -790,8 +790,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
         attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr),
         attrs.decl, enumerator_clang_type, attrs.is_scoped_enum);
   } else {
-    enumerator_clang_type =
-        m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+    enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type);
   }
 
   LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die);
index 48bc572..a038788 100644 (file)
@@ -1154,8 +1154,7 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type,
   default:
     return false;
   }
-  CompilerType underlying_type =
-      m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+  CompilerType underlying_type = m_ast.GetEnumerationIntegerType(enum_type);
   uint32_t byte_size = m_ast.getASTContext().getTypeSize(
       ClangUtil::GetQualType(underlying_type));
   auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
index 2fa5dc3..475c927 100644 (file)
@@ -7899,8 +7899,7 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
 clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
     const CompilerType &enum_type, const Declaration &decl, const char *name,
     int64_t enum_value, uint32_t enum_value_bit_size) {
-  CompilerType underlying_type =
-      GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
+  CompilerType underlying_type = GetEnumerationIntegerType(enum_type);
   bool is_signed = false;
   underlying_type.IsIntegerType(is_signed);
 
@@ -7910,20 +7909,14 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
   return AddEnumerationValueToEnumerationType(enum_type, decl, name, value);
 }
 
-CompilerType
-TypeSystemClang::GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) {
-  clang::QualType enum_qual_type(GetCanonicalQualType(type));
-  const clang::Type *clang_type = enum_qual_type.getTypePtr();
-  if (clang_type) {
-    const clang::EnumType *enutype =
-        llvm::dyn_cast<clang::EnumType>(clang_type);
-    if (enutype) {
-      clang::EnumDecl *enum_decl = enutype->getDecl();
-      if (enum_decl)
-        return GetType(enum_decl->getIntegerType());
-    }
-  }
-  return CompilerType();
+CompilerType TypeSystemClang::GetEnumerationIntegerType(CompilerType type) {
+  clang::QualType qt(ClangUtil::GetQualType(type));
+  const clang::Type *clang_type = qt.getTypePtrOrNull();
+  const auto *enum_type = llvm::dyn_cast_or_null<clang::EnumType>(clang_type);
+  if (!enum_type)
+    return CompilerType();
+
+  return GetType(enum_type->getDecl()->getIntegerType());
 }
 
 CompilerType
index dc9a10b..2fd12c8 100644 (file)
@@ -857,7 +857,10 @@ public:
       const CompilerType &enum_type, const Declaration &decl, const char *name,
       const llvm::APSInt &value);
 
-  CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type);
+  /// Returns the underlying integer type for an enum type. If the given type
+  /// is invalid or not an enum-type, the function returns an invalid
+  /// CompilerType.
+  CompilerType GetEnumerationIntegerType(CompilerType type);
 
   // Pointers & References
 
index b0a42a2..a3345e8 100644 (file)
@@ -231,6 +231,42 @@ TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {
   EXPECT_EQ("", ast.getDisplayName());
 }
 
+TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) {
+  EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid());
+}
+
+TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) {
+  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
+  CompilerType t = m_ast->GetEnumerationIntegerType(int_type);
+  EXPECT_FALSE(t.IsValid());
+}
+
+TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
+  // All possible underlying integer types of enums.
+  const std::vector<lldb::BasicType> types_to_test = {
+      eBasicTypeInt,          eBasicTypeUnsignedInt, eBasicTypeLong,
+      eBasicTypeUnsignedLong, eBasicTypeLongLong,    eBasicTypeUnsignedLongLong,
+  };
+
+  for (bool scoped : {true, false}) {
+    SCOPED_TRACE("scoped: " + std::to_string(scoped));
+    for (lldb::BasicType basic_type : types_to_test) {
+      SCOPED_TRACE(std::to_string(basic_type));
+
+      TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple());
+      CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
+      EXPECT_TRUE(basic_compiler_type.IsValid());
+
+      CompilerType enum_type =
+          ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(),
+                                    Declaration(), basic_compiler_type, scoped);
+      CompilerType t = ast.GetEnumerationIntegerType(enum_type);
+      // Check that the type we put in at the start is found again.
+      EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());
+    }
+  }
+}
+
 TEST_F(TestTypeSystemClang, TestIsClangType) {
   clang::ASTContext &context = m_ast->getASTContext();
   lldb::opaque_compiler_type_t bool_ctype =