Hi!LLVM has a class, ConstantExpr, that is very handy for compile-time evaluation of const expressions. Unfortunately I cannot find any methods in it that would be helpful in evaluation of expressions similar to this: (uintptr_t)(&(*(TYPE*)0).FIELD), which is basically the implementation of the offsetof(TYPE, FIELD) macro.
Specifically, there seem to be no provisions for dereferencing a pointer.Does LLVM have any facilities (that I missed), that would help language front-ends in dealing with this sort of expressions?
Obviously, clang does it somehow, but so far I was not able to locate the relevant bit of code. Any pointers would be appreciated!
Vadim
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Fri, Jan 2, 2015 at 1:58 AM, Vadim Chugunov <vad...@gmail.com> wrote:Hi!LLVM has a class, ConstantExpr, that is very handy for compile-time evaluation of const expressions. Unfortunately I cannot find any methods in it that would be helpful in evaluation of expressions similar to this: (uintptr_t)(&(*(TYPE*)0).FIELD), which is basically the implementation of the offsetof(TYPE, FIELD) macro.I think the closest entity for this sort of thing is LLVM's ConstantExpr::getOffsetOf.
Specifically, there seem to be no provisions for dereferencing a pointer.Does LLVM have any facilities (that I missed), that would help language front-ends in dealing with this sort of expressions?
Obviously, clang does it somehow, but so far I was not able to locate the relevant bit of code. Any pointers would be appreciated!Clang handles record types in a very abstract way, it doesn't rely on LLVM IR at any level. An ASTRecordLayout is built for a record type and the ASTRecordLayout::getFieldIndex method is used to determine the offset for a particular field.
So it handles all const expression evaluation in the front-end?Yes, clang has it's own constant expression evaluator which understands the rules of C++.Let's take an example.The expression (long)&x/(long)&y divides two globals by each other. This expression is lowered to the following LLVM IR Constant:i64 sdiv (i64 ptrtoint (i32* @x to i64), i64 ptrtoint (i32* @y to i64))This Constant is a ConstantExpr but certainly not indicative of something that would be 'constexpr' in C++.
Do you start from offsetof() or the expanded form? For various reasons,
it is normally defined to use __builtin_offsetof, since the problems you
have run into also stop the "legacy" C version from being appropoiate
for C++ as it doesn't create an ICE.