diff options
-rw-r--r-- | lib/CodeGen/MicrosoftCXXABI.cpp | 47 | ||||
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-constructors.cpp | 12 | ||||
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-methods.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-static-initializers.cpp | 6 |
4 files changed, 49 insertions, 22 deletions
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 6a2925bbd9..b000c68a95 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -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 diff --git a/test/CodeGenCXX/microsoft-abi-constructors.cpp b/test/CodeGenCXX/microsoft-abi-constructors.cpp index ac27f13308..467f4174b7 100644 --- a/test/CodeGenCXX/microsoft-abi-constructors.cpp +++ b/test/CodeGenCXX/microsoft-abi-constructors.cpp @@ -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 } + diff --git a/test/CodeGenCXX/microsoft-abi-methods.cpp b/test/CodeGenCXX/microsoft-abi-methods.cpp index 6b7f00495d..6911bc2eec 100644 --- a/test/CodeGenCXX/microsoft-abi-methods.cpp +++ b/test/CodeGenCXX/microsoft-abi-methods.cpp @@ -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" } diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp index d8b789943a..1ef4ace63c 100644 --- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -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" |