Author: Michael Buch
Date: 2025-09-09T09:50:11+01:00
New Revision: 06d202b6cb13b38165af03dbf12a3beaac0b38ea

URL: 
https://github.com/llvm/llvm-project/commit/06d202b6cb13b38165af03dbf12a3beaac0b38ea
DIFF: 
https://github.com/llvm/llvm-project/commit/06d202b6cb13b38165af03dbf12a3beaac0b38ea.diff

LOG: [clang][DebugInfo] Emit unified (Itanium) mangled name to structor 
declarations (#154142)

Depends on https://github.com/llvm/llvm-project/pull/154137

This patch is motivated by
https://github.com/llvm/llvm-project/pull/149827, where we plan on using
mangled names on structor declarations to find the exact structor
definition that LLDB's expression evaluator should call.

Given a `DW_TAG_subprogram` for a function declaration, the most
convenient way for a debugger to find the corresponding definition is to
use the `DW_AT_linkage_name` (i.e., the mangled name). However, we
currently can't do that for constructors/destructors because Clang
doesn't attach linkage names to them. This is because, depending on ABI,
there can be multiple definitions for a single constructor/destructor
declaration. The way GCC works around this is by producing a `C4`/`D4`
"unified" mangling for structor declarations (see
[godbolt](https://godbolt.org/z/Wds6cja9K)). GDB uses this to locate the
relevant definitions.

This patch aligns Clang with GCC's DWARF output and allows us to
implement the same lookup scheme in LLDB.

Added: 
    clang/test/DebugInfo/CXX/local-structor-linkage-names.cpp
    clang/test/DebugInfo/CXX/structor-linkage-names.cpp

Modified: 
    clang/include/clang/Basic/ABI.h
    clang/include/clang/Basic/DebugOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/AST/MicrosoftMangle.cpp
    clang/lib/CodeGen/CGClass.cpp
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/CodeGen/CGDebugInfo.h
    clang/lib/CodeGen/ItaniumCXXABI.cpp
    clang/lib/CodeGen/MicrosoftCXXABI.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/DebugInfo/CXX/artificial-arg.cpp
    clang/test/DebugInfo/ObjCXX/cyclic.mm

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/ABI.h b/clang/include/clang/Basic/ABI.h
index 231bad799a42c..8279529c316cf 100644
--- a/clang/include/clang/Basic/ABI.h
+++ b/clang/include/clang/Basic/ABI.h
@@ -27,14 +27,16 @@ enum CXXCtorType {
   Ctor_Comdat,         ///< The COMDAT used for ctors
   Ctor_CopyingClosure, ///< Copying closure variant of a ctor
   Ctor_DefaultClosure, ///< Default closure variant of a ctor
+  Ctor_Unified,        ///< GCC-style unified dtor
 };
 
 /// C++ destructor types.
 enum CXXDtorType {
-    Dtor_Deleting, ///< Deleting dtor
-    Dtor_Complete, ///< Complete object dtor
-    Dtor_Base,     ///< Base object dtor
-    Dtor_Comdat    ///< The COMDAT used for dtors
+  Dtor_Deleting, ///< Deleting dtor
+  Dtor_Complete, ///< Complete object dtor
+  Dtor_Base,     ///< Base object dtor
+  Dtor_Comdat,   ///< The COMDAT used for dtors
+  Dtor_Unified,  ///< GCC-style unified dtor
 };
 
 } // end namespace clang

diff  --git a/clang/include/clang/Basic/DebugOptions.def 
b/clang/include/clang/Basic/DebugOptions.def
index c6e736e92744c..a768b12fa4e0d 100644
--- a/clang/include/clang/Basic/DebugOptions.def
+++ b/clang/include/clang/Basic/DebugOptions.def
@@ -125,6 +125,12 @@ DEBUGOPT(DebugNameTable, 2, 0, Compatible)
 /// Whether to use DWARF base address specifiers in .debug_ranges.
 DEBUGOPT(DebugRangesBaseAddress, 1, 0, Compatible)
 
+/// Whether to add linkage names to constructor/destructor declarations.
+/// This is an escape hatch for cases where attaching the additional linkage
+/// names would increase debug-info size (particularly the .debug_str section)
+/// too much.
+DEBUGOPT(DebugStructorDeclLinkageNames, 1, 0, Benign)
+
 /// Whether to embed source in DWARF debug line section.
 DEBUGOPT(EmbedSource, 1, 0, Compatible)
 

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 718808d583e8c..ea5a94f840470 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4789,6 +4789,18 @@ def gembed_source : Flag<["-"], "gembed-source">, 
Group<g_flags_Group>,
 def gno_embed_source : Flag<["-"], "gno-embed-source">, Group<g_flags_Group>,
     Flags<[NoXarchOption]>,
     HelpText<"Restore the default behavior of not embedding source text in 
DWARF debug sections">;
+defm structor_decl_linkage_names
+    : BoolGOption<"structor-decl-linkage-names",
+                  CodeGenOpts<"DebugStructorDeclLinkageNames">, DefaultTrue,
+                  NegFlag<SetFalse>,
+                  PosFlag<SetTrue, [], [],
+                          "Attach linkage names to C++ constructor/destructor "
+                          "declarations in DWARF."
+                          "Implies -g.">,
+                  BothFlags<[], [ClangOption, CLOption, CC1Option]>>,
+                  DocBrief<[{On some ABIs (e.g., Itanium), constructors and 
destructors may have multiple variants. Historically, when generating DWARF, 
Clang did not attach ``DW_AT_linkage_name``s to structor DIEs because there 
were multiple possible manglings (depending on the structor variant) that could 
be used. With ``-gstructor-decl-linkage-names``, for ABIs with structor 
variants, we attach a "unified" mangled name to structor declarations DIEs 
which debuggers can use to look up all the definitions for a structor 
declaration. E.g., a "unified" mangled name ``_ZN3FooC4Ev`` may have multiple 
definitions associated with it such as ``_ZN3FooC1Ev`` and ``_ZN3FooC2Ev``.
+
+Enabling this flag results in a better interactive debugging experience (both 
GDB and LLDB have support for understanding these "unified" linkage names). 
However, it comes with a significant increase in debug-info size (particularly 
the `.debug_str` section). As an escape hatch, users can disable this feature 
using ``-gno-structor-decl-linkage-names``.}]>;
 defm key_instructions : BoolGOption<"key-instructions",
     CodeGenOpts<"DebugKeyInstructions">, DefaultFalse,
     NegFlag<SetFalse>, PosFlag<SetTrue, [], [],

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ffadfce67d631..163cd43abd45a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -6026,6 +6026,8 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T,
   //                  ::= CI2 <type> # base inheriting constructor
   //
   // In addition, C5 is a comdat name with C1 and C2 in it.
+  // C4 represents a ctor declaration and is used by debuggers to look up
+  // the various ctor variants.
   Out << 'C';
   if (InheritedFrom)
     Out << 'I';
@@ -6036,6 +6038,9 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T,
   case Ctor_Base:
     Out << '2';
     break;
+  case Ctor_Unified:
+    Out << '4';
+    break;
   case Ctor_Comdat:
     Out << '5';
     break;
@@ -6053,6 +6058,8 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   //                  ::= D2  # base object destructor
   //
   // In addition, D5 is a comdat name with D1, D2 and, if virtual, D0 in it.
+  // D4 represents a dtor declaration and is used by debuggers to look up
+  // the various dtor variants.
   switch (T) {
   case Dtor_Deleting:
     Out << "D0";
@@ -6063,6 +6070,9 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   case Dtor_Base:
     Out << "D2";
     break;
+  case Dtor_Unified:
+    Out << "D4";
+    break;
   case Dtor_Comdat:
     Out << "D5";
     break;

diff  --git a/clang/lib/AST/MicrosoftMangle.cpp 
b/clang/lib/AST/MicrosoftMangle.cpp
index 2ac38a24456c7..d96472e393f68 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1496,6 +1496,8 @@ void 
MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   // it.
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
+  case Dtor_Unified:
+    llvm_unreachable("not expecting a unified dtor type");
   }
   llvm_unreachable("Unsupported dtor type?");
 }

diff  --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index bae55aa1e1928..6742c196053a2 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1481,6 +1481,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList 
&Args) {
   // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
   // always delegate because we might not have a definition in this TU.
   switch (DtorType) {
+  case Dtor_Unified:
+    llvm_unreachable("not expecting a unified dtor");
   case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
 

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0385dbdac869b..578d09f7971d6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2177,24 +2177,47 @@ static bool isFunctionLocalClass(const CXXRecordDecl 
*RD) {
   return false;
 }
 
+llvm::StringRef
+CGDebugInfo::GetMethodLinkageName(const CXXMethodDecl *Method) const {
+  assert(Method);
+
+  const bool IsCtorOrDtor =
+      isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
+
+  if (IsCtorOrDtor && !CGM.getCodeGenOpts().DebugStructorDeclLinkageNames)
+    return {};
+
+  // In some ABIs (particularly Itanium) a single ctor/dtor
+  // corresponds to multiple functions. Attach a "unified"
+  // linkage name for those (which is the convention GCC uses).
+  // Otherwise, attach no linkage name.
+  if (IsCtorOrDtor && !CGM.getTarget().getCXXABI().hasConstructorVariants())
+    return {};
+
+  if (const auto *Ctor = llvm::dyn_cast<CXXConstructorDecl>(Method))
+    return CGM.getMangledName(GlobalDecl(Ctor, CXXCtorType::Ctor_Unified));
+
+  if (const auto *Dtor = llvm::dyn_cast<CXXDestructorDecl>(Method))
+    return CGM.getMangledName(GlobalDecl(Dtor, CXXDtorType::Dtor_Unified));
+
+  return CGM.getMangledName(Method);
+}
+
 llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
     const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
-  bool IsCtorOrDtor =
-      isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
+  assert(Method);
 
   StringRef MethodName = getFunctionName(Method);
   llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
 
-  // Since a single ctor/dtor corresponds to multiple functions, it doesn't
-  // make sense to give a single ctor/dtor a linkage name.
   StringRef MethodLinkageName;
   // FIXME: 'isFunctionLocalClass' seems like an arbitrary/unintentional
   // property to use here. It may've been intended to model "is non-external
   // type" but misses cases of non-function-local but non-external classes such
   // as those in anonymous namespaces as well as the reverse - external types
   // that are function local, such as those in (non-local) inline functions.
-  if (!IsCtorOrDtor && !isFunctionLocalClass(Method->getParent()))
-    MethodLinkageName = CGM.getMangledName(Method);
+  if (!isFunctionLocalClass(Method->getParent()))
+    MethodLinkageName = GetMethodLinkageName(Method);
 
   // Get the location for the method.
   llvm::DIFile *MethodDefUnit = nullptr;

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index ff9c3cd2d1136..f86077369a42a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -899,6 +899,10 @@ class CGDebugInfo {
       std::memcpy(Data + A.size(), B.data(), B.size());
     return StringRef(Data, A.size() + B.size());
   }
+
+  /// If one exists, returns the linkage name of the specified \
+  /// (non-null) \c Method. Returns empty string otherwise.
+  llvm::StringRef GetMethodLinkageName(const CXXMethodDecl *Method) const;
 };
 
 /// A scoped helper to set the current debug location to the specified

diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp 
b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index d5b5fd7200855..7dc2eaf1e9f75 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -91,6 +91,8 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
 
       case Dtor_Comdat:
         llvm_unreachable("emitting dtor comdat as function?");
+      case Dtor_Unified:
+        llvm_unreachable("emitting unified dtor as function?");
       }
       llvm_unreachable("bad dtor kind");
     }
@@ -108,6 +110,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
 
       case Ctor_Comdat:
         llvm_unreachable("emitting ctor comdat as function?");
+
+      case Ctor_Unified:
+        llvm_unreachable("emitting unified ctor as function?");
       }
       llvm_unreachable("bad dtor kind");
     }

diff  --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 88f0648660965..94190a149e859 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -77,6 +77,8 @@ class MicrosoftCXXABI : public CGCXXABI {
         return false;
 
       case Dtor_Comdat: llvm_unreachable("emitting dtor comdat as function?");
+      case Dtor_Unified:
+        llvm_unreachable("unexpected unified dtor type");
       }
       llvm_unreachable("bad dtor kind");
     }
@@ -1417,6 +1419,8 @@ llvm::GlobalValue::LinkageTypes 
MicrosoftCXXABI::getCXXDestructorLinkage(
     // and are emitted everywhere they are used. They are internal if the class
     // is internal.
     return llvm::GlobalValue::LinkOnceODRLinkage;
+  case Dtor_Unified:
+    llvm_unreachable("MS C++ ABI does not support unified dtors");
   case Dtor_Comdat:
     llvm_unreachable("MS C++ ABI does not support comdat dtors");
   }

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 21e45c6b56bbb..a357a8828b13d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4608,6 +4608,10 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, 
const llvm::Triple &T,
                    KeyInstructionsOnByDefault))
     CmdArgs.push_back("-gkey-instructions");
 
+  if (!Args.hasFlag(options::OPT_gstructor_decl_linkage_names,
+                    options::OPT_gno_structor_decl_linkage_names, true))
+    CmdArgs.push_back("-gno-structor-decl-linkage-names");
+
   if (EmitCodeView) {
     CmdArgs.push_back("-gcodeview");
 

diff  --git a/clang/test/DebugInfo/CXX/artificial-arg.cpp 
b/clang/test/DebugInfo/CXX/artificial-arg.cpp
index a0cf131f83e15..21b8d047b3456 100644
--- a/clang/test/DebugInfo/CXX/artificial-arg.cpp
+++ b/clang/test/DebugInfo/CXX/artificial-arg.cpp
@@ -25,7 +25,8 @@ int main(int argc, char **argv) {
 // CHECK: ![[CLASSTYPE:.*]] = distinct !DICompositeType(tag: 
DW_TAG_class_type, name: "A",
 // CHECK-SAME:                                 identifier: "_ZTS1A"
 // CHECK: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: 
![[CLASSTYPE]],{{.*}} DIFlagArtificial
-// CHECK: !DISubprogram(name: "A", scope: ![[CLASSTYPE]]
+// CHECK: !DISubprogram(name: "A"
+// CHECK-SAME:          scope: ![[CLASSTYPE]]
 // CHECK-SAME:          line: 12
 // CHECK-SAME:          DIFlagPublic
 // CHECK: !DISubroutineType(types: [[FUNCTYPE:![0-9]*]])

diff  --git a/clang/test/DebugInfo/CXX/local-structor-linkage-names.cpp 
b/clang/test/DebugInfo/CXX/local-structor-linkage-names.cpp
new file mode 100644
index 0000000000000..4b4261ee3fbd8
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/local-structor-linkage-names.cpp
@@ -0,0 +1,29 @@
+// Tests that we emit don't emit unified constructor/destructor linkage names
+// for function-local constructors.
+
+// Check with -gstructor-decl-linkage-names.
+// RUN: %clang_cc1 -triple aarch64-apple-macosx -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            -gstructor-decl-linkage-names %s -o - | FileCheck %s 
--check-prefixes=CHECK
+//
+// Check with -gno-structor-decl-linkage-names.
+// RUN: %clang_cc1 -triple aarch64-apple-macosx -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            -gno-structor-decl-linkage-names %s -o - | FileCheck %s 
--check-prefixes=CHECK
+
+struct HasNestedCtor {
+  HasNestedCtor();
+};
+
+HasNestedCtor::HasNestedCtor() {
+  struct Local {
+    Local() {}
+    ~Local() {}
+  } l;
+}
+
+// CHECK:      !DISubprogram(name: "Local"
+// CHECK-NOT:                linkageName
+// CHECK-SAME: )
+
+// CHECK:      !DISubprogram(name: "~Local"
+// CHECK-NOT:                linkageName
+// CHECK-SAME: )

diff  --git a/clang/test/DebugInfo/CXX/structor-linkage-names.cpp 
b/clang/test/DebugInfo/CXX/structor-linkage-names.cpp
new file mode 100644
index 0000000000000..b7aac198c5180
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/structor-linkage-names.cpp
@@ -0,0 +1,89 @@
+// Tests that we emit unified constructor/destructor linkage names
+// for ABIs that support it.
+
+// Check that -gstructor-decl-linkage-names is the default.
+// RUN: %clang_cc1 -triple aarch64-apple-macosx -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            %s -o - | FileCheck %s --check-prefixes=CHECK,ITANIUM
+//
+// Check with -gstructor-decl-linkage-names.
+// RUN: %clang_cc1 -triple aarch64-apple-macosx -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            -gstructor-decl-linkage-names %s -o - | FileCheck %s 
--check-prefixes=CHECK,ITANIUM
+//
+// Check with -gno-structor-decl-linkage-names.
+// RUN: %clang_cc1 -triple aarch64-apple-macosx -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            -gno-structor-decl-linkage-names %s -o - | FileCheck %s 
--check-prefixes=CHECK,DISABLE
+//
+// Check ABI without structor variants.
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm 
-debug-info-kind=standalone \
+// RUN:            -gstructor-decl-linkage-names %s -o - | FileCheck %s 
--check-prefixes=CHECK,MSABI
+
+struct Base {
+  Base(int x);
+  ~Base();
+};
+
+Base::Base(int x) {}
+Base::~Base() {}
+
+// Check that we emit unified ctor/dtor (C4/D4) on Itanium but not for MS-ABI.
+
+// CHECK: ![[BASE_CTOR_DECL:[0-9]+]] = !DISubprogram(name: "Base"
+// MSABI-NOT:                                        linkageName:
+// DISABLE-NOT:                                      linkageName:
+// ITANIUM-SAME:                                     linkageName: 
"_ZN4BaseC4Ei"
+// CHECK-SAME:                                       spFlags: 0
+
+// CHECK: ![[BASE_DTOR_DECL:[0-9]+]] = !DISubprogram(name: "~Base"
+// MSABI-NOT:                                        linkageName:
+// DISABLE-NOT:                                      linkageName:
+// ITANIUM-SAME:                                     linkageName: 
"_ZN4BaseD4Ev"
+// CHECK-SAME:                                       spFlags: 0
+
+// Check that the ctor/dtor definitions have linkage names that aren't
+// the ones on the declaration.
+
+// CHECK: !DISubprogram(name: "Base"
+// MSABI-SAME:          linkageName:
+// ITANIUM-SAME:        linkageName: "_ZN4BaseC2Ei"
+// CHECK-SAME:          spFlags: DISPFlagDefinition
+// CHECK-SAME:          declaration: ![[BASE_CTOR_DECL]]
+
+// ITANIUM: !DISubprogram(name: "Base"
+// ITANIUM-SAME:          linkageName: "_ZN4BaseC1Ei"
+// ITANIUM-SAME:          spFlags: DISPFlagDefinition
+// ITANIUM-SAME:          declaration: ![[BASE_CTOR_DECL]]
+
+// CHECK: !DISubprogram(name: "~Base"
+// MSABI-SAME:          linkageName:
+// ITANIUM-SAME:        linkageName: "_ZN4BaseD2Ev"
+// CHECK-SAME:          spFlags: DISPFlagDefinition
+// CHECK-SAME:          declaration: ![[BASE_DTOR_DECL]]
+
+// ITANIUM: !DISubprogram(name: "~Base"
+// ITANIUM-SAME:          linkageName: "_ZN4BaseD1Ev"
+// ITANIUM-SAME:          spFlags: DISPFlagDefinition
+// ITANIUM-SAME:          declaration: ![[BASE_DTOR_DECL]]
+
+struct Derived : public Base {
+    using Base::Base;
+} d(5);
+
+// CHECK: !DISubprogram(name: "Base"
+// MSABI-SAME:          linkageName:
+// ITANIUM-SAME:        linkageName: "_ZN7DerivedCI14BaseEi"
+// CHECK-SAME:          spFlags: {{.*}}DISPFlagDefinition
+// CHECK-SAME:          declaration: ![[BASE_INHERIT_CTOR_DECL:[0-9]+]]
+
+// CHECK: [[BASE_INHERIT_CTOR_DECL]] = !DISubprogram(name: "Base"
+// MSABI-NOT:                                        linkageName:
+// DISABLE-NOT:                                      linkageName:
+// ITANIUM-SAME:                                     linkageName: 
"_ZN7DerivedCI44BaseEi"
+// CHECK-SAME                                        spFlags: 0
+
+// ITANIUM: !DISubprogram(name: "Base"
+// ITANIUM-SAME:          linkageName: "_ZN7DerivedCI24BaseEi"
+// ITANIUM-SAME:          spFlags: DISPFlagDefinition
+// ITANIUM-SAME:          declaration: ![[BASE_INHERIT_CTOR_DECL:[0-9]+]]
+
+// MSABI:   !DISubprogram(name: "~Derived"
+// DISABLE: !DISubprogram(name: "~Derived"

diff  --git a/clang/test/DebugInfo/ObjCXX/cyclic.mm 
b/clang/test/DebugInfo/ObjCXX/cyclic.mm
index 2fb1611c904d0..a062b6ad50612 100644
--- a/clang/test/DebugInfo/ObjCXX/cyclic.mm
+++ b/clang/test/DebugInfo/ObjCXX/cyclic.mm
@@ -10,8 +10,9 @@
 // CHECK-SAME:                             identifier:
 // CHECK: ![[BMEMBERS]] = !{![[BB:[0-9]+]]}
   B(struct A *);
-// CHECK: ![[BB]] = !DISubprogram(name: "B", scope: ![[B]]
-// CHECK-SAME:                    line: [[@LINE-2]],
+// CHECK: ![[BB]] = !DISubprogram(name: "B",
+// CHECK-SAME:                    scope: ![[B]]
+// CHECK-SAME:                    line: [[@LINE-3]],
 // CHECK-SAME:                    type: ![[TY:[0-9]+]],
 // CHECK: ![[TY]] = !DISubroutineType(types: ![[ARGS:[0-9]+]])
 // CHECK: ![[ARGS]] = !{null, ![[THIS:[0-9]+]], !{{[^,]+}}}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to