public static bool ParseProgram(string path, out Program program) { program = null; int errCount; try { errCount = Parser.Parse(path, new List<string>(), out program); if (errCount != 0 || program == null) { Warning($"Parse errors detected in {path}"); return false; } } catch (IOException e) { Warning($"Error opening file \"{path}\": {e.Message}"); return false; } errCount = program.Resolve(); if (errCount > 0) { Warning($"Name resolution errors in {path}"); return false; } ModSetCollector c = new ModSetCollector(); c.DoModSetAnalysis(program); return true; }
public static void DoModSetAnalysis(Program program) { Contract.Requires(program != null); if (CommandLineOptions.Clo.Trace) { // Console.WriteLine(); // Console.WriteLine("Running modset analysis ..."); // int procCount = 0; // foreach (Declaration/*!*/ decl in program.TopLevelDeclarations) // { // Contract.Assert(decl != null); // if (decl is Procedure) // procCount++; // } // Console.WriteLine("Number of procedures = {0}", procCount);*/ } modSets = new Dictionary<Procedure/*!*/, HashSet<Variable/*!*/>/*!*/>(); yieldingProcs = new HashSet<Procedure>(); asyncAndParallelCallTargetProcs = new HashSet<Procedure>(); HashSet<Procedure/*!*/> implementedProcs = new HashSet<Procedure/*!*/>(); foreach (Declaration/*!*/ decl in program.TopLevelDeclarations) { Contract.Assert(decl != null); if (decl is Implementation) { Implementation impl = (Implementation)decl; if (impl.Proc != null) implementedProcs.Add(impl.Proc); } } foreach (Declaration/*!*/ decl in program.TopLevelDeclarations) { Contract.Assert(decl != null); if (decl is Procedure) { if (!implementedProcs.Contains(cce.NonNull((Procedure)decl))) { enclosingProc = (Procedure)decl; foreach (IdentifierExpr/*!*/ expr in enclosingProc.Modifies) { Contract.Assert(expr != null); ProcessVariable(expr.Decl); } enclosingProc = null; } else { modSets.Add(decl as Procedure, new HashSet<Variable>()); } } } moreProcessingRequired = true; while (moreProcessingRequired) { moreProcessingRequired = false; ModSetCollector modSetCollector = new ModSetCollector(); modSetCollector.Visit(program); } foreach (Procedure x in modSets.Keys) { x.Modifies = new List<IdentifierExpr>(); foreach (Variable v in modSets[x]) { x.Modifies.Add(new IdentifierExpr(v.tok, v)); } } foreach (Procedure x in yieldingProcs) { if (!QKeyValue.FindBoolAttribute(x.Attributes, "yields")) { x.AddAttribute("yields"); } } foreach (Procedure x in asyncAndParallelCallTargetProcs) { if (!QKeyValue.FindBoolAttribute(x.Attributes, "stable")) { x.AddAttribute("stable"); } } if (false /*CommandLineOptions.Clo.Trace*/) { Console.WriteLine("Number of procedures with nonempty modsets = {0}", modSets.Keys.Count); foreach (Procedure/*!*/ x in modSets.Keys) { Contract.Assert(x != null); Console.Write("{0} : ", x.Name); bool first = true; foreach (Variable/*!*/ y in modSets[x]) { Contract.Assert(y != null); if (first) first = false; else Console.Write(", "); Console.Write("{0}", y.Name); } Console.WriteLine(""); } } }