Skip to content

Commit 6fc22b7

Browse files
committed
[DO-NOT-MERGE] Add unified linkage to structor declarations
1 parent 41f5252 commit 6fc22b7

File tree

19 files changed

+154
-106
lines changed

19 files changed

+154
-106
lines changed

clang/include/clang/Basic/ABI.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,16 @@ enum CXXCtorType {
2727
Ctor_Comdat, ///< The COMDAT used for ctors
2828
Ctor_CopyingClosure, ///< Copying closure variant of a ctor
2929
Ctor_DefaultClosure, ///< Default closure variant of a ctor
30+
Ctor_Unified, ///< GCC-style unified ctor.
3031
};
3132

3233
/// C++ destructor types.
3334
enum CXXDtorType {
34-
Dtor_Deleting, ///< Deleting dtor
35-
Dtor_Complete, ///< Complete object dtor
36-
Dtor_Base, ///< Base object dtor
37-
Dtor_Comdat ///< The COMDAT used for dtors
35+
Dtor_Deleting, ///< Deleting dtor
36+
Dtor_Complete, ///< Complete object dtor
37+
Dtor_Base, ///< Base object dtor
38+
Dtor_Comdat, ///< The COMDAT used for dtors
39+
Dtor_Unified, ///< GCC-style unified dtor.
3840
};
3941

4042
} // end namespace clang

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6056,6 +6056,9 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T,
60566056
case Ctor_Base:
60576057
Out << '2';
60586058
break;
6059+
case Ctor_Unified:
6060+
Out << '4';
6061+
break;
60596062
case Ctor_Comdat:
60606063
Out << '5';
60616064
break;
@@ -6083,6 +6086,9 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
60836086
case Dtor_Base:
60846087
Out << "D2";
60856088
break;
6089+
case Dtor_Unified:
6090+
Out << "D4";
6091+
break;
60866092
case Dtor_Comdat:
60876093
Out << "D5";
60886094
break;

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,8 @@ void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
14941494
// <operator-name> ::= ?_E # vector deleting destructor
14951495
// FIXME: Add a vector deleting dtor type. It goes in the vtable, so we need
14961496
// it.
1497+
case Dtor_Unified:
1498+
llvm_unreachable("not expecting a unified dtor");
14971499
case Dtor_Comdat:
14981500
llvm_unreachable("not expecting a COMDAT");
14991501
}

clang/lib/CodeGen/CGClass.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
14931493
// we'd introduce *two* handler blocks. In the Microsoft ABI, we
14941494
// always delegate because we might not have a definition in this TU.
14951495
switch (DtorType) {
1496+
case Dtor_Unified:
1497+
llvm_unreachable("not expecting a unified dtor");
14961498
case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
14971499
case Dtor_Deleting: llvm_unreachable("already handled deleting case");
14981500

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "clang/AST/RecordLayout.h"
3030
#include "clang/AST/RecursiveASTVisitor.h"
3131
#include "clang/AST/VTableBuilder.h"
32+
#include "clang/Basic/ABI.h"
3233
#include "clang/Basic/CodeGenOptions.h"
3334
#include "clang/Basic/SourceManager.h"
3435
#include "clang/Basic/Version.h"
@@ -2177,22 +2178,29 @@ static bool isFunctionLocalClass(const CXXRecordDecl *RD) {
21772178

21782179
llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
21792180
const CXXMethodDecl *Method, llvm::DIFile *Unit, llvm::DIType *RecordTy) {
2180-
bool IsCtorOrDtor =
2181-
isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
2182-
21832181
StringRef MethodName = getFunctionName(Method);
21842182
llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
21852183

2186-
// Since a single ctor/dtor corresponds to multiple functions, it doesn't
2187-
// make sense to give a single ctor/dtor a linkage name.
2184+
const bool ShouldAddLinkageName =
2185+
(!isa<CXXConstructorDecl>(Method) && !isa<CXXDestructorDecl>(Method)) ||
2186+
CGM.getTarget().getCXXABI().isItaniumFamily();
2187+
21882188
StringRef MethodLinkageName;
21892189
// FIXME: 'isFunctionLocalClass' seems like an arbitrary/unintentional
21902190
// property to use here. It may've been intended to model "is non-external
21912191
// type" but misses cases of non-function-local but non-external classes such
21922192
// as those in anonymous namespaces as well as the reverse - external types
21932193
// that are function local, such as those in (non-local) inline functions.
2194-
if (!IsCtorOrDtor && !isFunctionLocalClass(Method->getParent()))
2195-
MethodLinkageName = CGM.getMangledName(Method);
2194+
if (ShouldAddLinkageName && !isFunctionLocalClass(Method->getParent())) {
2195+
if (auto *Ctor = dyn_cast<CXXConstructorDecl>(Method))
2196+
MethodLinkageName =
2197+
CGM.getMangledName(GlobalDecl(Ctor, CXXCtorType::Ctor_Unified));
2198+
else if (auto *Dtor = dyn_cast<CXXDestructorDecl>(Method))
2199+
MethodLinkageName =
2200+
CGM.getMangledName(GlobalDecl(Dtor, CXXDtorType::Dtor_Unified));
2201+
else
2202+
MethodLinkageName = CGM.getMangledName(Method);
2203+
}
21962204

21972205
// Get the location for the method.
21982206
llvm::DIFile *MethodDefUnit = nullptr;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "clang/AST/Mangle.h"
3838
#include "clang/AST/RecursiveASTVisitor.h"
3939
#include "clang/AST/StmtVisitor.h"
40+
#include "clang/Basic/ABI.h"
4041
#include "clang/Basic/Builtins.h"
4142
#include "clang/Basic/CodeGenOptions.h"
4243
#include "clang/Basic/Diagnostic.h"
@@ -2150,7 +2151,8 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
21502151
if (const auto *CD = dyn_cast<CXXConstructorDecl>(CanonicalGD.getDecl())) {
21512152
if (!getTarget().getCXXABI().hasConstructorVariants()) {
21522153
CXXCtorType OrigCtorType = GD.getCtorType();
2153-
assert(OrigCtorType == Ctor_Base || OrigCtorType == Ctor_Complete);
2154+
assert(OrigCtorType == Ctor_Base || OrigCtorType == Ctor_Complete ||
2155+
OrigCtorType == Ctor_Unified);
21542156
if (OrigCtorType == Ctor_Base)
21552157
CanonicalGD = GlobalDecl(CD, Ctor_Complete);
21562158
}

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
8989
case Dtor_Base:
9090
return false;
9191

92+
case Dtor_Unified:
93+
llvm_unreachable("unexpected unified dtor");
94+
9295
case Dtor_Comdat:
9396
llvm_unreachable("emitting dtor comdat as function?");
9497
}
@@ -102,6 +105,9 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
102105
case Ctor_Base:
103106
return false;
104107

108+
case Ctor_Unified:
109+
llvm_unreachable("unexpected unified ctor");
110+
105111
case Ctor_CopyingClosure:
106112
case Ctor_DefaultClosure:
107113
llvm_unreachable("closure ctors in Itanium ABI?");

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -251,43 +251,11 @@ static unsigned GetCXXMethodCVQuals(const DWARFDIE &subprogram,
251251
return cv_quals;
252252
}
253253

254-
static const char *GetMangledOrStructorName(const DWARFDIE &die) {
255-
const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);
256-
if (name)
257-
return name;
258-
259-
name = die.GetName();
260-
if (!name)
261-
return nullptr;
262-
263-
DWARFDIE parent = die.GetParent();
264-
if (!parent.IsStructUnionOrClass())
265-
return nullptr;
266-
267-
const char *parent_name = parent.GetName();
268-
if (!parent_name)
269-
return nullptr;
270-
271-
// Constructor.
272-
if (::strcmp(parent_name, name) == 0)
273-
return name;
274-
275-
// Destructor.
276-
if (name[0] == '~' && ::strcmp(parent_name, name + 1) == 0)
277-
return name;
278-
279-
return nullptr;
280-
}
281-
282254
static std::string MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
283-
char const *name = GetMangledOrStructorName(die);
255+
const char *name = die.GetMangledName(/*substitute_name_allowed*/ false);
284256
if (!name)
285257
return {};
286258

287-
auto *cu = die.GetCU();
288-
if (!cu)
289-
return {};
290-
291259
SymbolFileDWARF *dwarf = die.GetDWARF();
292260
if (!dwarf)
293261
return {};

lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,39 @@ using namespace lldb_private;
2222
using namespace lldb;
2323
using namespace lldb_private::plugin::dwarf;
2424

25+
static bool IsUnifiedStructorLookup(const DWARFDIE &die) {
26+
auto spec =
27+
die.GetAttributeValueAsReferenceDIE(llvm::dwarf::DW_AT_specification);
28+
if (!spec)
29+
return false;
30+
31+
const char *spec_mangled_name =
32+
spec.GetMangledName(/*substitute_name_allowed=*/false);
33+
if (!spec_mangled_name)
34+
return false;
35+
36+
const char *spec_name = spec.GetName();
37+
if (!spec_name)
38+
return false;
39+
40+
const char *ctx_name = spec.GetParent().GetName();
41+
if (!ctx_name)
42+
return false;
43+
44+
// We have a ctor.
45+
if (::strcmp(ctx_name, spec_name) == 0)
46+
return true;
47+
48+
if (spec_name[0] != '~')
49+
return false;
50+
51+
// We have a dtor.
52+
if (::strcmp(ctx_name, spec_name + 1) == 0)
53+
return true;
54+
55+
return false;
56+
}
57+
2558
DWARFIndex::~DWARFIndex() = default;
2659

2760
IterationAction DWARFIndex::ProcessFunctionDIE(
@@ -60,7 +93,8 @@ IterationAction DWARFIndex::ProcessFunctionDIE(
6093
return IterationAction::Continue;
6194

6295
// In case of a full match, we just insert everything we find.
63-
if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name)
96+
if (name_type_mask & eFunctionNameTypeFull &&
97+
(die.GetMangledName() == name || IsUnifiedStructorLookup(die)))
6498
return callback(die);
6599

66100
// If looking for ObjC selectors, we need to also check if the name is a

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,6 +2492,8 @@ static int ClangToItaniumCtorKind(clang::CXXCtorType kind) {
24922492
return 1;
24932493
case clang::CXXCtorType::Ctor_Base:
24942494
return 2;
2495+
case clang::CXXCtorType::Ctor_Unified:
2496+
return 4;
24952497
case clang::CXXCtorType::Ctor_CopyingClosure:
24962498
case clang::CXXCtorType::Ctor_DefaultClosure:
24972499
case clang::CXXCtorType::Ctor_Comdat:
@@ -2507,6 +2509,8 @@ static int ClangToItaniumDtorKind(clang::CXXDtorType kind) {
25072509
return 1;
25082510
case clang::CXXDtorType::Dtor_Base:
25092511
return 2;
2512+
case clang::CXXDtorType::Dtor_Unified:
2513+
return 4;
25102514
case clang::CXXDtorType::Dtor_Comdat:
25112515
llvm_unreachable("Unexpected destructor kind.");
25122516
}
@@ -2523,14 +2527,14 @@ GetItaniumCtorDtorVariant(llvm::StringRef discriminator) {
25232527
return std::nullopt;
25242528

25252529
if (is_ctor) {
2526-
if (structor_kind > clang::CXXCtorType::Ctor_DefaultClosure)
2530+
if (structor_kind > clang::CXXCtorType::Ctor_Unified)
25272531
return std::nullopt;
25282532

25292533
return ClangToItaniumCtorKind(
25302534
static_cast<clang::CXXCtorType>(structor_kind));
25312535
}
25322536

2533-
if (structor_kind > clang::CXXDtorType::Dtor_Comdat)
2537+
if (structor_kind > clang::CXXDtorType::Dtor_Unified)
25342538
return std::nullopt;
25352539

25362540
return ClangToItaniumDtorKind(static_cast<clang::CXXDtorType>(structor_kind));
@@ -2542,25 +2546,14 @@ SymbolFileDWARF::FindFunctionDefinition(const FunctionCallLabel &label,
25422546
DWARFDIE definition;
25432547
llvm::DenseMap<int, DWARFDIE> structor_variant_to_die;
25442548

2545-
// eFunctionNameTypeFull for mangled name lookup.
2546-
// eFunctionNameTypeMethod is required for structor lookups (since we look
2547-
// those up by DW_AT_name).
25482549
Module::LookupInfo info(ConstString(label.lookup_name),
2549-
lldb::eFunctionNameTypeFull |
2550-
lldb::eFunctionNameTypeMethod,
2550+
lldb::eFunctionNameTypeFull,
25512551
lldb::eLanguageTypeUnknown);
25522552

25532553
m_index->GetFunctions(info, *this, {}, [&](DWARFDIE entry) {
25542554
if (entry.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_declaration, 0))
25552555
return IterationAction::Continue;
25562556

2557-
auto spec = entry.GetAttributeValueAsReferenceDIE(DW_AT_specification);
2558-
if (!spec)
2559-
return IterationAction::Continue;
2560-
2561-
if (spec != declaration)
2562-
return IterationAction::Continue;
2563-
25642557
// We're not picking a specific structor variant DIE, so we're done here.
25652558
if (label.discriminator.empty()) {
25662559
definition = entry;

0 commit comments

Comments
 (0)