80 lines · python
1"""2Tests the scenario where we evaluate expressions3of two types in different modules that reference4a class template instantiated with the same5template argument.6 7Note that,81. Since the decls originate from modules, LLDB9 marks them as such and Clang doesn't create10 a LookupPtr map on the corresponding DeclContext.11 This prevents regular DeclContext::lookup from12 succeeding.132. Because we reference the same class template14 from two different modules we get a redeclaration15 chain for the class's ClassTemplateSpecializationDecl.16 The importer will import all FieldDecls into the17 same DeclContext on the redeclaration chain. If18 we don't do the bookkeeping correctly we end up19 with duplicate decls on the same DeclContext leading20 to crashes down the line.21"""22 23import lldb24from lldbsuite.test.decorators import *25from lldbsuite.test.lldbtest import *26from lldbsuite.test import lldbutil27 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, "return 0", 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, "return 0", 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 AST66 self.filecheck("target module dump ast", __file__)67 68 69# CHECK: ClassTemplateSpecializationDecl {{.*}} imported in Module2 struct ClassInMod3 definition70# CHECK-NEXT: |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial71# CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit72# CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param73# CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit74# CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param75# CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit76# CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit77# CHECK-NEXT: |-TemplateArgument type 'int'78# CHECK-NEXT: | `-BuiltinType {{.*}} 'int'79# CHECK-NEXT: `-FieldDecl {{.*}} imported in Module2 Member 'int'80