Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r0ac366b rd55d7a6  
    286286        }
    287287
    288         const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    289                 if ( ! tables ) return nullptr;
    290                 if ( tables->scope < scope ) return nullptr;
     288        DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
     289                if ( ! tables ) return 0;
     290                if ( tables->scope < scope ) return 0;
    291291
    292292                IdTable::const_iterator decls = tables->idTable.find( id );
     
    294294                        const MangleTable &mangleTable = decls->second;
    295295                        MangleTable::const_iterator decl = mangleTable.find( mangleName );
    296                         if ( decl != mangleTable.end() ) return &decl->second;
     296                        if ( decl != mangleTable.end() ) return decl->second.id;
    297297                }
    298298
    299299                return tables->base.lookupIdAtScope( id, mangleName, scope );
    300         }
    301 
    302         Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) {
    303                 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
    304300        }
    305301
     
    377373        }
    378374
    379         bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
     375        bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) {
    380376                // if we're giving the same name mangling to things of different types then there is something wrong
    381                 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing.id ) )
    382                         || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing.id ) ) );
    383 
    384                 if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
     377                assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )
     378                        || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );
     379
     380                if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) {
    385381                        // new definition shadows the autogenerated one, even at the same scope
    386382                        return false;
    387                 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) {
    388 
    389                         // it is a conflict if one declaration is deleted and the other is not
    390                         if ( deleteStmt && ! existing.deleteStmt ) {
    391                                 return handleConflicts( existing, "deletion of defined identifier " );
    392                         } else if ( ! deleteStmt && existing.deleteStmt ) {
    393                                 return handleConflicts( existing, "definition of deleted identifier " );
    394                         }
    395 
     383                } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
    396384                        // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    397385                        // we should ignore outermost pointer qualifiers, except _Atomic?
    398                         FunctionDecl * newentry = dynamic_cast< FunctionDecl * >( added );
    399                         FunctionDecl * oldentry = dynamic_cast< FunctionDecl * >( existing.id );
     386                        FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added );
     387                        FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing );
    400388                        if ( newentry && oldentry ) {
    401389                                if ( newentry->get_statements() && oldentry->get_statements() ) {
    402                                         return handleConflicts( existing, "duplicate function definition for " );
     390                                        throw SemanticError( added, "duplicate function definition for " );
    403391                                } // if
    404392                        } else {
     
    407395                                // xxx - perhaps it's actually if either is intrinsic then this is okay?
    408396                                //       might also need to be same storage class?
    409                                 ObjectDecl * newobj = dynamic_cast< ObjectDecl * >( added );
    410                                 ObjectDecl * oldobj = dynamic_cast< ObjectDecl * >( existing.id );
     397                                ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added );
     398                                ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing );
    411399                                if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) {
    412                                         return handleConflicts( existing, "duplicate object definition for " );
     400                                        throw SemanticError( added, "duplicate object definition for " );
    413401                                } // if
    414402                        } // if
    415403                } else {
    416                         return handleConflicts( existing, "duplicate definition for " );
     404                        throw SemanticError( added, "duplicate definition for " );
    417405                } // if
    418406
     
    420408        }
    421409
    422         void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) {
     410        void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) {
    423411                if ( decl->name == "" ) return;
    424412                debugPrint( "Adding Id " << decl->name << std::endl );
     
    443431                        // isomorphic to C type-compatibility, which it may not be.
    444432                        if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
    445                                 throw SemanticError( "conflicting overload of C function ", decl );
    446                         }
    447                 } else {
    448                         // Check that a Cforall declaration doesn't override any C declaration
     433                                throw SemanticError( decl, "conflicting overload of C function " );
     434                        }
     435                } else {
     436                        // Check that a Cforall declaration doesn't overload any C declaration
    449437                        if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
    450                                 throw SemanticError( "Cforall declaration hides C function ", decl );
     438                                throw SemanticError( decl, "Cforall declaration hides C function " );
    451439                        }
    452440                }
    453441
    454442                // Skip repeat declarations of the same identifier
    455                 IdData * existing = lookupIdAtScope( name, mangleName, scope );
    456                 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return;
     443                DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );
     444                if ( existing && addedIdConflicts( existing, decl ) ) return;
    457445
    458446                // add to indexer
    459                 tables->idTable[ name ][ mangleName ] = { decl, baseExpr, deleteStmt };
     447                tables->idTable[ name ][ mangleName ] = { decl, baseExpr };
    460448                ++tables->size;
    461         }
    462 
    463         void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    464                 // default handling of conflicts is to raise an error
    465                 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, baseExpr );
    466         }
    467 
    468         void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
    469                 // default handling of conflicts is to raise an error
    470                 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, nullptr, deleteStmt );
    471449        }
    472450
     
    477455                        return true;
    478456                } else {
    479                         throw SemanticError( "redeclaration of ", added );
     457                        throw SemanticError( added, "redeclaration of " );
    480458                }
    481459        }
     
    504482                        return false;
    505483                } else if ( ! added->get_members().empty() ) {
    506                         throw SemanticError( "redeclaration of ", added );
     484                        throw SemanticError( added, "redeclaration of " );
    507485                } // if
    508486                return true;
     
    595573        }
    596574
    597         void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) {
     575        void Indexer::addMembers( AggregateDecl * aggr, Expression * expr ) {
    598576                for ( Declaration * decl : aggr->members ) {
    599577                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    600                                 addId( dwt, handleConflicts, expr );
     578                                addId( dwt, expr );
    601579                                if ( dwt->name == "" ) {
    602580                                        Type * t = dwt->get_type()->stripReferences();
     
    604582                                                Expression * base = expr->clone();
    605583                                                ResolvExpr::referenceToRvalueConversion( base );
    606                                                 addMembers( t->getAggr(), new MemberExpr( dwt, base ), handleConflicts );
     584                                                addMembers( t->getAggr(), new MemberExpr( dwt, base ) );
    607585                                        }
    608586                                }
     
    611589        }
    612590
    613         void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) {
     591        void Indexer::addWith( std::list< Expression * > & withExprs ) {
    614592                for ( Expression * expr : withExprs ) {
    615593                        if ( expr->result ) {
     
    617595                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    618596
    619                                 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) {
    620                                         // on conflict, delete the identifier
    621                                         existing.deleteStmt = withStmt;
    622                                         return true;
    623                                 });
     597                                addMembers( aggr, expr );
    624598                        }
    625599                }
     
    680654
    681655        void Indexer::print( std::ostream &os, int indent ) const {
    682                 using std::cerr;
     656            using std::cerr;
    683657
    684658                if ( tables ) {
     
    706680
    707681        Expression * Indexer::IdData::combine() const {
    708                 Expression * ret = nullptr;
    709682                if ( baseExpr ) {
    710683                        Expression * base = baseExpr->clone();
    711684                        ResolvExpr::referenceToRvalueConversion( base );
    712                         ret = new MemberExpr( id, base );
     685                        Expression * ret = new MemberExpr( id, base );
    713686                        // xxx - this introduces hidden environments, for now remove them.
    714687                        // std::swap( base->env, ret->env );
    715688                        delete base->env;
    716689                        base->env = nullptr;
    717                 } else {
    718                         ret = new VariableExpr( id );
    719                 }
    720                 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt );
    721                 return ret;
     690                        return ret;
     691                } else {
     692                        return new VariableExpr( id );
     693                }
    722694        }
    723695} // namespace SymTab
Note: See TracChangeset for help on using the changeset viewer.