From e8077752f655155ad6e64353adab65b84d0bcc5a Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Mon, 6 Oct 2014 05:18:55 +0000 Subject: [PATCH] DebugInfo: Don't include implicit special members in the list of class members By leaving these members out of the member list, we avoid them being emitted into type unit definitions - while still allowing the definition/declaration to be injected into the compile unit as expected. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219101 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 35 +++++++++---------- .../CodeGenCXX/debug-info-template-member.cpp | 13 +++---- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index a8838f2dd3..f5286ff79a 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1157,24 +1157,23 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit, // have templated functions iterate over every declaration to gather // the functions. for(const auto *I : RD->decls()) { - if (const auto *Method = dyn_cast(I)) { - // Reuse the existing member function declaration if it exists. - // It may be associated with the declaration of the type & should be - // reused as we're building the definition. - // - // This situation can arise in the vtable-based debug info reduction where - // implicit members are emitted in a non-vtable TU. - llvm::DenseMap::iterator MI = - SPCache.find(Method->getCanonicalDecl()); - if (MI == SPCache.end()) { - // If the member is implicit, lazily create it when we see the - // definition, not before. (an ODR-used implicit default ctor that's - // never actually code generated should not produce debug info) - if (!Method->isImplicit()) - EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy)); - } else - EltTys.push_back(MI->second); - } + const auto *Method = dyn_cast(I); + // If the member is implicit, don't add it to the member list. This avoids + // the member being added to type units by LLVM, while still allowing it + // to be emitted into the type declaration/reference inside the compile + // unit. + if (!Method || Method->isImplicit()) + continue; + // Reuse the existing member function declaration if it exists. + // It may be associated with the declaration of the type & should be + // reused as we're building the definition. + // + // This situation can arise in the vtable-based debug info reduction where + // implicit members are emitted in a non-vtable TU. + auto MI = SPCache.find(Method->getCanonicalDecl()); + EltTys.push_back(MI == SPCache.end() + ? CreateCXXMemberFunction(Method, Unit, RecordTy) + : MI->second); } } diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index d540425d66..7aa1d3d8b3 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -28,21 +28,22 @@ inline int add3(int x) { // CHECK: [[VIRT_T]] = metadata !{metadata !"0x2f\00T\000\000"{{, [^,]+}}, metadata !"_ZTS4elem", {{.*}} ; [ DW_TAG_template_type_parameter ] // CHECK: [[C:![0-9]*]] = {{.*}}, metadata [[C_MEM:![0-9]*]], metadata !"_ZTS7MyClass", null, metadata !"_ZTS7MyClass"} ; [ DW_TAG_structure_type ] [MyClass] -// CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_FUNC:![0-9]*]], metadata [[C_CTOR:![0-9]*]]} +// CHECK: [[C_MEM]] = metadata !{metadata [[C_VPTR:![0-9]*]], metadata [[C_FUNC:![0-9]*]]} // CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$MyClass] // CHECK: [[C_FUNC]] = {{.*}} ; [ DW_TAG_subprogram ] [line 7] [func] -// CHECK: [[C_CTOR]] = {{.*}} ; [ DW_TAG_subprogram ] [line 0] [MyClass] // CHECK: [[ELEM:![0-9]*]] = {{.*}}, metadata [[ELEM_MEM:![0-9]*]], null, null, metadata !"_ZTS4elem"} ; [ DW_TAG_structure_type ] [elem] {{.*}} [def] // CHECK: [[ELEM_MEM]] = metadata !{metadata [[ELEM_X:![0-9]*]]} // CHECK: [[ELEM_X]] = {{.*}} ; [ DW_TAG_member ] [x] {{.*}} [static] [from _ZTS4virtI4elemE] -// Check that the member function template specialization refers to its class by -// scope, even though it didn't appear in the class's member list (C_MEM). This -// prevents the function from being added to type units, while still appearing -// in the type declaration/reference in the compile unit. +// Check that the member function template specialization and implicit special +// members (the default ctor) refer to their class by scope, even though they +// didn't appear in the class's member list (C_MEM). This prevents the functions +// from being added to type units, while still appearing in the type +// declaration/reference in the compile unit. // CHECK: metadata !"_ZTS7MyClass", {{.*}} ; [ DW_TAG_subprogram ] [line 4] [add<2>] +// CHECK: metadata !"_ZTS7MyClass", {{.*}} ; [ DW_TAG_subprogram ] [line 0] [MyClass] template struct outer { -- 2.50.1