I'm getting this in debugger, where 't' is 'Type*':
(gdb) p t->isPrimitiveType()
$15 = false
(gdb) p t->getPrimitiveID()
$16 = PointerTyID
(gdb) p t->getPrimitiveSize()
$17 = 0
There are a couple of things that I'd like to ask. First, if
isPrimitiveType() returns false, that the fact that getPrimitiveID
returns reasonable value is quite strange. Maybe, the method is better
called just getID, since it can get id for both primitive and derived
You're right, getPrimitiveID seems misnamed. It should be named
getTypeID() or something.
Second, why getPrimitiveSize() returns 0? In seems that LLVM knows the size a
pointer occupies (at least it puts in in LLVM assembly), so why not return
it? For me, that would be quite convenient -- I would only check that type
passed to a function has size of either 4 or 8 bytes and that would catch
both primitives and pointers.
It returns zero because it's not a primitive type :), and because it
doesn't know the size at that point. All primitive types have fixed sizes
independent of the target machine (a 32-bit int is always 4 bytes), so
this method makes sense for primitives. For derived types, a variety of
target-specific properties can effect the size of objects (field
alignment, structure layout rules, etc).
Because of this, all of this information is encapsulated in the TargetData
structure. It can tell you the size of an arbitrary type, field offsets,
etc. If you're working in the context of an LLVM pass, you just
addRequired<TargetData> and getAnalysis<TargetData> when needed (there are
lots of examples in the source base).
It would be somewhat convenient to put these into the type objects
themselves, but type objects are shared between LLVM modules, and it's
possible to have multiple LLVM modules loaded for multiple different
targets at the same time. They would all refer to the same types, but
they could have different sizes in the context of the different targets
they are being compiled for.