/* * This file is part of the Cforall project * * $Id: IdTable.cc,v 1.6 2005/08/29 20:14:17 rcbilson Exp $ * */ #include #include "SynTree/Declaration.h" #include "ResolvExpr/typeops.h" #include "Indexer.h" #include "Mangler.h" #include "IdTable.h" #include "SemanticError.h" using std::string; namespace SymTab { IdTable::IdTable() : scopeLevel( 0 ) { } void IdTable::enterScope() { scopeLevel++; } void IdTable::leaveScope() { for( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) { for( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) { std::stack< DeclEntry >& entry = inner->second; if( !entry.empty() && entry.top().second == scopeLevel ) { entry.pop(); } } } scopeLevel--; assert( scopeLevel >= 0 ); } void IdTable::addDecl( DeclarationWithType *decl ) { const string &name = decl->get_name(); string manglename; if( decl->get_linkage() == LinkageSpec::C ) { manglename = name; } else { manglename = Mangler::mangle( decl ); } InnerTableType &declTable = table[ name ]; InnerTableType::iterator it = declTable.find( manglename ); if( it == declTable.end() ) { declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) ); } else { std::stack< DeclEntry >& entry = it->second; if( !entry.empty() && entry.top().second == scopeLevel ) { if( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) { FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl ); FunctionDecl *old = dynamic_cast< FunctionDecl* >( entry.top().first ); if( newentry && old && newentry->get_statements() && old->get_statements() ) { throw SemanticError( "duplicate function definition for ", decl ); } else { ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl ); ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( entry.top().first ); if( newobj && oldobj && newobj->get_init() && oldobj->get_init() ) { throw SemanticError( "duplicate definition for ", decl ); } } } else { throw SemanticError( "duplicate definition for ", decl ); } } else { declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) ); } } for( InnerTableType::const_iterator i = declTable.begin(); i != declTable.end(); ++i ) { if( !i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) { throw SemanticError( "invalid overload of C function ", i->second.top().first ); } } } void IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const { OuterTableType::const_iterator outer = table.find( id ); if( outer == table.end() ) return; const InnerTableType &declTable = outer->second; for( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) { const std::stack< DeclEntry >& entry = it->second; if( !entry.empty() ) { decls.push_back( entry.top().first ); } } } void IdTable::dump( std::ostream &os ) const { for( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) { for( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) { const std::stack< DeclEntry >& entry = inner->second; if( !entry.empty() && entry.top().second == scopeLevel ) { os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl; } } } } } // namespace SymTab