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