/* ---------------------------------------------------------------------
%   Copyright (C) 2007 Association for the COINS Compiler Infrastructure
%       (Read COPYING for detailed information.)
--------------------------------------------------------------------- */
package coins.sym;

import coins.SymRoot;

/** Var Class represents Variable symbols.
<PRE>
 *
 *   Sym --- Symbol class (super class of all symbol classes).
 *     |     Symbols in the same scope are contained in the same
 *     |     symbol table (instance of SymTable).
 *     |
 *     |- Var   --- Variable that can be assigned a value
 *     |    |       and variable with const attribute.
 *     |    |- Param --- Formal parameter class.		<---------- This!
 *     |    |- Elem  --- Class for structure element,
 *     |    |            union element, etc.
 *     |    |- Field --- Class for field in a class.
</PRE>
 */

/** Param Class
 *  Param class (formal parameter class) interface.
 *  Anonymous parameter should be assigned a generated name.
 **/

public class ParamImpl extends VarImpl implements Param
{
  /** Parameter index number */
  protected int
    fIndex = 0;

  /** Optional parameter generated for "..." specification */
  protected boolean
    fOptional = false;

  /** fCallByReference true if call-by-reference,
      false if call-by-value. **/
  protected boolean
    fCallByReference = false;

  ////////////////////SF030531[
  /** array parameter size. **/
  private long arrayParamSize = 0;
  // ex. func(int p[2][4],int q[][3],int *r)
  // int p[2][4] => int (*q)[4] (arrayParamSize==2)
  // int q[][3]  => int (*p)[3] (arrayParamSize==-1)
  // int *r      => not changed (arrayParamSize==0)
  ////////////////////SF030531]

public
ParamImpl( SymRoot pSymRoot )
{
  super(pSymRoot);
}

public
ParamImpl( SymRoot pSymRoot, String pParamName, Sym pDefinedIn )
{
  super(pSymRoot);
  fName = pParamName;
  fDefinedIn = pDefinedIn;
  fKind = Sym.KIND_PARAM;
}

public
ParamImpl( SymRoot pSymRoot, String pParamName, int pIndex, Sym pDefinedIn )
{
  super(pSymRoot);
  fName = pParamName;
  fIndex = pIndex;
  fKind = Sym.KIND_PARAM;
  fDefinedIn = pDefinedIn;
}

    /** getParamIndex
     *  Get parameter index.
     *  "this" should be a Param (parameter) symbol.
     *  See setNextVar(...), DefinedIn( ) which will set the index value.
     *  @return parameter index (1: first parameter, 2: second parameter,
     *      3: third parameter, etc. in DefinedIn( ) subprogram).
     **/
    public int getParamIndex( ) {
        return fIndex;
    }
    public void setParamIndex( int pIndex ) {
        fIndex = pIndex;
    }

public Param
generateOptionalParam( ) { //## DELETE
  Param lOptionalParam = symRoot.symTable.
          generateParam(symRoot.typeVoid, null);
  ((ParamImpl)lOptionalParam).fOptional = true;
  return lOptionalParam;
} // generateOptionalParam

    /** isOptionalParam      (##2)
     *  See if this is optional parameter generated for "..." specification.
     *  "this" should be a Param (parameter) symbol.
     *  @return true if this is an optional paramater generated by
     *      setOptionalParam in SubpInterface, false otherwise.
     **/
    public boolean isOptionalParam( ) {
        return fOptional;
    }
public void
markAsOptional()
{
  fOptional = true;
}

public void
markAsCallByReference()
{
  fCallByReference = true;
}

public void
markAsCallByValue()
{
  fCallByReference = false;
}

public boolean
isCallByReference()
{
  return fCallByReference;
}

public boolean
isCallByValue()
{
  return ! fCallByReference;
}

public Subp
getSubp()
{
  if (fRecordedIn != null) {
    return fRecordedIn.getSubp();
  }else
    return null;
} // getSubp

public long
getArrayParamSize() //SF030531
{
  return arrayParamSize; //SF030531
}

public void
setArrayParamSize(long s) //SF030531
{
  arrayParamSize = s; //SF030531
}

} // ParamImpl class
