diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-16 15:18:21 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-16 15:18:21 +0000 |
commit | 1e4df92f4939a79a77be57ff145a252730749b11 (patch) | |
tree | 939202d44c99415dbf25610d58610db8a446f3fb /clang/lib/AST/ItaniumMangle.cpp | |
parent | 65f105719121ecddd8826f6d1f4f3b60d7d3a28d (diff) | |
download | bcm5719-llvm-1e4df92f4939a79a77be57ff145a252730749b11.tar.gz bcm5719-llvm-1e4df92f4939a79a77be57ff145a252730749b11.zip |
Add support for putting constructors and destructos in explicit comdats.
There are situations when clang knows that the C1 and C2 constructors
or the D1 and D2 destructors are identical. We already optimize some
of these cases, but cannot optimize it when the GlobalValue is
weak_odr.
The problem with weak_odr is that an old TU seeing the same code will
have a C1 and a C2 comdat with the corresponding symbols. We cannot
suddenly start putting the C2 symbol in the C1 comdat as we cannot
guarantee that the linker will not pick a .o with only C1 in it.
The solution implemented by GCC is to expand the ABI to have a comdat
whose name uses a C5/D5 suffix and always has both symbols. That is
what this patch implements.
llvm-svn: 217874
Diffstat (limited to 'clang/lib/AST/ItaniumMangle.cpp')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 486fab39eac..bdde133ac43 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -150,6 +150,8 @@ public: void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &) override; + void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &) override; + void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) override; void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override; void mangleDynamicAtExitDestructor(const VarDecl *D, @@ -3249,8 +3251,8 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) { void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { // <ctor-dtor-name> ::= C1 # complete object constructor // ::= C2 # base object constructor - // ::= C3 # complete object allocating constructor // + // In addition, C5 is a comdat name with C1 and C2 in it. switch (T) { case Ctor_Complete: Out << "C1"; @@ -3258,8 +3260,8 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { case Ctor_Base: Out << "C2"; break; - case Ctor_CompleteAllocating: - Out << "C3"; + case Ctor_Comdat: + Out << "C5"; break; } } @@ -3269,6 +3271,7 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { // ::= D1 # complete object destructor // ::= D2 # base object destructor // + // In addition, D5 is a comdat name with D1, D2 and, if virtual, D0 in it. switch (T) { case Dtor_Deleting: Out << "D0"; @@ -3279,6 +3282,9 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { case Dtor_Base: Out << "D2"; break; + case Dtor_Comdat: + Out << "D5"; + break; } } @@ -3689,6 +3695,18 @@ void ItaniumMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D, Mangler.mangle(D); } +void ItaniumMangleContextImpl::mangleCXXCtorComdat(const CXXConstructorDecl *D, + raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out, D, Ctor_Comdat); + Mangler.mangle(D); +} + +void ItaniumMangleContextImpl::mangleCXXDtorComdat(const CXXDestructorDecl *D, + raw_ostream &Out) { + CXXNameMangler Mangler(*this, Out, D, Dtor_Comdat); + Mangler.mangle(D); +} + void ItaniumMangleContextImpl::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &Out) { |