/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */
package cx2x.translator.transformation.claw.parallelize;

import cx2x.translator.language.ClawLanguage;
import cx2x.xcodeml.helper.XnodeUtil;
import cx2x.xcodeml.transformation.Transformation;
import cx2x.xcodeml.transformation.Transformer;
import cx2x.xcodeml.xnode.*;

/**
 * The parallelize forward transformation applies the changes in the subroutine
 * signatures to function call and function in which the call is nested if
 * needed.
 *
 * @author clementval
 */
public class ParallelizeForward extends Transformation {

  private final ClawLanguage _claw;
  private Xnode _fctCall;
  private String _fctType;
  private boolean _localFct = false;

  /**
   * Constructs a new Parallelize transformation triggered from a specific
   * pragma.
   * @param directive The directive that triggered the define transformation.
   */
  public ParallelizeForward(ClawLanguage directive) {
    super(directive);
    _claw = directive; // Keep information about the claw directive here
  }


  @Override
  public boolean analyze(XcodeProgram xcodeml, Transformer transformer) {
    Xnode ex = XnodeUtil.findDirectNext(Xcode.EXPRSTATEMENT, _claw.getPragma());
    if(ex == null){
      xcodeml.addError("Directive is not followed by a fct call.",
          _claw.getPragma().getLineNo());
      return false;
    }

    _fctCall = ex.find(Xcode.FUNCTIONCALL);
    if(_fctCall == null){
      xcodeml.addError("Directive is not followed by a fct call.",
          _claw.getPragma().getLineNo());
      return false;
    }

    _fctType = _fctCall.find(Xcode.NAME).getAttribute(Xattr.TYPE);
    XfunctionType fctType = (XfunctionType)xcodeml.getTypeTable().get(_fctType);
    if(fctType != null){
      _localFct = true;
    } else {
      // TODO check whether the function is defined in another module
      xcodeml.addError("Function signature not found in the current module.",
          _claw.getPragma().getLineNo());
      return false;
    }
    return true;
  }

  @Override
  public void transform(XcodeProgram xcodeml, Transformer transformer,
                        Transformation other) throws Exception {

  }

  @Override
  public boolean canBeTransformedWith(Transformation other) {
    return false; // independent transformation
  }
}

@@ -364,16 +364,40 @@
 ode.*;%0A%0A
+import java.util.List;%0A%0A
 /**%0A * T
@@ -2223,26 +2223,1453 @@
 ws Exception
- %7B
+%0A  %7B%0A    XfunctionDefinition fDef = XnodeUtil.findParentFunction(_claw.getPragma());%0A%0A    XfunctionType fctType = (XfunctionType)xcodeml.getTypeTable().get(_fctType);%0A    List%3CXnode%3E params = fctType.getParams().getAll();%0A    List%3CXnode%3E args = _fctCall.find(Xcode.ARGUMENTS).getChildren();%0A%0A    // 1. Adapt function call with potential new arguments%0A    for(int i = args.size(); i %3C params.size(); i++)%7B%0A      Xnode p = params.get(i);%0A      String var = p.getValue();%0A      String type;%0A      if(!fDef.getSymbolTable().contains(var))%7B%0A        // Size variable have to be declared%0A        XbasicType intTypeIntentIn = XnodeUtil.createBasicType(xcodeml,%0A            xcodeml.getTypeTable().generateIntegerTypeHash(),%0A            Xname.TYPE_F_INT, Xintent.IN);%0A        xcodeml.getTypeTable().add(intTypeIntentIn);%0A        XnodeUtil.createIdAndDecl(var,%0A            intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, fDef, xcodeml);%0A        type = intTypeIntentIn.getType();%0A      %7D else %7B%0A        type = fDef.getSymbolTable().get(var).getType();%0A      %7D%0A%0A      Xnode arg = new Xnode(Xcode.VAR, xcodeml);%0A      arg.setAttribute(Xattr.TYPE, type);%0A      arg.setAttribute(Xattr.SCOPE, Xname.SCOPE_LOCAL);%0A      arg.setValue(var);%0A      _fctCall.find(Xcode.ARGUMENTS).appendToChildren(arg, false);%0A    %7D%0A%0A%0A    // 2. Adapt function/subroutine in which the function call is nested%0A%0A    // 3. Replicate the change in a potential module file%0A
 %0A%0A  %7D%0A%0A  @Ov

Add arguments to function call