private void GenerateStructConstructors(ContractDefinition contract, StructDefinition structDefn) { // generate the internal one without base constructors string procName = structDefn.CanonicalName + "_ctor"; List <BoogieVariable> inParams = new List <BoogieVariable>(); inParams.AddRange(TransUtils.GetDefaultInParams()); foreach (var member in structDefn.Members) { Debug.Assert(!member.TypeDescriptions.IsStruct(), "Do no handle nested structs yet!"); var formalType = TransUtils.GetBoogieTypeFromSolidityTypeName(member.TypeName); var formalName = member.Name; inParams.Add(new BoogieFormalParam(new BoogieTypedIdent(formalName, formalType))); } List <BoogieVariable> outParams = new List <BoogieVariable>(); List <BoogieAttribute> attributes = new List <BoogieAttribute>(); if (context.TranslateFlags.GenerateInlineAttributes) { attributes.Add(new BoogieAttribute("inline", 1)); } ; BoogieProcedure procedure = new BoogieProcedure(procName, inParams, outParams, attributes); context.Program.AddDeclaration(procedure); List <BoogieVariable> localVars = new List <BoogieVariable>(); BoogieStmtList procBody = new BoogieStmtList(); foreach (var member in structDefn.Members) { //f[this] = f_arg Debug.Assert(!member.TypeDescriptions.IsStruct(), "Do no handle nested structs yet!"); var mapName = member.Name + "_" + structDefn.CanonicalName; var formalName = member.Name; var mapSelectExpr = new BoogieMapSelect(new BoogieIdentifierExpr(mapName), new BoogieIdentifierExpr("this")); procBody.AddStatement(new BoogieAssignCmd(mapSelectExpr, new BoogieIdentifierExpr(member.Name))); } BoogieImplementation implementation = new BoogieImplementation(procName, inParams, outParams, localVars, procBody); context.Program.AddDeclaration(implementation); }
public override bool Visit(ModifierDefinition modifier) { //if (modifier.Parameters.Length() > 0) //{ // throw new System.Exception("modifiers with parameters not implemented"); //} var modifierInParams = TransUtils.GetDefaultInParams(); foreach (var parameter in modifier.Parameters.Parameters) { string name = null; name = TransUtils.GetCanonicalLocalVariableName(parameter, context); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(parameter.TypeName); modifierInParams.Add(new BoogieFormalParam(new BoogieTypedIdent(name, type))); } Block body = modifier.Body; bool hasPre = false; bool hasPost = false; List <Statement> postlude = new List <Statement>(); // this list does not include locals introduced during translation List <BoogieLocalVariable> localVarsDeclared = new List <BoogieLocalVariable>(); bool translatingPre = true; foreach (Statement statement in body.Statements) { if (statement is VariableDeclarationStatement varDecls) { foreach (VariableDeclaration varDecl in varDecls.Declarations) { string name = TransUtils.GetCanonicalLocalVariableName(varDecl, context); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(varDecl.TypeName); // Issue a warning for intXX variables in case /useModularArithemtic option is used: if (context.TranslateFlags.UseModularArithmetic && varDecl.TypeDescriptions.IsInt()) { Console.WriteLine($"Warning: signed integer arithmetic is not handled with /useModularArithmetic option"); } var boogieVariable = new BoogieLocalVariable(new BoogieTypedIdent(name, type)); if (translatingPre) { localVarsDeclared.Add(boogieVariable); // don't add locals after placeholder } } // throw new System.Exception("locals within modifiers not supported"); } if (statement is PlaceholderStatement) { translatingPre = false; // only capture those locals declared in the prefix, these are visible to postlude context.AddPreludeLocalsToModifier(modifier.Name, localVarsDeclared); continue; } if (translatingPre) { hasPre = true; } else { hasPost = true; } } var attributes = new List <BoogieAttribute>(); attributes.Add(new BoogieAttribute("inline", 1)); if (hasPre) { List <BoogieVariable> inParams = new List <BoogieVariable>(modifierInParams); List <BoogieVariable> outParams = new List <BoogieVariable>(); outParams.AddRange(localVarsDeclared.Select(x => new BoogieFormalParam(new BoogieTypedIdent("__out_mod_" + x.Name, x.TypedIdent.Type)))); BoogieProcedure preludeProc = new BoogieProcedure(modifier.Name + "_pre", inParams, outParams, attributes); context.AddModiferToPreProc(modifier.Name, preludeProc); BoogieImplementation preludeImpl = new BoogieImplementation(modifier.Name + "_pre", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPreImpl(modifier.Name, preludeImpl); } if (hasPost) { List <BoogieVariable> inParams = new List <BoogieVariable>(modifierInParams); inParams.AddRange(localVarsDeclared); List <BoogieVariable> outParams = new List <BoogieVariable>(); BoogieProcedure postludeProc = new BoogieProcedure(modifier.Name + "_post", inParams, outParams, attributes); context.AddModiferToPostProc(modifier.Name, postludeProc); BoogieImplementation postludeImpl = new BoogieImplementation(modifier.Name + "_post", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPostImpl(modifier.Name, postludeImpl); } return(false); }
public override bool Visit(ModifierDefinition modifier) { //if (modifier.Parameters.Length() > 0) //{ // throw new System.Exception("modifiers with parameters not implemented"); //} var modifierInParams = TransUtils.GetDefaultInParams(); foreach (var parameter in modifier.Parameters.Parameters) { string name = null; name = TransUtils.GetCanonicalLocalVariableName(parameter); BoogieType type = TransUtils.GetBoogieTypeFromSolidityTypeName(parameter.TypeName); modifierInParams.Add(new BoogieFormalParam(new BoogieTypedIdent(name, type))); } Block body = modifier.Body; bool hasPre = false; bool hasPost = false; List <Statement> postlude = new List <Statement>(); bool translatingPre = true; foreach (Statement statement in body.Statements) { if (statement is VariableDeclarationStatement) { throw new System.Exception("locals within modifiers not supported"); } if (statement is PlaceholderStatement) { translatingPre = false; continue; } if (translatingPre) { hasPre = true; } else { hasPost = true; } } if (hasPre) { List <BoogieVariable> inParams = modifierInParams; List <BoogieVariable> outParams = new List <BoogieVariable>(); BoogieProcedure preludeProc = new BoogieProcedure(modifier.Name + "_pre", inParams, outParams); context.AddModiferToPreProc(modifier.Name, preludeProc); BoogieImplementation preludeImpl = new BoogieImplementation(modifier.Name + "_pre", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPreImpl(modifier.Name, preludeImpl); } if (hasPost) { List <BoogieVariable> inParams = modifierInParams; List <BoogieVariable> outParams = new List <BoogieVariable>(); BoogieProcedure postludeProc = new BoogieProcedure(modifier.Name + "_post", inParams, outParams); context.AddModiferToPostProc(modifier.Name, postludeProc); BoogieImplementation postludeImpl = new BoogieImplementation(modifier.Name + "_post", inParams, outParams, new List <BoogieVariable>(), new BoogieStmtList()); context.AddModiferToPostImpl(modifier.Name, postludeImpl); } return(false); }