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