From 293c183d55457067af27745085ba2a56046985c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Bispo?= Date: Wed, 18 Dec 2024 01:09:04 +0000 Subject: [PATCH] Adds changes of 5 commits --- .../fe/specs/clang/utils/ChildrenAdapter.java | 38 +-- Clava-JS/src-api/Joinpoints.ts | 18 +- Clava-JS/src-api/clava/ClavaJoinPoints.ts | 8 +- .../analysis/flow/control/BasicBlockNode.java | 2 +- .../specs/clava/ast/stmt/CXXForRangeStmt.java | 21 +- .../pt/up/fe/specs/clava/ast/stmt/DoStmt.java | 18 +- .../up/fe/specs/clava/ast/stmt/ForStmt.java | 48 ++-- .../pt/up/fe/specs/clava/ast/stmt/IfStmt.java | 26 +- .../up/fe/specs/clava/ast/stmt/WhileStmt.java | 18 +- .../fe/specs/clava/context/ClavaFactory.java | 11 +- .../transform/loop/LoopAnalysisUtils.java | 60 ++--- .../clava/transform/loop/LoopTiling.java | 52 ++-- .../specs/clava/utils/StmtWithCondition.java | 19 +- .../foriter/ForIterationsExpression.java | 107 ++++---- ClavaLaraApi/src-lara/clava/Joinpoints.js | 16 +- .../src-lara/clava/clava/ClavaJoinPoints.js | 4 +- .../clava/clava/graphs/cfg/CfgBuilder.js | 2 +- .../clava/test/api/ClavaJoinPointsTest.js | 2 +- .../test/api/cpp/results/Code2VecTest.js.txt | 56 ++--- .../test/weaver/c/results/NullNodes.lara.txt | 2 - .../clava/test/weaver/c/results/Scope.js.txt | 2 +- .../cpp/results/GlobalAttributes.lara.txt | 4 - .../resources/clava/weaverspecs/artifacts.xml | 8 +- .../clava/weaverspecs/joinPointModel.xml | 236 +++++++++--------- .../up/fe/specs/clava/weaver/CxxWeaver.json | 52 +++- .../weaver/abstracts/joinpoints/ACilkFor.java | 24 +- .../weaver/abstracts/joinpoints/ALoop.java | 66 ++++- .../clava/weaver/importable/AstFactory.java | 8 +- .../clava/weaver/joinpoints/CxxLoop.java | 96 ++++--- 29 files changed, 553 insertions(+), 471 deletions(-) diff --git a/ClangAstParser/src/pt/up/fe/specs/clang/utils/ChildrenAdapter.java b/ClangAstParser/src/pt/up/fe/specs/clang/utils/ChildrenAdapter.java index 99c89c3b0..6e4772a7f 100644 --- a/ClangAstParser/src/pt/up/fe/specs/clang/utils/ChildrenAdapter.java +++ b/ClangAstParser/src/pt/up/fe/specs/clang/utils/ChildrenAdapter.java @@ -1,11 +1,11 @@ /** * Copyright 2018 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,30 +13,12 @@ package pt.up.fe.specs.clang.utils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.BiFunction; - import com.google.common.base.Preconditions; - import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ast.decl.NullDecl; import pt.up.fe.specs.clava.ast.decl.VarDecl; import pt.up.fe.specs.clava.ast.expr.Expr; -import pt.up.fe.specs.clava.ast.stmt.CXXCatchStmt; -import pt.up.fe.specs.clava.ast.stmt.CXXForRangeStmt; -import pt.up.fe.specs.clava.ast.stmt.CXXTryStmt; -import pt.up.fe.specs.clava.ast.stmt.CaseStmt; -import pt.up.fe.specs.clava.ast.stmt.CompoundStmt; -import pt.up.fe.specs.clava.ast.stmt.DeclStmt; -import pt.up.fe.specs.clava.ast.stmt.DefaultStmt; -import pt.up.fe.specs.clava.ast.stmt.DoStmt; -import pt.up.fe.specs.clava.ast.stmt.ForStmt; -import pt.up.fe.specs.clava.ast.stmt.IfStmt; -import pt.up.fe.specs.clava.ast.stmt.LabelStmt; -import pt.up.fe.specs.clava.ast.stmt.Stmt; -import pt.up.fe.specs.clava.ast.stmt.WhileStmt; +import pt.up.fe.specs.clava.ast.stmt.*; import pt.up.fe.specs.clava.context.ClavaContext; import pt.up.fe.specs.clava.utils.NullNode; import pt.up.fe.specs.util.SpecsCheck; @@ -45,6 +27,11 @@ import pt.up.fe.specs.util.exceptions.CaseNotDefinedException; import pt.up.fe.specs.util.exceptions.NotImplementedException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; + public class ChildrenAdapter { private final ClavaContext context; @@ -58,6 +45,7 @@ public ChildrenAdapter(ClavaContext context) { // } private final static ClassMap, ClavaContext, List>> CHILDREN_ADAPTERS; + static { CHILDREN_ADAPTERS = new ClassMap<>((list, context) -> list); CHILDREN_ADAPTERS.put(IfStmt.class, ChildrenAdapter::adaptIfStmt); @@ -110,7 +98,7 @@ public List adaptChildren(ClavaNode node, List children) { /** * Checks if the given Clava node is an instance of the expected class. Throws an exception if it is not. - * + * * @param * @param node * @param expectedClass @@ -152,8 +140,8 @@ private static List adaptForStmt(List children, ClavaConte List adaptedChildren = new ArrayList<>(children.size()); adaptedChildren.add(toStmt(check(children.get(0), STMT_OR_EXPR), context)); - adaptedChildren.add(toStmt(check(children.get(1), Expr.class), context)); - adaptedChildren.add(toStmt(check(children.get(2), Expr.class), context)); + adaptedChildren.add(check(children.get(1), Expr.class)); + adaptedChildren.add(check(children.get(2), Expr.class)); adaptedChildren.add(toCompoundStmt(check(children.get(3), STMT_OR_EXPR), false, context)); adaptedChildren.add(check(children.get(4), OPTIONAL_VARDECL)); diff --git a/Clava-JS/src-api/Joinpoints.ts b/Clava-JS/src-api/Joinpoints.ts index a56bd50da..adbf33fa3 100644 --- a/Clava-JS/src-api/Joinpoints.ts +++ b/Clava-JS/src-api/Joinpoints.ts @@ -2105,13 +2105,17 @@ export class Loop extends Statement { get body(): Scope { return wrapJoinPoint(this._javaObject.getBody()) } set body(value: Scope) { this._javaObject.setBody(unwrapJoinPoint(value)); } /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ get cond(): Statement { return wrapJoinPoint(this._javaObject.getCond()) } /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ set cond(value: string) { this._javaObject.setCond(unwrapJoinPoint(value)); } + /** + * The expression of the loop condition + */ + get condExpr(): Expression { return wrapJoinPoint(this._javaObject.getCondExpr()) } get condRelation(): Relation { return wrapJoinPoint(this._javaObject.getCondRelation()) } set condRelation(value: Relation) { this._javaObject.setCondRelation(unwrapJoinPoint(value)); } get controlVar(): string { return wrapJoinPoint(this._javaObject.getControlVar()) } @@ -2158,13 +2162,17 @@ export class Loop extends Statement { get nestedLevel(): number { return wrapJoinPoint(this._javaObject.getNestedLevel()) } get rank(): number[] { return wrapJoinPoint(this._javaObject.getRank()) } /** - * The statement of the loop step + * (deprecated) The expression of the loop step wrapped around a new exprStmt */ - get step(): Statement { return wrapJoinPoint(this._javaObject.getStep()) } + get step(): ExprStmt { return wrapJoinPoint(this._javaObject.getStep()) } /** - * The statement of the loop step + * (deprecated) The expression of the loop step wrapped around a new exprStmt */ set step(value: string) { this._javaObject.setStep(unwrapJoinPoint(value)); } + /** + * The expression of the loop step + */ + get stepExpr(): Expression { return wrapJoinPoint(this._javaObject.getStepExpr()) } /** * The expression of the iteration step */ diff --git a/Clava-JS/src-api/clava/ClavaJoinPoints.ts b/Clava-JS/src-api/clava/ClavaJoinPoints.ts index e27288456..fbc64fdfe 100644 --- a/Clava-JS/src-api/clava/ClavaJoinPoints.ts +++ b/Clava-JS/src-api/clava/ClavaJoinPoints.ts @@ -742,18 +742,18 @@ export default class ClavaJoinPoints { */ static forStmt( $init?: Joinpoints.Statement | string, - $condition?: Joinpoints.Statement | string, - $inc?: Joinpoints.Statement | string, + $condition?: Joinpoints.Expression | string, + $inc?: Joinpoints.Expression | string, $body?: Joinpoints.Statement | string ): Joinpoints.Loop { if (typeof $init === "string") { $init = ClavaJoinPoints.stmtLiteral($init); } if (typeof $condition === "string") { - $condition = ClavaJoinPoints.stmtLiteral($condition); + $condition = ClavaJoinPoints.exprLiteral($condition); } if (typeof $inc === "string") { - $inc = ClavaJoinPoints.stmtLiteral($inc); + $inc = ClavaJoinPoints.exprLiteral($inc); } if (typeof $body === "string") { $body = ClavaJoinPoints.stmtLiteral($body); diff --git a/ClavaAst/src/pt/up/fe/specs/clava/analysis/flow/control/BasicBlockNode.java b/ClavaAst/src/pt/up/fe/specs/clava/analysis/flow/control/BasicBlockNode.java index c6117d9dd..3bb1dcccc 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/analysis/flow/control/BasicBlockNode.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/analysis/flow/control/BasicBlockNode.java @@ -129,7 +129,7 @@ private String getBbCode(Stmt stmt) { builder.append("for").append("("); builder.append(f.getInit().map(init -> init.getCode()).orElse(";")); - builder.append(f.getCond().map(init -> " " + init.getCode()).orElse(";")); + builder.append(f.getCond().map(init -> " " + init.getCode()).orElse("")).append(";"); String incCode = f.getInc().map(init -> " " + init.getCode()).orElse(""); if (incCode.endsWith(";")) { incCode = incCode.substring(0, incCode.length() - 1); diff --git a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/CXXForRangeStmt.java b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/CXXForRangeStmt.java index 78a5920c4..74549b0fb 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/CXXForRangeStmt.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/CXXForRangeStmt.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,21 +13,19 @@ package pt.up.fe.specs.clava.ast.stmt; -import java.util.Collection; -import java.util.Optional; - import org.suikasoft.jOptions.Interfaces.DataStore; - import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ast.decl.VarDecl; import pt.up.fe.specs.clava.ast.expr.Expr; +import java.util.Collection; +import java.util.Optional; + /** * This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (range-declarator : * range-expression)' or 'for (init-statement range-declarator : range-expression)'. - * - * @author JBispo * + * @author JBispo */ public class CXXForRangeStmt extends LoopStmt { @@ -95,4 +93,9 @@ public String getCode() { public Optional getStmtCondition() { return Optional.of(getCond()); } + + @Override + public Optional getStmtCondExpr() { + return Optional.of(getCond()); + } } diff --git a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/DoStmt.java b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/DoStmt.java index 7d83aff7d..1c67e03e8 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/DoStmt.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/DoStmt.java @@ -1,11 +1,11 @@ /** * Copyright 2017 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,12 +13,12 @@ package pt.up.fe.specs.clava.ast.stmt; -import java.util.Collection; -import java.util.Optional; - import org.suikasoft.jOptions.Interfaces.DataStore; - import pt.up.fe.specs.clava.ClavaNode; +import pt.up.fe.specs.clava.ast.expr.Expr; + +import java.util.Collection; +import java.util.Optional; public class DoStmt extends LoopStmt { @@ -51,4 +51,8 @@ public String getCode() { } + @Override + public Optional getStmtCondExpr() { + return Optional.of(getCondition().getExpr()); + } } diff --git a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/ForStmt.java b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/ForStmt.java index 83ed23fc3..4d0c6f222 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/ForStmt.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/ForStmt.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,13 +13,7 @@ package pt.up.fe.specs.clava.ast.stmt; -import java.util.Collection; -import java.util.EnumSet; -import java.util.Optional; -import java.util.Set; - import org.suikasoft.jOptions.Interfaces.DataStore; - import pt.up.fe.specs.clava.ClavaLog; import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ast.decl.VarDecl; @@ -33,6 +27,11 @@ import pt.up.fe.specs.clava.utils.foriter.ForIterationsExpression; import pt.up.fe.specs.util.treenode.NodeInsertUtils; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Optional; +import java.util.Set; + public class ForStmt extends LoopStmt { private static final Set RELATIONAL_OPS = EnumSet.of(BinaryOperatorKind.LE, @@ -46,12 +45,12 @@ public Optional getInit() { return getOptionalChild(Stmt.class, 0); } - public Optional getCond() { - return getOptionalChild(Stmt.class, 1); + public Optional getCond() { + return getOptionalChild(Expr.class, 1); } - public Optional getInc() { - return getOptionalChild(Stmt.class, 2); + public Optional getInc() { + return getOptionalChild(Expr.class, 2); } @Override @@ -88,15 +87,15 @@ protected String getCode(String forKeyword) { // System.out.println("COND CODE: " + getCond().map(cond -> " " + cond.getCode()).orElse(";")); // System.out.println("VARDECL CODE: " + condVar.map(var -> var.getCode()).orElse("")); - var condCode = condVar.map(var -> var.getCode() + ";") - .orElse(getCond().map(cond -> " " + cond.getCode()).orElse(";")); + var condCode = condVar.map(var -> var.getCode()) + .orElse(getCond().map(cond -> " " + cond.getCode()).orElse("")) + ";"; code.append(condCode); // code.append(getCond().map(cond -> " " + cond.getCode()).orElse(";")); // Get 'inc' code String incCode = getInc() - .map(init -> " " + removeSemicolon(init.getCode())) + .map(init -> " " + init.getCode()) .orElse(""); code.append(incCode); @@ -137,7 +136,6 @@ public void setInc(LiteralStmt literalStmt) { public Optional getCondOperator() { return getCond() - .map(cond -> cond.getChild(0)) .filter(BinaryOperator.class::isInstance) .map(BinaryOperator.class::cast); @@ -145,11 +143,11 @@ public Optional getCondOperator() { /** * The value expression of the test relation in the condition of an OpenM canonical loop form. - * + * *

* The value expression is define if the condition expression is a binary operator with one of the following * operators: <, <=, >, >= - * + * * @return */ public Optional getConditionValueExpr() { @@ -177,7 +175,7 @@ public Optional getInitVar() { /** * A ClavaNode that implements Nameable, that represents the iteration variable. - * + * * @return */ public Optional getIterationVarNode() { @@ -255,12 +253,12 @@ private Optional getInitValueExpr(ClavaNode initExpr) { /** * The value by which the iteration variable changes each iteration. - * + * *

* Supports values for increment expressions of Canonical Loop Forms as defined by the OpenMP standard. */ public Optional getStepValueExpr() { - return getInc().flatMap(inc -> getStepValueExpr(inc.getChild(0))); + return getInc().flatMap(inc -> getStepValueExpr(inc)); } private Optional getStepValueExpr(ClavaNode incExpr) { @@ -310,11 +308,15 @@ private Optional getStepValueExpr(ClavaNode incExpr) { } /** - * * @return an expression that represents the number of iterations of the loop */ @Override public Optional getIterationsExpr() { return ForIterationsExpression.newInstance(this).flatMap(iter -> iter.getIterationsExpr()); } + + @Override + public Optional getStmtCondExpr() { + return getCond(); + } } \ No newline at end of file diff --git a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/IfStmt.java b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/IfStmt.java index 7f1a1d8be..1e1837b66 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/IfStmt.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/IfStmt.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,17 +13,16 @@ package pt.up.fe.specs.clava.ast.stmt; -import java.util.Collection; -import java.util.Optional; - import org.suikasoft.jOptions.Interfaces.DataStore; - import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ClavaNodes; import pt.up.fe.specs.clava.ast.decl.VarDecl; import pt.up.fe.specs.clava.ast.expr.Expr; import pt.up.fe.specs.clava.utils.StmtWithCondition; +import java.util.Collection; +import java.util.Optional; + public class IfStmt extends Stmt implements StmtWithCondition { public IfStmt(DataStore data, Collection children) { @@ -46,10 +45,10 @@ public void setCondition(Expr condition) { /** * The 'then' block. - * + * *

* In C++ the IfStmt can have no then (e.g., "if(true);"). - * + * * @return */ public Optional getThen() { @@ -115,7 +114,14 @@ private String getElseCode(CompoundStmt elseStmt) { @Override public Optional getStmtCondition() { - return getDeclCondition().map(ClavaNode.class::cast); + var nullableStmtCondition = getDeclCondition().map(ClavaNode.class::cast).orElse(getCondition()); + return Optional.of(nullableStmtCondition); + + //return getDeclCondition().map(ClavaNode.class::cast); } + @Override + public Optional getStmtCondExpr() { + return Optional.of(getCondition()); + } } diff --git a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/WhileStmt.java b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/WhileStmt.java index 9248d175c..60e341649 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/WhileStmt.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/ast/stmt/WhileStmt.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,14 +13,14 @@ package pt.up.fe.specs.clava.ast.stmt; -import java.util.Collection; -import java.util.Optional; - import org.suikasoft.jOptions.Interfaces.DataStore; - import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ClavaNodes; import pt.up.fe.specs.clava.ast.decl.VarDecl; +import pt.up.fe.specs.clava.ast.expr.Expr; + +import java.util.Collection; +import java.util.Optional; public class WhileStmt extends LoopStmt { @@ -65,4 +65,8 @@ public Optional getStmtCondition() { return Optional.of(nullableStmtCondition); } + @Override + public Optional getStmtCondExpr() { + return Optional.of(getCondition().getExpr()); + } } diff --git a/ClavaAst/src/pt/up/fe/specs/clava/context/ClavaFactory.java b/ClavaAst/src/pt/up/fe/specs/clava/context/ClavaFactory.java index 115a70d97..ae47aa7d2 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/context/ClavaFactory.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/context/ClavaFactory.java @@ -768,10 +768,17 @@ public IfStmt ifStmt(Expr condition, CompoundStmt thenBody, CompoundStmt elseBod } - public ForStmt forStmt(Stmt init, Stmt cond, Stmt inc, CompoundStmt body) { + /** + * @param init + * @param cond may use null, Java does not allow ExprStmt | NullStmt + * @param inc may use null, Java does not allow ExprStmt | NullStmt + * @param body + * @return + */ + public ForStmt forStmt(Stmt init, Expr cond, Expr inc, CompoundStmt body) { DataStore forStmtData = newDataStore(ForStmt.class); - return new ForStmt(forStmtData, Arrays.asList(init, cond, inc, body, nullDecl())); + return new ForStmt(forStmtData, Arrays.asList(init, cond != null ? cond : nullStmt(), inc != null ? inc : nullStmt(), body, nullDecl())); } public WhileStmt whileStmt(Stmt cond, CompoundStmt body) { diff --git a/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopAnalysisUtils.java b/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopAnalysisUtils.java index a4f0a320b..7bc7f427c 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopAnalysisUtils.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopAnalysisUtils.java @@ -1,11 +1,11 @@ /** * Copyright 2017 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,38 +13,26 @@ package pt.up.fe.specs.clava.transform.loop; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ast.decl.Decl; import pt.up.fe.specs.clava.ast.decl.VarDecl; -import pt.up.fe.specs.clava.ast.expr.BinaryOperator; -import pt.up.fe.specs.clava.ast.expr.DeclRefExpr; -import pt.up.fe.specs.clava.ast.expr.Expr; -import pt.up.fe.specs.clava.ast.expr.Literal; -import pt.up.fe.specs.clava.ast.expr.UnaryOperator; +import pt.up.fe.specs.clava.ast.expr.*; import pt.up.fe.specs.clava.ast.expr.enums.BinaryOperatorKind; import pt.up.fe.specs.clava.ast.expr.enums.ExprUse; import pt.up.fe.specs.clava.ast.expr.enums.UnaryOperatorKind; -import pt.up.fe.specs.clava.ast.stmt.BreakStmt; -import pt.up.fe.specs.clava.ast.stmt.ContinueStmt; -import pt.up.fe.specs.clava.ast.stmt.DeclStmt; -import pt.up.fe.specs.clava.ast.stmt.ExprStmt; -import pt.up.fe.specs.clava.ast.stmt.ForStmt; -import pt.up.fe.specs.clava.ast.stmt.LoopStmt; -import pt.up.fe.specs.clava.ast.stmt.ReturnStmt; -import pt.up.fe.specs.clava.ast.stmt.Stmt; +import pt.up.fe.specs.clava.ast.stmt.*; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; public class LoopAnalysisUtils { /** * Checks if the for loop has init, cond and inc statements. * - * @param forLoop - * the loop to test + * @param forLoop the loop to test * @return true if it has all the elements, false otherwise */ static boolean hasHeader(ForStmt forLoop) { @@ -131,15 +119,7 @@ public static boolean hasSimpleCond(ForStmt targetFor) { return false; } - // cond is a binary expression - Stmt cond = targetFor.getCond().get(); - - if (!(cond instanceof ExprStmt)) { - - return false; - } - - Expr expr = ((ExprStmt) cond).getExpr(); + Expr expr = targetFor.getCond().get(); if (!(expr instanceof BinaryOperator)) { @@ -179,16 +159,8 @@ public static boolean hasSimpleInc(ForStmt targetFor) { return false; } - // inc has to be an expression statement - Stmt inc = targetFor.getInc().get(); - - if (!(inc instanceof ExprStmt)) { - - return false; - } - // the expression needs to be a unary or a binary operation - Expr expr = ((ExprStmt) inc).getExpr(); + Expr expr = targetFor.getInc().get(); if (!(expr instanceof UnaryOperator || expr instanceof BinaryOperator)) { @@ -220,12 +192,12 @@ public static boolean hasSimpleInc(ForStmt targetFor) { public static List getControlVarNames(ForStmt targetFor) { - Stmt inc = targetFor.getInc().orElse(null); + var inc = targetFor.getInc().orElse(null); if (inc == null) { return Collections.emptyList(); } - List controlVars = inc.getDescendants(DeclRefExpr.class).stream() + List controlVars = inc.getDescendantsAndSelf(DeclRefExpr.class).stream() .filter(d -> d.use() == ExprUse.READWRITE || d.use() == ExprUse.WRITE).map(DeclRefExpr::getRefName) .collect(Collectors.toList()); @@ -274,7 +246,7 @@ public static Optional getUpperBound(ForStmt targetFor) { return Optional.empty(); } - BinaryOperator comparison = (BinaryOperator) ((ExprStmt) targetFor.getCond().get()).getExpr(); + BinaryOperator comparison = (BinaryOperator) targetFor.getCond().get(); return Optional.of(comparison.getRhs()); diff --git a/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopTiling.java b/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopTiling.java index 32829fba9..9b937a0e7 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopTiling.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/transform/loop/LoopTiling.java @@ -1,11 +1,11 @@ /** * Copyright 2017 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,24 +13,19 @@ package pt.up.fe.specs.clava.transform.loop; -import java.util.List; - import pt.up.fe.specs.clava.ast.decl.VarDecl; import pt.up.fe.specs.clava.ast.expr.BinaryOperator; import pt.up.fe.specs.clava.ast.expr.Expr; import pt.up.fe.specs.clava.ast.expr.LiteralExpr; -import pt.up.fe.specs.clava.ast.stmt.CompoundStmt; -import pt.up.fe.specs.clava.ast.stmt.DeclStmt; -import pt.up.fe.specs.clava.ast.stmt.ExprStmt; -import pt.up.fe.specs.clava.ast.stmt.ForStmt; -import pt.up.fe.specs.clava.ast.stmt.LoopStmt; -import pt.up.fe.specs.clava.ast.stmt.Stmt; +import pt.up.fe.specs.clava.ast.stmt.*; import pt.up.fe.specs.clava.ast.type.Type; import pt.up.fe.specs.clava.ast.type.enums.BuiltinKind; import pt.up.fe.specs.clava.context.ClavaContext; import pt.up.fe.specs.clava.context.ClavaFactory; import pt.up.fe.specs.util.treenode.NodeInsertUtils; +import java.util.List; + public class LoopTiling { private final ClavaFactory factory; @@ -92,7 +87,6 @@ private Stmt tile(LoopStmt targetLoop, Stmt referenceStmt, String blockSize, boo } /** - * * Note: for now it's based on literal statements, which means that the elements of the statements are not present * in the tree and cannot be iterated through. * @@ -103,12 +97,12 @@ private Stmt tile(LoopStmt targetLoop, Stmt referenceStmt, String blockSize, boo * @param oldUpperBound */ private void addBlockLoop(ForStmt targetFor, Stmt referenceStmt, String blockSize, String blockVarName, - Expr oldLowerBound, Expr oldUpperBound) { + Expr oldLowerBound, Expr oldUpperBound) { // make header parts - Stmt init = factory.literalStmt("int " + blockVarName + " = " + oldLowerBound.getCode() + ";"); - Stmt cond = factory.literalStmt(blockVarName + " < " + oldUpperBound.getCode() + ";"); - Stmt inc = factory.literalStmt(blockVarName + " += " + blockSize); + var init = factory.literalStmt("int " + blockVarName + " = " + oldLowerBound.getCode() + ";"); + var cond = factory.literalExpr(blockVarName + " < " + oldUpperBound.getCode(), factory.builtinType(BuiltinKind.Int)); + var inc = factory.literalExpr(blockVarName + " += " + blockSize, factory.builtinType(BuiltinKind.Int)); // make for loop CompoundStmt emptyBody = factory.compoundStmt(); @@ -121,14 +115,14 @@ private void addBlockLoop(ForStmt targetFor, Stmt referenceStmt, String blockSiz } private Stmt changeTarget(ForStmt targetFor, String blockSize, String blockVarName, Expr oldUpperBound, - boolean useTernary) { + boolean useTernary) { changeInit(targetFor, blockVarName); return changeCond(targetFor, blockSize, blockVarName, oldUpperBound, useTernary); } private Stmt changeCond(ForStmt targetFor, String blockSize, String blockVarName, Expr oldUpperBound, - boolean useTernary) { + boolean useTernary) { Type oldUpperBoundType = oldUpperBound.getType(); String oldUpperBoundCode = oldUpperBound.getCode(); @@ -162,7 +156,7 @@ private Stmt changeCond(ForStmt targetFor, String blockSize, String blockVarName } private Stmt makeLimitCheck(ForStmt targetFor, Type oldUpperBoundType, String oldUpperBoundCode, - String blockLimit, String limitVar) { + String blockLimit, String limitVar) { String limitVarDecl = oldUpperBoundType.unqualifiedType().getCode(targetFor) + " " + limitVar + " = " + blockLimit + ";"; @@ -213,25 +207,23 @@ private void changeInit(ForStmt targetFor, String blockVarName) { /** * Tests whether the transformation can be applied. The following conditions must be met: - * + *

* 1) Target loop is a FOR loop - * + *

* 2) targetLoop contains init, cond and inc statements - * + *

* 3) init is a simple assignment ot the control variable (e.g., i = 0) - * + *

* 4) cond is a simple binary comparison (e.g., i < SIZE) - * + *

* 5) inc is a simple increment (e.g., i++ or i+=1) - * + *

* 6) referenceLoop is an ancestor of targetLoop or the same loop - * + *

* 7) no complex control flow inside the loop (break, continue, return and goto) * - * @param targetLoop - * the loop that will be tiled - * @param referenceStmt - * the loop before which the new block-iterating loop will be introduced + * @param targetLoop the loop that will be tiled + * @param referenceStmt the loop before which the new block-iterating loop will be introduced * @return true if we the transformation can be applied, false otherwise */ // public boolean test(LoopStmt targetLoop, LoopStmt referenceLoop) { diff --git a/ClavaAst/src/pt/up/fe/specs/clava/utils/StmtWithCondition.java b/ClavaAst/src/pt/up/fe/specs/clava/utils/StmtWithCondition.java index b06351cf2..a39a6e4d8 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/utils/StmtWithCondition.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/utils/StmtWithCondition.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,11 +13,20 @@ package pt.up.fe.specs.clava.utils; -import java.util.Optional; - import pt.up.fe.specs.clava.ClavaNode; +import pt.up.fe.specs.clava.ast.expr.Expr; + +import java.util.Optional; public interface StmtWithCondition { + /** + * Because ifs and whiles can have a VarDecl as a condition (instead of expression), this method returns ClavaNode, + * the common node between both. + * + * @return the node of this statement that represents a condition + */ Optional getStmtCondition(); + + Optional getStmtCondExpr(); } diff --git a/ClavaAst/src/pt/up/fe/specs/clava/utils/foriter/ForIterationsExpression.java b/ClavaAst/src/pt/up/fe/specs/clava/utils/foriter/ForIterationsExpression.java index 9ec5ab26c..f13d30d63 100644 --- a/ClavaAst/src/pt/up/fe/specs/clava/utils/foriter/ForIterationsExpression.java +++ b/ClavaAst/src/pt/up/fe/specs/clava/utils/foriter/ForIterationsExpression.java @@ -1,11 +1,11 @@ /** * Copyright 2020 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,25 +13,19 @@ package pt.up.fe.specs.clava.utils.foriter; -import java.util.Optional; - import pt.up.fe.specs.clava.ClavaLog; import pt.up.fe.specs.clava.ClavaNodes; -import pt.up.fe.specs.clava.ast.expr.BinaryOperator; -import pt.up.fe.specs.clava.ast.expr.DeclRefExpr; -import pt.up.fe.specs.clava.ast.expr.Expr; -import pt.up.fe.specs.clava.ast.expr.Literal; -import pt.up.fe.specs.clava.ast.expr.UnaryOperator; +import pt.up.fe.specs.clava.ast.expr.*; import pt.up.fe.specs.clava.ast.expr.enums.BinaryOperatorKind; import pt.up.fe.specs.clava.ast.expr.enums.UnaryOperatorKind; -import pt.up.fe.specs.clava.ast.stmt.ExprStmt; import pt.up.fe.specs.clava.ast.stmt.ForStmt; -import pt.up.fe.specs.clava.ast.stmt.Stmt; import pt.up.fe.specs.clava.ast.type.BuiltinType; import pt.up.fe.specs.clava.ast.type.Type; import pt.up.fe.specs.clava.utils.Typable; import pt.up.fe.specs.util.exceptions.NotImplementedException; +import java.util.Optional; + public class ForIterationsExpression { // private final VarDecl iterVar; @@ -42,7 +36,7 @@ public class ForIterationsExpression { private final ConditionData conditionData; public ForIterationsExpression(String iterVarName, Type iterVarType, Expr initExpr, - StepData stepData, ConditionData conditionData) { + StepData stepData, ConditionData conditionData) { // this.iterVar = iterVar; this.iterVarName = iterVarName; this.iterVarType = iterVarType; @@ -119,14 +113,14 @@ private Expr getBoundary(boolean isStart) { Expr boundary = null; switch (stepData.getDirection()) { - case INC: - boundary = isStart ? initExpr : conditionData.getValue(); - break; - case DEC: - boundary = isStart ? conditionData.getValue() : initExpr; - break; - default: - throw new NotImplementedException(stepData.getDirection()); + case INC: + boundary = isStart ? initExpr : conditionData.getValue(); + break; + case DEC: + boundary = isStart ? conditionData.getValue() : initExpr; + break; + default: + throw new NotImplementedException(stepData.getDirection()); } // Add parenthesis, if necessary @@ -175,7 +169,7 @@ public static Optional newInstance(ForStmt forStmt) { } // Get step value and step direction - var stepData = forStmt.getInc().flatMap(incStmt -> getStepData(incStmt, iterVarName)).orElse(null); + var stepData = forStmt.getInc().flatMap(incExpr -> getStepData(incExpr, iterVarName)).orElse(null); if (stepData == null) { ClavaLog.debug( "ForIterationsExpression: could not determine step data of 'for' at " + forStmt.getLocation()); @@ -209,18 +203,18 @@ private static boolean verify(ForIterationsExpression forIterations) { // LT and LE should only be used with INC, GT and GE should only be used with DEC switch (forIterations.getStepData().getDirection()) { - case INC: - if (condRelation == ForCondRelation.GE || condRelation == ForCondRelation.GT) { - ClavaLog.debug(() -> "ForIterationsExpression: cannot use > or >= in condition when step increases"); - return false; - } - break; - case DEC: - if (condRelation == ForCondRelation.LE || condRelation == ForCondRelation.LT) { - ClavaLog.debug(() -> "ForIterationsExpression: cannot use < or <= in condition when step decreases"); - return false; - } - break; + case INC: + if (condRelation == ForCondRelation.GE || condRelation == ForCondRelation.GT) { + ClavaLog.debug(() -> "ForIterationsExpression: cannot use > or >= in condition when step increases"); + return false; + } + break; + case DEC: + if (condRelation == ForCondRelation.LE || condRelation == ForCondRelation.LT) { + ClavaLog.debug(() -> "ForIterationsExpression: cannot use < or <= in condition when step decreases"); + return false; + } + break; } // LE and GE are only supported when iteration variable in an integer @@ -249,15 +243,8 @@ private static boolean verify(ForIterationsExpression forIterations) { return true; } - private static Optional getConditionData(Stmt conditionStmt, String iterVarName) { + private static Optional getConditionData(Expr condExpr, String iterVarName) { - // Only supports ExprStmt - if (!(conditionStmt instanceof ExprStmt)) { - ClavaLog.debug(() -> "ForIterationsExpression: cond statement is not an ExprStmt, " + conditionStmt); - return Optional.empty(); - } - - var condExpr = ((ExprStmt) conditionStmt).getExpr(); if (!(condExpr instanceof BinaryOperator)) { ClavaLog.debug(() -> "ForIterationsExpression: cond expr is not a binary operator, " + condExpr); @@ -285,19 +272,19 @@ private static Optional getConditionData(Stmt conditionStmt, Stri private static ForCondRelation getCondRelation(BinaryOperatorKind op, int iterVarIndex) { switch (op) { - case LT: - return iterVarIndex == 0 ? ForCondRelation.LT : ForCondRelation.GT; - case GT: - return iterVarIndex == 0 ? ForCondRelation.GT : ForCondRelation.LT; - case LE: - return iterVarIndex == 0 ? ForCondRelation.LE : ForCondRelation.GE; - case GE: - return iterVarIndex == 0 ? ForCondRelation.GE : ForCondRelation.LE; - default: - ClavaLog.debug( - () -> "ForIterationsExpression: unsupported binary operator in condition expression, " - + op.getOpString()); - return null; + case LT: + return iterVarIndex == 0 ? ForCondRelation.LT : ForCondRelation.GT; + case GT: + return iterVarIndex == 0 ? ForCondRelation.GT : ForCondRelation.LT; + case LE: + return iterVarIndex == 0 ? ForCondRelation.LE : ForCondRelation.GE; + case GE: + return iterVarIndex == 0 ? ForCondRelation.GE : ForCondRelation.LE; + default: + ClavaLog.debug( + () -> "ForIterationsExpression: unsupported binary operator in condition expression, " + + op.getOpString()); + return null; } } @@ -333,15 +320,7 @@ private static int getVarIndex(String varName, BinaryOperator expr) { return -1; } - private static Optional getStepData(Stmt incStmt, String iterVarName) { - - // Only supports ExprStmt - if (!(incStmt instanceof ExprStmt)) { - ClavaLog.debug(() -> "ForIterationsExpression: step statement is not an ExprStmt, " + incStmt); - return Optional.empty(); - } - - var incExpr = ((ExprStmt) incStmt).getExpr(); + private static Optional getStepData(Expr incExpr, String iterVarName) { // var += incr // var -= incr diff --git a/ClavaLaraApi/src-lara/clava/Joinpoints.js b/ClavaLaraApi/src-lara/clava/Joinpoints.js index 695d2adf4..f97853f03 100644 --- a/ClavaLaraApi/src-lara/clava/Joinpoints.js +++ b/ClavaLaraApi/src-lara/clava/Joinpoints.js @@ -1807,13 +1807,17 @@ export class Loop extends Statement { get body() { return wrapJoinPoint(this._javaObject.getBody()); } set body(value) { this._javaObject.setBody(unwrapJoinPoint(value)); } /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ get cond() { return wrapJoinPoint(this._javaObject.getCond()); } /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ set cond(value) { this._javaObject.setCond(unwrapJoinPoint(value)); } + /** + * The expression of the loop condition + */ + get condExpr() { return wrapJoinPoint(this._javaObject.getCondExpr()); } get condRelation() { return wrapJoinPoint(this._javaObject.getCondRelation()); } set condRelation(value) { this._javaObject.setCondRelation(unwrapJoinPoint(value)); } get controlVar() { return wrapJoinPoint(this._javaObject.getControlVar()); } @@ -1860,13 +1864,17 @@ export class Loop extends Statement { get nestedLevel() { return wrapJoinPoint(this._javaObject.getNestedLevel()); } get rank() { return wrapJoinPoint(this._javaObject.getRank()); } /** - * The statement of the loop step + * (deprecated) The expression of the loop step wrapped around a new exprStmt */ get step() { return wrapJoinPoint(this._javaObject.getStep()); } /** - * The statement of the loop step + * (deprecated) The expression of the loop step wrapped around a new exprStmt */ set step(value) { this._javaObject.setStep(unwrapJoinPoint(value)); } + /** + * The expression of the loop step + */ + get stepExpr() { return wrapJoinPoint(this._javaObject.getStepExpr()); } /** * The expression of the iteration step */ diff --git a/ClavaLaraApi/src-lara/clava/clava/ClavaJoinPoints.js b/ClavaLaraApi/src-lara/clava/clava/ClavaJoinPoints.js index 2a12aa326..25860ed88 100644 --- a/ClavaLaraApi/src-lara/clava/clava/ClavaJoinPoints.js +++ b/ClavaLaraApi/src-lara/clava/clava/ClavaJoinPoints.js @@ -395,10 +395,10 @@ export default class ClavaJoinPoints { $init = ClavaJoinPoints.stmtLiteral($init); } if (typeof $condition === "string") { - $condition = ClavaJoinPoints.stmtLiteral($condition); + $condition = ClavaJoinPoints.exprLiteral($condition); } if (typeof $inc === "string") { - $inc = ClavaJoinPoints.stmtLiteral($inc); + $inc = ClavaJoinPoints.exprLiteral($inc); } if (typeof $body === "string") { $body = ClavaJoinPoints.stmtLiteral($body); diff --git a/ClavaLaraApi/src-lara/clava/clava/graphs/cfg/CfgBuilder.js b/ClavaLaraApi/src-lara/clava/clava/graphs/cfg/CfgBuilder.js index ebb89ebf6..b3f1f3617 100644 --- a/ClavaLaraApi/src-lara/clava/clava/graphs/cfg/CfgBuilder.js +++ b/ClavaLaraApi/src-lara/clava/clava/graphs/cfg/CfgBuilder.js @@ -296,7 +296,7 @@ export default class CfgBuilder { if ($loop === undefined) { throw new Error("Loop is undefined"); } - const $afterStmt = $loop.kind === "for" ? $loop.step : $loop.cond; + const $afterStmt = $loop.kind === "for" ? $loop.stepExpr : $loop.condExpr; const afterNode = this.nodes.get($afterStmt.astId) ?? this.endNode; this.addEdge(node, afterNode, CfgEdgeType.UNCONDITIONAL); } diff --git a/ClavaWeaver/resources/clava/test/api/ClavaJoinPointsTest.js b/ClavaWeaver/resources/clava/test/api/ClavaJoinPointsTest.js index 2e34df871..9d94fc024 100644 --- a/ClavaWeaver/resources/clava/test/api/ClavaJoinPointsTest.js +++ b/ClavaWeaver/resources/clava/test/api/ClavaJoinPointsTest.js @@ -47,7 +47,7 @@ println( println("Empty for:\n" + ClavaJoinPoints.forStmt().code); println( "Complete for:\n" + - ClavaJoinPoints.forStmt("int i=0;", "i<10;", "i++;", "i = i+1;\ni = i - 1;") + ClavaJoinPoints.forStmt("int i=0;", "i<10", "i++", "i = i+1;\ni = i - 1;") .code ); diff --git a/ClavaWeaver/resources/clava/test/api/cpp/results/Code2VecTest.js.txt b/ClavaWeaver/resources/clava/test/api/cpp/results/Code2VecTest.js.txt index a62178157..0bffa663f 100644 --- a/ClavaWeaver/resources/clava/test/api/cpp/results/Code2VecTest.js.txt +++ b/ClavaWeaver/resources/clava/test/api/cpp/results/Code2VecTest.js.txt @@ -1,55 +1,55 @@ Warning: using laraImport() for file 'JoinPointsCommonPath.js', however it does not define a variable or class 'JoinPointsCommonPath' -decl (up) file (down) decl +decl (up) file (down) decl __________________________________ -decl (up) file (down) function (down) param +decl (up) file (down) function (down) param __________________________________ -decl (up) file (down) function (down) stmt (down) stmt (down) varDecl (down) expr +decl (up) file (down) function (down) stmt (down) stmt (down) varDecl (down) expr __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr +decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) expr (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) expr (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) stmt (down) varRef +decl (up) file (down) function (down) stmt (down) stmt (down) varRef __________________________________ -decl (up) file (down) decl +decl (up) file (down) decl __________________________________ -decl (up) file (down) function (down) param +decl (up) file (down) function (down) param __________________________________ -decl (up) file (down) function (down) stmt (down) stmt (down) varDecl (down) expr +decl (up) file (down) function (down) stmt (down) stmt (down) varDecl (down) expr __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr +decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) expr (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) expr (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef +decl (up) file (down) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef __________________________________ -decl (up) file (down) function (down) stmt (down) stmt (down) varRef +decl (up) file (down) function (down) stmt (down) stmt (down) varRef __________________________________ -param (up) function (down) stmt (down) stmt (down) varDecl (down) expr +param (up) function (down) stmt (down) stmt (down) varDecl (down) expr __________________________________ -param (up) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr +param (up) function (down) stmt (down) loop (down) stmt (down) varDecl (down) expr __________________________________ -param (up) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +param (up) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -param (up) function (down) stmt (down) loop (down) stmt (down) binary (down) varRef +param (up) function (down) stmt (down) loop (down) binary (down) varRef __________________________________ -param (up) function (down) stmt (down) loop (down) stmt (down) expr (down) varRef +param (up) function (down) stmt (down) loop (down) expr (down) varRef __________________________________ -param (up) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef +param (up) function (down) stmt (down) loop (down) stmt (down) stmt (down) expr (down) varRef __________________________________ -param (up) function (down) stmt (down) stmt (down) varRef +param (up) function (down) stmt (down) stmt (down) varRef __________________________________ -varRef (up) binary (down) varRef -__________________________________ -varRef (up) binary (down) varRef +varRef (up) binary (down) varRef __________________________________ +varRef (up) binary (down) varRef +__________________________________ \ No newline at end of file diff --git a/ClavaWeaver/resources/clava/test/weaver/c/results/NullNodes.lara.txt b/ClavaWeaver/resources/clava/test/weaver/c/results/NullNodes.lara.txt index 5cbb0cdb7..62fbccf7b 100644 --- a/ClavaWeaver/resources/clava/test/weaver/c/results/NullNodes.lara.txt +++ b/ClavaWeaver/resources/clava/test/weaver/c/results/NullNodes.lara.txt @@ -1,8 +1,6 @@ code : int i; astName : DeclStmt code : int A[100]; astName : DeclStmt code : i = 0; astName : ExprStmt - code : i < 100; astName : ExprStmt - code : i++; astName : ExprStmt code : A[i] = i; astName : ExprStmt code : return 0; diff --git a/ClavaWeaver/resources/clava/test/weaver/c/results/Scope.js.txt b/ClavaWeaver/resources/clava/test/weaver/c/results/Scope.js.txt index 267c3eab0..af80fe9a2 100644 --- a/ClavaWeaver/resources/clava/test/weaver/c/results/Scope.js.txt +++ b/ClavaWeaver/resources/clava/test/weaver/c/results/Scope.js.txt @@ -1,2 +1,2 @@ -numStatements (depth): 9 +numStatements (depth): 7 numStatements (flat): 3 \ No newline at end of file diff --git a/ClavaWeaver/resources/clava/test/weaver/cpp/results/GlobalAttributes.lara.txt b/ClavaWeaver/resources/clava/test/weaver/cpp/results/GlobalAttributes.lara.txt index 34305e5cf..2fac4cf82 100644 --- a/ClavaWeaver/resources/clava/test/weaver/cpp/results/GlobalAttributes.lara.txt +++ b/ClavaWeaver/resources/clava/test/weaver/cpp/results/GlobalAttributes.lara.txt @@ -12,20 +12,16 @@ intLiteral -> 0 declStmt -> int i = 0; vardecl -> int i = 0 intLiteral -> 0 -exprStmt -> i < 10; binaryOp -> i < 10 varref -> i intLiteral -> 10 -exprStmt -> i++; unaryOp -> i++ varref -> i declStmt -> int j = 0; vardecl -> int j = 0 intLiteral -> 0 -exprStmt -> j < 10; binaryOp -> j < 10 varref -> j intLiteral -> 10 -exprStmt -> j++; unaryOp -> j++ varref -> j \ No newline at end of file diff --git a/ClavaWeaver/resources/clava/weaverspecs/artifacts.xml b/ClavaWeaver/resources/clava/weaverspecs/artifacts.xml index 8ef4655bc..29f54eacb 100644 --- a/ClavaWeaver/resources/clava/weaverspecs/artifacts.xml +++ b/ClavaWeaver/resources/clava/weaverspecs/artifacts.xml @@ -371,8 +371,12 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ tooltip="The expression of the first value of the control variable (e.g. '0' in 'size_t i = 0;')"> - - + + + + diff --git a/ClavaWeaver/resources/clava/weaverspecs/joinPointModel.xml b/ClavaWeaver/resources/clava/weaverspecs/joinPointModel.xml index 4873accb5..b796b6420 100644 --- a/ClavaWeaver/resources/clava/weaverspecs/joinPointModel.xml +++ b/ClavaWeaver/resources/clava/weaverspecs/joinPointModel.xml @@ -13,49 +13,49 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ + tooltip="Utility joinpoint, to represent empty nodes when directly accessing the tree"/> + tooltip="Utility joinpoint, to represent certain problems when generating join points"/> - - - - - - - - - + + + + + + + + tooltip="Represents an include directive (e.g., #include <stdio.h>)"> - + tooltip="Represents a member of a struct/union/class"> @@ -66,64 +66,64 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - - - + tooltip="A pragma that references a point in the code and sticks to it"> + tooltip="Represents an OpenMP pragma (e.g., #pragma omp parallel)"> + tooltip="Represents one declaration (e.g., int foo(){return 0;}) or definition (e.g., int foo();) in the code"/> - + + tooltip="Represents a decl that comes from a declarator (e.g., function, field, variable)"/> - + tooltip="Base node for declarations which introduce a typedef-name"> + tooltip="Declaration of a typedef-name via the 'typedef' type specifier"> - @@ -145,16 +145,16 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - - + + tooltip="Represents a C++ class method declaration or definition"> @@ -166,20 +166,20 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - - - - - - - - + + + + + + @@ -189,41 +189,41 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - - - - - - - - + + + + + + + - - + + - - - + + @@ -233,40 +233,40 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - - + - + - + - + - + - + - + - + - + - + @@ -283,20 +283,20 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - + - - - + @@ -310,7 +310,7 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - @@ -318,66 +318,66 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ - + - + + tooltip="expression of the array access subscript"/> - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + @@ -435,7 +435,7 @@ https://docs.google.com/document/d/1uPrvuVBXHSbjDTfehpEeLDz9hgIr8EuJJJvBc5A70rs/ + tooltip="Represents a type that was referred to using an elaborated type keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, or both. This type is used to keep track of a type name as written in the source code, including tag keywords and any nested-name-specifiers. The type itself is always 'sugar', used to express what was written in the source code but containing no additional semantic information."> diff --git a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/CxxWeaver.json b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/CxxWeaver.json index 78839ead0..8b039cd99 100644 --- a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/CxxWeaver.json +++ b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/CxxWeaver.json @@ -15683,13 +15683,22 @@ }, { "type": "attribute", - "tooltip": "The statement of the loop condition", + "tooltip": "(deprecated) The expression of the loop condition wrapped around a new exprStmt", "children": [ { - "type": "statement", + "type": "expression", "name": "cond" }] }, + { + "type": "attribute", + "tooltip": "The expression of the loop condition", + "children": [ + { + "type": "expression", + "name": "condExpr" + }] + }, { "type": "attribute", "children": [ @@ -15831,13 +15840,22 @@ }, { "type": "attribute", - "tooltip": "The statement of the loop step", + "tooltip": "(deprecated) The expression of the loop step wrapped around a new exprStmt", "children": [ { - "type": "statement", + "type": "expression", "name": "step" }] }, + { + "type": "attribute", + "tooltip": "The expression of the loop step", + "children": [ + { + "type": "expression", + "name": "stepExpr" + }] + }, { "type": "attribute", "tooltip": "The expression of the iteration step", @@ -53466,13 +53484,22 @@ }, { "type": "attribute", - "tooltip": "The statement of the loop condition", + "tooltip": "(deprecated) The expression of the loop condition wrapped around a new exprStmt", "children": [ { - "type": "statement", + "type": "expression", "name": "cond" }] }, + { + "type": "attribute", + "tooltip": "The expression of the loop condition", + "children": [ + { + "type": "expression", + "name": "condExpr" + }] + }, { "type": "attribute", "children": [ @@ -53614,13 +53641,22 @@ }, { "type": "attribute", - "tooltip": "The statement of the loop step", + "tooltip": "(deprecated) The expression of the loop step wrapped around a new exprStmt", "children": [ { - "type": "statement", + "type": "expression", "name": "step" }] }, + { + "type": "attribute", + "tooltip": "The expression of the loop step", + "children": [ + { + "type": "expression", + "name": "stepExpr" + }] + }, { "type": "attribute", "tooltip": "The expression of the iteration step", diff --git a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ACilkFor.java b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ACilkFor.java index 341b87de4..49a2491fd 100644 --- a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ACilkFor.java +++ b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ACilkFor.java @@ -147,19 +147,37 @@ public String getInitValueImpl() { * @return the attribute's value */ @Override - public AStatement getCondImpl() { + public AExpression getCondImpl() { return this.aLoop.getCondImpl(); } + /** + * Get value on attribute condExpr + * @return the attribute's value + */ + @Override + public AExpression getCondExprImpl() { + return this.aLoop.getCondExprImpl(); + } + /** * Get value on attribute step * @return the attribute's value */ @Override - public AStatement getStepImpl() { + public AExpression getStepImpl() { return this.aLoop.getStepImpl(); } + /** + * Get value on attribute stepExpr + * @return the attribute's value + */ + @Override + public AExpression getStepExprImpl() { + return this.aLoop.getStepExprImpl(); + } + /** * Get value on attribute endValue * @return the attribute's value @@ -1559,7 +1577,9 @@ protected enum CilkForAttributes { INIT("init"), INITVALUE("initValue"), COND("cond"), + CONDEXPR("condExpr"), STEP("step"), + STEPEXPR("stepExpr"), ENDVALUE("endValue"), STEPVALUE("stepValue"), HASCONDRELATION("hasCondRelation"), diff --git a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ALoop.java b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ALoop.java index 042fa06a6..ac5b16f45 100644 --- a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ALoop.java +++ b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/abstracts/joinpoints/ALoop.java @@ -388,19 +388,19 @@ public void defInitValueImpl(String value) { } /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ - public abstract AStatement getCondImpl(); + public abstract AExpression getCondImpl(); /** - * The statement of the loop condition + * (deprecated) The expression of the loop condition wrapped around a new exprStmt */ public final Object getCond() { try { if(hasListeners()) { eventTrigger().triggerAttribute(Stage.BEGIN, this, "cond", Optional.empty()); } - AStatement result = this.getCondImpl(); + AExpression result = this.getCondImpl(); if(hasListeners()) { eventTrigger().triggerAttribute(Stage.END, this, "cond", Optional.ofNullable(result)); } @@ -411,19 +411,42 @@ public final Object getCond() { } /** - * The statement of the loop step + * The expression of the loop condition */ - public abstract AStatement getStepImpl(); + public abstract AExpression getCondExprImpl(); /** - * The statement of the loop step + * The expression of the loop condition + */ + public final Object getCondExpr() { + try { + if(hasListeners()) { + eventTrigger().triggerAttribute(Stage.BEGIN, this, "condExpr", Optional.empty()); + } + AExpression result = this.getCondExprImpl(); + if(hasListeners()) { + eventTrigger().triggerAttribute(Stage.END, this, "condExpr", Optional.ofNullable(result)); + } + return result!=null?result:getUndefinedValue(); + } catch(Exception e) { + throw new AttributeException(get_class(), "condExpr", e); + } + } + + /** + * (deprecated) The expression of the loop step wrapped around a new exprStmt + */ + public abstract AExpression getStepImpl(); + + /** + * (deprecated) The expression of the loop step wrapped around a new exprStmt */ public final Object getStep() { try { if(hasListeners()) { eventTrigger().triggerAttribute(Stage.BEGIN, this, "step", Optional.empty()); } - AStatement result = this.getStepImpl(); + AExpression result = this.getStepImpl(); if(hasListeners()) { eventTrigger().triggerAttribute(Stage.END, this, "step", Optional.ofNullable(result)); } @@ -433,6 +456,29 @@ public final Object getStep() { } } + /** + * The expression of the loop step + */ + public abstract AExpression getStepExprImpl(); + + /** + * The expression of the loop step + */ + public final Object getStepExpr() { + try { + if(hasListeners()) { + eventTrigger().triggerAttribute(Stage.BEGIN, this, "stepExpr", Optional.empty()); + } + AExpression result = this.getStepExprImpl(); + if(hasListeners()) { + eventTrigger().triggerAttribute(Stage.END, this, "stepExpr", Optional.ofNullable(result)); + } + return result!=null?result:getUndefinedValue(); + } catch(Exception e) { + throw new AttributeException(get_class(), "stepExpr", e); + } + } + /** * The expression of the last value of the control variable (e.g. 'length' in 'i < length;') */ @@ -2021,7 +2067,9 @@ protected void fillWithAttributes(List attributes) { attributes.add("init"); attributes.add("initValue"); attributes.add("cond"); + attributes.add("condExpr"); attributes.add("step"); + attributes.add("stepExpr"); attributes.add("endValue"); attributes.add("stepValue"); attributes.add("hasCondRelation"); @@ -2099,7 +2147,9 @@ protected enum LoopAttributes { INIT("init"), INITVALUE("initValue"), COND("cond"), + CONDEXPR("condExpr"), STEP("step"), + STEPEXPR("stepExpr"), ENDVALUE("endValue"), STEPVALUE("stepValue"), HASCONDRELATION("hasCondRelation"), diff --git a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/importable/AstFactory.java b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/importable/AstFactory.java index b55d84a72..d4730ea98 100644 --- a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/importable/AstFactory.java +++ b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/importable/AstFactory.java @@ -721,19 +721,19 @@ public static AAccessSpecifier accessSpecifier(String accessSpecifierString) { return CxxJoinpoints.create(accessSpecifierDecl, AAccessSpecifier.class); } - public static ALoop forStmt(AStatement init, AStatement condition, AStatement inc, AStatement body) { + public static ALoop forStmt(AStatement init, AExpression condition, AExpression inc, AStatement body) { // If null, create NullStmt var initStmt = init != null ? (Stmt) init.getNode() : CxxWeaver.getFactory().nullStmt(); - var condStmt = condition != null ? (Stmt) condition.getNode() : CxxWeaver.getFactory().nullStmt(); - var incStmt = inc != null ? (Stmt) inc.getNode() : CxxWeaver.getFactory().nullStmt(); + var condExpr = condition != null ? (Expr) condition.getNode() : null; + var incExpr = inc != null ? (Expr) inc.getNode() : null; var bodyStmt = body != null ? (Stmt) body.getNode() : CxxWeaver.getFactory().nullStmt(); // If body is not a CompoundStmt, make it var compoundStmt = ClavaNodes.toCompoundStmt(bodyStmt); - var forStmt = CxxWeaver.getFactory().forStmt(initStmt, condStmt, incStmt, compoundStmt); + var forStmt = CxxWeaver.getFactory().forStmt(initStmt, condExpr, incExpr, compoundStmt); return CxxJoinpoints.create(forStmt, ALoop.class); } diff --git a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/joinpoints/CxxLoop.java b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/joinpoints/CxxLoop.java index 10bea3947..836d20cc6 100644 --- a/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/joinpoints/CxxLoop.java +++ b/ClavaWeaver/src/pt/up/fe/specs/clava/weaver/joinpoints/CxxLoop.java @@ -1,11 +1,11 @@ /** * Copyright 2016 SPeCS. - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. under the License. @@ -13,32 +13,14 @@ package pt.up.fe.specs.clava.weaver.joinpoints; -import java.util.Arrays; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import org.lara.interpreter.utils.DefMap; - import com.google.common.base.Preconditions; - +import org.lara.interpreter.utils.DefMap; import pt.up.fe.specs.clava.ClavaLog; import pt.up.fe.specs.clava.ClavaNode; import pt.up.fe.specs.clava.ClavaNodes; import pt.up.fe.specs.clava.ast.expr.BinaryOperator; import pt.up.fe.specs.clava.ast.expr.enums.BinaryOperatorKind; -import pt.up.fe.specs.clava.ast.stmt.CXXForRangeStmt; -import pt.up.fe.specs.clava.ast.stmt.CompoundStmt; -import pt.up.fe.specs.clava.ast.stmt.DoStmt; -import pt.up.fe.specs.clava.ast.stmt.ForStmt; -import pt.up.fe.specs.clava.ast.stmt.LiteralStmt; -import pt.up.fe.specs.clava.ast.stmt.LoopStmt; -import pt.up.fe.specs.clava.ast.stmt.Stmt; -import pt.up.fe.specs.clava.ast.stmt.WhileStmt; +import pt.up.fe.specs.clava.ast.stmt.*; import pt.up.fe.specs.clava.ast.type.Type; import pt.up.fe.specs.clava.ast.type.enums.BuiltinKind; import pt.up.fe.specs.clava.transform.loop.LoopAnalysisUtils; @@ -46,10 +28,7 @@ import pt.up.fe.specs.clava.transform.loop.LoopTiling; import pt.up.fe.specs.clava.weaver.CxxJoinpoints; import pt.up.fe.specs.clava.weaver.CxxWeaver; -import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.AExpression; -import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.ALoop; -import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.AScope; -import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.AStatement; +import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.*; import pt.up.fe.specs.clava.weaver.abstracts.joinpoints.enums.ALoopKindEnum; import pt.up.fe.specs.clava.weaver.defs.CxxLoopDefs; import pt.up.fe.specs.clava.weaver.enums.Relation; @@ -58,6 +37,8 @@ import pt.up.fe.specs.util.lazy.Lazy; import pt.up.fe.specs.util.lazy.ThreadSafeLazy; +import java.util.*; + public class CxxLoop extends ALoop { private static final Lazy, ALoopKindEnum>> LOOP_TYPE = new ThreadSafeLazy<>( @@ -250,6 +231,13 @@ public AStatement getCondImpl() { return CxxJoinpoints.create(ClavaNodes.toStmt(condition), AStatement.class); } + @Override + public AExpression getCondExprImpl() { + return loop.getStmtCondExpr() + .map(expr -> CxxJoinpoints.create(expr, AExpression.class)) + .orElse(null); + } + @Override public List selectStep() { var step = getStepImpl(); @@ -258,18 +246,23 @@ public List selectStep() { } @Override - public AStatement getStepImpl() { + public AExpression getStepImpl() { if (!(loop instanceof ForStmt)) { return null; } - Stmt inc = ((ForStmt) loop).getInc().orElse(null); + var inc = ((ForStmt) loop).getInc().orElse(null); if (inc == null) { return null; } - return CxxJoinpoints.create(inc, AStatement.class); + return CxxJoinpoints.create(inc, AExpression.class); + } + + @Override + public AExpression getStepExprImpl() { + return getStepImpl(); } @Override @@ -330,11 +323,11 @@ public void setKindImpl(String kind) { } switch (loopKind) { - case WHILE: - convertToWhile(); - break; - default: - throw new RuntimeException("Not implemented: " + loopKind); + case WHILE: + convertToWhile(); + break; + default: + throw new RuntimeException("Not implemented: " + loopKind); } } @@ -351,7 +344,10 @@ private void convertToWhile() { // WhileStmt whileStmt = ClavaNodeFactory.whileStmt(loop.getInfo(), ((ForStmt) loop).getCond().orElse(null), // loop.getBody()); - Stmt cond = ((ForStmt) loop).getCond().orElse(CxxWeaver.getFactory().nullStmt()); + Stmt cond = ((ForStmt) loop).getCond() + .map(expr -> (Stmt) getFactory().exprStmt(expr)) + .orElse(CxxWeaver.getFactory().nullStmt()); + WhileStmt whileStmt = CxxWeaver.getFactory().whileStmt(cond, loop.getBody()); replaceWith(CxxJoinpoints.create(whileStmt)); @@ -634,20 +630,20 @@ public void setCondRelationImpl(String operator) { private BinaryOperatorKind getOpKind(Relation relation) { switch (relation) { - case EQ: - return BinaryOperatorKind.EQ; - case GE: - return BinaryOperatorKind.GE; - case GT: - return BinaryOperatorKind.GT; - case LE: - return BinaryOperatorKind.LE; - case LT: - return BinaryOperatorKind.LT; - case NE: - return BinaryOperatorKind.NE; - default: - throw new NotImplementedException(relation); + case EQ: + return BinaryOperatorKind.EQ; + case GE: + return BinaryOperatorKind.GE; + case GT: + return BinaryOperatorKind.GT; + case LE: + return BinaryOperatorKind.LE; + case LT: + return BinaryOperatorKind.LT; + case NE: + return BinaryOperatorKind.NE; + default: + throw new NotImplementedException(relation); } }