1""" 2Tests the scenario where we evaluate expressions 3of two types in different modules that reference 4a class template instantiated with the same 5template argument. 6 7Note that, 81. Since the decls originate from modules, LLDB 9 marks them as such and Clang doesn't create 10 a LookupPtr map on the corresponding DeclContext. 11 This prevents regular DeclContext::lookup from 12 succeeding. 132. Because we reference the same class template 14 from two different modules we get a redeclaration 15 chain for the class's ClassTemplateSpecializationDecl. 16 The importer will import all FieldDecls into the 17 same DeclContext on the redeclaration chain. If 18 we don't do the bookkeeping correctly we end up 19 with duplicate decls on the same DeclContext leading 20 to crashes down the line. 21""" 22 23import lldb 24from lldbsuite.test.decorators import * 25from lldbsuite.test.lldbtest import * 26from lldbsuite.test import lldbutil 27 28 29class TestTemplateWithSameArg(TestBase): 30 def setUp(self): 31 TestBase.setUp(self) 32 self.build() 33 self.main_source_file = lldb.SBFileSpec("main.cpp") 34 35 @add_test_categories(["gmodules"]) 36 def test_same_template_arg(self): 37 lldbutil.run_to_source_breakpoint(self, "Break here", self.main_source_file) 38 39 self.expect_expr( 40 "FromMod1", 41 result_type="ClassInMod1", 42 result_children=[ 43 ValueCheck( 44 name="VecInMod1", children=[ValueCheck(name="Member", value="137")] 45 ) 46 ], 47 ) 48 49 self.expect_expr( 50 "FromMod2", 51 result_type="ClassInMod2", 52 result_children=[ 53 ValueCheck( 54 name="VecInMod2", children=[ValueCheck(name="Member", value="42")] 55 ) 56 ], 57 ) 58 59 @add_test_categories(["gmodules"]) 60 def test_duplicate_decls(self): 61 lldbutil.run_to_source_breakpoint(self, "Break here", self.main_source_file) 62 63 self.expect_expr("(intptr_t)&FromMod1 + (intptr_t)&FromMod2") 64 65 # Make sure we only have a single 'Member' decl on the AST 66 self.filecheck("target module dump ast", __file__) 67 68 69# CHECK: ClassTemplateSpecializationDecl {{.*}} imported in Module2 struct ClassInMod3 definition 70# CHECK-NEXT: |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial 71# CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit 72# CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param 73# CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit 74# CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param 75# CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit 76# CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit 77# CHECK-NEXT: |-TemplateArgument type 'int' 78# CHECK-NEXT: | `-BuiltinType {{.*}} 'int' 79# CHECK-NEXT: `-FieldDecl {{.*}} imported in Module2 Member 'int' 80