[cfe-commits] [PATCH] CodeGen support for transparent_union
Stefan Kristiansson
stefan.kristiansson at saunalahti.fi
Fri Aug 10 20:48:08 PDT 2012
On Sat, Aug 11, 2012 at 1:03 AM, Jan Voung <jvoung at google.com> wrote:
>
> What if the union variants were pointers or ints, etc.?
> Wouldn't the calling convention be different in that case?
>
> E.g.,
>
> glibc's __SOCKADDR_ARG is either a transparent union,
> or struct sockaddr *__restrict, depending on some pre-processor defines.
>
Those cases are still handled correctly, that is exactly the problem
this patch tries to solve.
It was actually the __SOCKADDR_ARG, but in uclibc, combined with an ABI
for the backend I'm working on that says that unions always are passed
by reference
that made me take a look at this.
Assuming long and pointers have the same machine representation:
$ cat transparent-union.c
struct s {
int a;
int b;
long c;
};
typedef union {
struct s *a;
int *b;
long c;
} ARG __attribute__ ((__transparent_union__));
void f0(ARG u);
void f1(struct s *a)
{
f0(a);
}
void f2(int *a)
{
f0(a);
}
void f3(long a)
{
f0(a);
}
$ clang -O2 -c -S transparent-union.c -emit-llvm -o -
; ModuleID = 'transparent-union.c'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.s = type { i32, i32, i64 }
define void @f1(%struct.s* %a) nounwind uwtable {
entry:
tail call void @f0(%struct.s* %a) nounwind
ret void
}
declare void @f0(%struct.s*)
define void @f2(i32* %a) nounwind uwtable {
entry:
%0 = bitcast i32* %a to %struct.s*
tail call void @f0(%struct.s* %0) nounwind
ret void
}
define void @f3(i64 %a) nounwind uwtable {
entry:
%0 = inttoptr i64 %a to %struct.s*
tail call void @f0(%struct.s* %0) nounwind
ret void
}
Stefan
More information about the cfe-commits
mailing list