]> granicus.if.org Git - clang/commitdiff
Make sure that we mangle overloaded operators that are member functions correctly...
authorAnders Carlsson <andersca@mac.com>
Tue, 22 Dec 2009 06:36:32 +0000 (06:36 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 22 Dec 2009 06:36:32 +0000 (06:36 +0000)
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).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91893 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Mangle.cpp
test/CodeGenCXX/mangle.cpp
test/CodeGenCXX/member-functions.cpp

index 6c28d22f6b683412aef53fa716bbc0c86e200d61..089d77764e4df1b2fb6efda2f46366e78330cbd4 100644 (file)
@@ -480,10 +480,17 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
     mangleType(Context.getASTContext().getCanonicalType(Name.getCXXNameType()));
     break;
 
-  case DeclarationName::CXXOperatorName:
-    mangleOperatorName(Name.getCXXOverloadedOperator(),
-                       cast<FunctionDecl>(ND)->getNumParams());
+  case DeclarationName::CXXOperatorName: {
+    unsigned Arity = cast<FunctionDecl>(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<CXXMethodDecl>(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        # /
index 090a3f17eef137927b86083a275c43a1b38ca244..88465cf9d98b5c1c44bdbd6ebbaea859302b0cba 100644 (file)
@@ -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 <bool b> void f4(int (*)[b ? 1 : 2]) { };
 template void f4<true>(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; }
+
index ebc9ed758bec0bd387a5cb944f1d8efd1c3d25c7..087e62c5bb3701c84317b80a5d40ff3e685b00db 100644 (file)
@@ -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;
 }