mirror of
https://github.com/github/codeql.git
synced 2026-02-28 21:03:50 +01:00
Make separate classes for control flow node kinds
This puts all the logic of a particular control flow node kind into one place and makes it easier to add new kinds.
This commit is contained in:
@@ -105,29 +105,19 @@ module ControlFlow {
|
||||
/** A node in the expression-level control-flow graph. */
|
||||
class Node extends TNode {
|
||||
/** Gets the statement containing this node, if any. */
|
||||
Stmt getEnclosingStmt() {
|
||||
result = this.asStmt() or
|
||||
result = this.asExpr().getEnclosingStmt()
|
||||
}
|
||||
Stmt getEnclosingStmt() { none() }
|
||||
|
||||
/** Gets the immediately enclosing callable whose body contains this node. */
|
||||
Callable getEnclosingCallable() {
|
||||
this = TExitNode(result) or
|
||||
result = this.asStmt().getEnclosingCallable() or
|
||||
result = this.asExpr().getEnclosingCallable()
|
||||
}
|
||||
Callable getEnclosingCallable() { none() }
|
||||
|
||||
/** Gets the statement this `Node` corresponds to, if any. */
|
||||
Stmt asStmt() { this = TStmtNode(result) }
|
||||
Stmt asStmt() { none() }
|
||||
|
||||
/** Gets the expression this `Node` corresponds to, if any. */
|
||||
Expr asExpr() { this = TExprNode(result) }
|
||||
Expr asExpr() { none() }
|
||||
|
||||
/** Gets the call this `Node` corresponds to, if any. */
|
||||
Call asCall() {
|
||||
result = this.asExpr() or
|
||||
result = this.asStmt()
|
||||
}
|
||||
Call asCall() { none() }
|
||||
|
||||
/** Gets an immediate successor of this node. */
|
||||
Node getASuccessor() { result = succ(this) }
|
||||
@@ -148,33 +138,77 @@ module ControlFlow {
|
||||
BasicBlock getBasicBlock() { result.getANode() = this }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() {
|
||||
result = this.asExpr().toString()
|
||||
or
|
||||
result = this.asStmt().toString()
|
||||
or
|
||||
result = "Exit" and this instanceof ExitNode
|
||||
}
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() {
|
||||
result = this.asExpr().getLocation() or
|
||||
result = this.asStmt().getLocation() or
|
||||
result = this.(ExitNode).getEnclosingCallable().getLocation()
|
||||
}
|
||||
Location getLocation() { none() }
|
||||
|
||||
/**
|
||||
* Gets the most appropriate AST node for this control flow node, if any.
|
||||
*/
|
||||
ExprParent getAstNode() {
|
||||
result = this.asExpr() or
|
||||
result = this.asStmt() or
|
||||
this = TExitNode(result)
|
||||
}
|
||||
ExprParent getAstNode() { none() }
|
||||
}
|
||||
|
||||
/** A control-flow node that represents the evaluation of an expression. */
|
||||
class ExprNode extends Node, TExprNode {
|
||||
Expr e;
|
||||
|
||||
ExprNode() { this = TExprNode(e) }
|
||||
|
||||
override Stmt getEnclosingStmt() { result = e.getEnclosingStmt() }
|
||||
|
||||
override Callable getEnclosingCallable() { result = e.getEnclosingCallable() }
|
||||
|
||||
override Expr asExpr() { result = e }
|
||||
|
||||
override Call asCall() { result = e }
|
||||
|
||||
override ExprParent getAstNode() { result = e }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = e.toString() }
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
override Location getLocation() { result = e.getLocation() }
|
||||
}
|
||||
|
||||
/** A control-flow node that represents a statement. */
|
||||
class StmtNode extends Node, TStmtNode {
|
||||
Stmt s;
|
||||
|
||||
StmtNode() { this = TStmtNode(s) }
|
||||
|
||||
override Stmt getEnclosingStmt() { result = s }
|
||||
|
||||
override Callable getEnclosingCallable() { result = s.getEnclosingCallable() }
|
||||
|
||||
override Stmt asStmt() { result = s }
|
||||
|
||||
override Call asCall() { result = s }
|
||||
|
||||
override ExprParent getAstNode() { result = s }
|
||||
|
||||
override string toString() { result = s.toString() }
|
||||
|
||||
override Location getLocation() { result = s.getLocation() }
|
||||
}
|
||||
|
||||
/** A control flow node indicating the termination of a callable. */
|
||||
class ExitNode extends Node, TExitNode { }
|
||||
class ExitNode extends Node, TExitNode {
|
||||
Callable c;
|
||||
|
||||
ExitNode() { this = TExitNode(c) }
|
||||
|
||||
override Callable getEnclosingCallable() { result = c }
|
||||
|
||||
override ExprParent getAstNode() { result = c }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "Exit" }
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
}
|
||||
|
||||
class ControlFlowNode = ControlFlow::Node;
|
||||
|
||||
Reference in New Issue
Block a user