public MethodCfgAndTac AnalyzeIntraProcedural(IMethodDefinition methodDefinition) { // System.Console.WriteLine("Traversing: {0}", methodDefinition.GetName()); if (Stubber.SuppressM(methodDefinition)) { return(null); } if (methodDefinition.IsExternal) { return(null); } if (methodDefinition.IsAbstract) { return(null); } ITypeDefinition containingDefn = methodDefinition.ContainingTypeDefinition; ISourceLocationProvider sourceLocationProvider = null; if (containingDefn != null) { IModule mod = TypeHelper.GetDefiningUnit(containingDefn) as IModule; if (moduleToPdbMap.ContainsKey(mod)) { sourceLocationProvider = moduleToPdbMap[mod]; } else { if (!(mod == null || mod == Dummy.Module || mod == Dummy.Assembly)) { sourceLocationProvider = GetPdbReader(mod.Location); moduleToPdbMap[mod] = sourceLocationProvider; } } } var disassembler = new Disassembler(host, methodDefinition, sourceLocationProvider); var methodBody = disassembler.Execute(); var cfAnalysis = new ControlFlowAnalysis(methodBody); // var cfg = cfAnalysis.GenerateNormalControlFlow(); var cfg = cfAnalysis.GenerateExceptionalControlFlow(); var domAnalysis = new DominanceAnalysis(cfg); domAnalysis.Analyze(); domAnalysis.GenerateDominanceTree(); var loopAnalysis = new NaturalLoopAnalysis(cfg); loopAnalysis.Analyze(); var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg); domFrontierAnalysis.Analyze(); var splitter = new WebAnalysis(cfg, methodDefinition); splitter.Analyze(); splitter.Transform(); methodBody.UpdateVariables(); var typeAnalysis = new TypeInferenceAnalysis(cfg, methodDefinition.Type); typeAnalysis.Analyze(); var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(cfg); forwardCopyAnalysis.Analyze(); forwardCopyAnalysis.Transform(methodBody); // backwardCopyAnalysis is buggy - it says so in the source file - see notes in src/test // var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg); // backwardCopyAnalysis.Analyze(); // backwardCopyAnalysis.Transform(methodBody); var liveVariables = new LiveVariablesAnalysis(cfg); liveVariables.Analyze(); var ssa = new StaticSingleAssignment(methodBody, cfg); ssa.Transform(); ssa.Prune(liveVariables); methodBody.UpdateVariables(); MethodCfgAndTac mct = new MethodCfgAndTac(cfg, methodBody); foreach (IExceptionHandlerBlock ehInfo in disassembler.GetExceptionHandlers()) { if (ehInfo is CatchExceptionHandler) { mct.ehInfoList.Add(ehInfo as CatchExceptionHandler); } } return(mct); }
public void Traverse(IMethodDefinition methodDefinition) { ControlFlowGraph cfg; MethodBody methodBody; IList <CatchExceptionHandler> ehInfoList; if (methodToCfgAndTacMap.ContainsKey(methodDefinition)) { MethodCfgAndTac mct = methodToCfgAndTacMap[methodDefinition]; if (mct == null) { return; } cfg = mct.cfg; methodBody = mct.methodBody; ehInfoList = mct.ehInfoList; } else { MethodCfgAndTac mct = AnalyzeIntraProcedural(methodDefinition); methodToCfgAndTacMap[methodDefinition] = mct; if (mct == null) { return; } cfg = mct.cfg; methodBody = mct.methodBody; ehInfoList = mct.ehInfoList; } if (rtaAnalyzer != null) { if (rtaAnalyzer.entryPtClasses.Contains(methodDefinition.ContainingTypeDefinition)) { if (rtaAnalyzer.rootIsExe) { // Add only the Main method as entry point if (Utils.IsMainMethod(methodDefinition)) { rtaAnalyzer.rtaLogSW.WriteLine("Adding main method: {0}", methodDefinition.FullName()); IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition); // The assumption is that addedMeth is not a template method. Here it is safe because it holds for the main method. if (addedMeth != null) { rtaAnalyzer.entryPtMethods.Add(addedMeth); } } } else { if (methodDefinition.Visibility == TypeMemberVisibility.Public || methodDefinition.Visibility == TypeMemberVisibility.Family) { // Otherwise, add all public methods as entry points IMethodDefinition addedMeth = Stubber.CheckAndAdd(methodDefinition); rtaAnalyzer.rtaLogSW.WriteLine("Adding method: {0}", methodDefinition.FullName()); // The assumption here is that addedMeth is not a template method. // TODO: It may be the case that this assumption does not hold in some cases. if (addedMeth != null) { rtaAnalyzer.entryPtMethods.Add(addedMeth); } } } } if (rtaAnalyzer.methods.Contains(methodDefinition) && !rtaAnalyzer.visitedMethods.Contains(methodDefinition)) { rtaAnalyzer.visitedMethods.Add(methodDefinition); // rtaAnalyzer.rtaLogSW.WriteLine("SRK_DBG: Visiting method: {0}", methodDefinition.GetName()); rtaAnalyzer.VisitMethod(methodBody, cfg); } else { rtaAnalyzer.ignoredMethods.Add(methodDefinition); } } else if (factGen != null) { if (factGen.methods.Contains(methodDefinition)) { factGen.GenerateFacts(methodBody, cfg, ehInfoList); } } }