Index: translator/CodeGen/CodeGenerator2.cc
===================================================================
--- translator/CodeGen/CodeGenerator2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/CodeGenerator2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,715 @@
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <list>
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+
+#include "utility.h"
+#include "UnimplementedError.h"
+
+#include "CodeGenerator2.h"
+#include "OperatorTable.h"
+#include "GenType.h"
+
+using namespace std;
+
+namespace CodeGen {
+
+  int CodeGenerator2::tabsize = 4;
+
+  CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before(os), after() { }
+
+  CodeGenerator2::CodeGenerator2(std::ostream &os, std::string init, int indent, bool infunp )
+    : cur_indent( indent ), insideFunction( infunp ), before(os), after()
+  {
+    //before << std::string( init );
+  }
+
+  CodeGenerator2::CodeGenerator2(std::ostream &os, char *init, int indent, bool infunp )
+    : cur_indent( indent ), insideFunction( infunp ), before(os), after()
+  {
+    //before << std::string( init );
+  }
+
+  CodeGenerator2::~CodeGenerator2() {
+    after.freeze( false );
+  }
+
+  string
+  mangleName( DeclarationWithType *decl ) {
+    if( decl->get_mangleName() != "" ) {
+      return decl->get_mangleName();
+    } else {
+      return decl->get_name();
+    }
+  }
+  
+  //*** Declarations
+  void CodeGenerator2::visit(FunctionDecl *functionDecl){
+  
+    handleStorageClass( functionDecl );
+    before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
+
+    // how to get this to the Functype?
+    std::list< Declaration * > olds = functionDecl->get_oldDecls();
+    if( ! olds.empty() ) {
+      before << " /* function has old declaration */";
+    }
+
+    // acceptAll( functionDecl->get_oldDecls(), *this );
+    if( functionDecl->get_statements() ) {
+      functionDecl->get_statements()->accept(*this);
+    }
+  }
+
+  void CodeGenerator2::visit(ObjectDecl *objectDecl){
+
+    handleStorageClass( objectDecl );
+    before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
+    
+    if( objectDecl->get_init() ) {
+      before << " = ";
+      objectDecl->get_init()->accept( *this );
+    }
+    if( objectDecl->get_bitfieldWidth() ) {
+      before << ":";
+      objectDecl->get_bitfieldWidth()->accept( *this );
+    }
+  }
+
+  void
+  CodeGenerator2::handleAggregate( AggregateDecl *aggDecl )
+  {
+    if ( aggDecl->get_name() != "" )
+      before << aggDecl->get_name();
+    
+    std::list< Declaration * > &memb = aggDecl->get_members();
+
+    if( ! memb.empty() ){
+      before << endl << string(cur_indent, ' ') << "{" << endl;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++){
+	before << string(cur_indent, ' '); 
+	(*i)->accept(*this);
+	before << ";" << endl;
+      }
+
+      cur_indent -= CodeGenerator2::tabsize; 
+
+      before << string(cur_indent, ' ') << "}";
+    }
+  }
+
+  void CodeGenerator2::visit( StructDecl *structDecl ){
+    before << "struct ";
+    handleAggregate( structDecl );
+  }
+
+  void 
+  CodeGenerator2::visit(UnionDecl *aggregateDecl)
+  {
+    before << "union ";
+    handleAggregate( aggregateDecl );
+  }
+  
+  void 
+  CodeGenerator2::visit(EnumDecl *aggDecl)
+  {
+    before << "enum ";
+
+    if ( aggDecl->get_name() != "" )
+      before << aggDecl->get_name();
+    
+    std::list< Declaration* > &memb = aggDecl->get_members();
+
+    if( ! memb.empty() ){
+      before << endl << "{" << endl;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++){
+        ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
+        assert( obj );
+	before << string(cur_indent, ' ') << mangleName( obj ); 
+	if( obj->get_init() ) {
+	  before << " = ";
+	  obj->get_init()->accept(*this);
+	}
+	before << "," << endl;
+      }
+
+      cur_indent -= CodeGenerator2::tabsize; 
+
+      before << "}" << endl;
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(ContextDecl *aggregateDecl)
+  {
+  }
+  
+  void 
+  CodeGenerator2::visit(TypedefDecl *typeDecl)
+  {
+    before << "typedef ";
+    before << genType( typeDecl->get_base(), typeDecl->get_name() );
+  }
+  
+  void 
+  CodeGenerator2::visit(TypeDecl *typeDecl)
+  {
+    // really, we should mutate this into something that isn't a TypeDecl
+    // but that requires large-scale changes, still to be done
+    before << "extern unsigned long " << typeDecl->get_name();
+    if( typeDecl->get_base() ) {
+      before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
+    }
+  }
+
+  //*** Initializer
+  void
+  CodeGenerator2::visit(SingleInit *init)
+  {
+    init->get_value()->accept( *this );
+  }
+
+  void
+  CodeGenerator2::visit(ListInit *init)
+  {
+    before << "{ ";
+    genCommaList( init->begin_initializers(), init->end_initializers() );
+    before << " }";
+  }
+
+  //*** Constant
+  void CodeGenerator2::visit(Constant *constant) { 
+    before << constant->get_value() ;
+  }
+
+  //*** Expressions
+  void 
+  CodeGenerator2::visit(ApplicationExpr *applicationExpr)
+  {
+    if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
+      OperatorInfo opInfo;
+      if( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
+        std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
+        switch( opInfo.type ) {
+        case OT_PREFIXASSIGN:
+        case OT_POSTFIXASSIGN:
+        case OT_INFIXASSIGN:
+        {
+          assert( arg != applicationExpr->get_args().end() );
+          if( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
+            
+            *arg = addrExpr->get_arg();
+          } else {
+            UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
+            newExpr->get_args().push_back( *arg );
+            *arg = newExpr;
+          }
+          break;
+        }
+          
+        default:
+          // do nothing
+          ;
+        }
+        
+        switch( opInfo.type ) {
+        case OT_INDEX:
+          assert( applicationExpr->get_args().size() == 2 );
+          (*arg++)->accept( *this );
+          before << "[";
+          (*arg)->accept( *this );
+          before << "]";
+          break;
+          
+        case OT_CALL:
+          // there are no intrinsic definitions of the function call operator
+          assert( false );
+          break;
+          
+        case OT_PREFIX:
+        case OT_PREFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 1 );
+          before << "(";
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_POSTFIX:
+        case OT_POSTFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 1 );
+          (*arg)->accept( *this );
+          before << opInfo.symbol;
+          break;
+
+        case OT_INFIX:
+        case OT_INFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 2 );
+          before << "(";
+          (*arg++)->accept( *this );
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_CONSTANT:
+          // there are no intrinsic definitions of 0 or 1 as functions
+          assert( false );
+        }
+      } else {
+        varExpr->accept( *this );
+        before << "(";
+        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
+        before << ")";
+      }
+    } else {
+      applicationExpr->get_function()->accept( *this );
+      before << "(";
+      genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
+      before << ")";
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(UntypedExpr *untypedExpr)
+  {
+    if( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
+      OperatorInfo opInfo;
+      if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
+        std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
+        switch( opInfo.type ) {
+        case OT_INDEX:
+          assert( untypedExpr->get_args().size() == 2 );
+          (*arg++)->accept( *this );
+          before << "[";
+          (*arg)->accept( *this );
+          before << "]";
+          break;
+          
+        case OT_CALL:
+          assert( false );
+          break;
+          
+        case OT_PREFIX:
+        case OT_PREFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 1 );
+          before << "(";
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_POSTFIX:
+        case OT_POSTFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 1 );
+          (*arg)->accept( *this );
+          before << opInfo.symbol;
+          break;
+  
+        case OT_INFIX:
+        case OT_INFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 2 );
+          before << "(";
+          (*arg++)->accept( *this );
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_CONSTANT:
+          // there are no intrinsic definitions of 0 or 1 as functions
+          assert( false );
+        }
+      } else {
+        nameExpr->accept( *this );
+        before << "(";
+        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
+        before << ")";
+      }
+    } else {
+      untypedExpr->get_function()->accept( *this );
+      before << "(";
+      genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
+      before << ")";
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(NameExpr *nameExpr)
+  {
+    OperatorInfo opInfo;
+    if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
+      assert( opInfo.type == OT_CONSTANT );
+      before << opInfo.symbol;
+    } else {
+      before << nameExpr->get_name();
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(AddressExpr *addressExpr)
+  {
+    before << "(&";
+    // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
+    if( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
+      before << mangleName( variableExpr->get_var() );
+    } else {
+      addressExpr->get_arg()->accept( *this );
+    }
+    before << ")";
+  }
+
+  void 
+  CodeGenerator2::visit(CastExpr *castExpr)
+  {
+    before << "((";
+    if( castExpr->get_results().empty() ) {
+      before << "void" ;
+    } else {
+      before << genType( castExpr->get_results().front(), "" );
+    }
+    before << ")";
+    castExpr->get_arg()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(UntypedMemberExpr *memberExpr)
+  {
+    assert( false );
+  }
+  
+  void 
+  CodeGenerator2::visit(MemberExpr *memberExpr)
+  {
+    memberExpr->get_aggregate()->accept( *this );
+    before << "." << mangleName( memberExpr->get_member() );
+  }
+  
+  void 
+  CodeGenerator2::visit(VariableExpr *variableExpr)
+  {
+    OperatorInfo opInfo;
+    if( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
+      before << opInfo.symbol;
+    } else {
+      before << mangleName( variableExpr->get_var() );
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(ConstantExpr *constantExpr)
+  {
+    assert( constantExpr->get_constant() );
+    constantExpr->get_constant()->accept( *this );
+  }
+  
+  void 
+  CodeGenerator2::visit(SizeofExpr *sizeofExpr)
+  {
+    before << "sizeof(";
+    if( sizeofExpr->get_isType() ) {
+      before << genType( sizeofExpr->get_type(), "" );
+    } else {
+      sizeofExpr->get_expr()->accept( *this );
+    }
+    before << ")";
+ }
+  
+  void 
+  CodeGenerator2::visit(LogicalExpr *logicalExpr)
+  {
+    before << "(";
+    logicalExpr->get_arg1()->accept( *this );
+    if( logicalExpr->get_isAnd() ) {
+      before << " && ";
+    } else {
+      before << " || ";
+    }
+    logicalExpr->get_arg2()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(ConditionalExpr *conditionalExpr)
+  {
+    before << "(";
+    conditionalExpr->get_arg1()->accept( *this );
+    before << " ? ";
+    conditionalExpr->get_arg2()->accept( *this );
+    before << " : ";
+    conditionalExpr->get_arg3()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(CommaExpr *commaExpr)
+  {
+    before << "(";
+    commaExpr->get_arg1()->accept( *this );
+    before << " , ";
+    commaExpr->get_arg2()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(TupleExpr *tupleExpr)
+  {
+  }
+  
+  void 
+  CodeGenerator2::visit(TypeExpr *typeExpr)
+  {
+  }
+  
+  
+  //*** Statements
+  void CodeGenerator2::visit(CompoundStmt *compoundStmt){
+    std::list<Statement*> ks = compoundStmt->get_kids();
+
+    before << endl << string(cur_indent,' ') << "{" << endl;
+
+    cur_indent += CodeGenerator2::tabsize; 
+
+    for(std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++){
+      before << string(cur_indent, ' ') << printLabels( (*i)->get_labels() )  ;
+      (*i)->accept(*this);
+      shift_left();
+      before << endl;
+    }
+    cur_indent -= CodeGenerator2::tabsize; 
+
+    before << string(cur_indent,' ') << "}" << endl;
+  }
+
+  void CodeGenerator2::visit(ExprStmt *exprStmt){
+    if(exprStmt != 0){
+      exprStmt->get_expr()->accept( *this );
+      shift_left();
+      before << ";" ;
+    }
+  }
+
+  void CodeGenerator2::visit(IfStmt *ifStmt){
+    before << "if (";
+    ifStmt->get_condition()->accept(*this);
+    after << ")" << endl ;
+    shift_left(); 
+
+    cur_indent += CodeGenerator2::tabsize;
+    before << string(cur_indent, ' ');
+    ifStmt->get_thenPart()->accept(*this);
+    cur_indent -= CodeGenerator2::tabsize; 
+    shift_left(); before << endl;
+
+    if(ifStmt->get_elsePart() != 0){
+      before << string(cur_indent, ' ') << " else " << endl ;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      ifStmt->get_elsePart()->accept(*this);
+      cur_indent -= CodeGenerator2::tabsize; 
+    }
+  }
+
+  void CodeGenerator2::visit(SwitchStmt *switchStmt){
+    //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( switchStmt->get_labels() ) 
+    before << "switch (" ;
+    switchStmt->get_condition()->accept(*this);
+    after << ")" << std::endl ;
+    shift_left();
+
+    before << string(cur_indent, ' ') << "{" << std::endl;
+    cur_indent += CodeGenerator2::tabsize;
+
+    std::list< Statement * > stmts = switchStmt->get_branches();
+    bool lastBreak = false; 
+
+    // horrible, horrible hack
+    if( dynamic_cast<BranchStmt *>(stmts.back()) != 0 ) {
+      lastBreak = true;
+      stmts.pop_back();
+    }
+    acceptAll(stmts, *this );
+    if ( lastBreak ) {
+      Statement *st = switchStmt->get_branches().back();
+      before << CodeGenerator2::printLabels(st->get_labels());
+      st->accept(*this);
+    }
+      
+    cur_indent -= CodeGenerator2::tabsize; 
+
+    before << /* "\r" << */ string(cur_indent, ' ') << "}" << endl ;
+  }
+
+  void CodeGenerator2::visit(CaseStmt *caseStmt){
+    before << string(cur_indent, ' ');
+    if (caseStmt->isDefault()) 
+      before << "default "  ;
+    else {
+      before << "case "  ;
+      caseStmt->get_condition()->accept(*this);
+    }
+    after << ":" << std::endl ;
+    shift_left();
+
+    std::list<Statement *> sts = caseStmt->get_statements();
+
+    cur_indent += CodeGenerator2::tabsize;
+    for(std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++){
+      before << /* "\r" << */ string(cur_indent, ' ') << printLabels( (*i)->get_labels() )  ;
+      (*i)->accept(*this);
+      shift_left();
+      before << ";" << endl;
+    }
+    cur_indent -= CodeGenerator2::tabsize;
+  }
+
+  void CodeGenerator2::visit(BranchStmt *branchStmt){
+    switch(branchStmt->get_type()){
+    case BranchStmt::Goto:
+      if( ! branchStmt->get_target().empty() )
+	before << "goto " << branchStmt->get_target();
+      else { 
+	if ( branchStmt->get_computedTarget() != 0 ) {
+	  before << "goto *";
+	  branchStmt->get_computedTarget()->accept(*this);
+	}
+      }
+      break;
+    case BranchStmt::Break:
+      before << "break";
+      break;
+    case BranchStmt::Continue:
+      before << "continue";
+      break;
+    }
+    before << ";";
+  }
+
+
+  void CodeGenerator2::visit(ReturnStmt *returnStmt){
+    before << "return ";
+
+    // xxx -- check for null expression;
+    if ( returnStmt->get_expr() ){
+      returnStmt->get_expr()->accept( *this );
+    }
+    after << ";";
+  }
+
+  void CodeGenerator2::visit(WhileStmt *whileStmt){
+    if( whileStmt->get_isDoWhile() )
+      before << "do" ;
+    else {
+      before << "while(" ;
+      whileStmt->get_condition()->accept(*this);
+      after << ")";
+    }
+    after << "{" << endl  ;
+    shift_left();
+
+    whileStmt->get_body()->accept( *this );
+
+    before << /* "\r" << */ string(cur_indent, ' ') << "}" ;
+
+    if( whileStmt->get_isDoWhile() ){
+      before << " while(" ;
+      whileStmt->get_condition()->accept(*this);
+      after << ");";
+    }
+
+    after << endl;
+  }
+
+  void CodeGenerator2::visit(ForStmt *forStmt){
+    before << "for (";
+
+    if( forStmt->get_initialization() != 0 )
+      forStmt->get_initialization()->accept( *this );
+    else
+      before << ";";
+    shift_left();
+
+    if( forStmt->get_condition() != 0 )
+      forStmt->get_condition()->accept( *this );
+    shift_left(); before << ";";
+
+    if( forStmt->get_increment() != 0 )
+      forStmt->get_increment()->accept( *this );
+    shift_left(); before << ")" << endl;
+
+    if( forStmt->get_body() != 0 ){
+      cur_indent += CodeGenerator2::tabsize; 
+      before << string(cur_indent, ' ') << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
+      forStmt->get_body()->accept( *this );
+      cur_indent -= CodeGenerator2::tabsize; 
+    }
+  }
+
+  void CodeGenerator2::visit(NullStmt *nullStmt){
+    //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( nullStmt->get_labels() );
+    before << "/* null statement */ ;";
+  }
+
+  void CodeGenerator2::visit(DeclStmt *declStmt){
+    declStmt->get_decl()->accept( *this );
+    
+    if( doSemicolon( declStmt->get_decl() ) ) {
+      after << ";";
+    }
+    shift_left();
+  }
+
+  std::string CodeGenerator2::printLabels ( std::list< Label > &l ) {
+    std::string str("");
+    l.unique();
+
+    for( std::list< Label >::iterator i = l.begin(); i != l.end(); i++)
+      str += *i + ": ";
+
+    return str;
+  }
+
+  void CodeGenerator2::shift_left(){
+    before << string(after.str(), after.pcount());
+
+    after.freeze( false );
+    after.seekp(0);
+  }
+
+  void 
+  CodeGenerator2::handleStorageClass( Declaration *decl )
+  {
+    switch( decl->get_storageClass() ) {
+    case Declaration::NoStorageClass:
+      break;
+    case Declaration::Auto:
+      break;
+    case Declaration::Static:
+      before << "static ";
+      break;
+    case Declaration::Extern:
+      before << "extern ";
+      break;
+    case Declaration::Register:
+      before << "register ";
+      break;
+    case Declaration::Fortran:
+      before << "fortran ";
+      break;
+    }
+  }
+
+} // namespace CodeGen
+
+
Index: translator/CodeGen/CodeGenerator2.h
===================================================================
--- translator/CodeGen/CodeGenerator2.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/CodeGenerator2.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,123 @@
+#ifndef CODEGENV_H
+#define CODEGENV_H
+
+#include <strstream>
+#include <list>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+namespace CodeGen {
+
+  class CodeGenerator2 : public Visitor
+    {
+    public:
+      static int tabsize;
+
+      CodeGenerator2( std::ostream &os );
+      CodeGenerator2(std::ostream &os, std::string, int indent = 0, bool infun = false );
+      CodeGenerator2(std::ostream &os, char *, int indent = 0, bool infun = false );
+
+      CodeGenerator2( CodeGenerator2 & );
+
+      virtual ~CodeGenerator2();
+
+      //*** Declaration
+      virtual void visit(StructDecl *);
+      virtual void visit(FunctionDecl *);
+      virtual void visit(ObjectDecl *);
+      virtual void visit(UnionDecl *aggregateDecl);
+      virtual void visit(EnumDecl *aggregateDecl);
+      virtual void visit(ContextDecl *aggregateDecl);
+      virtual void visit(TypedefDecl *typeDecl);
+      virtual void visit(TypeDecl *typeDecl);
+
+      //*** Initializer
+      virtual void visit(SingleInit *);
+      virtual void visit(ListInit *);
+
+      //*** Constant
+      virtual void visit(Constant *);
+
+      //*** Expression
+      virtual void visit(ApplicationExpr *applicationExpr);
+      virtual void visit(UntypedExpr *untypedExpr);
+      virtual void visit(NameExpr *nameExpr);
+      virtual void visit(AddressExpr *addressExpr);
+      virtual void visit(CastExpr *castExpr);
+      virtual void visit(UntypedMemberExpr *memberExpr);
+      virtual void visit(MemberExpr *memberExpr);
+      virtual void visit(VariableExpr *variableExpr);
+      virtual void visit(ConstantExpr *constantExpr); 
+      virtual void visit(SizeofExpr *sizeofExpr);
+      virtual void visit(LogicalExpr *logicalExpr);
+      virtual void visit(ConditionalExpr *conditionalExpr);
+      virtual void visit(CommaExpr *commaExpr);
+      virtual void visit(TupleExpr *tupleExpr);
+      virtual void visit(TypeExpr *typeExpr);
+
+      //*** Statements
+      virtual void visit(CompoundStmt *);
+      virtual void visit(ExprStmt *);
+      virtual void visit(IfStmt *);
+      virtual void visit(SwitchStmt *);
+      virtual void visit(CaseStmt *);
+      virtual void visit(BranchStmt *);
+      virtual void visit(ReturnStmt *);
+      virtual void visit(WhileStmt *);
+      virtual void visit(ForStmt *);
+      virtual void visit(NullStmt *);
+      virtual void visit(DeclStmt *); 
+
+      std::string get_string(void);
+      void add_string_left(std::string s) { before << s; }
+      void shift_left();
+      template< class Iterator > void genCommaList( Iterator begin, Iterator end );
+
+    private:
+      int cur_indent;
+      bool insideFunction;
+      std::ostream &before;
+      std::ostrstream after;
+
+      static std::string printLabels ( std::list < Label > & );
+      void handleStorageClass( Declaration *decl );
+      void handleAggregate( AggregateDecl *aggDecl );
+      void handleTypedef( NamedTypeDecl *namedType );
+
+    };
+    
+  template< class Iterator >
+  void
+  CodeGenerator2::genCommaList( Iterator begin, Iterator end )
+  {
+    if( begin == end ) return;
+    
+    for( ;; ) {
+      (*begin++)->accept( *this );
+      
+      if( begin == end ) return;
+      
+      before << ", ";
+    }
+  }
+  
+  inline bool
+  doSemicolon( Declaration* decl )
+  {
+    if( FunctionDecl* func = dynamic_cast< FunctionDecl* >( decl ) ) {
+      return !func->get_statements();
+    }
+    return true;
+  }
+  
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGENV_H */
+
+/*
+  Local Variables:
+  mode: "c++"
+  End:
+*/
Index: translator/CodeGen/FixNames.cc
===================================================================
--- translator/CodeGen/FixNames.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/FixNames.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixNames.cc,v 1.8 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#include "FixNames.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Mangler.h"
+#include "OperatorTable.h"
+
+namespace CodeGen {
+
+class FixNames : public Visitor
+{
+public:
+  virtual void visit( ObjectDecl *objectDecl );
+  virtual void visit( FunctionDecl *functionDecl );
+};
+
+void
+fixNames( std::list< Declaration* > translationUnit )
+{
+  FixNames fixer;
+  acceptAll( translationUnit, fixer );
+}
+
+void
+fixDWT( DeclarationWithType *dwt )
+{
+  if( dwt->get_name() != "" ) {
+    if( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) {
+      dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
+    }
+  }
+}
+
+void 
+FixNames::visit( ObjectDecl *objectDecl )
+{
+  Visitor::visit( objectDecl );
+  fixDWT( objectDecl );
+}
+
+void 
+FixNames::visit( FunctionDecl *functionDecl )
+{
+  Visitor::visit( functionDecl );
+  fixDWT( functionDecl );
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/FixNames.h
===================================================================
--- translator/CodeGen/FixNames.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/FixNames.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixNames.h,v 1.2 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#ifndef FIXNAMES_H
+#define FIXNAMES_H
+
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+void fixNames( std::list< Declaration* > translationUnit );
+
+} // namespace CodeGen
+
+#endif /* #ifndef FIXNAMES_H */
Index: translator/CodeGen/GenType.cc
===================================================================
--- translator/CodeGen/GenType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/GenType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,273 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenType.cc,v 1.6 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#include <strstream>
+#include <cassert>
+
+#include "GenType.h"
+#include "CodeGenerator2.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+
+namespace CodeGen {
+
+class GenType : public Visitor
+{
+public:
+  GenType( const std::string &typeString );
+  std::string get_typeString() const { return typeString; }
+  void set_typeString( const std::string &newValue ) { typeString = newValue; }
+  
+  virtual void visit( FunctionType *funcType );
+  virtual void visit( VoidType *voidType );
+  virtual void visit( BasicType *basicType );
+  virtual void visit( PointerType *pointerType );
+  virtual void visit( ArrayType *arrayType );
+  virtual void visit( StructInstType *structInst );
+  virtual void visit( UnionInstType *unionInst );
+  virtual void visit( EnumInstType *enumInst );
+  virtual void visit( TypeInstType *typeInst );
+  
+private:
+  void handleQualifiers( Type *type );
+  void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
+  
+  std::string typeString;
+};
+
+std::string
+genType( Type *type, const std::string &baseString )
+{
+  GenType gt( baseString );
+  type->accept( gt );
+  return gt.get_typeString();
+}
+
+GenType::GenType( const std::string &typeString )
+  : typeString( typeString )
+{
+}
+
+void GenType::visit(VoidType *voidType){
+  typeString = "void " + typeString;
+  handleQualifiers( voidType );
+}
+
+void GenType::visit(BasicType *basicType)
+{
+  std::string typeWords;
+  switch(basicType->get_kind()){
+  case BasicType::Bool:
+    typeWords = "bool";
+    break;
+  case BasicType::Char:
+  case BasicType::SignedChar:
+    typeWords = "char";
+    break;
+  case BasicType::UnsignedChar:
+    typeWords = "unsigned char";
+    break;
+  case BasicType::ShortSignedInt:
+    typeWords = "short";
+    break;
+  case BasicType::ShortUnsignedInt:
+    typeWords = "short unsigned";
+    break;
+  case BasicType::SignedInt:
+    typeWords = "int";
+    break;
+  case BasicType::UnsignedInt:
+    typeWords = "unsigned int";
+    break;
+  case BasicType::LongSignedInt:
+    typeWords = "long int";
+    break;
+  case BasicType::LongUnsignedInt:
+    typeWords = "long unsigned int";
+    break;
+  case BasicType::LongLongSignedInt:
+    typeWords = "long long int";
+    break;
+  case BasicType::LongLongUnsignedInt:
+    typeWords = "long long unsigned int";
+    break;
+  case BasicType::Float:
+    typeWords = "float";
+    break;
+  case BasicType::Double:
+    typeWords = "double";
+    break;
+  case BasicType::LongDouble:
+    typeWords = "long double";
+    break;
+  case BasicType::FloatComplex:
+    typeWords = "float _Complex";
+    break;
+  case BasicType::DoubleComplex:
+    typeWords = "double _Complex";
+    break;
+  case BasicType::LongDoubleComplex:
+    typeWords = "long double _Complex";
+    break;
+  case BasicType::FloatImaginary:
+    typeWords = "float _Imaginary";
+    break;
+  case BasicType::DoubleImaginary:
+    typeWords = "double _Imaginary";
+    break;
+  case BasicType::LongDoubleImaginary:
+    typeWords = "long double _Imaginary";
+    break;
+  default:
+    assert( false );
+  }
+  typeString = typeWords + " " + typeString;
+  handleQualifiers( basicType );
+}
+
+void
+GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
+{
+  std::ostrstream os;
+  if( typeString != "" ) {
+    if( typeString[ 0 ] == '*' ) {
+      os << "(" << typeString << ")";
+    } else {
+      os << typeString;
+    }
+  }
+  os << "[";
+  if( isStatic ) {
+    os << "static ";
+  }
+  if( qualifiers.isConst ) {
+    os << "const ";
+  }
+  if( qualifiers.isVolatile ) {
+    os << "volatile ";
+  }
+  if( isVarLen ) {
+    os << "*";
+  }
+  if( dimension != 0 ) {
+    CodeGenerator2 cg( os );
+    dimension->accept( cg );
+  }
+  os << "]";
+  
+  typeString = std::string( os.str(), os.pcount() );
+  
+  base->accept ( *this );
+}
+
+void GenType::visit(PointerType *pointerType) {
+  assert(pointerType->get_base() != 0);
+  if( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
+    genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
+  } else {
+    handleQualifiers( pointerType );
+    if( typeString[ 0 ] == '?' ) {
+      typeString = "* " + typeString;
+    } else {
+      typeString = "*" + typeString;
+    }
+    pointerType->get_base()->accept ( *this );
+  }
+}
+
+void GenType::visit(ArrayType *arrayType){
+  genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
+}
+
+void GenType::visit(FunctionType *funcType) {
+  std::ostrstream os;
+
+  if( typeString != "" ) {
+    if( typeString[ 0 ] == '*' ) {
+      os << "(" << typeString << ")";
+    } else {
+      os << typeString;
+    }
+  }
+  
+  /************* parameters ***************/
+
+  const std::list<DeclarationWithType*> &pars = funcType->get_parameters();
+
+  if( pars.empty() ) {
+    if( funcType->get_isVarArgs() ) {
+      os << "()";
+    } else {
+      os << "(void)";
+    }
+  } else {
+    CodeGenerator2 cg( os );
+    os << "(" ;
+
+    cg.genCommaList( pars.begin(), pars.end() );
+    
+    if( funcType->get_isVarArgs() ){
+      os << ", ...";
+    }
+    os << ")";
+  }
+  
+  typeString = std::string( os.str(), os.pcount() );
+
+  if( funcType->get_returnVals().size() == 0 ) {
+    typeString = "void " + typeString;
+  } else {
+
+    funcType->get_returnVals().front()->get_type()->accept( *this );
+
+  }
+  
+}
+
+void GenType::visit( StructInstType *structInst ) 
+{
+  typeString = "struct " + structInst->get_name() + " " + typeString;
+  handleQualifiers( structInst );
+}
+
+void 
+GenType::visit( UnionInstType *unionInst )
+{
+  typeString = "union " + unionInst->get_name() + " " + typeString;
+  handleQualifiers( unionInst );
+}
+
+void 
+GenType::visit( EnumInstType *enumInst )
+{
+  typeString = "enum " + enumInst->get_name() + " " + typeString;
+  handleQualifiers( enumInst );
+}
+
+void 
+GenType::visit( TypeInstType *typeInst )
+{
+  typeString = typeInst->get_name() + " " + typeString;
+  handleQualifiers( typeInst );
+}
+
+void 
+GenType::handleQualifiers( Type *type )
+{
+  if( type->get_isConst() ) {
+    typeString = "const " + typeString;
+  }
+  if( type->get_isVolatile() ) {
+    typeString = "volatile " + typeString;
+  }
+  if( type->get_isRestrict() ) {
+    typeString = "__restrict " + typeString;
+  }
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/GenType.h
===================================================================
--- translator/CodeGen/GenType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/GenType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenType.h,v 1.2 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#ifndef CODEGEN_GENTYPE_H
+#define CODEGEN_GENTYPE_H
+
+#include <string>
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+std::string genType( Type *type, const std::string &baseString );
+
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGEN_GENTYPE_H */
Index: translator/CodeGen/Generate.cc
===================================================================
--- translator/CodeGen/Generate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/Generate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <list>
+
+#include "Generate.h"
+#include "SynTree/Declaration.h"
+
+#include "CodeGenerator2.h"
+
+using namespace std;
+
+namespace CodeGen {
+
+  void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
+
+    CodeGen::CodeGenerator2 cgv( os );
+
+    for(std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end();  i++)
+      {
+        if( LinkageSpec::isGeneratable( (*i)->get_linkage() ) && (doIntrinsics || !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) ) {
+    	  (*i)->accept(cgv);
+    	  cgv.shift_left();
+    	  if( doSemicolon( *i ) ) {
+      	    os << ";";
+      	  }
+      	  os << std::endl;
+    	}
+      }
+
+  }
+
+} // namespace CodeGen
+
+
Index: translator/CodeGen/Generate.h
===================================================================
--- translator/CodeGen/Generate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/Generate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+#ifndef GENERATE_H
+#define GENERATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+  void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics );
+
+} // namespace CodeGen
+
+#endif /* #ifndef GENERATE_H */
Index: translator/CodeGen/OperatorTable.cc
===================================================================
--- translator/CodeGen/OperatorTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/OperatorTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: OperatorTable.cc,v 1.6 2003/01/19 04:19:31 rcbilson Exp $
+ *
+ */
+
+#include <map>
+
+#include "OperatorTable.h"
+
+namespace CodeGen {
+
+namespace {
+
+const OperatorInfo tableValues[] = {
+{	"?[?]",		"",		"_operator_index",		OT_INDEX		},
+{	"?()",		"",		"_operator_call",		OT_CALL			},
+{	"?++",		"++",		"_operator_postincr",		OT_POSTFIXASSIGN	},
+{	"?--",		"--",		"_operator_postdecr",		OT_POSTFIXASSIGN	},
+{	"*?",		"*",		"_operator_deref",		OT_PREFIX		},
+{	"+?",		"+",		"_operator_unaryplus",		OT_PREFIX		},
+{	"-?",		"-",		"_operator_unaryminus",		OT_PREFIX		},
+{	"~?",		"~",		"_operator_bitnot",		OT_PREFIX		},
+{	"!?",		"!",		"_operator_lognot",		OT_PREFIX		},
+{	"++?",		"++",		"_operator_preincr",		OT_PREFIXASSIGN		},
+{	"--?",		"--",		"_operator_predecr",		OT_PREFIXASSIGN		},
+{	"?*?",		"*",		"_operator_multiply",		OT_INFIX		},
+{	"?/?",		"/",		"_operator_divide",		OT_INFIX		},
+{	"?%?",		"%",		"_operator_modulus",		OT_INFIX		},
+{	"?+?",		"+",		"_operator_add",		OT_INFIX		},
+{	"?-?",		"-",		"_operator_subtract",		OT_INFIX		},
+{	"?<<?",		"<<",		"_operator_shiftleft",		OT_INFIX		},
+{	"?>>?",		">>",		"_operator_shiftright",		OT_INFIX		},
+{	"?<?",		"<",		"_operator_less",		OT_INFIX		},
+{	"?>?",		">",		"_operator_greater",		OT_INFIX		},
+{	"?<=?",		"<=",		"_operator_lessequal",		OT_INFIX		},
+{	"?>=?",		">=",		"_operator_greaterequal",	OT_INFIX		},
+{	"?==?",		"==",		"_operator_equal",		OT_INFIX		},
+{	"?!=?",		"!=",		"_operator_notequal",		OT_INFIX		},
+{	"?&?",		"&",		"_operator_bitand",		OT_INFIX		},
+{	"?^?",		"^",		"_operator_bitxor",		OT_INFIX		},
+{	"?|?",		"|",		"_operator_bitor",		OT_INFIX		},
+{	"?=?",		"=",		"_operator_assign",		OT_INFIXASSIGN		},
+{	"?*=?",		"*=",		"_operator_multassign",		OT_INFIXASSIGN		},
+{	"?/=?",		"/=",		"_operator_divassign",		OT_INFIXASSIGN		},
+{	"?%=?",		"%=",		"_operator_modassign",		OT_INFIXASSIGN		},
+{	"?+=?",		"+=",		"_operator_addassign",		OT_INFIXASSIGN		},
+{	"?-=?",		"-=",		"_operator_subassign",		OT_INFIXASSIGN		},
+{	"?<<=?",	"<<=",		"_operator_shiftleftassign",	OT_INFIXASSIGN		},
+{	"?>>=?",	">>=",		"_operator_shiftrightassign",	OT_INFIXASSIGN		},
+{	"?&=?",		"&=",		"_operator_bitandassign",	OT_INFIXASSIGN		},
+{	"?^=?",		"^=",		"_operator_bitxorassign",	OT_INFIXASSIGN		},
+{	"?|=?",		"|=",		"_operator_bitorassign",	OT_INFIXASSIGN		},
+{	"0",		"0",		"_constant_zero",		OT_CONSTANT		},
+{	"1",		"1",		"_constant_one",			OT_CONSTANT		}
+};
+
+const int numOps = sizeof( tableValues ) / sizeof( OperatorInfo );
+
+std::map< std::string, OperatorInfo > table;
+
+void
+initialize()
+{
+  for( int i = 0; i < numOps; ++i ) {
+    table[ tableValues[i].inputName ] = tableValues[i];
+  }
+}
+
+} // namespace
+
+bool
+operatorLookup( std::string funcName, OperatorInfo &info )
+{
+  static bool init = false;
+  if( !init ) {
+    initialize();
+  }
+  std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
+  if( i == table.end() ) {
+    return false;
+  } else {
+    info = i->second;
+    return true;
+  }
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/OperatorTable.h
===================================================================
--- translator/CodeGen/OperatorTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/OperatorTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: OperatorTable.h,v 1.4 2003/01/19 04:19:31 rcbilson Exp $
+ *
+ */
+
+#ifndef CODEGEN_OPERATORTABLE_H
+#define CODEGEN_OPERATORTABLE_H
+
+#include <string>
+
+namespace CodeGen {
+
+enum OperatorType
+{
+  OT_INDEX,
+  OT_CALL,
+  OT_PREFIX,
+  OT_POSTFIX,
+  OT_INFIX,
+  OT_PREFIXASSIGN,
+  OT_POSTFIXASSIGN,
+  OT_INFIXASSIGN,
+  OT_CONSTANT
+};
+
+struct OperatorInfo
+{
+  std::string inputName;
+  std::string symbol;
+  std::string outputName;
+  OperatorType type;
+};
+
+bool operatorLookup( std::string funcName, OperatorInfo &info );
+
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGEN_OPERATORTABLE_H */
Index: translator/CodeGen/module.mk
===================================================================
--- translator/CodeGen/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+SRC +=  CodeGen/Generate.cc \
+	CodeGen/CodeGenerator2.cc \
+	CodeGen/GenType.cc \
+	CodeGen/FixNames.cc \
+	CodeGen/OperatorTable.cc \
+	$(NULL)
