// $Id: Ident.java,v 1.8 2002/02/25 17:21:37 msato Exp $
// $RWC_Release: Omni-1.6 $
// $RWC_Copyright:
//  Omni Compiler Software Version 1.5-1.6
//  Copyright (C) 2002 PC Cluster Consortium
//  
//  This software is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License version
//  2.1 published by the Free Software Foundation.
//  
//  Omni Compiler Software Version 1.0-1.4
//  Copyright (C) 1999, 2000, 2001.
//   Tsukuba Research Center, Real World Computing Partnership, Japan.
//  
//  Please check the Copyright and License information in the files named
//  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
//  Software release kit.
//  
//  
//  $
package exc.object;

//
// identifer
//
public class Ident extends Xobject {
  /* stroage class is stored as code */
  /* data type is stored as object data type */
  String name;	/* key */
  Xobject value;	/* base address expression value */
  boolean declared;	/* declared in (VAR_DECL ) */
  int num;		/* for TEMP_VAR, or bit-field */

  // constructor 
  public Ident(String name,int stg_class,Xtype type, Xobject v){
    super(stg_class,type);
    if(name != null) this.name = name.intern();
    this.value = v;
  }

  // constructor for temporary variable
  public Ident(int num,Xtype type){
    super(StorageClass.REG,type);
    this.num = num;
  }

  public int getStorageClass() { return code; }
  public void setStorageClass(int code) { this.code=code; }
  public String getName(){ 
    if(code == StorageClass.REG) return "_r_"+Integer.toHexString(num);
    else return name; 
  }
  public void setName(String name){
    this.name = name;
  }
  public Xobject getAddr() { 
    // address of array argument is the base address of array, not variable.
    if(code == StorageClass.PARAM && type.isArray()) 
      return Xcons.PointerRef(value);
    return value; 
  }
  public Xobject getValue() { return value; }
  public boolean isDeclared() { return declared; }
  public void Declared() { declared = true; }
  public int regn() { return num; }

  public void setBitField(int n){ num = n; }
  public int getBitField() { return num; }

  public Xobject copy(){
    return new Ident(name,code,type,value);
  }

  public boolean equals(Xobject x){
    /* note: id is not replicated. */
    return this == x;
  }

  public String toString(){
    if(getStorageClass() == StorageClass.REG){
      return "[0x"+Integer.toHexString(num)+" "
	+(type==null?"*":type.toString())+" () *]";
    }
    return "["+(name==null ? "*":name)+" "
+StorageClass.getName(getStorageClass())+" "
  +(type==null?"*":type.toString())+" "
  +(value==null?"()":value.toString())
  + ((num != 0) ? Integer.toString(num):"")
  + (declared ? "":" *")+"]";
  }

  // return value for refernce 'id'
  public Xobject Ref(){
    if(getStorageClass() == StorageClass.REG)
      return Xcons.Int(Xcode.REG,type,num);
    if(type.isArray() || type.isFunction()) return value;
    return Xcons.PointerRef(value);
  }

  // return value for referenece 'id[i]' == *(id + i)
  public Xobject Index(int i){
    if(type.isPointer())
      return Xcons.PointerRef(Xcons.binaryOp(Xcode.PLUS_EXPR,Ref(),
					     Xcons.IntConstant(i)));
    else fatal("Index: not Pointer");
    return null;
  }

  public Xobject Index(Xobject i){
    if(type.isPointer())
      return Xcons.PointerRef(Xcons.binaryOp(Xcode.PLUS_EXPR,Ref(),i));
    else fatal("Index: not Pointer");
    return null;
  }

  public Xobject Call(Xobject args){
    if(type.isFunction())
      return Xcons.List(Xcode.FUNCTION_CALL,type.getRef(),
			value,args);
    else fatal("Call: not Function");
    return null;
  }

  //
  // static member to construct variable
  //
  public static Ident Local(String name, Xtype t){
    if(t.isArray())
      return new Ident(name,StorageClass.AUTO,t,
		       Xcons.Symbol(Xcode.LARRAY_ADDR,
				    Xtype.Pointer(t),name));
    else
      return new Ident(name,StorageClass.AUTO,t,
		       Xcons.Symbol(Xcode.LVAR_ADDR,
				    Xtype.Pointer(t),name));
  }

  public static Ident Param(String name, Xtype t){
    if(t.isArray()){
      t = Xtype.Pointer(t.getRef());  // convert to pointer
      return new Ident(name,StorageClass.PARAM,t,
		       Xcons.Symbol(Xcode.PARAM_ADDR,
				    Xtype.Pointer(t),name));
    } else
      return new Ident(name,StorageClass.PARAM,t,
		       Xcons.Symbol(Xcode.PARAM_ADDR,
				    Xtype.Pointer(t),name));
  }

  public static Ident TempVar(int num, Xtype t){
    if(t.isArray()){
      t = Xtype.Pointer(t.getRef());  // convert to pointer
      return new Ident(num,t);
    } else  return new Ident(num,t);
  }

  static void fatal(String msg){
    System.err.println("Fatal Ident:"+msg);
    Thread.dumpStack();
    System.exit(1);
  }
}



