1"""
2Tests const static data members as specified by C++11 [class.static.data]p3.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10class TestCase(TestBase):
11
12    def test(self):
13        self.build()
14        lldbutil.run_to_source_breakpoint(self, "// break here",
15                                          lldb.SBFileSpec("main.cpp"))
16
17        # Test using a simple const static integer member.
18        self.expect_expr("A::int_val", result_value="1")
19
20        # Try accessing the int member via some expressions that still produce
21        # an lvalue.
22        self.expect_expr("a.int_val", result_value="1")
23        self.expect_expr("(A::int_val)", result_value="1")
24        self.expect_expr("+A::int_val", result_value="1")
25        self.expect_expr("1,A::int_val", result_value="1")
26        self.expect_expr("true ? A::int_val : A::int_val", result_value="1")
27
28        # Test a simple integer member that was also defined in a namespace
29        # scope and has an address.
30        self.expect_expr("A::int_val_with_address", result_value="2")
31
32        # Test a bool member.
33        self.expect_expr("A::bool_val", result_value="true")
34
35        # Test that minimum and maximum values for each data type are right.
36        self.expect_expr("A::char_max == char_max", result_value="true")
37        self.expect_expr("A::uchar_max == uchar_max", result_value="true")
38        self.expect_expr("A::int_max == int_max", result_value="true")
39        self.expect_expr("A::uint_max == uint_max", result_value="true")
40        self.expect_expr("A::long_max == long_max", result_value="true")
41        self.expect_expr("A::ulong_max == ulong_max", result_value="true")
42        self.expect_expr("A::longlong_max == longlong_max", result_value="true")
43        self.expect_expr("A::ulonglong_max == ulonglong_max", result_value="true")
44
45        self.expect_expr("A::char_min == char_min", result_value="true")
46        self.expect_expr("A::uchar_min == uchar_min", result_value="true")
47        self.expect_expr("A::int_min == int_min", result_value="true")
48        self.expect_expr("A::uint_min == uint_min", result_value="true")
49        self.expect_expr("A::long_min == long_min", result_value="true")
50        self.expect_expr("A::ulong_min == ulong_min", result_value="true")
51        self.expect_expr("A::longlong_min == longlong_min", result_value="true")
52        self.expect_expr("A::ulonglong_min == ulonglong_min", result_value="true")
53
54        # Test an unscoped enum.
55        self.expect_expr("A::enum_val", result_value="enum_case2")
56        # Test an unscoped enum with an invalid enum case.
57        self.expect_expr("A::invalid_enum_val", result_value="enum_case1 | enum_case2 | 0x4")
58
59        # Test a scoped enum.
60        self.expect_expr("A::scoped_enum_val", result_value="scoped_enum_case2")
61        # Test an scoped enum with an invalid enum case.
62        self.expect_expr("A::invalid_scoped_enum_val", result_value="scoped_enum_case1 | 0x4")
63
64        # Test an enum with fixed underlying type.
65        self.expect_expr("A::scoped_char_enum_val", result_value="case2")
66        self.expect_expr("A::scoped_ll_enum_val_neg", result_value="case0")
67        self.expect_expr("A::scoped_ll_enum_val", result_value="case2")
68
69        # Test an aliased enum with fixed underlying type.
70        self.expect_expr("ClassWithEnumAlias::enum_alias",
71                         result_value="scoped_enum_case2")
72        self.expect_expr("ClassWithEnumAlias::enum_alias_alias",
73                         result_value="scoped_enum_case1")
74
75        # Test taking address.
76        if lldbplatformutil.getPlatform() == "windows":
77            # On Windows data members without the out-of-class definitions still have
78            # valid adresses and the following expression works fine.
79            self.expect_expr("const int *i = &A::int_val; *i", result_value="1")
80        else:
81            # On other platforms (Linux, macos) data members without the out-of-class
82            # definitions don't have valid addresses and the following code produces
83            # a linker error.
84            self.expect("expr const int *i = &A::int_val; *i", error=True,
85                        substrs=["Couldn't lookup symbols:"])
86
87        # This should work on all platforms.
88        self.expect_expr("const int *i = &A::int_val_with_address; *i",
89                         result_value="2")
90
91    # dsymutil strips the debug info for classes that only have const static
92    # data members without a definition namespace scope.
93    @expectedFailureAll(debug_info=["dsym"])
94    def test_class_with_only_const_static(self):
95        self.build()
96        lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.cpp"))
97
98        self.expect_expr("ClassWithOnlyConstStatic::member", result_value="3")
99
100        # Test `constexpr static`.
101        self.expect_expr("ClassWithConstexprs::member", result_value="2")
102        self.expect_expr("ClassWithConstexprs::enum_val", result_value="enum_case2")
103        self.expect_expr("ClassWithConstexprs::scoped_enum_val", result_value="scoped_enum_case2")
104