/*
 * This file is part of the Cforall project
 *
 * $Id: AggregateTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
 *
 */

#ifndef SYMTAB_AGGREGATETABLE_H
#define SYMTAB_AGGREGATETABLE_H

#include <map>
#include <stack>
#include <string>
#include <functional>

#include "StackTable.h"
#include "SynTree/Declaration.h"

namespace SymTab {

template< class AggregateDeclClass >
class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass*, AggregateDeclClass*, AggregateDeclClass* >
{
public:
  AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added )
  {
    if( existing->get_members().empty() ) {
      return added;
    } else if( !added->get_members().empty() ) {
      throw SemanticError( "redeclaration of ", added );
    }
    return existing;
  }
  
};

typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;

} // namespace SymTab

#endif /* #ifndef SYMTAB_AGGREGATETABLE_H */
