brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.6 KiB · 9de7eb2 Raw
217 lines · python
1"""2Tests const static data members as specified by C++11 [class.static.data]p3.3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class TestCase(TestBase):12    def test(self):13        self.build()14        lldbutil.run_to_source_breakpoint(15            self, "// break here", lldb.SBFileSpec("main.cpp")16        )17 18        # Test using a simple const static integer member.19        self.expect_expr("A::int_val", result_value="1")20 21        # Try accessing the int member via some expressions that still produce22        # an lvalue.23        self.expect_expr("a.int_val", result_value="1")24        self.expect_expr("(A::int_val)", result_value="1")25        self.expect_expr("+A::int_val", result_value="1")26        self.expect_expr("1,A::int_val", result_value="1")27        self.expect_expr("true ? A::int_val : A::int_val", result_value="1")28 29        # Test a simple integer member that was also defined in a namespace30        # scope and has an address.31        self.expect_expr("A::int_val_with_address", result_value="2")32 33        # Test a bool member.34        self.expect_expr("A::bool_val", result_value="true")35 36        # Test that minimum and maximum values for each data type are right.37        self.expect_expr("A::char_max == char_max", result_value="true")38        self.expect_expr("A::schar_max == schar_max", result_value="true")39        self.expect_expr("A::uchar_max == uchar_max", result_value="true")40        self.expect_expr("A::int_max == int_max", result_value="true")41        self.expect_expr("A::uint_max == uint_max", result_value="true")42        self.expect_expr("A::long_max == long_max", result_value="true")43        self.expect_expr("A::ulong_max == ulong_max", result_value="true")44        self.expect_expr("A::longlong_max == longlong_max", result_value="true")45        self.expect_expr("A::ulonglong_max == ulonglong_max", result_value="true")46        self.expect_expr("A::wchar_max == wchar_max", result_value="true")47 48        self.expect_expr("A::char_min == char_min", result_value="true")49        self.expect_expr("A::schar_min == schar_min", result_value="true")50        self.expect_expr("A::uchar_min == uchar_min", result_value="true")51        self.expect_expr("A::int_min == int_min", result_value="true")52        self.expect_expr("A::uint_min == uint_min", result_value="true")53        self.expect_expr("A::long_min == long_min", result_value="true")54        self.expect_expr("A::ulong_min == ulong_min", result_value="true")55        self.expect_expr("A::longlong_min == longlong_min", result_value="true")56        self.expect_expr("A::ulonglong_min == ulonglong_min", result_value="true")57        self.expect_expr("A::wchar_min == wchar_min", result_value="true")58 59        # Test an unscoped enum.60        self.expect_expr("A::enum_val", result_value="enum_case2")61        # Test an unscoped enum with bool as the underlying type.62        self.expect_expr("A::enum_bool_val", result_value="enum_bool_case1")63 64        # Test a scoped enum.65        self.expect_expr("A::scoped_enum_val", result_value="scoped_enum_case2")66        # Test an scoped enum with a value that isn't an enumerator.67        self.expect_expr(68            "A::not_enumerator_scoped_enum_val", result_value="scoped_enum_case1 | 0x4"69        )70        # This time with more than one enum value plus the extra.71        self.expect_expr(72            "A::not_enumerator_scoped_enum_val_2",73            result_value="scoped_enum_case1 | scoped_enum_case2 | 0x4",74        )75 76        # Test an enum with fixed underlying type.77        self.expect_expr("A::scoped_char_enum_val", result_value="case2")78        self.expect_expr("A::scoped_ll_enum_val_neg", result_value="case0")79        self.expect_expr("A::scoped_ll_enum_val", result_value="case2")80 81        # Test taking address.82        if lldbplatformutil.getPlatform() == "windows":83            # On Windows data members without the out-of-class definitions still have84            # valid adresses and the following expression works fine.85            self.expect_expr("const int *i = &A::int_val; *i", result_value="1")86        else:87            # On other platforms (Linux, macos) data members without the out-of-class88            # definitions don't have valid addresses and the following code produces89            # a linker error.90            self.expect(91                "expr const int *i = &A::int_val; *i",92                error=True,93                substrs=["Couldn't look up symbols:"],94            )95 96        # This should work on all platforms.97        self.expect_expr(98            "const int *i = &A::int_val_with_address; *i", result_value="2"99        )100 101        # Printing the whole type takes a slightly different code path. Check that102        # it does not crash.103        self.expect("image lookup -t A")104 105    # dsymutil strips the debug info for classes that only have const static106    # data members without locations.107    @expectedFailureAll(debug_info=["dsym"], dwarf_version=["<", "5"])108    def test_class_with_only_const_static(self):109        self.build()110        lldbutil.run_to_source_breakpoint(111            self, "// break here", lldb.SBFileSpec("main.cpp")112        )113 114        self.expect_expr("ClassWithOnlyConstStatic::member", result_value="3")115 116    def check_global_var(self, name: str, expect_type, expect_val):117        var_list = self.target().FindGlobalVariables(name, lldb.UINT32_MAX)118        self.assertGreaterEqual(len(var_list), 1)119        varobj = var_list[0]120        self.assertEqual(varobj.type.name, expect_type)121        self.assertEqual(varobj.value, expect_val)122 123    def check_inline_static_members(self, flags):124        self.build(dictionary={"CXXFLAGS_EXTRAS": flags})125        lldbutil.run_to_source_breakpoint(126            self, "// break here", lldb.SBFileSpec("main.cpp")127        )128 129        self.check_global_var("A::int_val", "const int", "1")130        self.check_global_var("A::int_val_with_address", "const int", "2")131        self.check_global_var("A::inline_int_val", "const int", "3")132        self.check_global_var("A::bool_val", "const bool", "true")133        self.check_global_var("A::enum_val", "Enum", "enum_case2")134        self.check_global_var("A::enum_bool_val", "EnumBool", "enum_bool_case1")135        self.check_global_var("A::scoped_enum_val", "ScopedEnum", "scoped_enum_case2")136 137        self.check_global_var("ClassWithOnlyConstStatic::member", "const int", "3")138 139        self.check_global_var("ClassWithConstexprs::member", "const int", "2")140        self.check_global_var("ClassWithConstexprs::enum_val", "Enum", "enum_case2")141        self.check_global_var(142            "ClassWithConstexprs::scoped_enum_val", "ScopedEnum", "scoped_enum_case2"143        )144 145    # Fails on Windows for unknown reasons.146    @skipIfWindows147    # On linux this passes due to the manual index148    @expectedFailureDarwin(debug_info=no_match(["dsym"]))149    @skipIf(debug_info=["dsym"], compiler=["clang"], compiler_version=["<", "19.0"])150    def test_inline_static_members_dwarf5(self):151        self.check_inline_static_members("-gdwarf-5")152 153    # On linux this passes due to the manual index154    @expectedFailureDarwin155    def test_inline_static_members_dwarf4(self):156        self.check_inline_static_members("-gdwarf-4")157 158    # With older versions of Clang, LLDB fails to evaluate classes with only159    # constexpr members when dsymutil is enabled160    @expectedFailureAll(161        debug_info=["dsym"], compiler=["clang"], compiler_version=["<", "14.0"]162    )163    def test_class_with_only_constexpr_static(self):164        self.build()165        lldbutil.run_to_source_breakpoint(166            self, "// break here", lldb.SBFileSpec("main.cpp")167        )168 169        # Test `constexpr static`.170        self.expect_expr("ClassWithConstexprs::member", result_value="2")171        self.expect_expr("ClassWithConstexprs::enum_val", result_value="enum_case2")172        self.expect_expr(173            "ClassWithConstexprs::scoped_enum_val", result_value="scoped_enum_case2"174        )175 176        # Test an aliased enum with fixed underlying type.177        self.expect_expr(178            "ClassWithEnumAlias::enum_alias", result_value="scoped_enum_case2"179        )180        self.expect_expr(181            "ClassWithEnumAlias::enum_alias_alias", result_value="scoped_enum_case1"182        )183 184    def check_shadowed_static_inline_members(self, flags):185        """Tests that the expression evaluator and SBAPI can both186        correctly determine the requested inline static variable187        in the presence of multiple variables of the same name."""188 189        self.build(dictionary={"CXXFLAGS_EXTRAS": flags})190        lldbutil.run_to_name_breakpoint(self, "bar")191 192        self.check_global_var("ns::Foo::mem", "const int", "10")193 194        self.expect_expr("mem", result_value="10")195        self.expect_expr("Foo::mem", result_value="10")196        self.expect_expr("ns::Foo::mem", result_value="10")197        self.expect_expr("::Foo::mem", result_value="-29")198 199    # Fails on Windows for unknown reasons.200    @skipIfWindows201    # On linux this passes due to the manual index202    @expectedFailureDarwin(debug_info=no_match(["dsym"]))203    @skipIf(debug_info=["dsym"], compiler=["clang"], compiler_version=["<", "19.0"])204    def test_shadowed_static_inline_members_dwarf5(self):205        self.check_shadowed_static_inline_members("-gdwarf-5")206 207    # On linux this passes due to the manual index208    @expectedFailureDarwin209    def test_shadowed_static_inline_members_dwarf4(self):210        self.check_shadowed_static_inline_members("-gdwarf-4")211 212    @expectedFailureAll(bugnumber="target var doesn't honour global namespace")213    def test_shadowed_static_inline_members_xfail(self):214        self.build()215        lldbutil.run_to_name_breakpoint(self, "bar")216        self.check_global_var("::Foo::mem", "const int", "-29")217