static constant structs

I hope this is the correct forum in which to ask this question.

Currently I am writing code meant to compile with LLVM 3.0. I am trying
to figure out, using the C++ API, how to create a constant static
struct, or the equivalent. Since I am copying data from existing C
structs, I am currently I am using a ConstantArray global variable, and
then pointer casting it to the appropriate type when I use it, but this
seems overly clunky.

    Constant *cip = ConstantArray::get(
        ctx(), StringRef((char *)&addr_, sizeof(addr_)), false);
    return new GlobalVariable(
        *mod(), cip->getType(), true,
        GlobalVariable::PrivateLinkage, cip);

In a previous version of my code, I replaced cip->getType() with the
llvm equivalent of the type of addr_. This worked until I tried with a
build of llvm that had assertions turned on. Even without that, I am
hoping there is a better way to do this that I have managed to overlook.

Hi Michael,

I hope this is the correct forum in which to ask this question.

Currently I am writing code meant to compile with LLVM 3.0. I am trying
to figure out, using the C++ API, how to create a constant static
struct, or the equivalent. Since I am copying data from existing C
structs, I am currently I am using a ConstantArray global variable, and
then pointer casting it to the appropriate type when I use it, but this
seems overly clunky.

     Constant *cip = ConstantArray::get(
         ctx(), StringRef((char *)&addr_, sizeof(addr_)), false);
     return new GlobalVariable(
         *mod(), cip->getType(), true,
         GlobalVariable::PrivateLinkage, cip);

In a previous version of my code, I replaced cip->getType() with the
llvm equivalent of the type of addr_. This worked until I tried with a
build of llvm that had assertions turned on. Even without that, I am
hoping there is a better way to do this that I have managed to overlook.

I'm not sure I understood your question, but it sounds like you may want to call
this ConstantArray method (with AddNull = false).

   /// This method constructs a ConstantArray and initializes it with a text
   /// string. The default behavior (AddNull==true) causes a null terminator to
   /// be placed at the end of the array. This effectively increases the length
   /// of the array by one (you've been warned). However, in some situations
   /// this is not desired so if AddNull==false then the string is copied without
   /// null termination.
   static Constant *get(LLVMContext &Context, StringRef Initializer,
                        bool AddNull = true);

Ciao, Duncan.

Duncan Sands <baldrick@free.fr> writes:

I hope this is the correct forum in which to ask this question.

Currently I am writing code meant to compile with LLVM 3.0. I am trying
to figure out, using the C++ API, how to create a constant static
struct, or the equivalent. Since I am copying data from existing C
structs, I am currently I am using a ConstantArray global variable, and
then pointer casting it to the appropriate type when I use it, but this
seems overly clunky.

     Constant *cip = ConstantArray::get(
         ctx(), StringRef((char *)&addr_, sizeof(addr_)), false);
     return new GlobalVariable(
         *mod(), cip->getType(), true,
         GlobalVariable::PrivateLinkage, cip);

In a previous version of my code, I replaced cip->getType() with the
llvm equivalent of the type of addr_. This worked until I tried with a
build of llvm that had assertions turned on. Even without that, I am
hoping there is a better way to do this that I have managed to overlook.

I'm not sure I understood your question, but it sounds like you may
want to call this ConstantArray method (with AddNull = false).

Um... That's exactly what the example above demonstrates. But maybe I
did not explain my problem well enough. If I have a type like, for
example:

{ i32, [ 4 x i8 ] }

How can I create a constant of this type like this:

{ i32 0x1ffff, [ i8 0, i8 4, i8 10, i8 8 ] }

from the C++ API without going through nasty pointer cast tricks?

Hi,

Um... That's exactly what the example above demonstrates. But maybe I
did not explain my problem well enough. If I have a type like, for
example:

{ i32, [ 4 x i8 ] }

How can I create a constant of this type like this:

{ i32 0x1ffff, [ i8 0, i8 4, i8 10, i8 8 ] }

from the C++ API without going through nasty pointer cast tricks?

for each number, you create a corresponding ConstantInt using ConstantInt::get
   static Constant *get(Type *Ty, uint64_t V, bool isSigned = false);
(there are a bunch of other methods too). Once you have them, you create the
array using ConstantArray::get
   static Constant *get(ArrayType *T, ArrayRef<Constant*> V);
Then you create the struct using ConstantStruct::get
   static Constant *get(StructType *T, ArrayRef<Constant*> V);

Ciao, Duncan.