diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2355,6 +2355,7 @@ bool is_external = false; // On DW_TAG_members, this means the member is static uint32_t i; + clang::Optional integer_const_value; for (i = 0; i < num_attributes && !is_artificial; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; @@ -2432,6 +2433,11 @@ case DW_AT_external: is_external = form_value.Boolean(); break; + case DW_AT_const_value: + if (DWARFFormValue::IsDataForm(form_value.Form())) { + integer_const_value = form_value.Unsigned(); + } + break; default: case DW_AT_declaration: @@ -2508,9 +2514,18 @@ if (var_type) { if (accessibility == eAccessNone) accessibility = eAccessPublic; - TypeSystemClang::AddVariableToRecordType( - class_clang_type, name, var_type->GetLayoutCompilerType(), - accessibility); + CompilerType layout_var_type = var_type->GetLayoutCompilerType(); + clang::VarDecl *var_decl = TypeSystemClang::AddVariableToRecordType( + class_clang_type, name, layout_var_type, accessibility); + bool is_signed = false; + if (integer_const_value && + layout_var_type.IsIntegerOrEnumerationType(is_signed)) { + clang::QualType var_qual_type = var_decl->getType(); + unsigned var_bit_size = + m_ast.getASTContext().getIntWidth(var_qual_type); + llvm::APInt init_value(var_bit_size, *integer_const_value, is_signed); + TypeSystemClang::SetIntegerInitializerForVariable(var_decl, init_value); + } } return; } diff --git a/lldb/test/API/lang/cpp/static_const_members/Makefile b/lldb/test/API/lang/cpp/static_const_members/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/static_const_members/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/static_const_members/TestStaticConstMembers.py b/lldb/test/API/lang/cpp/static_const_members/TestStaticConstMembers.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/static_const_members/TestStaticConstMembers.py @@ -0,0 +1,50 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestStaticConstMembers(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_static_const_var_definition(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", + lldb.SBFileSpec("main.cpp", False)) + self.expect_expr("C::static_const_var_i32", result_value="42") + self.expect_expr("C::static_constexpr_i32_other", result_value="43") + + @expectedFailureAll() + def test_static_const_member_lval(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", + lldb.SBFileSpec("main.cpp", False)) + self.expect_expr("C::static_const_i32", result_value="40") + self.expect_expr("C::static_const_i32_neg", result_value="-40") + self.expect_expr("C::static_constexpr_i32", result_value="41") + self.expect_expr("C::static_const_ui32", result_value="4294967295") + self.expect_expr("C::static_const_enum", result_value="E42") + self.expect_expr("C::static_const_i8", result_value="-1") + + def test_static_const_member_rval(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", + lldb.SBFileSpec("main.cpp", False)) + self.expect_expr("C::static_const_i32 + 2", result_value="42") + self.expect_expr("-C::static_const_i32_neg", result_value="40") + self.expect_expr("C::static_constexpr_i32 | 0", result_value="41") + self.expect_expr("-C::static_const_ui32", result_value="1") + self.expect_expr("C::static_const_ui32 + 0u", result_value="4294967295") + self.expect_expr("-C::static_constexpr_ui32", result_value="2") + self.expect_expr("(int)C::static_const_enum", result_value="42") + self.expect_expr("C::static_const_i8 + 0", result_value="-1") + + @expectedFailureAll() + def test_static_const_member_address(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", + lldb.SBFileSpec("main.cpp", False)) + self.expect_expr("deref(&(C::static_const_var_i32))", result_value="42") + self.expect_expr("deref(&(C::static_const_i32))", result_value="40") diff --git a/lldb/test/API/lang/cpp/static_const_members/main.cpp b/lldb/test/API/lang/cpp/static_const_members/main.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/API/lang/cpp/static_const_members/main.cpp @@ -0,0 +1,29 @@ +enum class E { + E0 = 0, + E42 = 42, +}; + +struct C { + static const int static_const_i32 = 40; + static const int static_const_i32_neg = -40; + static constexpr int static_constexpr_i32 = 41; + static const unsigned static_const_ui32 = 0xffffffff; + static constexpr unsigned static_constexpr_ui32 = 0xfffffffe; + static const int static_const_var_i32; + static constexpr int static_constexpr_i32_other = 43; + static const E static_const_enum = E::E42; + static const char static_const_i8 = -1; +}; + +const int C::static_const_var_i32 = 42; +constexpr int C::static_constexpr_i32_other; + +int deref(const int *p) { return *p; } + +int main() { + const int *pi = &C::static_constexpr_i32_other; + int rv = C::static_const_i32 + C::static_const_i32_neg + + C::static_constexpr_i32 + (int)C::static_const_ui32 + + C::static_const_var_i32 + deref(pi); + return rv; // break here +}