<div>Does this help :-</div>
<div> </div>
<div>struct TaggedUnionType {<br>  enum { Byte, Char, Int } Type;<br>  union {<br>    uint_8 b;<br>    char c;<br>    uint32_t i;<br>  };<br>};</div>
<div>int main( int argc, char *argv[])<br>{<br>    TaggedUnionType t;<br>    t.Type = Int;<br>    t.i = 0xAA55;</div>
<div>    switch( t.Type)<br>    {<br>    case Byte:<br>      {<br>        printf( "Byte = %0x2\n", t.b);<br>        break;<br>      }<br>    case Char:<br>      {<br>        printf( "Char = %c\n", t.c);<br>

        break;<br>      }<br>    case Int:<br>      {<br>        printf( "Int = %0x8\n", t.i);<br>        break;<br>      }<br>    return 0;<br>}</div>
<div> </div>
<div>Output from LLVM disassembler<br></div>
<div>; ModuleID = '/tmp/webcompile/_613_0.bc'<br>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"<br>target triple = "i386-pc-linux-gnu"<br>

 %struct.TaggedUnionType = type { i32, %"struct.TaggedUnionType::._11" }<br> %"struct.TaggedUnionType::._11" = type { i32 }<br>@.str = internal constant [13 x i8] c"Byte = %0x2\0A\00"  ; <[13 x i8]*> [#uses=1]<br>

@.str1 = internal constant [11 x i8] c"Char = %c\0A\00"  ; <[11 x i8]*> [#uses=1]<br>@.str2 = internal constant [12 x i8] c"Int = %0x8\0A\00"  ; <[12 x i8]*> [#uses=1]</div>
<div>define i32 @main(i32 %argc, i8** %argv) {<br>entry:<br> %argc_addr = alloca i32  ; <i32*> [#uses=1]<br> %argv_addr = alloca i8**  ; <i8***> [#uses=1]<br> %retval = alloca i32  ; <i32*> [#uses=2]<br>

 %t = alloca %struct.TaggedUnionType  ; <%struct.TaggedUnionType*> [#uses=6]<br> %0 = alloca i32  ; <i32*> [#uses=2]<br> %"alloca point" = bitcast i32 0 to i32  ; <i32> [#uses=0]<br> store i32 %argc, i32* %argc_addr<br>

 store i8** %argv, i8*** %argv_addr<br> %1 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0  ; <i32*> [#uses=1]<br> store i32 2, i32* %1, align 4<br> %2 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br>

 %3 = getelementptr %"struct.TaggedUnionType::._11"* %2, i32 0, i32 0  ; <i32*> [#uses=1]<br> store i32 43605, i32* %3, align 4<br> %4 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 0  ; <i32*> [#uses=1]<br>

 %5 = load i32* %4, align 4  ; <i32> [#uses=1]<br> switch i32 %5, label %bb3 [<br>  i32 0, label %bb<br>  i32 1, label %bb1<br>  i32 2, label %bb2<br> ]</div>
<div>bb:  ; preds = %entry<br> %6 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %7 = getelementptr %"struct.TaggedUnionType::._11"* %6, i32 0, i32 0  ; <i32*> [#uses=1]<br>

 %8 = bitcast i32* %7 to i8*  ; <i8*> [#uses=1]<br> %9 = load i8* %8, align 4  ; <i8> [#uses=1]<br> %10 = zext i8 %9 to i32  ; <i32> [#uses=1]<br> %11 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([13 x i8]* @.str, i32 0, i32 0), i32 %10)  ; <i32> [#uses=0]<br>

 br label %bb3</div>
<div>bb1:  ; preds = %entry<br> %12 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %13 = getelementptr %"struct.TaggedUnionType::._11"* %12, i32 0, i32 0  ; <i32*> [#uses=1]<br>

 %14 = bitcast i32* %13 to i8*  ; <i8*> [#uses=1]<br> %15 = load i8* %14, align 4  ; <i8> [#uses=1]<br> %16 = sext i8 %15 to i32  ; <i32> [#uses=1]<br> %17 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([11 x i8]* @.str1, i32 0, i32 0), i32 %16)  ; <i32> [#uses=0]<br>

 br label %bb3</div>
<div>bb2:  ; preds = %entry<br> %18 = getelementptr %struct.TaggedUnionType* %t, i32 0, i32 1  ; <%"struct.TaggedUnionType::._11"*> [#uses=1]<br> %19 = getelementptr %"struct.TaggedUnionType::._11"* %18, i32 0, i32 0  ; <i32*> [#uses=1]<br>

 %20 = load i32* %19, align 4  ; <i32> [#uses=1]<br> %21 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([12 x i8]* @.str2, i32 0, i32 0), i32 %20)  ; <i32> [#uses=0]<br> br label %bb3</div>
<div>bb3:  ; preds = %bb2, %bb1, %bb, %entry<br> store i32 0, i32* %0, align 4<br> %22 = load i32* %0, align 4  ; <i32> [#uses=1]<br> store i32 %22, i32* %retval, align 4<br> br label %return</div>
<div>return:  ; preds = %bb3<br> %retval4 = load i32* %retval  ; <i32> [#uses=1]<br> ret i32 %retval4<br>}</div>
<div>declare i32 @printf(i8* noalias, ...)</div>
<div><br>Use :-</div>
<div> </div>
<div>    <a href="http://llvm.org/demo/index.cgi">http://llvm.org/demo/index.cgi</a></div>
<div> </div>
<div>To convert the code. Making sure optimization is turned off, its good optimization !</div>
<div> </div>
<div>The other approach is a C++ style inheritance and have a base class with a tag in and sub types as inheriting classes.</div>
<div> </div>
<div>Hope this helps,</div>
<div> </div>
<div>Aaron</div>
<div> </div>
<div> </div>
<div> </div>
<div> </div>
<div><br><br> </div>
<div class="gmail_quote">2009/6/13 Wesley W. Terpstra <span dir="ltr"><<a href="mailto:wesley@terpstra.ca">wesley@terpstra.ca</a>></span><br>
<blockquote style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex" class="gmail_quote">Good afternoon!<br><br>I'm trying to write an LLVM codegen for a Standard ML compiler<br>(MLton). So far things seem to match up quite nicely, but I have hit<br>

two sticking points. I'm hoping LLVM experts might know how to handle<br>these two cases better.<br><br>1: In ML we have some types that are actually one of several possible<br>types. Expressed in C this might be thought of as a union. The codegen<br>

only ever accesses these 'union types' via pointer. Before actually<br>indexing into the type, it always casts from the 'union pointer type'<br>to a specific pointer type.<br><br>As a concrete example. I have two types %a and %b. I want to express a<br>

third type %c that is either %a* or %b*. Later I'll cast the %c to<br>either %a* or %b*.<br><br>Currently I just represent %c as i8*. I assume that this can have<br>consequences in terms of aliasing. I tried opaque*, but llvm-as didn't<br>

like that. Is there any way to better represent the type %c to LLVM?<br><br>2: In the ML heap we have objects that are garbage collected. Objects<br>are preceded by a header that describes the object to the garbage<br>collector. However, pointers to the objects point past the header and<br>

at the actual object. Sometimes, however, the program itself accesses<br>the header. For example, to determine the length of an array (the<br>length is in the header). For every type I output it like this:<br><br>%opt_33 = { i32, %opt_45*, float }<br>

<br>I could also create another type which includes the header something like:<br>%opt_33_with_header = {i32, %opt_33 }<br><br>Is there any way to express that a pointer is actually a pointer to an<br>interior element of a type? Something like %opt_33_in_heap =<br>

%opt_33_with_header:1 ?<br><br>Currently when I want to read the header of an %opt_33, I cast it to a<br>i32* and then use getelementptr -1. Is there a better way?<br>_______________________________________________<br>LLVM Developers mailing list<br>

<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu/" target="_blank">http://llvm.cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>

</blockquote></div><br>