Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r6a57da5 rbed4c63e  
    1919#include <typeinfo>
    2020#include <unordered_map>
    21 #include <unordered_set>
    2221#include <utility>
    2322
     
    436435
    437436        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
    438                 std::unordered_set< std::string > foundMangleNames;
     437                if ( ! tables ) return;
     438
     439                IdTable::const_iterator decls = tables->idTable.find( id );
     440                if ( decls != tables->idTable.end() ) {
     441                        const MangleTable &mangleTable = decls->second;
     442                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
     443                                out.push_back( decl->second );
     444                        }
     445                }
    439446               
    440                 Indexer::Impl *searchTables = tables;
    441                 while ( searchTables ) {
    442 
    443                         IdTable::const_iterator decls = searchTables->idTable.find( id );
    444                         if ( decls != searchTables->idTable.end() ) {
    445                                 const MangleTable &mangleTable = decls->second;
    446                                 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    447                                         // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found
    448                                         if ( foundMangleNames.insert( decl->first ).second == false ) continue;
    449                                        
    450                                         out.push_back( decl->second );
    451                                 }
    452                         }
    453                        
    454                         // get declarations from base indexers
    455                         searchTables = searchTables->base.tables;
    456                 }
     447                // get declarations from base indexers
     448                tables->base.lookupId( id, out );
    457449        }
    458450
     
    506498        }
    507499
    508         bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
     500        bool Indexer::hasCDeclWithName( const std::string &id ) const {
    509501                if ( ! tables ) return false;
    510502
     
    513505                        const MangleTable &mangleTable = decls->second;
    514506                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    515                                 // check for C decls with the same name, skipping
    516                                 // those with a compatible type (by mangleName)
    517                                 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
    518                         }
    519                 }
    520 
    521                 return tables->base.hasIncompatibleCDecl( id, mangleName );
     507                                if ( decl->second->get_linkage() == LinkageSpec::C ) return true;
     508                        }
     509                }
     510
     511                return tables->base.hasCDeclWithName( id );
    522512        }
    523513       
     
    602592                const std::string &name = decl->get_name();
    603593                std::string mangleName;
    604                 if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
     594                if ( decl->get_linkage() == LinkageSpec::C ) {
     595                        mangleName = name;
     596                } else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
    605597                        // mangle the name without including the appropriate suffix, so overridable routines are placed into the
    606598                        // same "bucket" as their user defined versions.
     
    613605                if ( ! existing || ! addedIdConflicts( existing, decl ) ) {
    614606                        // this ensures that no two declarations with the same unmangled name both have C linkage
    615                         if ( decl->get_linkage() == LinkageSpec::C && hasIncompatibleCDecl( name, mangleName ) ) {
     607                        if ( decl->get_linkage() == LinkageSpec::C && hasCDeclWithName( name ) ) {
    616608                                throw SemanticError( "invalid overload of C function ", decl );
    617                         } // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    618                           // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
    619                           // have their name as their manglename, hence the error can never trigger).
    620                           // The code here is closer to correct, but name mangling would have to be completely
    621                           // isomorphic to C type-compatibility, which it may not be.
     609                        }
    622610                       
    623611                        tables->idTable[ name ][ mangleName ] = decl;
Note: See TracChangeset for help on using the changeset viewer.