]> granicus.if.org Git - clang/commitdiff
In the MS ABI, ctors return 'this'. Patch by Dmitry Sokolov.
authorJohn McCall <rjmccall@apple.com>
Tue, 25 Sep 2012 08:00:39 +0000 (08:00 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 25 Sep 2012 08:00:39 +0000 (08:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164592 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-constructors.cpp
test/CodeGenCXX/microsoft-abi-methods.cpp
test/CodeGenCXX/microsoft-abi-static-initializers.cpp

index 6a2925bbd953e7a5fb08857a3d3b2febf1298c0e..b000c68a952cd028f14f090be75e36e04e763826 100644 (file)
@@ -33,10 +33,7 @@ public:
   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
                                  CXXCtorType Type,
                                  CanQualType &ResTy,
-                                 SmallVectorImpl<CanQualType> &ArgTys) {
-    // 'this' is already in place
-    // TODO: 'for base' flag
-  }  
+                                 SmallVectorImpl<CanQualType> &ArgTys);
 
   void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
                                 CXXDtorType Type,
@@ -48,15 +45,9 @@ public:
 
   void BuildInstanceFunctionParams(CodeGenFunction &CGF,
                                    QualType &ResTy,
-                                   FunctionArgList &Params) {
-    BuildThisParam(CGF, Params);
-    // TODO: 'for base' flag
-  }
+                                   FunctionArgList &Params);
 
-  void EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
-    EmitThisParam(CGF);
-    // TODO: 'for base' flag
-  }
+  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
 
   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
                        llvm::GlobalVariable *DeclPtr,
@@ -99,10 +90,42 @@ public:
   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
                                    llvm::Value *allocPtr,
                                    CharUnits cookieSize);
+  static bool needThisReturn(GlobalDecl GD);
 };
 
 }
 
+bool MicrosoftCXXABI::needThisReturn(GlobalDecl GD) {
+  const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
+  return isa<CXXConstructorDecl>(MD);
+}
+
+void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
+                                 CXXCtorType Type,
+                                 CanQualType &ResTy,
+                                 SmallVectorImpl<CanQualType> &ArgTys) {
+  // 'this' is already in place
+  // TODO: 'for base' flag
+  // Ctor returns this ptr
+  ResTy = ArgTys[0];
+}
+
+void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
+                                                  QualType &ResTy,
+                                                  FunctionArgList &Params) {
+  BuildThisParam(CGF, Params);
+  if (needThisReturn(CGF.CurGD)) {
+    ResTy = Params[0]->getType();
+  }
+}
+
+void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
+  EmitThisParam(CGF);
+  if (needThisReturn(CGF.CurGD)) {
+    CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
+  }
+}
+
 bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
                                    QualType elementType) {
   // Microsoft seems to completely ignore the possibility of a
index ac27f13308d8041437bb530c58bf579fa43e58ad..467f4174b7b5e19de0627b33b0be3630a1588719 100644 (file)
@@ -9,13 +9,17 @@ class A {
 void no_contstructor_destructor_infinite_recursion() {
   A a;
 
-// Make sure that the constructor doesn't call itself:
-// CHECK: define {{.*}} @"\01??0A@@QAE@XZ"
-// CHECK-NOT: call void @"\01??0A@@QAE@XZ"
-// CHECK: ret
+// CHECK:      define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"(%class.A* %this)
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %this.addr = alloca %class.A*, align 4
+// CHECK-NEXT:   store %class.A* %this, %class.A** %this.addr, align 4
+// CHECK-NEXT:   %this1 = load %class.A** %this.addr
+// CHECK-NEXT:   ret %class.A* %this1
+// CHECK-NEXT: }
 
 // Make sure that the destructor doesn't call itself:
 // CHECK: define {{.*}} @"\01??1A@@QAE@XZ"
 // CHECK-NOT: call void @"\01??1A@@QAE@XZ"
 // CHECK: ret
 }
+
index 6b7f00495d2b9aec2f4663105d19afcfe5dc1801..6911bc2eecc9aef4a5f5109a3bad9d16ee2d09e2 100644 (file)
@@ -71,8 +71,8 @@ void constructors() {
   Child c;
 // Make sure that the Base constructor call in the Child constructor uses
 // the right calling convention:
-// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Child@@QAE@XZ"
-// CHECK: call x86_thiscallcc void @"\01??0Base@@QAE@XZ"
+// CHECK: define linkonce_odr x86_thiscallcc %class.Child* @"\01??0Child@@QAE@XZ"
+// CHECK: %call = call x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ"
 // CHECK: ret
 
 // Make sure that the Base destructor call in the Child denstructor uses
@@ -85,5 +85,5 @@ void constructors() {
 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Base@@QAE@XZ"
 
 // Make sure that the Base constructor definition uses the right CC:
-// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Base@@QAE@XZ"
+// CHECK: define linkonce_odr x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ"
 }
index d8b789943a430942efc6869ac58f195dada10d47..1ef4ace63c8d9230a721f5f2849352f0ed047e92 100644 (file)
@@ -6,7 +6,7 @@ struct S {
 } s;
 
 // CHECK: define internal void [[INIT_s:@.*global_var.*]] nounwind
-// CHECK: call x86_thiscallcc void @"\01??0S@@QAE@XZ"
+// CHECK: %call = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
 // CHECK: call i32 @atexit(void ()* @"__dtor_\01?s@@3US@@A")
 // CHECK: ret void
 
@@ -34,11 +34,11 @@ void force_usage() {
 }
 
 // CHECK: define internal void [[INIT_foo:@.*global_var.*]] nounwind
-// CHECK: call x86_thiscallcc void @"\01??0A@@QAE@XZ"
+// CHECK: %call = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
 // CHECK: call i32 @atexit(void ()* [[FOO_DTOR:@"__dtor_.*foo@.*]])
 // CHECK: ret void
 
-// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0A@@QAE@XZ"
+// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
 
 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"