Changeset 4a9ccc3 for src/SymTab


Ignore:
Timestamp:
Jan 24, 2017, 3:56:33 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
ad6343e
Parents:
0bfaf80
Message:

propagate sized status through trait instances

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r0bfaf80 r4a9ccc3  
    114114                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    115115          private:
    116                 using Indexer::visit;
     116                using Parent::visit;
    117117                void visit( StructInstType *structInst ) final;
    118118                void visit( UnionInstType *unionInst ) final;
     
    131131
    132132        /// Replaces array and function types in forall lists by appropriate pointer type
    133         class Pass3 : public Indexer {
     133        class Pass3 final : public Indexer {
    134134                typedef Indexer Parent;
    135135          public:
     136                using Parent::visit;
    136137                Pass3( const Indexer *indexer );
    137138          private:
    138                 virtual void visit( ObjectDecl *object );
    139                 virtual void visit( FunctionDecl *func );
     139                virtual void visit( ObjectDecl *object ) override;
     140                virtual void visit( FunctionDecl *func ) override;
    140141
    141142                const Indexer *indexer;
     
    375376        }
    376377
    377         void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
    378                 Parent::visit( contextInst );
    379                 if ( contextInst->get_name() == "sized" ) {
     378        void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     379                Parent::visit( traitInst );
     380                if ( traitInst->get_name() == "sized" ) {
    380381                        // "sized" is a special trait with no members - just flick the sized status on for the type variable
    381                         if ( contextInst->get_parameters().size() != 1 ) {
    382                                 throw SemanticError( "incorrect number of context parameters: ", contextInst );
     382                        if ( traitInst->get_parameters().size() != 1 ) {
     383                                throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    383384                        }
    384                         TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
     385                        TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
    385386                        TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
    386387                        TypeDecl * decl = inst->get_baseType();
     
    389390                        return;
    390391                }
    391                 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
    392                 if ( ! ctx ) {
    393                         throw SemanticError( "use of undeclared context " + contextInst->get_name() );
    394                 } // if
    395                 for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    396                         for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    397                                 if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
    398                                         cloneAll( otherCtx->get_members(), contextInst->get_members() );
    399                                 } else {
    400                                         contextInst->get_members().push_back( (*assert )->clone() );
    401                                 } // if
     392                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     393                if ( ! traitDecl ) {
     394                        throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     395                } // if
     396                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
     397                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
     398                } // if
     399
     400                for ( TypeDecl * td : traitDecl->get_parameters() ) {
     401                        for ( DeclarationWithType * assert : td->get_assertions() ) {
     402                                traitInst->get_members().push_back( assert->clone() );
    402403                        } // for
    403404                } // for
    404405
    405                 if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
    406                         throw SemanticError( "incorrect number of context parameters: ", contextInst );
    407                 } // if
    408 
    409                 // need to clone members of the context for ownership purposes
     406                // need to clone members of the trait for ownership purposes
    410407                std::list< Declaration * > members;
    411                 std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
    412 
    413                 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
     408                std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
     409
     410                applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
     411
     412                // need to carry over the 'sized' status of each decl in the instance
     413                for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
     414                        TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
     415                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
     416                                TypeDecl * formalDecl = std::get<0>(p);
     417                                TypeDecl * instDecl = inst->get_baseType();
     418                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
     419                        }
     420                }
    414421        }
    415422
     
    457464        }
    458465
    459         /// Fix up assertions
    460         void forallFixer( Type *func ) {
    461                 for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     466        /// Fix up assertions - flattens assertion lists, removing all trait instances
     467        void forallFixer( Type * func ) {
     468                for ( TypeDecl * type : func->get_forall() ) {
    462469                        std::list< DeclarationWithType * > toBeDone, nextRound;
    463                         toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
     470                        toBeDone.splice( toBeDone.end(), type->get_assertions() );
    464471                        while ( ! toBeDone.empty() ) {
    465                                 for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    466                                         if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
    467                                                 for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    468                                                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
    469                                                         assert( dwt );
     472                                for ( DeclarationWithType * assertion : toBeDone ) {
     473                                        if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     474                                                // expand trait instance into all of its members
     475                                                for ( Declaration * member : traitInst->get_members() ) {
     476                                                        DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
    470477                                                        nextRound.push_back( dwt->clone() );
    471478                                                }
    472                                                 delete ctx;
     479                                                delete traitInst;
    473480                                        } else {
     481                                                // pass assertion through
    474482                                                FixFunction fixer;
    475                                                 *assertion = (*assertion )->acceptMutator( fixer );
     483                                                assertion = assertion->acceptMutator( fixer );
    476484                                                if ( fixer.get_isVoid() ) {
    477485                                                        throw SemanticError( "invalid type void in assertion of function ", func );
    478486                                                }
    479                                                 (*type )->get_assertions().push_back( *assertion );
     487                                                type->get_assertions().push_back( assertion );
    480488                                        } // if
    481489                                } // for
Note: See TracChangeset for help on using the changeset viewer.