Indexing backwards through a structure

Given a structure like this (using C syntax rather than LLVM because I'm
still not fluent with LLVM assembly):

struct Object
{
  int i1;
  int i2;
  int i3;
};

Then, if I have an int* pointer which I know is pointing to the i3
element, what's the best way of recovering a pointer to the structure as
a whole?

My fallback option is to cast the pointer to an int64, use getelementptr
to determine the offset of the i3 element, subtract, cast back to a
pointer, etc. However this feels very clunky to me and I'd like a
cleaner way of doing it.

Any suggestions?

(The actual use case: I have an object with embedded vtables; given a
pointer to one of the vtables, I need to get the pointer to the actual
object instance. Does LLVM has any built-in support for doing this sort
of thing?)

Hi David,

Given a structure like this (using C syntax rather than LLVM because I'm
still not fluent with LLVM assembly):

struct Object
{
int i1;
int i2;
int i3;
};

Then, if I have an int* pointer which I know is pointing to the i3
element, what's the best way of recovering a pointer to the structure as
a whole?

My fallback option is to cast the pointer to an int64, use getelementptr
to determine the offset of the i3 element, subtract, cast back to a
pointer, etc. However this feels very clunky to me and I'd like a
cleaner way of doing it.

Casting the pointer to "i8 *" and then using getelementptr with a
single index, to add a (negative) number of bytes to the pointer, is
probably a bit cleaner.

As for how you calculate the number to subtract, you can either try to
implement offsetof() as a complicated ConstantExpr using
getelementptr, or you can just know that the value is 8. Most front
ends know what the target data layout is, so they can just use a
constant.

As a general suggestion, try writing the code in C and seeing what
llvm-gcc or clang turns it into.

life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }

Ha!

Jay.

[...]

As a general suggestion, try writing the code in C and seeing what
llvm-gcc or clang turns it into.

I hadn't thought of that; a bit of experimentation with the demo website shows that clang is doing raw pointer arithmetic, but with getelementptr to avoid too many casts:

%struct.Object = type { i32, double, i32 }

define %struct.Object* @getobj(i32* %ptr) nounwind readnone {
entry:
   %0 = getelementptr inbounds i32* %ptr, i64 -4 ; <i32*>
   %1 = bitcast i32* %0 to %struct.Object* ; <%struct.Object*>
   ret %struct.Object* %1
}

The offset to getelementptr does, therefore, have structure layout information baked into it.

Using getelementptr for raw pointer arithmetic is a neat trick and avoids the evil of having to cast pointers to ints, so I think I'll just do that.

life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }

   "There are three things a man must do,
    Before his life is done.
    Write two lines of APL
    And make the buggers run."
       -- Anonymous