1*03a8e70aSRaphael Isemann""" 2*03a8e70aSRaphael IsemannThis tests LLDB's ability to merge structs into the shared per-target Clang 3*03a8e70aSRaphael IsemannASTContext. 4*03a8e70aSRaphael Isemann 5*03a8e70aSRaphael IsemannThis just focuses on indirect imports (i.e., a declaration gets imported from 6*03a8e70aSRaphael Isemannthe lldb::Module AST into the expression AST and then the declaration gets 7*03a8e70aSRaphael Isemannimported to the scratch AST because it is part of the ValueObject type of the 8*03a8e70aSRaphael Isemannresult) and direct imports (i.e., a declaration gets directly imported from a 9*03a8e70aSRaphael Isemannlldb::Module AST to the scratch AST, e.g., via 'frame var'). 10*03a8e70aSRaphael Isemann""" 11*03a8e70aSRaphael Isemann 12*03a8e70aSRaphael Isemannimport lldb 13*03a8e70aSRaphael Isemannfrom lldbsuite.test.decorators import * 14*03a8e70aSRaphael Isemannfrom lldbsuite.test.lldbtest import * 15*03a8e70aSRaphael Isemannfrom lldbsuite.test import lldbutil 16*03a8e70aSRaphael Isemann 17*03a8e70aSRaphael Isemann 18*03a8e70aSRaphael Isemannclass TestCase(TestBase): 19*03a8e70aSRaphael Isemann 20*03a8e70aSRaphael Isemann def common_setup(self): 21*03a8e70aSRaphael Isemann self.build() 22*03a8e70aSRaphael Isemann lldbutil.run_to_source_breakpoint( 23*03a8e70aSRaphael Isemann self, "// break here", lldb.SBFileSpec("main.cpp") 24*03a8e70aSRaphael Isemann ) 25*03a8e70aSRaphael Isemann 26*03a8e70aSRaphael Isemann def do_pass(self, kind, var, expected_type, expected_children): 27*03a8e70aSRaphael Isemann if kind == "expression": 28*03a8e70aSRaphael Isemann self.expect_expr( 29*03a8e70aSRaphael Isemann var, result_type=expected_type, result_children=expected_children 30*03a8e70aSRaphael Isemann ) 31*03a8e70aSRaphael Isemann elif kind == "path": 32*03a8e70aSRaphael Isemann self.expect_var_path(var, type=expected_type, children=expected_children) 33*03a8e70aSRaphael Isemann else: 34*03a8e70aSRaphael Isemann self.fail("Unknown var evaluation kind: " + var) 35*03a8e70aSRaphael Isemann 36*03a8e70aSRaphael Isemann def pull_in_and_merge(self, var, type, children): 37*03a8e70aSRaphael Isemann """ 38*03a8e70aSRaphael Isemann Pulls in the specified variable into the scratch AST. Afterwards tries 39*03a8e70aSRaphael Isemann merging the declaration. The method of pulling the declaration into the 40*03a8e70aSRaphael Isemann scratch AST is defined by the first_pass/second_pass instance variables. 41*03a8e70aSRaphael Isemann """ 42*03a8e70aSRaphael Isemann 43*03a8e70aSRaphael Isemann # This pulls in the declaration into the scratch AST. 44*03a8e70aSRaphael Isemann self.do_pass(self.first_pass, var, type, children) 45*03a8e70aSRaphael Isemann # This pulls in the declaration a second time and forces us to merge with 46*03a8e70aSRaphael Isemann # the existing declaration (or reuse the existing declaration). 47*03a8e70aSRaphael Isemann self.do_pass(self.second_pass, var, type, children) 48*03a8e70aSRaphael Isemann 49*03a8e70aSRaphael Isemann def do_tests(self): 50*03a8e70aSRaphael Isemann """ Just forwards all the variables/types/childrens to pull_in_and_merge. """ 51*03a8e70aSRaphael Isemann self.pull_in_and_merge( 52*03a8e70aSRaphael Isemann "decl_in_func", type="DeclInFunc", children=[ValueCheck(name="member")] 53*03a8e70aSRaphael Isemann ) 54*03a8e70aSRaphael Isemann self.pull_in_and_merge( 55*03a8e70aSRaphael Isemann "top_level_struct", 56*03a8e70aSRaphael Isemann type="TopLevelStruct", 57*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 58*03a8e70aSRaphael Isemann ) 59*03a8e70aSRaphael Isemann self.pull_in_and_merge( 60*03a8e70aSRaphael Isemann "inner_struct", 61*03a8e70aSRaphael Isemann type="OuterStruct::InnerStruct", 62*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 63*03a8e70aSRaphael Isemann ) 64*03a8e70aSRaphael Isemann self.pull_in_and_merge( 65*03a8e70aSRaphael Isemann "typedef_struct", 66*03a8e70aSRaphael Isemann type="TypedefStruct", 67*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 68*03a8e70aSRaphael Isemann ) 69*03a8e70aSRaphael Isemann self.pull_in_and_merge( 70*03a8e70aSRaphael Isemann "namespace_struct", 71*03a8e70aSRaphael Isemann type="NS::NamespaceStruct", 72*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 73*03a8e70aSRaphael Isemann ) 74*03a8e70aSRaphael Isemann self.pull_in_and_merge( 75*03a8e70aSRaphael Isemann "unnamed_namespace_struct", 76*03a8e70aSRaphael Isemann type="UnnamedNamespaceStruct", 77*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 78*03a8e70aSRaphael Isemann ) 79*03a8e70aSRaphael Isemann self.pull_in_and_merge( 80*03a8e70aSRaphael Isemann "extern_c_struct", 81*03a8e70aSRaphael Isemann type="ExternCStruct", 82*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 83*03a8e70aSRaphael Isemann ) 84*03a8e70aSRaphael Isemann 85*03a8e70aSRaphael Isemann @no_debug_info_test 86*03a8e70aSRaphael Isemann def test_direct_and_indirect(self): 87*03a8e70aSRaphael Isemann """ 88*03a8e70aSRaphael Isemann First variable paths pull in a declaration directly. Then the expression 89*03a8e70aSRaphael Isemann evaluator pulls the declaration in indirectly. 90*03a8e70aSRaphael Isemann """ 91*03a8e70aSRaphael Isemann self.common_setup() 92*03a8e70aSRaphael Isemann self.first_pass = "path" 93*03a8e70aSRaphael Isemann self.second_pass = "expression" 94*03a8e70aSRaphael Isemann self.do_tests() 95*03a8e70aSRaphael Isemann 96*03a8e70aSRaphael Isemann @no_debug_info_test 97*03a8e70aSRaphael Isemann def test_indirect_and_indirect(self): 98*03a8e70aSRaphael Isemann """ 99*03a8e70aSRaphael Isemann The expression evaluator pulls in the declaration indirectly and then 100*03a8e70aSRaphael Isemann repeat that process. 101*03a8e70aSRaphael Isemann """ 102*03a8e70aSRaphael Isemann self.common_setup() 103*03a8e70aSRaphael Isemann self.first_pass = "expression" 104*03a8e70aSRaphael Isemann self.second_pass = "expression" 105*03a8e70aSRaphael Isemann self.do_tests() 106*03a8e70aSRaphael Isemann 107*03a8e70aSRaphael Isemann @no_debug_info_test 108*03a8e70aSRaphael Isemann def test_indirect_and_direct(self): 109*03a8e70aSRaphael Isemann """ 110*03a8e70aSRaphael Isemann The expression evaluator pulls in the declaration indirectly and then 111*03a8e70aSRaphael Isemann variable paths pull it in directly. 112*03a8e70aSRaphael Isemann """ 113*03a8e70aSRaphael Isemann self.common_setup() 114*03a8e70aSRaphael Isemann self.first_pass = "expression" 115*03a8e70aSRaphael Isemann self.second_pass = "path" 116*03a8e70aSRaphael Isemann self.do_tests() 117*03a8e70aSRaphael Isemann 118*03a8e70aSRaphael Isemann @no_debug_info_test 119*03a8e70aSRaphael Isemann def test_direct_and_direct(self): 120*03a8e70aSRaphael Isemann """ 121*03a8e70aSRaphael Isemann Variable paths pulls in the declaration indirectly and then repeat that 122*03a8e70aSRaphael Isemann process. 123*03a8e70aSRaphael Isemann """ 124*03a8e70aSRaphael Isemann self.common_setup() 125*03a8e70aSRaphael Isemann self.first_pass = "path" 126*03a8e70aSRaphael Isemann self.second_pass = "path" 127*03a8e70aSRaphael Isemann self.do_tests() 128