Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rb128d3e r2bf9c37  
    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;
     
    287291
    288292        HoistStruct::HoistStruct() : inStruct( false ) {
    289         }
    290 
    291         void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {
    292                 std::list< Declaration * >::iterator i = declList.begin();
    293                 while ( i != declList.end() ) {
    294                         std::list< Declaration * >::iterator next = i;
    295                         ++next;
    296                         if ( pred( *i ) ) {
    297                                 if ( doDelete ) {
    298                                         delete *i;
    299                                 } // if
    300                                 declList.erase( i );
    301                         } // if
    302                         i = next;
    303                 } // while
    304293        }
    305294
     
    453442        }
    454443
    455         void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     444        template< typename Decl >
     445        void normalizeAssertions( std::list< Decl * > & assertions ) {
     446                // ensure no duplicate trait members after the clone
     447                auto pred = [](Decl * d1, Decl * d2) {
     448                        // only care if they're equal
     449                        DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 );
     450                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
     451                        if ( dwt1 && dwt2 ) {
     452                                if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     453                                        // std::cerr << "=========== equal:" << std::endl;
     454                                        // std::cerr << "d1: " << d1 << std::endl;
     455                                        // std::cerr << "d2: " << d2 << std::endl;
     456                                        return false;
     457                                }
     458                        }
     459                        return d1 < d2;
     460                };
     461                std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred );
     462                // if ( unique_members.size() != assertions.size() ) {
     463                //      std::cerr << "============different" << std::endl;
     464                //      std::cerr << unique_members.size() << " " << assertions.size() << std::endl;
     465                // }
     466
     467                std::list< Decl * > order;
     468                order.splice( order.end(), assertions );
     469                std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) {
     470                        return unique_members.count( decl );
     471                });
     472        }
     473
     474        // expand assertions from trait instance, performing the appropriate type variable substitutions
     475        template< typename Iterator >
     476        void expandAssertions( TraitInstType * inst, Iterator out ) {
     477                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
     478                std::list< DeclarationWithType * > asserts;
     479                for ( Declaration * decl : inst->baseTrait->members ) {
     480                        asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) );
     481                }
     482                // substitute trait decl parameters for instance parameters
     483                applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out );
     484        }
     485
     486        void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
     487                Parent::visit( traitDecl );
     488
     489                if ( traitDecl->name == "sized" ) {
     490                        // "sized" is a special trait - flick the sized status on for the type variable
     491                        assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() );
     492                        TypeDecl * td = traitDecl->parameters.front();
     493                        td->set_sized( true );
     494                }
     495
     496                // move assertions from type parameters into the body of the trait
     497                for ( TypeDecl * td : traitDecl->parameters ) {
     498                        for ( DeclarationWithType * assert : td->assertions ) {
     499                                if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) {
     500                                        expandAssertions( inst, back_inserter( traitDecl->members ) );
     501                                } else {
     502                                        traitDecl->members.push_back( assert->clone() );
     503                                }
     504                        }
     505                        deleteAll( td->assertions );
     506                        td->assertions.clear();
     507                } // for
     508        }
     509
     510        void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
    456511                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 
    470512                // handle other traits
    471                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     513                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
    472514                if ( ! traitDecl ) {
    473                         throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     515                        throw SemanticError( "use of undeclared trait " + traitInst->name );
    474516                } // if
    475517                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    476518                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    477519                } // 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() ) );
     520                traitInst->baseTrait = traitDecl;
    490521
    491522                // need to carry over the 'sized' status of each decl in the instance
     
    498529                        }
    499530                }
     531                // normalizeAssertions( traitInst->members );
    500532        }
    501533
     
    561593        void forallFixer( Type * func ) {
    562594                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
     595                        std::list< DeclarationWithType * > asserts;
     596                        asserts.splice( asserts.end(), type->assertions );
     597                        // expand trait instances into their members
     598                        for ( DeclarationWithType * assertion : asserts ) {
     599                                if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     600                                        // expand trait instance into all of its members
     601                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     602                                        delete traitInst;
     603                                } else {
     604                                        // pass other assertions through
     605                                        type->assertions.push_back( assertion );
     606                                } // if
     607                        } // for
     608                        // apply FixFunction to every assertion to check for invalid void type
     609                        for ( DeclarationWithType *& assertion : type->assertions ) {
     610                                FixFunction fixer;
     611                                assertion = assertion->acceptMutator( fixer );
     612                                if ( fixer.get_isVoid() ) {
     613                                        throw SemanticError( "invalid type void in assertion of function ", func );
     614                                } // if
     615                        } // for
     616                        // normalizeAssertions( type->assertions );
    587617                } // for
    588618        }
     
    752782                CompoundStmt *ret = Mutator::mutate( compoundStmt );
    753783                scopeLevel -= 1;
    754                 std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
    755                 while ( i != compoundStmt->get_kids().end() ) {
    756                         std::list< Statement * >::iterator next = i+1;
    757                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
     784                // remove and delete decl stmts
     785                filter( compoundStmt->kids, [](Statement * stmt) {
     786                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    758787                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    759                                         delete *i;
    760                                         compoundStmt->get_kids().erase( i );
     788                                        return true;
    761789                                } // if
    762790                        } // if
    763                         i = next;
    764                 } // while
     791                        return false;
     792                }, true);
    765793                typedefNames.endScope();
    766794                return ret;
     
    771799        template<typename AggDecl>
    772800        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    773                 std::list<Declaration *>::iterator it = aggDecl->get_members().begin();
    774                 for ( ; it != aggDecl->get_members().end(); ) {
    775                         std::list< Declaration * >::iterator next = it+1;
    776                         if ( dynamic_cast< TypedefDecl * >( *it ) ) {
    777                                 delete *it;
    778                                 aggDecl->get_members().erase( it );
    779                         } // if
    780                         it = next;
    781                 }
     801                filter( aggDecl->members, isTypedef, true );
    782802                return aggDecl;
    783803        }
Note: See TracChangeset for help on using the changeset viewer.