// $Id: OMPanalyzeDecl.java,v 1.5 2000/10/10 03:40:49 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.openmp;

import exc.object.*;
import exc.block.*;
import java.util.Vector;

public class OMPanalyzeDecl implements OMPfileEnv {
  protected XobjectFile env;
  Vector thdprv_vars = new Vector();

  public OMPanalyzeDecl(){ }

  public OMPanalyzeDecl(XobjectFile env){
    this.env = env;
  }

  public void init(XobjectFile env){
    this.env = env;
  }

  public XobjectFile getFile() { return env; }

  public void analyze(XobjectDef d){
      Xobject x = d.getDef();
      if(x.Opcode() == Xcode.OMP_PRAGMA){
	if(x.getArg(0).getInt() != OMP.THREADPRIVATE)
	  OMP.fatal("not threadprivate in decl");
	declThreadPrivate(x.getArg(1));
      }
  }

  // declare threadprivate variables
  public void declThreadPrivate(Xobject args){
    Xtype voidP_t = Xtype.Pointer(BasicType.voidType);
    for(XobjArgs a = args.getArgs(); a != null; a = a.nextArgs()){
      Ident id = env.findIdent(a.getArg().getName());
      if(id == null){
	OMP.fatal("undefined variable '"+a.getArg().getName()+
		  "'in threadprivate directive");
	continue;
      }
      
      if(isThreadPrivate(id)) continue;	// already defined as threadprivate
      thdprv_vars.addElement(id);

      OMP.setThreadPrivate(id);
      if(OMP.leaveThreadPrivateFlag) continue;

      // declare threadprivate pointer table
      String thdprv_name = "_thdprv_"+id.getName();
      switch(id.getStorageClass()){
      case StorageClass.EXTDEF:
	env.declGlobalIdent(thdprv_name,voidP_t);
	break;
      case StorageClass.EXTERN:
	env.declExternIdent(thdprv_name,voidP_t);
	break;
      case StorageClass.STATIC:
	env.declStaticIdent(thdprv_name,voidP_t);
	break;
      default:
	OMP.fatal("declThreadPrivate: bad class, "+id.getName());
      }
    }
  }

  public boolean isThreadPrivate(Ident id){
    if(thdprv_vars.isEmpty()) return false;
    return thdprv_vars.indexOf(id) != -1;
  }
    
  public Ident findThreadPrivate(Block b,String name){
    if(thdprv_vars.isEmpty()) return null;
    Ident id = b.findIdent(name);
    if(id == null) return null;
    if(thdprv_vars.indexOf(id) != -1) return id;
    return null;
  }
}

