Ignore:
Timestamp:
Mar 22, 2016, 12:48:17 PM (8 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
6c91065
Parents:
ae357ec
Message:

Fix indexer bugs introduced in refactor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    rae357ec r5447e09  
    1919#include <typeinfo>
    2020#include <unordered_map>
     21#include <unordered_set>
    2122#include <utility>
    2223
     
    435436
    436437        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
    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                 }
     438                std::unordered_set< std::string > foundMangleNames;
    446439               
    447                 // get declarations from base indexers
    448                 tables->base.lookupId( id, out );
     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                }
    449457        }
    450458
     
    498506        }
    499507
    500         bool Indexer::hasCDeclWithName( const std::string &id ) const {
     508        bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
    501509                if ( ! tables ) return false;
    502510
     
    505513                        const MangleTable &mangleTable = decls->second;
    506514                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    507                                 if ( decl->second->get_linkage() == LinkageSpec::C ) return true;
    508                         }
    509                 }
    510 
    511                 return tables->base.hasCDeclWithName( id );
     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 );
    512522        }
    513523       
     
    592602                const std::string &name = decl->get_name();
    593603                std::string mangleName;
     604                // TODO the first branch of this if is a bug-for-bug replication of Richard's code;
     605                // it can allow C decls to hide CFA decls when they shouldn't, but the current prelude
     606                // depends on this bug to build ... <stdlib>'s random() should be fixed to *not* hide
     607                // <stdlib.h>'s random() before this first branch is taken out again
    594608                if ( decl->get_linkage() == LinkageSpec::C ) {
    595609                        mangleName = name;
     
    605619                if ( ! existing || ! addedIdConflicts( existing, decl ) ) {
    606620                        // this ensures that no two declarations with the same unmangled name both have C linkage
    607                         if ( decl->get_linkage() == LinkageSpec::C && hasCDeclWithName( name ) ) {
     621                        if ( decl->get_linkage() == LinkageSpec::C && hasIncompatibleCDecl( name, mangleName ) ) {
    608622                                throw SemanticError( "invalid overload of C function ", decl );
    609                         }
     623                        } // NOTE this is broken in Richard's original code in such a way that it never triggers (it
     624                          // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
     625                          // have their name as their manglename, hence the error can never trigger).
     626                          // The elided code here is closer to correct, but name mangling would have to be completely
     627                          // isomorphic to C type-compatibility, which it may not be.
    610628                       
    611629                        tables->idTable[ name ][ mangleName ] = decl;
Note: See TracChangeset for help on using the changeset viewer.