From: Greg Clayton Date: Fri, 29 Apr 2016 20:48:39 +0000 (+0000) Subject: Make sure LLDB can deal with forward declarations to enums without crashing or asserting. X-Git-Tag: llvmorg-3.9.0-rc1~7413 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=909b277845a75595651de1e93b8e315d5d632077;p=platform%2Fupstream%2Fllvm.git Make sure LLDB can deal with forward declarations to enums without crashing or asserting. llvm-svn: 268098 --- diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py b/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py index b0c5c88..3e0f742 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py +++ b/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py @@ -63,7 +63,14 @@ class EnumTypesTestCase(TestBase): 'Sunday', 'kNumDays', '5']; - + + # Make sure a pointer to an anonymous enum type does crash LLDB and displays correctly using + # frame variable and expression commands + self.expect('frame variable f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', 'f.op', '0x0000000000000000']) + self.expect('frame variable *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops', '*f.op', '']) + self.expect('expr f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', '$', '0x0000000000000000']) + self.expect('expr *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['error:'], error = True) + bkpt = self.target().FindBreakpointByID(bkpt_id) for enum_value in enum_values: self.expect("frame variable day", 'check for valid enumeration value', diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c b/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c index 3d59654..be0fa57 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c +++ b/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c @@ -8,6 +8,15 @@ //===----------------------------------------------------------------------===// #include +#include + +// Forward declare an enumeration (only works in C, not C++) +typedef enum ops ops; + +struct foo { + ops *op; +}; + int main (int argc, char const *argv[]) { enum days { @@ -21,6 +30,8 @@ int main (int argc, char const *argv[]) kNumDays }; enum days day; + struct foo f; + f.op = NULL; for (day = Monday - 1; day <= kNumDays + 1; day++) { printf("day as int is %i\n", (int)day); // Set break point at this line. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 62d8f89..0d53ccf 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1011,9 +1011,18 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, } if (!enumerator_clang_type) - enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, - DW_ATE_signed, - byte_size * 8); + { + if (byte_size > 0) + { + enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL, + DW_ATE_signed, + byte_size * 8); + } + else + { + enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt); + } + } clang_type = m_ast.CreateEnumerationType (type_name_cstr, GetClangDeclContextContainingDIE (die, nullptr), diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index e80faa1..6b61646 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -8545,24 +8545,28 @@ ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type) clang::ASTContext *ast = lldb_ast->getASTContext(); /// TODO This really needs to be fixed. - - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - clang::QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) + + QualType integer_type(enum_decl->getIntegerType()); + if (!integer_type.isNull()) { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; + unsigned NumPositiveBits = 1; + unsigned NumNegativeBits = 0; + + clang::QualType promotion_qual_type; + // If the enum integer type is less than an integer in bit width, + // then we must promote it to an integer size. + if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) + { + if (enum_decl->getIntegerType()->isSignedIntegerType()) + promotion_qual_type = ast->IntTy; + else + promotion_qual_type = ast->UnsignedIntTy; + } else - promotion_qual_type = ast->UnsignedIntTy; + promotion_qual_type = enum_decl->getIntegerType(); + + enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); } - else - promotion_qual_type = enum_decl->getIntegerType(); - - enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); } return true; }