[LLVMdev] Offset to C++ structure members
Paul J. Lucas
paul at lucasmail.org
Tue Oct 2 11:33:05 PDT 2012
On Oct 1, 2012, at 9:58 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> Using GEP on an i8* is a bit nicer to the optimizer, though, because
> using ptrtoint/inttoptr has effects on alias analysis.
My understanding is that, in order to use GEP, you have to provide the LLVM code with the struct layout, i.e., build a StructType object. In my case, that struct is declared in C++ code already and, in order to use GEP, I'd have to replicate the struct layout (exactly as the C++ compiler would) in LLVM code -- something that I'd rather not do, not to mention that it's fairly "brittle" even if I could manage to get it right. (Simple structs would probably be easy, but struct that have virtual functions or multiple base classes would be much harder.)
> I'm not entirely sure how you're using mbr_offset_of
Given 't', an instance of some class T, and some member T::m, find the integer offset in bytes from &t to &t.m. This offset, when added to &t, should be &t.m.
I'm using mbr_offset_of to get the C++ compiler to do the work of telling me what the correct offset is for the already existing struct.
> but it's broken if there are any classes with virtual bases involved.
Really? This simple code works just fine:
struct A { int ai; };
struct X : virtual A { int xi; };
struct Y : virtual A { int yi; };
struct S : X, Y {
string a;
string b;
};
template<class ClassType,class MbrType> inline
ptrdiff_t mbr_offset_of( MbrType ClassType::*p ) {
ClassType const *const c = static_cast<ClassType*>( nullptr );
return reinterpret_cast<ptrdiff_t>( &(c->*p) );
}
int main() {
ptrdiff_t offset = mbr_offset_of( &S::b );
S s;
string *p = (string*)((char*)&s + offset);
p->assign( "Hello, world!" );
cout << *p << endl;
return 0;
}
Despite that, however, the equivalent code in LLVM (once I introduce a base class for S, even just ordinary inheritance), crashes. I don't understand why, however. I print out the offset, and it's the correct value that's getting added to the Pointer.
- Paul
More information about the llvm-dev
mailing list