Changeset be9036d for src/SymTab


Ignore:
Timestamp:
Aug 31, 2017, 3:29:38 PM (7 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:
326338ae
Parents:
5b21138
git-author:
Rob Schluntz <rschlunt@…> (08/31/17 15:29:33)
git-committer:
Rob Schluntz <rschlunt@…> (08/31/17 15:29:38)
Message:

Reorganize TraitInstType? and TraitDecl?, add sized trait definition to prelude

Previously, TraitInstType? cloned all of the members of TraitDecl?. This commit changes
TraitInstType? to instead contain a pointer to the base TraitDecl?, analogous to StructInstType?
and StructDecl?, etc. In particular, this makes the code simpler and makes it easier to
fully expand the members of a trait declaration.

Location:
src/SymTab
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r5b21138 rbe9036d  
    554554
    555555
    556         void Indexer::visit( TraitInstType *contextInst ) {
    557                 acceptAll( contextInst->get_parameters(), *this );
    558                 acceptAll( contextInst->get_members(), *this );
     556        void Indexer::visit( TraitInstType *traitInst ) {
     557                acceptAll( traitInst->get_parameters(), *this );
    559558        }
    560559
  • src/SymTab/Validate.cc

    r5b21138 rbe9036d  
    127127          public:
    128128                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    129                 using Parent::visit;
     129                using Parent::visit;
     130                void visit( TypeInstType *typeInst ) final;
     131
    130132                void visit( EnumInstType *enumInst ) final;
    131133                void visit( StructInstType *structInst ) final;
    132134                void visit( UnionInstType *unionInst ) final;
    133                 void visit( TraitInstType *contextInst ) final;
     135                void visit( TraitInstType *traitInst ) final;
     136
    134137                void visit( EnumDecl *enumDecl ) final;
    135138                void visit( StructDecl *structDecl ) final;
    136139                void visit( UnionDecl *unionDecl ) final;
    137                 void visit( TypeInstType *typeInst ) final;
     140                void visit( TraitDecl * traitDecl ) final;
     141
    138142          private:
    139143                const Indexer *indexer;
     
    453457        }
    454458
    455         void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     459        template< typename Decl >
     460        void normalizeAssertions( std::list< Decl * > & assertions ) {
     461                // ensure no duplicate trait members after the clone
     462                auto pred = [](Decl * d1, Decl * d2) {
     463                        // only care if they're equal
     464                        DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 );
     465                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
     466                        if ( dwt1 && dwt2 ) {
     467                                if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     468                                        // std::cerr << "=========== equal:" << std::endl;
     469                                        // std::cerr << "d1: " << d1 << std::endl;
     470                                        // std::cerr << "d2: " << d2 << std::endl;
     471                                        return false;
     472                                }
     473                        }
     474                        return d1 < d2;
     475                };
     476                std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred );
     477                // if ( unique_members.size() != assertions.size() ) {
     478                //      std::cerr << "============different" << std::endl;
     479                //      std::cerr << unique_members.size() << " " << assertions.size() << std::endl;
     480                // }
     481
     482                std::list< Decl * > order;
     483                order.splice( order.end(), assertions );
     484                std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) {
     485                        return unique_members.count( decl );
     486                });
     487        }
     488
     489        // expand assertions from trait instance, performing the appropriate type variable substitutions
     490        template< typename Iterator >
     491        void expandAssertions( TraitInstType * inst, Iterator out ) {
     492                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
     493                std::list< DeclarationWithType * > asserts;
     494                for ( Declaration * decl : inst->baseTrait->members ) {
     495                        asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) );
     496                }
     497                // substitute trait decl parameters for instance parameters
     498                applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out );
     499        }
     500
     501        void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
     502                Parent::visit( traitDecl );
     503
     504                if ( traitDecl->name == "sized" ) {
     505                        // "sized" is a special trait - flick the sized status on for the type variable
     506                        assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() );
     507                        TypeDecl * td = traitDecl->parameters.front();
     508                        td->set_sized( true );
     509                }
     510
     511                // move assertions from type parameters into the body of the trait
     512                for ( TypeDecl * td : traitDecl->parameters ) {
     513                        for ( DeclarationWithType * assert : td->assertions ) {
     514                                if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) {
     515                                        expandAssertions( inst, back_inserter( traitDecl->members ) );
     516                                } else {
     517                                        traitDecl->members.push_back( assert->clone() );
     518                                }
     519                        }
     520                        deleteAll( td->assertions );
     521                        td->assertions.clear();
     522                } // for
     523        }
     524
     525        void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
    456526                Parent::visit( traitInst );
    457                 if ( traitInst->get_name() == "sized" ) {
    458                         // "sized" is a special trait with no members - just flick the sized status on for the type variable
    459                         if ( traitInst->get_parameters().size() != 1 ) {
    460                                 throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    461                         }
    462                         TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
    463                         TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
    464                         TypeDecl * decl = inst->get_baseType();
    465                         decl->set_sized( true );
    466                         // since "sized" is special, the next few steps don't apply
    467                         return;
    468                 }
    469 
    470527                // handle other traits
    471                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     528                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
    472529                if ( ! traitDecl ) {
    473                         throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     530                        throw SemanticError( "use of undeclared trait " + traitInst->name );
    474531                } // if
    475532                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    476533                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    477534                } // if
    478 
    479                 for ( TypeDecl * td : traitDecl->get_parameters() ) {
    480                         for ( DeclarationWithType * assert : td->get_assertions() ) {
    481                                 traitInst->get_members().push_back( assert->clone() );
    482                         } // for
    483                 } // for
    484 
    485                 // need to clone members of the trait for ownership purposes
    486                 std::list< Declaration * > members;
    487                 std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
    488 
    489                 applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
     535                traitInst->baseTrait = traitDecl;
    490536
    491537                // need to carry over the 'sized' status of each decl in the instance
     
    498544                        }
    499545                }
     546                // normalizeAssertions( traitInst->members );
    500547        }
    501548
     
    561608        void forallFixer( Type * func ) {
    562609                for ( TypeDecl * type : func->get_forall() ) {
    563                         std::list< DeclarationWithType * > toBeDone, nextRound;
    564                         toBeDone.splice( toBeDone.end(), type->get_assertions() );
    565                         while ( ! toBeDone.empty() ) {
    566                                 for ( DeclarationWithType * assertion : toBeDone ) {
    567                                         if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    568                                                 // expand trait instance into all of its members
    569                                                 for ( Declaration * member : traitInst->get_members() ) {
    570                                                         DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
    571                                                         nextRound.push_back( dwt->clone() );
    572                                                 }
    573                                                 delete traitInst;
    574                                         } else {
    575                                                 // pass assertion through
    576                                                 FixFunction fixer;
    577                                                 assertion = assertion->acceptMutator( fixer );
    578                                                 if ( fixer.get_isVoid() ) {
    579                                                         throw SemanticError( "invalid type void in assertion of function ", func );
    580                                                 }
    581                                                 type->get_assertions().push_back( assertion );
    582                                         } // if
    583                                 } // for
    584                                 toBeDone.clear();
    585                                 toBeDone.splice( toBeDone.end(), nextRound );
    586                         } // while
     610                        std::list< DeclarationWithType * > asserts;
     611                        asserts.splice( asserts.end(), type->assertions );
     612                        // expand trait instances into their members
     613                        for ( DeclarationWithType * assertion : asserts ) {
     614                                if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     615                                        // expand trait instance into all of its members
     616                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     617                                        delete traitInst;
     618                                } else {
     619                                        // pass other assertions through
     620                                        type->assertions.push_back( assertion );
     621                                } // if
     622                        } // for
     623                        // apply FixFunction to every assertion to check for invalid void type
     624                        for ( DeclarationWithType *& assertion : type->assertions ) {
     625                                FixFunction fixer;
     626                                assertion = assertion->acceptMutator( fixer );
     627                                if ( fixer.get_isVoid() ) {
     628                                        throw SemanticError( "invalid type void in assertion of function ", func );
     629                                } // if
     630                        } // for
     631                        // normalizeAssertions( type->assertions );
    587632                } // for
    588633        }
Note: See TracChangeset for help on using the changeset viewer.