// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // IdTable.cc -- // // Author : Richard C. Bilson // Created On : Sun May 17 17:04:02 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Sun May 17 17:07:43 2015 // Update Count : 3 // #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(); } // if } // for } // for 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 ); } // if 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 ); } // if } // if } else { throw SemanticError( "duplicate definition for ", decl ); } // if } else { declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) ); } // if } // if // ensure the set of routines with C linkage cannot be overloaded for ( InnerTableType::iterator i = declTable.begin(); i != declTable.end(); ++i ) { if ( ! i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) { InnerTableType::iterator j = i; for ( j++; j != declTable.end(); ++j ) { if ( ! j->second.empty() && j->second.top().first->get_linkage() == LinkageSpec::C ) { throw SemanticError( "invalid overload of C function " ); } // if } // for } // if } // for } 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 ); } // if } // for } DeclarationWithType * IdTable::lookupId( const std::string &id) const { DeclarationWithType* result = 0; int depth = -1; OuterTableType::const_iterator outer = table.find( id ); if ( outer == table.end() ) return 0; 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() && entry.top().second > depth ) { result = entry.top().first; depth = entry.top().second; } // if } // for return result; } 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 ) { #if 0 const std::stack< DeclEntry >& entry = inner->second; if ( ! entry.empty() ) { // && entry.top().second == scopeLevel ) { os << outer->first << " (" << inner->first << ") (" << entry.top().second << ")" << std::endl; } else { os << outer->first << " (" << inner->first << ") ( entry-empty)" << std::endl; } // if #endif #if 0 std::stack stack = inner->second; os << "dumping a stack" << std::endl; while ( ! stack.empty()) { DeclEntry d = stack.top(); os << outer->first << " (" << inner->first << ") (" << d.second << ") " << std::endl; stack.pop(); } // while #endif } // for } // for #if 0 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; } // if } // for } // for #endif } } // namespace SymTab // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //