I have ended up making a rather complicated type system to handle
quite a few things, all stemming from the fact that the integer type
has no sign information (even if it did not use it, would be nice to
look at it in my code generator to so I can put out one function type
or another when something like udiv/sdiv is called). I essentially
have a variant that holds either an llvm::Type* (which at this point
pretty much just holds the primitives, like the floating point types,
labels, etc...), or it holds a structure I made that just holds an
llvm::Type integer, but represents that integer as unsigned (where-as
if it is in the llvm::Type part of the variant it is treated as
signed), and a few other things. The other things include basically
any type that can hold any other type, from arrays to structs and so
forth. It was easy enough, I had made on the order of a crap-ton of
static_visitors to handle the variant in all its very fast, but still
overwhelming uglyness. I have got to the point where I need need to
represent the function type, this has suddenly introduced a whole new
class of uglyness to handle as the types can propagate into the blocks
and so forth.
I am just wondering if I am missing some very simple way to handle
this. Such as, is there any way in LLVM to 'typedef' (not alias) one
of the integer types (say, an i32) to be another 'type' in such a way
that my codegen can read it and handle the output instructions
different. I have even been thinking of just doing something as
simple as making it so even bitsized integers are considered signed
and odd are unsigned (then converting the odd ones to an even on a
word boundary, so a signed and unsigned i32 would be generated the
same when finished being compiled, but would be represented during
creation as the signed being i32 and the unsigned as an i33, or
vice-versa, whichever).
Does anyone have any ideas about handling this in a much cleaner way
that does not involve creating my own entire type system? How do
others handle this, or do other even expose multiple integer types or
just handle them all as signed or something?
My mind is starting to go numb from all the type system creation over
the past three days (which, although is very powerful, added quite a
few features over llvm that I do not really need, but still...), and I
cannot even get to my point of starting to split up functions into
parts until I get either my type system sorted through it (which will
probably take another week... at least), or I dump it all and use some
more 'llvm'ish way?