Confusion between GetElementPtr and C++ API

Looking at the documentation of `GetElementPtr`:

http://llvm.org/docs/GetElementPtr.html

The examples rely on multiple indexes: the 1st for the struct member
and the 2nd for the element in the array. This supposedly returns an
offset from the base pointer

I'm trying to figure out what's the correct way to create a given
`GetElementPtr` instruction with the C++ API. Unfortunately, there are
several varieties of the `CreateXXXGEP` instruction, with a parameter
"val" that I presume is one of the indices. No version of it seems to
use two indices as in the documentation:
http://llvm.org/docs/doxygen/html/classllvm_1_1IRBuilder.html

Even the `CreateStructGEP` uses a single idx parameter!

I want to do a very simple thing; I want to take a char buffer:

    Value* vB = llvm::ConstantDataArray::GetString(...)

and use the pointer to the array to pass it to another function that
expects `i8*`

Looking at the documentation of `GetElementPtr`:

The Often Misunderstood GEP Instruction — LLVM 18.0.0git documentation

The examples rely on multiple indexes: the 1st for the struct member
and the 2nd for the element in the array. This supposedly returns an
offset from the base pointer

Sort of the other way around. Imagine that GEP assumes that your
pointer is a pointer to the first element of an array. (eg: you have a
char* pointing to multiple characters) So the first index indexes into
that implicit array ((gep %x, 1) gives you a char* that points to the
second character rather than the first). The second index then indexes
into the structure your pointer points to, and so on.

I'm trying to figure out what's the correct way to create a given
`GetElementPtr` instruction with the C++ API. Unfortunately, there are
several varieties of the `CreateXXXGEP` instruction, with a parameter
"val" that I presume is one of the indices.

Val would be the pointer you want to index into.

No version of it seems to
use two indices as in the documentation:
LLVM: llvm::IRBuilder< FolderTy, InserterTy > Class Template Reference

Several variants take exactly two indices (CreateConstGEP.*2_*) which
would be fine for your needs (you just want a (gep %x, 0, 0 - which
should give you an i8*)).

Even the `CreateStructGEP` uses a single idx parameter!

It has an implicit 0 first index (if you follow the doxygen links you
can see that it just forwards to CreateConstInboundsGEP2_32 (
LLVM: include/llvm/IR/IRBuilder.h Source File )) -
as the name (perhaps poorly) implies, this is for indexing into a
single structure, so the first index is just 0 (you're not pointing to
the first element of an array, so there are no other elements to
access along that axis).

- David