[cfe-commits] r151122 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGenCXX/thiscall-struct-return.cpp
Aaron Ballman
aaron at aaronballman.com
Tue Feb 21 19:04:13 PST 2012
Author: aaronballman
Date: Tue Feb 21 21:04:13 2012
New Revision: 151122
URL: http://llvm.org/viewvc/llvm-project?rev=151122&view=rev
Log:
Adding support for Microsoft's thiscall calling convention. Clang side of the patch.
Added:
cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp (with props)
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=151122&r1=151121&r2=151122&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Feb 21 21:04:13 2012
@@ -424,7 +424,8 @@
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
}
- static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
+ static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context,
+ unsigned callingConvention);
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
/// such that the argument will be passed in memory.
@@ -435,11 +436,13 @@
public:
- ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyReturnType(QualType RetTy,
+ unsigned callingConvention) const;
ABIArgInfo classifyArgumentType(QualType RetTy) const;
virtual void computeInfo(CGFunctionInfo &FI) const {
- FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
+ FI.getCallingConvention());
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
it->info = classifyArgumentType(it->type);
@@ -485,7 +488,8 @@
/// shouldReturnTypeInRegister - Determine if the given type should be
/// passed in a register (for the Darwin ABI).
bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
- ASTContext &Context) {
+ ASTContext &Context,
+ unsigned callingConvention) {
uint64_t Size = Context.getTypeSize(Ty);
// Type must be register sized.
@@ -510,7 +514,8 @@
// Arrays are treated like records.
if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
- return shouldReturnTypeInRegister(AT->getElementType(), Context);
+ return shouldReturnTypeInRegister(AT->getElementType(), Context,
+ callingConvention);
// Otherwise, it must be a record type.
const RecordType *RT = Ty->getAs<RecordType>();
@@ -518,6 +523,13 @@
// FIXME: Traverse bases here too.
+ // For thiscall conventions, structures will never be returned in
+ // a register. This is for compatibility with the MSVC ABI
+ if (callingConvention == llvm::CallingConv::X86_ThisCall &&
+ RT->isStructureType()) {
+ return false;
+ }
+
// Structure types are passed in register if all fields would be
// passed in a register.
for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
@@ -529,14 +541,15 @@
continue;
// Check fields recursively.
- if (!shouldReturnTypeInRegister(FD->getType(), Context))
+ if (!shouldReturnTypeInRegister(FD->getType(), Context,
+ callingConvention))
return false;
}
-
return true;
}
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const {
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
+ unsigned callingConvention) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -583,7 +596,8 @@
// Small structures which are register sized are generally returned
// in a register.
- if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
+ if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
+ callingConvention)) {
uint64_t Size = getContext().getTypeSize(RetTy);
// As a special-case, if the struct is a "single-element" struct, and
Added: cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp?rev=151122&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp Tue Feb 21 21:04:13 2012
@@ -0,0 +1,41 @@
+// For MSVC ABI compatibility, all structures returned by value using the
+// thiscall calling convention must use the hidden parameter.
+//
+// RUN: %clang_cc1 -triple i386-PC-Win32 %s -fms-compatibility -O0 -emit-llvm -o - | FileCheck %s
+
+// This structure would normally be returned via EAX
+struct S {
+ int i;
+};
+
+// This structure would normally be returned via EAX/EDX
+struct M {
+ int i;
+ int j;
+};
+
+class C {
+public:
+ C() {}
+
+ struct S __attribute__((thiscall)) Small() const {
+ struct S s = { 0 };
+ return s;
+ }
+
+ struct M __attribute__((thiscall)) Medium() const {
+ struct M m = { 0 };
+ return m;
+ }
+};
+
+// CHECK: define void @_Z4testv()
+void test( void ) {
+// CHECK: call void @_ZN1CC1Ev(%class.C* %c)
+ C c;
+
+// CHECK: call x86_thiscallcc void @_ZNK1C5SmallEv(%struct.S* sret %tmp, %class.C* %c)
+ (void)c.Small();
+// CHECK: call x86_thiscallcc void @_ZNK1C6MediumEv(%struct.M* sret %tmp1, %class.C* %c)
+ (void)c.Medium();
+}
Propchange: cfe/trunk/test/CodeGenCXX/thiscall-struct-return.cpp
------------------------------------------------------------------------------
svn:eol-style = native
More information about the cfe-commits
mailing list