From 8a35c7982c794ea7689e78845f1891f95202390d Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 22 Dec 2009 06:36:32 +0000 Subject: [PATCH] Make sure that we mangle overloaded operators that are member functions correctly, giving them the correct arity. With this seemingly insignificant fix, we are now able to build and link clang using clang itself! (LLVM still has to be built with gcc for the time being). llvm-svn: 91893 --- clang/lib/CodeGen/Mangle.cpp | 29 ++++++++++++++++------ clang/test/CodeGenCXX/mangle.cpp | 22 ++++++++++++++-- clang/test/CodeGenCXX/member-functions.cpp | 2 +- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 6c28d22f6b68..089d77764e4d 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -480,10 +480,17 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { mangleType(Context.getASTContext().getCanonicalType(Name.getCXXNameType())); break; - case DeclarationName::CXXOperatorName: - mangleOperatorName(Name.getCXXOverloadedOperator(), - cast(ND)->getNumParams()); + case DeclarationName::CXXOperatorName: { + unsigned Arity = cast(ND)->getNumParams(); + + // If we have a C++ member function, we need to include the 'this' pointer. + // FIXME: This does not make sense for operators that are static, but their + // names stay the same regardless of the arity (operator new for instance). + if (isa(ND)) + Arity++; + mangleOperatorName(Name.getCXXOverloadedOperator(), Arity); break; + } case DeclarationName::CXXLiteralOperatorName: // FIXME: This mangling is not yet official. @@ -611,16 +618,24 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) { case OO_Array_Delete: Out << "da"; break; // ::= ps # + (unary) // ::= pl # + - case OO_Plus: Out << (Arity == 1? "ps" : "pl"); break; + case OO_Plus: + assert((Arity == 1 || Arity == 2) && "Invalid arity!"); + Out << (Arity == 1? "ps" : "pl"); break; // ::= ng # - (unary) // ::= mi # - - case OO_Minus: Out << (Arity == 1? "ng" : "mi"); break; + case OO_Minus: + assert((Arity == 1 || Arity == 2) && "Invalid arity!"); + Out << (Arity == 1? "ng" : "mi"); break; // ::= ad # & (unary) // ::= an # & - case OO_Amp: Out << (Arity == 1? "ad" : "an"); break; + case OO_Amp: + assert((Arity == 1 || Arity == 2) && "Invalid arity!"); + Out << (Arity == 1? "ad" : "an"); break; // ::= de # * (unary) // ::= ml # * - case OO_Star: Out << (Arity == 1? "de" : "ml"); break; + case OO_Star: + assert((Arity == 1 || Arity == 2) && "Invalid arity!"); + Out << (Arity == 1? "de" : "ml"); break; // ::= co # ~ case OO_Tilde: Out << "co"; break; // ::= dv # / diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index 090a3f17eef1..88465cf9d98b 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -141,7 +141,7 @@ int f(struct a *x) { // PR5017 extern "C" { struct Debug { - const Debug& operator<< (unsigned a) const { } + const Debug& operator<< (unsigned a) const { return *this; } }; Debug dbg; // CHECK: @_ZNK5DebuglsEj @@ -270,5 +270,23 @@ template void f4<1>(int (*)[4]); // CHECK: define void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i template void f4(int (*)[b ? 1 : 2]) { }; template void f4(int (*)[1]); - } + +struct Ops { + Ops& operator+(const Ops&); + Ops& operator-(const Ops&); + Ops& operator&(const Ops&); + Ops& operator*(const Ops&); + + void *v; +}; + +// CHECK: define %struct.Ops* @_ZN3OpsplERKS_ +Ops& Ops::operator+(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsmiERKS_ +Ops& Ops::operator-(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsanERKS_ +Ops& Ops::operator&(const Ops&) { return *this; } +// CHECK: define %struct.Ops* @_ZN3OpsmlERKS_ +Ops& Ops::operator*(const Ops&) { return *this; } + diff --git a/clang/test/CodeGenCXX/member-functions.cpp b/clang/test/CodeGenCXX/member-functions.cpp index ebc9ed758bec..087e62c5bb37 100644 --- a/clang/test/CodeGenCXX/member-functions.cpp +++ b/clang/test/CodeGenCXX/member-functions.cpp @@ -58,6 +58,6 @@ struct T { void test3() { T t1, t2; - // RUN: grep "call i64 @_ZN1TpsERKS_" %t + // RUN: grep "call i64 @_ZN1TplERKS_" %t T result = t1 + t2; }