Does this help :-
struct TaggedUnionType {
enum { Byte, Char, Int } Type;
union {
uint_8 b;
char c;
uint32_t i;
};
};
int main( int argc, char *argv)
{
TaggedUnionType t;
t.Type = Int;
t.i = 0xAA55;
switch( t.Type)
{
case Byte:
{
printf( “Byte = %0x2\n”, t.b);
break;
}
case Char:
{
printf( “Char = %c\n”, t.c);
break;
}
case Int:
{
printf( “Int = %0x8\n”, t.i);
break;
}
return 0;
}
Output from LLVM disassembler
; ModuleID = ‘/tmp/webcompile/_613_0.bc’
target datalayout = “e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32”
target triple = “i386-pc-linux-gnu”
%struct.TaggedUnionType = type { i32, %“struct.TaggedUnionType::._11” }
%“struct.TaggedUnionType::._11” = type { i32 }
@.str = internal constant [13 x i8] c"Byte = %0x2\0A\00" ; <[13 x i8]> [#uses=1]
@.str1 = internal constant [11 x i8] c"Char = %c\0A\00" ; <[11 x i8]> [#uses=1]
@.str2 = internal constant [12 x i8] c"Int = %0x8\0A\00" ; <[12 x i8]> [#uses=1]
define i32 @main(i32 %argc, i8** %argv) {
entry:
%argc_addr = alloca i32 ; <i32> [#uses=1]
%argv_addr = alloca i8** ; <i8***> [#uses=1]
%retval = alloca i32 ; <i32*> [#uses=2]
%t = alloca %struct.TaggedUnionType ; <%struct.TaggedUnionType*> [#uses=6]
%0 = alloca i32 ; <i32*> [#uses=2]
%“alloca point” = bitcast i32 0 to i32 ; [#uses=0]
store i32 %argc, i32* %argc_addr
store i8** %argv, i8*** %argv_addr
%1 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0 ; <i32*> [#uses=1]
store i32 2, i32* %1, align 4
%2 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%“struct.TaggedUnionType::._11”> [#uses=1]
%3 = getelementptr %“struct.TaggedUnionType::._11” %2, i32 0, i32 0 ; <i32*> [#uses=1]
store i32 43605, i32* %3, align 4
%4 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0 ; <i32*> [#uses=1]
%5 = load i32* %4, align 4 ; [#uses=1]
switch i32 %5, label %bb3 [
i32 0, label %bb
i32 1, label %bb1
i32 2, label %bb2
]
bb: ; preds = %entry
%6 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%“struct.TaggedUnionType::._11”> [#uses=1]
%7 = getelementptr %“struct.TaggedUnionType::._11” %6, i32 0, i32 0 ; <i32*> [#uses=1]
%8 = bitcast i32* %7 to i8* ; <i8*> [#uses=1]
%9 = load i8* %8, align 4 ; [#uses=1]
%10 = zext i8 %9 to i32 ; [#uses=1]
%11 = call i32 (i8*, …)* @printf(i8* noalias getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 %10) ; [#uses=0]
br label %bb3
bb1: ; preds = %entry
%12 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%“struct.TaggedUnionType::._11”> [#uses=1]
%13 = getelementptr %“struct.TaggedUnionType::._11” %12, i32 0, i32 0 ; <i32*> [#uses=1]
%14 = bitcast i32* %13 to i8* ; <i8*> [#uses=1]
%15 = load i8* %14, align 4 ; [#uses=1]
%16 = sext i8 %15 to i32 ; [#uses=1]
%17 = call i32 (i8*, …)* @printf(i8* noalias getelementptr ([11 x i8]* @.str1, i32 0, i32 0), i32 %16) ; [#uses=0]
br label %bb3
bb2: ; preds = %entry
%18 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1 ; <%“struct.TaggedUnionType::._11”> [#uses=1]
%19 = getelementptr %“struct.TaggedUnionType::._11” %18, i32 0, i32 0 ; <i32*> [#uses=1]
%20 = load i32* %19, align 4 ; [#uses=1]
%21 = call i32 (i8*, …)* @printf(i8* noalias getelementptr ([12 x i8]* @.str2, i32 0, i32 0), i32 %20) ; [#uses=0]
br label %bb3
bb3: ; preds = %bb2, %bb1, %bb, %entry
store i32 0, i32* %0, align 4
%22 = load i32* %0, align 4 ; [#uses=1]
store i32 %22, i32* %retval, align 4
br label %return
return: ; preds = %bb3
%retval4 = load i32* %retval ; [#uses=1]
ret i32 %retval4
}
declare i32 @printf(i8* noalias, …)
Use :-
http://llvm.org/demo/index.cgi
To convert the code. Making sure optimization is turned off, its good optimization !
The other approach is a C++ style inheritance and have a base class with a tag in and sub types as inheriting classes.
Hope this helps,
Aaron
2009/6/13 Wesley W. Terpstra <wesley@terpstra.ca>