Creating global data with [ 0 x ... ] type

Hi

I'm trying to create some global data representing something similar
to a vtable in C++ (that'll be pointed to by the head of objects).
I've called this a "metadata" table below. It includes some
miscellaneous class-level information, as well as a typical vtable
list-of-function-pointers.

I need to have the vtable "inlined" into the metadata, in that I don't
want an extra indirection by storing a pointer to the vtable in the
metadata table. This means that the metadata table ends in a variable
sized array.

i.e.:

%VtableEntryType = type { i32, i32 }
%MetadataTable = type { i32, [0 x %VtableEntryType] }

However, I can't figure out how to initialize it:

; most entries elided for simplicity
@MyMetadataTable = global %MetadataTable {
  i32 0,
  [1 x %VtableEntryType] [ ; <--- problem here!
    %VtableEntryType { i32 1234, i32 1234 }
  ]
}

bitcast won't let me cast from [1 x %VtableEntryType] to [0 x
%VtableEntryType] (I guess because the size differs). Is there another
way to accomplish this initialization?

I currently have a different metadata-type per language-type, but when
there's 50k types in the system, it gets overly heavy to declare all
those types when the only thing that ever happens to @MyMetadataTable
is a store into the header of an object during allocation.

thanks,
scott

Hi Scott,

As you've already discovered, your global variable must be defined using its actual storage type, which includes using a concrete array length. Bitcast the GlobalVariable from { ..., [n x ...] }* to { ..., [0 x ...] }* at the use sites instead (note: casting the pointer type, not the struct type). You do not need to name the types, of course.

Note that the LLVM linker will introduce these bitcasts for you automatically (as will, in effect, the system linker).

— Gordon