in Sources/SolToBoogie/ProcedureTranslator.cs [2199:2292]
public override bool Visit(MemberAccess node)
{
preTranslationAction(node);
// length attribute of arrays
if (node.MemberName.Equals("length"))
{
currentExpr = TranslateArrayLength(node);
return false;
}
if (node.MemberName.Equals("balance"))
{
currentExpr = TranslateBalance(node);
return false;
}
// only structs will need to use x.f.g notation, since
// one can only access functions of nested contracts
// RESTRICTION: only handle e.f where e is Identifier | IndexExpr | FunctionCall
VeriSolAssert(node.Expression is Identifier || node.Expression is IndexAccess || node.Expression is FunctionCall,
$"Only handle non-nested structures, found {node.Expression.ToString()}");
if (node.Expression.TypeDescriptions.IsStruct())
{
var baseExpr = TranslateExpr(node.Expression);
var memberMap = node.MemberName + "_" + node.Expression.TypeDescriptions.TypeString.Split(" ")[1];
currentExpr = new BoogieMapSelect(
new BoogieIdentifierExpr(memberMap),
baseExpr);
return false;
}
if (node.Expression is Identifier)
{
Identifier identifier = node.Expression as Identifier;
if (identifier.Name.Equals("msg"))
{
if (node.MemberName.Equals("sender"))
{
currentExpr = new BoogieIdentifierExpr("msgsender_MSG");
}
else if (node.MemberName.Equals("value"))
{
currentExpr = new BoogieIdentifierExpr("msgvalue_MSG");
}
else
{
VeriSolAssert(false, $"Unknown member for msg: {node}");
}
return false;
}
else if (identifier.Name.Equals("this"))
{
if (node.MemberName.Equals("balance"))
{
currentExpr = new BoogieMapSelect(new BoogieIdentifierExpr("balance_ADDR"), new BoogieIdentifierExpr("this"));
}
return false;
}
else if (identifier.Name.Equals("block"))
{
if (node.MemberName.Equals("timestamp"))
currentExpr = new BoogieIdentifierExpr("now");
else
//we will havoc the value
currentExpr = GenerateNonDetExpr(node, node.ToString());
return false;
}
else if(identifier.Name.Equals("tx"))
{
currentExpr = GenerateNonDetExpr(node, node.ToString());
return false;
}
VeriSolAssert(context.HasASTNodeId(identifier.ReferencedDeclaration), $"Unknown node: {identifier}");
ASTNode refDecl = context.GetASTNodeById(identifier.ReferencedDeclaration);
if (refDecl is EnumDefinition)
{
int enumIndex = TransUtils.GetEnumValueIndex((EnumDefinition)refDecl, node.MemberName);
currentExpr = new BoogieLiteralExpr(enumIndex);
return false;
}
else
{
return true;
}
}
else
{
VeriSolAssert(false, $"Unknown expression type for member access: {node}");
throw new Exception();
}
}