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 def common_setup(self): 20*03a8e70aSRaphael Isemann self.build() 21*03a8e70aSRaphael Isemann lldbutil.run_to_source_breakpoint( 22*03a8e70aSRaphael Isemann self, "// break here", lldb.SBFileSpec("main.cpp") 23*03a8e70aSRaphael Isemann ) 24*03a8e70aSRaphael Isemann 25*03a8e70aSRaphael Isemann def do_pass(self, kind, var, expected_type, expected_children): 26*03a8e70aSRaphael Isemann if kind == "expression": 27*03a8e70aSRaphael Isemann self.expect_expr( 28*03a8e70aSRaphael Isemann var, result_type=expected_type, result_children=expected_children 29*03a8e70aSRaphael Isemann ) 30*03a8e70aSRaphael Isemann elif kind == "path": 31*03a8e70aSRaphael Isemann self.expect_var_path(var, type=expected_type, children=expected_children) 32*03a8e70aSRaphael Isemann else: 33*03a8e70aSRaphael Isemann self.fail("Unknown var evaluation kind: " + var) 34*03a8e70aSRaphael Isemann 35*03a8e70aSRaphael Isemann def pull_in_and_merge(self, var, type, children): 36*03a8e70aSRaphael Isemann """ 37*03a8e70aSRaphael Isemann Pulls in the specified variable into the scratch AST. Afterwards tries 38*03a8e70aSRaphael Isemann merging the declaration. The method of pulling the declaration into the 39*03a8e70aSRaphael Isemann scratch AST is defined by the first_pass/second_pass instance variables. 40*03a8e70aSRaphael Isemann """ 41*03a8e70aSRaphael Isemann 42*03a8e70aSRaphael Isemann # This pulls in the declaration into the scratch AST. 43*03a8e70aSRaphael Isemann self.do_pass(self.first_pass, var, type, children) 44*03a8e70aSRaphael Isemann # This pulls in the declaration a second time and forces us to merge with 45*03a8e70aSRaphael Isemann # the existing declaration (or reuse the existing declaration). 46*03a8e70aSRaphael Isemann self.do_pass(self.second_pass, var, type, children) 47*03a8e70aSRaphael Isemann 48*03a8e70aSRaphael Isemann def do_tests(self): 49*03a8e70aSRaphael Isemann """Just forwards all the variables/types/childrens to pull_in_and_merge.""" 50*03a8e70aSRaphael Isemann self.pull_in_and_merge( 51*03a8e70aSRaphael Isemann "decl_in_func", type="DeclInFunc", children=[ValueCheck(name="member")] 52*03a8e70aSRaphael Isemann ) 53*03a8e70aSRaphael Isemann self.pull_in_and_merge( 54*03a8e70aSRaphael Isemann "top_level_struct", 55*03a8e70aSRaphael Isemann type="TopLevelStruct", 56*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 57*03a8e70aSRaphael Isemann ) 58*03a8e70aSRaphael Isemann self.pull_in_and_merge( 59*03a8e70aSRaphael Isemann "inner_struct", 60*03a8e70aSRaphael Isemann type="OuterStruct::InnerStruct", 61*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 62*03a8e70aSRaphael Isemann ) 63*03a8e70aSRaphael Isemann self.pull_in_and_merge( 64*03a8e70aSRaphael Isemann "typedef_struct", 65*03a8e70aSRaphael Isemann type="TypedefStruct", 66*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 67*03a8e70aSRaphael Isemann ) 68*03a8e70aSRaphael Isemann self.pull_in_and_merge( 69*03a8e70aSRaphael Isemann "namespace_struct", 70*03a8e70aSRaphael Isemann type="NS::NamespaceStruct", 71*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 72*03a8e70aSRaphael Isemann ) 73*03a8e70aSRaphael Isemann self.pull_in_and_merge( 74*03a8e70aSRaphael Isemann "unnamed_namespace_struct", 75*03a8e70aSRaphael Isemann type="UnnamedNamespaceStruct", 76*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 77*03a8e70aSRaphael Isemann ) 78*03a8e70aSRaphael Isemann self.pull_in_and_merge( 79*03a8e70aSRaphael Isemann "extern_c_struct", 80*03a8e70aSRaphael Isemann type="ExternCStruct", 81*03a8e70aSRaphael Isemann children=[ValueCheck(name="member")], 82*03a8e70aSRaphael Isemann ) 83*03a8e70aSRaphael Isemann 84*03a8e70aSRaphael Isemann @no_debug_info_test 85*03a8e70aSRaphael Isemann def test_direct_and_indirect(self): 86*03a8e70aSRaphael Isemann """ 87*03a8e70aSRaphael Isemann First variable paths pull in a declaration directly. Then the expression 88*03a8e70aSRaphael Isemann evaluator pulls the declaration in indirectly. 89*03a8e70aSRaphael Isemann """ 90*03a8e70aSRaphael Isemann self.common_setup() 91*03a8e70aSRaphael Isemann self.first_pass = "path" 92*03a8e70aSRaphael Isemann self.second_pass = "expression" 93*03a8e70aSRaphael Isemann self.do_tests() 94*03a8e70aSRaphael Isemann 95*03a8e70aSRaphael Isemann @no_debug_info_test 96*03a8e70aSRaphael Isemann def test_indirect_and_indirect(self): 97*03a8e70aSRaphael Isemann """ 98*03a8e70aSRaphael Isemann The expression evaluator pulls in the declaration indirectly and then 99*03a8e70aSRaphael Isemann repeat that process. 100*03a8e70aSRaphael Isemann """ 101*03a8e70aSRaphael Isemann self.common_setup() 102*03a8e70aSRaphael Isemann self.first_pass = "expression" 103*03a8e70aSRaphael Isemann self.second_pass = "expression" 104*03a8e70aSRaphael Isemann self.do_tests() 105*03a8e70aSRaphael Isemann 106*03a8e70aSRaphael Isemann @no_debug_info_test 107*03a8e70aSRaphael Isemann def test_indirect_and_direct(self): 108*03a8e70aSRaphael Isemann """ 109*03a8e70aSRaphael Isemann The expression evaluator pulls in the declaration indirectly and then 110*03a8e70aSRaphael Isemann variable paths pull it in directly. 111*03a8e70aSRaphael Isemann """ 112*03a8e70aSRaphael Isemann self.common_setup() 113*03a8e70aSRaphael Isemann self.first_pass = "expression" 114*03a8e70aSRaphael Isemann self.second_pass = "path" 115*03a8e70aSRaphael Isemann self.do_tests() 116*03a8e70aSRaphael Isemann 117*03a8e70aSRaphael Isemann @no_debug_info_test 118*03a8e70aSRaphael Isemann def test_direct_and_direct(self): 119*03a8e70aSRaphael Isemann """ 120*03a8e70aSRaphael Isemann Variable paths pulls in the declaration indirectly and then repeat that 121*03a8e70aSRaphael Isemann process. 122*03a8e70aSRaphael Isemann """ 123*03a8e70aSRaphael Isemann self.common_setup() 124*03a8e70aSRaphael Isemann self.first_pass = "path" 125*03a8e70aSRaphael Isemann self.second_pass = "path" 126*03a8e70aSRaphael Isemann self.do_tests() 127