public void Validate() { if (this.calledFrom == Common.CalledFrom.ExternalOnly || this.calledFrom == Common.CalledFrom.Both) { if (string.IsNullOrWhiteSpace(globalID)) { throw new ValidatorException("The function, which can be called from outside the routine, must have a non-empty GlobalID property. Function: " + this.ID); } } if (BasicBlocks.FindAll(x => x.getSuccessors.Count == 0 && x.getPredecessors.Count > 0 && x.Instructions.Count == 1 && x.Instructions[0].TACtext == "return").Count == 0) { throw new ValidatorException("Function " + ID + " has no 'fake exit block'."); } if (BasicBlocks.FindAll(x => x.getSuccessors.Count == 0 && x.getPredecessors.Count > 0 && x.Instructions.Count == 1 && x.Instructions[0].TACtext == "return").Count > 1) { throw new ValidatorException("Function " + ID + " has more than one 'fake exit block'."); } foreach (BasicBlock bb in this.BasicBlocks) { if (bb.parent != this) { throw new ValidatorException("Basic block's 'parent' property is incorrect. Basic block: " + bb.ID); } bb.Validate(); } /* Instructions are unique, so they can be referenced only once within a function */ List <Instruction> all_instructions = new List <Instruction>(); BasicBlocks.ForEach(x => all_instructions.AddRange(x.Instructions)); if (all_instructions.Count != all_instructions.Distinct().Count()) { throw new ValidatorException("Multiple references to the same instruction."); } }