protected Tuple <ResolveResult, CppResolver> ResolveExpression(CppParsedFile file, AstNode expr, CompilationUnit unit) { if (expr == null) { return(null); } AstNode resolveNode; if (expr is Expression || expr is AstType) { resolveNode = expr; } else if (expr is VariableDeclarationStatement) { resolveNode = ((VariableDeclarationStatement)expr).Type; } else { resolveNode = expr; } // var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file); var csResolver = new CppAstResolver(new CppResolver(ctx), unit, CSharpParsedFile); var result = csResolver.Resolve(resolveNode); var state = csResolver.GetResolverStateBefore(resolveNode); return(Tuple.Create(result, state)); }
public static ReachabilityAnalysis Create(Statement statement, CppAstResolver resolver = null, CancellationToken cancellationToken = default(CancellationToken)) { var cfgBuilder = new ControlFlowGraphBuilder(); var cfg = cfgBuilder.BuildControlFlowGraph(statement, resolver, cancellationToken); return(Create(cfg, cancellationToken)); }
public DefiniteAssignmentAnalysis(Statement rootStatement, CppAstResolver resolver, CancellationToken cancellationToken) { if (rootStatement == null) { throw new ArgumentNullException("rootStatement"); } if (resolver == null) { throw new ArgumentNullException("resolver"); } this.resolver = resolver; visitor.analysis = this; DerivedControlFlowGraphBuilder cfgBuilder = new DerivedControlFlowGraphBuilder(); if (resolver.TypeResolveContext.Compilation.MainAssembly.UnresolvedAssembly is MinimalCorlib) { cfgBuilder.EvaluateOnlyPrimitiveConstants = true; } allNodes.AddRange(cfgBuilder.BuildControlFlowGraph(rootStatement, resolver, cancellationToken).Cast <DefiniteAssignmentNode>()); for (int i = 0; i < allNodes.Count; i++) { DefiniteAssignmentNode node = allNodes[i]; node.Index = i; // assign numbers to the nodes if (node.Type == ControlFlowNodeType.StartNode || node.Type == ControlFlowNodeType.BetweenStatements) { // Anonymous methods have separate control flow graphs, but we also need to analyze those. // Iterate backwards so that anonymous methods are inserted in the correct order for (AstNode child = node.NextStatement.LastChild; child != null; child = child.PrevSibling) { InsertAnonymousMethods(i + 1, child, cfgBuilder, cancellationToken); } } // Now register the node in the dictionaries: if (node.Type == ControlFlowNodeType.StartNode || node.Type == ControlFlowNodeType.BetweenStatements) { beginNodeDict.Add(node.NextStatement, node); } if (node.Type == ControlFlowNodeType.BetweenStatements || node.Type == ControlFlowNodeType.EndNode) { endNodeDict.Add(node.PreviousStatement, node); } if (node.Type == ControlFlowNodeType.LoopCondition) { conditionNodeDict.Add(node.NextStatement, node); } } // Verify that we created nodes for all statements: Debug.Assert(!rootStatement.DescendantsAndSelf.OfType <Statement>().Except(allNodes.Select(n => n.NextStatement)).Any()); // Verify that we put all nodes into the dictionaries: Debug.Assert(rootStatement.DescendantsAndSelf.OfType <Statement>().All(stmt => beginNodeDict.ContainsKey(stmt))); Debug.Assert(rootStatement.DescendantsAndSelf.OfType <Statement>().All(stmt => endNodeDict.ContainsKey(stmt))); this.analyzedRangeStart = 0; this.analyzedRangeEnd = allNodes.Count - 1; }
public IList <ControlFlowNode> BuildControlFlowGraph(Statement statement, CppAstResolver resolver, CancellationToken cancellationToken = default(CancellationToken)) { if (statement == null) { throw new ArgumentNullException("statement"); } if (resolver == null) { throw new ArgumentNullException("resolver"); } return(BuildControlFlowGraph(statement, resolver.Resolve, resolver.TypeResolveContext, cancellationToken)); }