public ABT.Expr GetPointerAddition(ABT.Expr ptr, ABT.Expr offset, Boolean order = true) {
if (ptr.Type.Kind != ABT.ExprTypeKind.POINTER) {
throw new InvalidOperationException();
}
if (offset.Type.Kind != ABT.ExprTypeKind.LONG) {
throw new InvalidOperationException();
}
var env = order ? ptr.Env : offset.Env;
if (ptr.IsConstExpr && offset.IsConstExpr) {
var baseValue = (Int32)((ABT.ConstPtr)ptr).Value;
Int32 scaleValue = ((ABT.PointerType)(ptr.Type)).RefType.SizeOf;
Int32 offsetValue = ((ABT.ConstLong)offset).Value;
return new ABT.ConstPtr((UInt32)(baseValue + scaleValue * offsetValue), ptr.Type, env);
}
var baseAddress = ABT.TypeCast.FromPointer(ptr, new ABT.LongType(ptr.Type.IsConst, ptr.Type.IsVolatile), ptr.Env);
var scaleFactor = new ABT.Multiply(
offset,
new ABT.ConstLong(((ABT.PointerType)(ptr.Type)).RefType.SizeOf, env)
);
var type = new ABT.LongType(offset.Type.IsConst, offset.Type.IsVolatile);
var add =
order
? new ABT.Add(baseAddress, scaleFactor)
: new ABT.Add(scaleFactor, baseAddress);
return ABT.TypeCast.ToPointer(add, ptr.Type, env);
}