From c541ef613537d24db7451995a692d1a2915760e1 Mon Sep 17 00:00:00 2001 From: Johannes Mey <johannes.mey@tu-dresden.de> Date: Tue, 17 Dec 2019 18:02:52 +0100 Subject: [PATCH] construct CfgBranch with relational NTA --- reusablecfg/src/main/jastadd/CFG.relast | 7 ++- reusablecfg/src/main/jastadd/PrintCfg.jrag | 21 ++++--- .../src/main/jastadd/PrintCfgTest.jrag | 21 ++++--- reusablecfg/src/main/jastadd/SimpleCFG.jrag | 56 +++++++++++-------- .../jastadd/VariableDeclarationScope.jrag | 2 +- 5 files changed, 64 insertions(+), 43 deletions(-) diff --git a/reusablecfg/src/main/jastadd/CFG.relast b/reusablecfg/src/main/jastadd/CFG.relast index 7a59542..312c6aa 100644 --- a/reusablecfg/src/main/jastadd/CFG.relast +++ b/reusablecfg/src/main/jastadd/CFG.relast @@ -27,8 +27,11 @@ CfgExit : CfgNode; CfgMethodCall : CfgNode; /** A conditional branch in the CFG. */ -CfgBranch : CfgNode; -rel CfgBranch.hostStatement -> Stmt; +abstract CfgBranch : CfgNode; +CfgStatementBranch : CfgBranch; +rel CfgStatementBranch.hostStatement -> Stmt; +CfgExpressionBranch : CfgBranch; +rel CfgExpressionBranch.hostExpression -> ConditionalExpr; /** A branch in the CFG caused by potential thrown exceptions. */ CfgException : CfgNode; diff --git a/reusablecfg/src/main/jastadd/PrintCfg.jrag b/reusablecfg/src/main/jastadd/PrintCfg.jrag index 45651f3..4c94b4e 100644 --- a/reusablecfg/src/main/jastadd/PrintCfg.jrag +++ b/reusablecfg/src/main/jastadd/PrintCfg.jrag @@ -115,17 +115,22 @@ aspect PrintCfg { inh String CfgMethodCall.callLabel(); eq MethodAccess.call().callLabel() = name() + "()"; - inh String CfgBranch.branchLabel(); - eq IfStmt.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")"; - eq ConditionalExpr.branch().branchLabel() = "if (" + getCondition().prettyPrint() + ")"; - eq ForStmt.branch().branchLabel() = "for (" + getCondition().prettyPrint() + ")"; - eq WhileStmt.branch().branchLabel() = "while (" + getCondition().prettyPrint() + ")"; - eq DoStmt.branch().branchLabel() = "do_while (" + getCondition().prettyPrint() + ")"; - eq EnhancedForStmt.branch().branchLabel() = String.format("for (%s %s : %s)", + syn String CfgBranch.branchLabel(); + eq CfgStatementBranch.branchLabel() = getHostStatement().branchLabel(); + eq CfgExpressionBranch.branchLabel() = getHostExpression().branchLabel(); + + syn String Stmt.branchLabel() = ""; + eq IfStmt.branchLabel() = "if (" + getCondition().prettyPrint() + ")"; + eq ForStmt.branchLabel() = "for (" + getCondition().prettyPrint() + ")"; + eq WhileStmt.branchLabel() = "while (" + getCondition().prettyPrint() + ")"; + eq DoStmt.branchLabel() = "do_while (" + getCondition().prettyPrint() + ")"; + eq EnhancedForStmt.branchLabel() = String.format("for (%s %s : %s)", getVariableDecl().getTypeAccess().prettyPrint(), getVariableDecl().getID(), getExpr().prettyPrint()); - eq SwitchStmt.branch().branchLabel() = "switch (" + getExpr().prettyPrint() + ")"; + eq SwitchStmt.branchLabel() = "switch (" + getExpr().prettyPrint() + ")"; + + syn String ConditionalExpr.branchLabel() = "if (" + getCondition().prettyPrint() + ")"; inh String CfgMarker.markerName(); eq BreakStmt.marker().markerName() = "break"; diff --git a/reusablecfg/src/main/jastadd/PrintCfgTest.jrag b/reusablecfg/src/main/jastadd/PrintCfgTest.jrag index d8f8c36..9fe1c1a 100644 --- a/reusablecfg/src/main/jastadd/PrintCfgTest.jrag +++ b/reusablecfg/src/main/jastadd/PrintCfgTest.jrag @@ -152,14 +152,19 @@ aspect PrintCfgTest { eq CfgMarker.varName() = markerVarName(); eq CfgMethodCall.varName() = methodAccess().getID(); - inh String CfgBranch.branchKind(); - eq IfStmt.branch().branchKind() = "if"; - eq ConditionalExpr.branch().branchKind() = "if"; - eq ForStmt.branch().branchKind() = "for"; - eq WhileStmt.branch().branchKind() = "while"; - eq DoStmt.branch().branchKind() = "doWhile"; - eq EnhancedForStmt.branch().branchKind() = "for"; - eq SwitchStmt.branch().branchKind() = "switch"; + syn String CfgBranch.branchKind(); + eq CfgStatementBranch.branchKind() = getHostStatement().branchKind(); + eq CfgExpressionBranch.branchKind() = getHostExpression().branchKind(); + + syn String Stmt.branchKind() = ""; + eq IfStmt.branchKind() = "if"; + eq ForStmt.branchKind() = "for"; + eq WhileStmt.branchKind() = "while"; + eq DoStmt.branchKind() = "doWhile"; + eq EnhancedForStmt.branchKind() = "for"; + eq SwitchStmt.branchKind() = "switch"; + + syn String ConditionalExpr.branchKind() = "if"; inh String CfgMarker.markerVarName(); eq BreakStmt.marker().markerVarName() = "breakMarker"; diff --git a/reusablecfg/src/main/jastadd/SimpleCFG.jrag b/reusablecfg/src/main/jastadd/SimpleCFG.jrag index 40c66bc..ab68075 100644 --- a/reusablecfg/src/main/jastadd/SimpleCFG.jrag +++ b/reusablecfg/src/main/jastadd/SimpleCFG.jrag @@ -60,7 +60,16 @@ aspect SimpleCFG { eq CfgMarker.successors() = succ(); /** Successors to this branch node. */ - inh Set<? extends CfgNode> CfgBranch.succ(); + syn Set<? extends CfgNode> CfgBranch.succ(); + eq CfgStatementBranch.succ() = getHostStatement().branchSucc(); + eq CfgExpressionBranch.succ() = getHostExpression().branchSucc(); + + /** Successors of a Stmt */ + syn Set<? extends CfgNode> Stmt.branchSucc() = Collections.emptySet(); + + + /** Successors of a Stmt */ + syn Set<? extends CfgNode> ConditionalExpr.branchSucc(); /** Successors to this method call node. */ inh Set<? extends CfgNode> CfgMethodCall.succ(); @@ -440,9 +449,9 @@ aspect SimpleCFG { eq Dot.getLeft().follow() = getRight().entry(); /** The branch node for this conditional expression. */ - syn nta CfgBranch ConditionalExpr.branch() { - CfgBranch branch = new CfgBranch(); - branch.setHostStatement(hostStatement()); + syn lazy CfgExpressionBranch ConditionalExpr.branch() { + CfgExpressionBranch branch = new CfgExpressionBranch(); + branch.setHostExpression(this); return branch; } @@ -467,12 +476,12 @@ aspect SimpleCFG { eq ConditionalExpr.thenEndMarker().succ() = Collections.singleton(follow()); eq ConditionalExpr.elseEndMarker().succ() = Collections.singleton(follow()); - eq ConditionalExpr.branch().succ() = + eq ConditionalExpr.branchSucc() = smallSet(getTrueExpr().entry(), getFalseExpr().entry()); /** The branch node for this statement. */ - syn nta CfgBranch IfStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch IfStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -493,14 +502,14 @@ aspect SimpleCFG { eq IfStmt.thenEndMarker().succ() = Collections.singleton(follow()); eq IfStmt.elseEndMarker().succ() = Collections.singleton(follow()); - eq IfStmt.branch().succ() = + eq IfStmt.branchSucc() = hasElse() ? smallSet(getThen().entry(), getElse().entry()) : smallSet(getThen().entry(), follow()); /** The branch node for this statement. */ - syn nta CfgBranch ForStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch ForStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -537,7 +546,7 @@ aspect SimpleCFG { ? Collections.singleton(getUpdateStmt(0).entry()) : Collections.singleton(getCondition().entry()); - eq ForStmt.branch().succ() { + eq ForStmt.branchSucc() { if (getCondition().isTrue()) { return Collections.singleton(getStmt().entry()); } else if (getCondition().isFalse()) { @@ -548,8 +557,8 @@ aspect SimpleCFG { } /** The branch node for this statement. */ - syn nta CfgBranch EnhancedForStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch EnhancedForStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -557,8 +566,7 @@ aspect SimpleCFG { /** The CFG end marker for this loop. */ syn nta CfgMarker EnhancedForStmt.loopEndMarker() = new CfgMarker(); - eq EnhancedForStmt.branch().succ() = - smallSet(getStmt().entry(), follow()); + eq EnhancedForStmt.branchSucc() = smallSet(getStmt().entry(), follow()); eq EnhancedForStmt.entry() = getExpr().entry(); @@ -571,8 +579,8 @@ aspect SimpleCFG { eq EnhancedForStmt.loopEndMarker().succ() = Collections.singleton(entry()); /** The branch node for this statement. */ - syn nta CfgBranch WhileStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch WhileStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -590,7 +598,7 @@ aspect SimpleCFG { eq WhileStmt.loopEndMarker().succ() = Collections.singleton(entry()); - eq WhileStmt.branch().succ() { + eq WhileStmt.branchSucc() { if (getCondition().isTrue()) { return Collections.singleton(getStmt().entry()); } else if (getCondition().isFalse()) { @@ -601,8 +609,8 @@ aspect SimpleCFG { } /** The branch node for this statement. */ - syn nta CfgBranch DoStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch DoStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -621,7 +629,7 @@ aspect SimpleCFG { eq DoStmt.getCondition().follow() = branch(); // Loop back. - eq DoStmt.branch().succ() { + eq DoStmt.branchSucc() { if (getCondition().isTrue()) { return Collections.singleton(entry()); } else if (getCondition().isFalse()) { @@ -631,8 +639,8 @@ aspect SimpleCFG { } } - syn nta CfgBranch SwitchStmt.branch() { - CfgBranch branch = new CfgBranch(); + syn lazy CfgStatementBranch SwitchStmt.branch() { + CfgStatementBranch branch = new CfgStatementBranch(); branch.setHostStatement(this); return branch; } @@ -641,7 +649,7 @@ aspect SimpleCFG { eq SwitchStmt.getExpr().follow() = branch(); - eq SwitchStmt.branch().succ() { + eq SwitchStmt.branchSucc() { Set<CfgNode> set = Collections.newSetFromMap( new IdentityHashMap<CfgNode, Boolean>()); boolean hasDefault = false; diff --git a/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag b/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag index 501017f..d48e114 100644 --- a/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag +++ b/reusablecfg/src/main/jastadd/VariableDeclarationScope.jrag @@ -27,7 +27,7 @@ aspect VariableDeclarationScope { */ syn boolean CfgNode.isDeclarationOf(Variable var) = false; - eq CfgBranch.isDeclarationOf(Variable var) = + eq CfgStatementBranch.isDeclarationOf(Variable var) = getHostStatement().declaresVariable(var) || getHostStatement().variableDeclaredInside(var); -- GitLab