1from lldbsuite.test.decorators import * 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test import lldbutil 4 5""" 6This test ensures that we only create Clang AST nodes in our module AST 7when we actually need them. 8 9All tests in this file behave like this: 10 1. Use LLDB to do something (expression evaluation, breakpoint setting, etc.). 11 2. Check that certain Clang AST nodes were not loaded during the previous 12 step. 13""" 14 15class TestCase(TestBase): 16 17 NO_DEBUG_INFO_TESTCASE = True 18 mydir = TestBase.compute_mydir(__file__) 19 20 def setUp(self): 21 TestBase.setUp(self) 22 # Only build this test once. 23 self.build() 24 25 # Clang declaration kind we are looking for. 26 class_decl_kind = "CXXRecordDecl" 27 # FIXME: This shouldn't be a CXXRecordDecl, but that's how we model 28 # structs in Clang. 29 struct_decl_kind = "CXXRecordDecl" 30 31 # The decls we use in this program in the format that 32 # decl_in_line and decl_completed_in_line expect (which is a pair of 33 # node type and the unqualified declaration name. 34 struct_first_member_decl = [struct_decl_kind, "StructFirstMember"] 35 struct_behind_ptr_decl = [struct_decl_kind, "StructBehindPointer"] 36 struct_behind_ref_decl = [struct_decl_kind, "StructBehindRef"] 37 struct_member_decl = [struct_decl_kind, "StructMember"] 38 some_struct_decl = [struct_decl_kind, "SomeStruct"] 39 other_struct_decl = [struct_decl_kind, "OtherStruct"] 40 class_in_namespace_decl = [class_decl_kind, "ClassInNamespace"] 41 class_we_enter_decl = [class_decl_kind, "ClassWeEnter"] 42 class_member_decl = [struct_decl_kind, "ClassMember"] 43 class_static_member_decl = [struct_decl_kind, "StaticClassMember"] 44 class_pointer_to_member_decl = [struct_decl_kind, "PointerToMember"] 45 unused_class_member_decl = [struct_decl_kind, "UnusedClassMember"] 46 unused_class_member_ptr_decl = [struct_decl_kind, "UnusedClassMemberPtr"] 47 48 def assert_no_decls_loaded(self): 49 """ 50 Asserts that no known declarations in this test are loaded 51 into the module's AST. 52 """ 53 self.assert_decl_not_loaded(self.struct_first_member_decl) 54 self.assert_decl_not_loaded(self.struct_behind_ptr_decl) 55 self.assert_decl_not_loaded(self.struct_behind_ref_decl) 56 self.assert_decl_not_loaded(self.struct_member_decl) 57 self.assert_decl_not_loaded(self.some_struct_decl) 58 self.assert_decl_not_loaded(self.other_struct_decl) 59 self.assert_decl_not_loaded(self.class_in_namespace_decl) 60 self.assert_decl_not_loaded(self.class_member_decl) 61 self.assert_decl_not_loaded(self.class_static_member_decl) 62 self.assert_decl_not_loaded(self.class_pointer_to_member_decl) 63 self.assert_decl_not_loaded(self.unused_class_member_decl) 64 65 def get_ast_dump(self): 66 """Returns the dumped Clang AST of the module as a string""" 67 res = lldb.SBCommandReturnObject() 68 ci = self.dbg.GetCommandInterpreter() 69 ci.HandleCommand('target modules dump ast a.out', res) 70 self.assertTrue(res.Succeeded()) 71 return res.GetOutput() 72 73 def decl_in_line(self, line, decl): 74 """ 75 Returns true iff the given line declares the given Clang decl. 76 The line is expected to be in the form of Clang's AST dump. 77 """ 78 line = line.rstrip() + "\n" 79 decl_kind = "-" + decl[0] + " " 80 # Either the decl is somewhere in the line or at the end of 81 # the line. 82 decl_name = " " + decl[1] + " " 83 decl_name_eol = " " + decl[1] + "\n" 84 if not decl_kind in line: 85 return False 86 return decl_name in line or decl_name_eol in line 87 88 def decl_completed_in_line(self, line, decl): 89 """ 90 Returns true iff the given line declares the given Clang decl and 91 the decl was completed (i.e., it has no undeserialized declarations 92 in it). 93 """ 94 return self.decl_in_line(line, decl) and not "<undeserialized declarations>" in line 95 96 # The following asserts are used for checking if certain Clang declarations 97 # were loaded or not since the target was created. 98 99 def assert_decl_loaded(self, decl): 100 """ 101 Asserts the given decl is currently loaded. 102 Note: This test is about checking that types/declarations are not 103 loaded. If this assert fails it is usually fine to turn it into a 104 assert_decl_not_loaded or assert_decl_not_completed assuming LLDB's 105 functionality has not suffered by not loading this declaration. 106 """ 107 ast = self.get_ast_dump() 108 found = False 109 for line in ast.splitlines(): 110 if self.decl_in_line(line, decl): 111 found = True 112 self.assertTrue(self.decl_completed_in_line(line, decl), 113 "Should have called assert_decl_not_completed") 114 self.assertTrue(found, "Declaration no longer loaded " + str(decl) + 115 ".\nAST:\n" + ast) 116 117 def assert_decl_not_completed(self, decl): 118 """ 119 Asserts that the given decl is currently not completed in the module's 120 AST. It may be loaded but then can can only contain undeserialized 121 declarations. 122 """ 123 ast = self.get_ast_dump() 124 found = False 125 for line in ast.splitlines(): 126 error_msg = "Unexpected completed decl: '" + line + "'.\nAST:\n" + ast 127 self.assertFalse(self.decl_completed_in_line(line, decl), error_msg) 128 129 def assert_decl_not_loaded(self, decl): 130 """ 131 Asserts that the given decl is currently not loaded in the module's 132 AST. 133 """ 134 ast = self.get_ast_dump() 135 found = False 136 for line in ast.splitlines(): 137 error_msg = "Unexpected loaded decl: '" + line + "'\nAST:\n" + ast 138 self.assertFalse(self.decl_in_line(line, decl), error_msg) 139 140 141 def clean_setup(self, location): 142 """ 143 Runs to the line with the source line with the given location string 144 and ensures that our module AST is empty. 145 """ 146 lldbutil.run_to_source_breakpoint(self, 147 "// Location: " + location, lldb.SBFileSpec("main.cpp")) 148 # Make sure no declarations are loaded initially. 149 self.assert_no_decls_loaded() 150 151 @add_test_categories(["dwarf"]) 152 def test_arithmetic_expression_in_main(self): 153 """ Runs a simple arithmetic expression which should load nothing. """ 154 self.clean_setup(location="multiple locals function") 155 156 self.expect("expr 1 + (int)2.0", substrs=['(int) $0']) 157 158 # This should not have loaded any decls. 159 self.assert_no_decls_loaded() 160 161 @add_test_categories(["dwarf"]) 162 def test_printing_local_variable_in_other_struct_func(self): 163 """ 164 Prints a local variable and makes sure no unrelated types are loaded. 165 """ 166 self.clean_setup(location="other struct function") 167 168 self.expect("expr other_struct_var", substrs=['(OtherStruct) $0']) 169 # The decl we run on was loaded. 170 self.assert_decl_loaded(self.other_struct_decl) 171 172 # This should not have loaded anything else. 173 self.assert_decl_not_loaded(self.some_struct_decl) 174 self.assert_decl_not_loaded(self.class_in_namespace_decl) 175 176 @add_test_categories(["dwarf"]) 177 def test_printing_struct_with_multiple_locals(self): 178 """ 179 Prints a local variable and checks that we don't load other local 180 variables. 181 """ 182 self.clean_setup(location="multiple locals function") 183 184 self.expect("expr struct_var", substrs=['(SomeStruct) $0']) 185 186 # We loaded SomeStruct and its member types for printing. 187 self.assert_decl_loaded(self.some_struct_decl) 188 self.assert_decl_loaded(self.struct_behind_ptr_decl) 189 self.assert_decl_loaded(self.struct_behind_ref_decl) 190 191 # FIXME: We don't use these variables, but we seem to load all local 192 # local variables. 193 self.assert_decl_not_completed(self.other_struct_decl) 194 self.assert_decl_not_completed(self.class_in_namespace_decl) 195 196 @add_test_categories(["dwarf"]) 197 def test_addr_of_struct(self): 198 """ 199 Prints the address of a local variable (which is a struct). 200 """ 201 self.clean_setup(location="multiple locals function") 202 203 self.expect("expr &struct_var", substrs=['(SomeStruct *) $0']) 204 205 # We loaded SomeStruct. 206 self.assert_decl_loaded(self.some_struct_decl) 207 208 # The member declarations should not be completed. 209 self.assert_decl_not_completed(self.struct_behind_ptr_decl) 210 self.assert_decl_not_completed(self.struct_behind_ref_decl) 211 212 # FIXME: The first member was behind a pointer so it shouldn't be 213 # completed. Somehow LLDB really wants to load the first member, so 214 # that is why have it defined here. 215 self.assert_decl_loaded(self.struct_first_member_decl) 216 217 # FIXME: We don't use these variables, but we seem to load all local 218 # local variables. 219 self.assert_decl_not_completed(self.other_struct_decl) 220 self.assert_decl_not_completed(self.class_in_namespace_decl) 221 222 @add_test_categories(["dwarf"]) 223 def test_class_function_access_member(self): 224 self.clean_setup(location="class function") 225 226 self.expect("expr member", substrs=['(ClassMember) $0']) 227 228 # We loaded the current class we touched. 229 self.assert_decl_loaded(self.class_we_enter_decl) 230 # We loaded the unused members of this class. 231 self.assert_decl_loaded(self.unused_class_member_decl) 232 self.assert_decl_not_completed(self.unused_class_member_ptr_decl) 233 # We loaded the member we used. 234 self.assert_decl_loaded(self.class_member_decl) 235 # We didn't load the type of the unused static member. 236 self.assert_decl_not_completed(self.class_static_member_decl) 237 # We didn't load the type of the unused pointer-to-member member. 238 self.assert_decl_not_completed(self.class_pointer_to_member_decl) 239 240 # This should not have loaded anything else. 241 self.assert_decl_not_loaded(self.other_struct_decl) 242 self.assert_decl_not_loaded(self.some_struct_decl) 243 self.assert_decl_not_loaded(self.class_in_namespace_decl) 244 245