return getRecordArgABI(RT, CXXABI);
}
+/// Pass transparent unions as if they were the type of the first element. Sema
+/// should ensure that all elements of the union have the same "machine type".
+static QualType useFirstFieldIfTransparentUnion(QualType Ty) {
+ if (const RecordType *UT = Ty->getAsUnionType()) {
+ const RecordDecl *UD = UT->getDecl();
+ if (UD->hasAttr<TransparentUnionAttr>()) {
+ assert(!UD->field_empty() && "sema created an empty transparent union");
+ return UD->field_begin()->getType();
+ }
+ }
+ return Ty;
+}
+
CGCXXABI &ABIInfo::getCXXABI() const {
return CGT.getCXXABI();
}
CCState &State) const {
// FIXME: Set alignment on indirect arguments.
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
// Check with the C++ ABI first.
const RecordType *RT = Ty->getAs<RecordType>();
if (RT) {
bool isNamedArg)
const
{
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
X86_64ABIInfo::Class Lo, Hi;
classify(Ty, 0, Lo, Hi, isNamedArg);
ABIArgInfo
PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
if (Ty->isAnyComplexType())
return ABIArgInfo::getDirect();
unsigned &AllocatedGPR,
bool &IsSmallAggr,
bool IsNamedArg) const {
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
// Handle illegal vector types here.
if (isIllegalVectorType(Ty)) {
uint64_t Size = getContext().getTypeSize(Ty);
// to four Elements.
bool IsEffectivelyAAPCS_VFP = getABIKind() == AAPCS_VFP && !isVariadic;
+ Ty = useFirstFieldIfTransparentUnion(Ty);
+
// Handle illegal vector types here.
if (isIllegalVectorType(Ty)) {
uint64_t Size = getContext().getTypeSize(Ty);
-// RUN: %clang_cc1 -Werror -triple i386-unknown-unknown -emit-llvm -o %t %s
-// RUN: FileCheck < %t %s
-//
-// FIXME: Note that we don't currently get the ABI right here. f0() should be
-// f0(i8*).
+// RUN: %clang_cc1 -Werror -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple i386-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM
+// RUN: %clang_cc1 -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s
typedef union {
void *f0;
void f0(transp_t0 obj);
-// CHECK-LABEL: define void @f1_0(i32* %a0)
-// CHECK: call void @f0(%union.transp_t0* byval align 4 %{{.*}})
+// CHECK-LABEL: define void @f1_0(i32* %a0)
+// CHECK: call void @f0(i8* %{{.*}})
// CHECK: call void %{{.*}}(i8* %{{[a-z0-9]*}})
// CHECK: }
+
+// ARM-LABEL: define arm_aapcscc void @f1_0(i32* %a0)
+// ARM: call arm_aapcscc void @f0(i8* %{{.*}})
+// ARM: call arm_aapcscc void %{{.*}}(i8* %{{[a-z0-9]*}})
+// ARM: }
void f1_0(int *a0) {
void (*f0p)(void *) = f0;
f0(a0);