Changeset a40d503


Ignore:
Timestamp:
Dec 1, 2017, 5:12:03 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
e4bc986
Parents:
3ca540f
Message:

Add base expression to Indexer MangleTable? and implement WithStmt? functionality

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r3ca540f ra40d503  
    469469                        std::cerr << std::endl;
    470470                )
    471                 std::list< DeclarationWithType* > candidates;
     471                std::list< SymTab::Indexer::IdData > candidates;
    472472                decls.lookupId( curDecl->get_name(), candidates );
    473473///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    474                 for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
     474                for ( const auto & data : candidates ) {
     475                        DeclarationWithType * candidate = data.id;
    475476                        PRINT(
    476477                                std::cerr << "inferRecursive: candidate is ";
    477                                 (*candidate)->print( std::cerr );
     478                                candidate->print( std::cerr );
    478479                                std::cerr << std::endl;
    479480                        )
     
    482483                        TypeEnvironment newEnv( newAlt.env );
    483484                        OpenVarSet newOpenVars( openVars );
    484                         Type *adjType = (*candidate)->get_type()->clone();
     485                        Type *adjType = candidate->get_type()->clone();
    485486                        adjustExprType( adjType, newEnv, indexer );
    486487                        adjType->accept( global_renamer );
     
    500501                                Alternative newerAlt( newAlt );
    501502                                newerAlt.env = newEnv;
    502                                 assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );
    503                                 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
     503                                assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    504504
    505505                                // everything with an empty idChain was pulled in by the current assertion.
     
    516516                                // DOESN'T WORK: grandchild nodes conflict with their cousins
    517517                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    518                                 Expression *varExpr = new VariableExpr( candDecl );
     518                                Expression *varExpr = data.combine();
    519519                                delete varExpr->get_result();
    520520                                varExpr->set_result( adjType->clone() );
     
    522522                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    523523                                        curDecl->print( std::cerr );
    524                                         std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";
    525                                         (*candidate)->print( std::cerr );
     524                                        std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
     525                                        candidate->print( std::cerr );
    526526                                        std::cerr << std::endl;
    527527                                )
     
    532532                                }
    533533                                // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    534                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
     534                                (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    535535                                inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
    536536                        } else {
     
    13171317
    13181318        void AlternativeFinder::visit( NameExpr *nameExpr ) {
    1319                 std::list< DeclarationWithType* > declList;
     1319                std::list< SymTab::Indexer::IdData > declList;
    13201320                indexer.lookupId( nameExpr->get_name(), declList );
    13211321                PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
    1322                 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    1323                         VariableExpr newExpr( *i );
    1324                         alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     1322                for ( auto & data : declList ) {
     1323                        Expression * newExpr = data.combine();
     1324                        // xxx - add in extra cost for with-statement exprs?
     1325                        alternatives.push_back( Alternative( newExpr, env, Cost::zero ) );
    13251326                        PRINT(
    13261327                                std::cerr << "decl is ";
    1327                                 (*i)->print( std::cerr );
     1328                                data.id->print( std::cerr );
    13281329                                std::cerr << std::endl;
    13291330                                std::cerr << "newExpr is ";
    1330                                 newExpr.print( std::cerr );
     1331                                newExpr->print( std::cerr );
    13311332                                std::cerr << std::endl;
    13321333                        )
     
    14201421        }
    14211422
    1422         void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    1423                 // assume no polymorphism
    1424                 // assume no implicit conversions
    1425                 assert( function->get_parameters().size() == 1 );
    1426                 PRINT(
    1427                         std::cerr << "resolvAttr: funcDecl is ";
    1428                         funcDecl->print( std::cerr );
    1429                         std::cerr << " argType is ";
    1430                         argType->print( std::cerr );
    1431                         std::cerr << std::endl;
    1432                 )
    1433                 if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    1434                         alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    1435                         for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    1436                                 alternatives.back().expr->set_result( (*i)->get_type()->clone() );
    1437                         } // for
    1438                 } // if
     1423        namespace {
     1424                void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
     1425                        // assume no polymorphism
     1426                        // assume no implicit conversions
     1427                        assert( function->get_parameters().size() == 1 );
     1428                        PRINT(
     1429                                std::cerr << "resolvAttr: funcDecl is ";
     1430                                data.id->print( std::cerr );
     1431                                std::cerr << " argType is ";
     1432                                argType->print( std::cerr );
     1433                                std::cerr << std::endl;
     1434                        )
     1435                        const SymTab::Indexer & indexer = finder.get_indexer();
     1436                        AltList & alternatives = finder.get_alternatives();
     1437                        if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     1438                                alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) );
     1439                                for ( DeclarationWithType * retVal : function->returnVals ) {
     1440                                        alternatives.back().expr->result = retVal->get_type()->clone();
     1441                                } // for
     1442                        } // if
     1443                }
    14391444        }
    14401445
     
    14431448                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    14441449                assert( nameExpr );
    1445                 std::list< DeclarationWithType* > attrList;
     1450                std::list< SymTab::Indexer::IdData > attrList;
    14461451                indexer.lookupId( nameExpr->get_name(), attrList );
    14471452                if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    1448                         for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
     1453                        for ( auto & data : attrList ) {
     1454                                DeclarationWithType * id = data.id;
    14491455                                // check if the type is function
    1450                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
     1456                                if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
    14511457                                        // assume exactly one parameter
    14521458                                        if ( function->get_parameters().size() == 1 ) {
    14531459                                                if ( attrExpr->get_isType() ) {
    1454                                                         resolveAttr( *i, function, attrExpr->get_type(), env );
     1460                                                        resolveAttr( data, function, attrExpr->get_type(), env, *this );
    14551461                                                } else {
    14561462                                                        AlternativeFinder finder( indexer, env );
     
    14581464                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    14591465                                                                if ( choice->expr->get_result()->size() == 1 ) {
    1460                                                                         resolveAttr(*i, function, choice->expr->get_result(), choice->env );
     1466                                                                        resolveAttr(data, function, choice->expr->get_result(), choice->env, *this );
    14611467                                                                } // fi
    14621468                                                        } // for
     
    14661472                        } // for
    14671473                } else {
    1468                         for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
    1469                                 VariableExpr newExpr( *i );
    1470                                 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
     1474                        for ( auto & data : attrList ) {
     1475                                alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) );
    14711476                                renameTypes( alternatives.back().expr );
    14721477                        } // for
  • src/ResolvExpr/AlternativeFinder.h

    r3ca540f ra40d503  
    142142                template< typename OutputIterator >
    143143                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
    144                 void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
    145144
    146145                const SymTab::Indexer &indexer;
  • src/SymTab/Indexer.cc

    r3ca540f ra40d503  
    4040
    4141namespace SymTab {
    42         typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
     42        std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) {
     43                return out << "(" << data.id << "," << data.baseExpr << ")";
     44        }
     45
     46        typedef std::unordered_map< std::string, Indexer::IdData > MangleTable;
    4347        typedef std::unordered_map< std::string, MangleTable > IdTable;
    4448        typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
     
    97101        }
    98102
    99         void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const {
     103        void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
    100104                // only need to perform this step for constructors, destructors, and assignment functions
    101105                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
     
    104108                struct ValueType {
    105109                        struct DeclBall {
    106                                 FunctionDecl * decl;
     110                                IdData decl;
    107111                                bool isUserDefinedFunc; // properties for this particular decl
    108112                                bool isDefaultCtor;
     
    120124                        // another FunctionDecl for the current type was found - determine
    121125                        // if it has special properties and update data structure accordingly
    122                         ValueType & operator+=( FunctionDecl * function ) {
     126                        ValueType & operator+=( IdData data ) {
     127                                DeclarationWithType * function = data.id;
    123128                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    124129                                bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    125130                                bool isDtor = InitTweak::isDestructor( function );
    126131                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    127                                 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
     132                                decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    128133                                existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    129134                                existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
     
    135140                }; // ValueType
    136141
    137                 std::list< DeclarationWithType * > copy;
     142                std::list< IdData > copy;
    138143                copy.splice( copy.end(), out );
    139144
    140145                // organize discovered declarations by type
    141146                std::unordered_map< std::string, ValueType > funcMap;
    142                 for ( DeclarationWithType * decl : copy ) {
    143                         if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {
     147                for ( auto decl : copy ) {
     148                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    144149                                std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
    145150                                assert( ! params.empty() );
     
    147152                                Type * base = InitTweak::getPointerBase( params.front()->get_type() );
    148153                                assert( base );
    149                                 funcMap[ Mangler::mangle( base ) ] += function;
     154                                funcMap[ Mangler::mangle( base ) ] += decl;
    150155                        } else {
    151156                                out.push_back( decl );
     
    164169                                bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    165170                                bool isUserDefinedFunc = ball.isUserDefinedFunc;
    166                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
     171                                bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    167172                                bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    168173                                bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
     
    219224        }
    220225
    221         void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
     226        void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
    222227                std::unordered_set< std::string > foundMangleNames;
    223228
     
    289294                        const MangleTable &mangleTable = decls->second;
    290295                        MangleTable::const_iterator decl = mangleTable.find( mangleName );
    291                         if ( decl != mangleTable.end() ) return decl->second;
     296                        if ( decl != mangleTable.end() ) return decl->second.id;
    292297                }
    293298
     
    304309                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    305310                                // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    306                                 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true;
     311                                if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true;
    307312                        }
    308313                }
     
    321326                                // check for C decls with the same name, skipping
    322327                                // those with an incompatible type (by mangleName)
    323                                 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true;
     328                                if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true;
    324329                        }
    325330                }
     
    403408        }
    404409
    405         void Indexer::addId( DeclarationWithType *decl ) {
     410        void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) {
    406411                debugPrint( "Adding Id " << decl->name << std::endl );
    407412                makeWritable();
     
    439444
    440445                // add to indexer
    441                 tables->idTable[ name ][ mangleName ] = decl;
     446                tables->idTable[ name ][ mangleName ] = { decl, baseExpr };
    442447                ++tables->size;
    443448        }
     
    573578                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    574579
    575                                 // xxx - this is wrong, needs to somehow hook up chain of objects
    576580                                for ( Declaration * decl : aggr->members ) {
    577581                                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    578                                                 addId( dwt );
     582                                                addId( dwt, expr );
    579583                                        }
    580584                                }
     
    661665
    662666        }
     667
     668        Expression * Indexer::IdData::combine() const {
     669                if ( baseExpr ) {
     670                        Expression * base = baseExpr->clone();
     671                        Expression * ret = new MemberExpr( id, base );
     672                        // xxx - this introduces hidden environments, for now remove them.
     673                        // std::swap( base->env, ret->env );
     674                        delete base->env;
     675                        base->env = nullptr;
     676                        return ret;
     677                } else {
     678                        return new VariableExpr( id );
     679                }
     680        }
    663681} // namespace SymTab
    664682
  • src/SymTab/Indexer.h

    r3ca540f ra40d503  
    3939                void leaveScope();
    4040
     41                struct IdData {
     42                        DeclarationWithType * id;
     43                        Expression * baseExpr; // WithExpr
     44
     45                        Expression * combine() const;
     46                };
     47
    4148                /// Gets all declarations with the given ID
    42                 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const;
     49                void lookupId( const std::string &id, std::list< IdData > &out ) const;
    4350                /// Gets the top-most type declaration with the given ID
    4451                NamedTypeDecl *lookupType( const std::string &id ) const;
     
    6774                TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
    6875
    69                 void addId( DeclarationWithType *decl );
     76                void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr );
    7077                void addType( NamedTypeDecl *decl );
    7178                void addStruct( const std::string &id );
     
    103110                // so that they will not be selected
    104111                // void removeSpecialOverrides( FunctionDecl *decl );
    105                 void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const;
     112                void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
    106113
    107114                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
Note: See TracChangeset for help on using the changeset viewer.