Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r5809461 r2ae171d8  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 28 13:47:23 2017
    13 // Update Count     : 359
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tus Aug  8 13:27:00 2017
     13// Update Count     : 358
    1414//
    1515
     
    127127          public:
    128128                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    129                 using Parent::visit;
    130                 void visit( TypeInstType *typeInst ) final;
    131 
     129                using Parent::visit;
    132130                void visit( EnumInstType *enumInst ) final;
    133131                void visit( StructInstType *structInst ) final;
    134132                void visit( UnionInstType *unionInst ) final;
    135                 void visit( TraitInstType *traitInst ) final;
    136 
     133                void visit( TraitInstType *contextInst ) final;
    137134                void visit( EnumDecl *enumDecl ) final;
    138135                void visit( StructDecl *structDecl ) final;
    139136                void visit( UnionDecl *unionDecl ) final;
    140                 void visit( TraitDecl * traitDecl ) final;
    141 
     137                void visit( TypeInstType *typeInst ) final;
    142138          private:
    143139                const Indexer *indexer;
     
    244240        };
    245241
    246         struct LabelAddressFixer final : public WithGuards {
    247                 std::set< Label > labels;
    248 
    249                 void premutate( FunctionDecl * funcDecl );
    250                 Expression * postmutate( AddressExpr * addrExpr );
    251         };
    252242
    253243        FunctionDecl * dereferenceOperator = nullptr;
     
    263253                PassVisitor<ValidateGenericParameters> genericParams;
    264254                PassVisitor<FindSpecialDeclarations> finder;
    265                 PassVisitor<LabelAddressFixer> labelAddrFixer;
    266255
    267256                EliminateTypedef::eliminateTypedef( translationUnit );
     
    281270                ArrayLength::computeLength( translationUnit );
    282271                acceptAll( translationUnit, finder );
    283                 mutateAll( translationUnit, labelAddrFixer );
    284272        }
    285273
     
    299287
    300288        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
    301304        }
    302305
     
    450453        }
    451454
    452         template< typename Decl >
    453         void normalizeAssertions( std::list< Decl * > & assertions ) {
    454                 // ensure no duplicate trait members after the clone
    455                 auto pred = [](Decl * d1, Decl * d2) {
    456                         // only care if they're equal
    457                         DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 );
    458                         DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
    459                         if ( dwt1 && dwt2 ) {
    460                                 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
    461                                         // std::cerr << "=========== equal:" << std::endl;
    462                                         // std::cerr << "d1: " << d1 << std::endl;
    463                                         // std::cerr << "d2: " << d2 << std::endl;
    464                                         return false;
    465                                 }
     455        void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     456                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 );
    466461                        }
    467                         return d1 < d2;
    468                 };
    469                 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred );
    470                 // if ( unique_members.size() != assertions.size() ) {
    471                 //      std::cerr << "============different" << std::endl;
    472                 //      std::cerr << unique_members.size() << " " << assertions.size() << std::endl;
    473                 // }
    474 
    475                 std::list< Decl * > order;
    476                 order.splice( order.end(), assertions );
    477                 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) {
    478                         return unique_members.count( decl );
    479                 });
    480         }
    481 
    482         // expand assertions from trait instance, performing the appropriate type variable substitutions
    483         template< typename Iterator >
    484         void expandAssertions( TraitInstType * inst, Iterator out ) {
    485                 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
    486                 std::list< DeclarationWithType * > asserts;
    487                 for ( Declaration * decl : inst->baseTrait->members ) {
    488                         asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) );
    489                 }
    490                 // substitute trait decl parameters for instance parameters
    491                 applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out );
    492         }
    493 
    494         void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
    495                 Parent::visit( traitDecl );
    496 
    497                 if ( traitDecl->name == "sized" ) {
    498                         // "sized" is a special trait - flick the sized status on for the type variable
    499                         assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() );
    500                         TypeDecl * td = traitDecl->parameters.front();
    501                         td->set_sized( true );
    502                 }
    503 
    504                 // move assertions from type parameters into the body of the trait
    505                 for ( TypeDecl * td : traitDecl->parameters ) {
    506                         for ( DeclarationWithType * assert : td->assertions ) {
    507                                 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) {
    508                                         expandAssertions( inst, back_inserter( traitDecl->members ) );
    509                                 } else {
    510                                         traitDecl->members.push_back( assert->clone() );
    511                                 }
    512                         }
    513                         deleteAll( td->assertions );
    514                         td->assertions.clear();
    515                 } // for
    516         }
    517 
    518         void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
    519                 Parent::visit( traitInst );
     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
    520470                // handle other traits
    521                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
     471                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
    522472                if ( ! traitDecl ) {
    523                         throw SemanticError( "use of undeclared trait " + traitInst->name );
     473                        throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
    524474                } // if
    525475                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    526476                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    527477                } // if
    528                 traitInst->baseTrait = traitDecl;
     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() ) );
    529490
    530491                // need to carry over the 'sized' status of each decl in the instance
     
    537498                        }
    538499                }
    539                 // normalizeAssertions( traitInst->members );
    540500        }
    541501
     
    601561        void forallFixer( Type * func ) {
    602562                for ( TypeDecl * type : func->get_forall() ) {
    603                         std::list< DeclarationWithType * > asserts;
    604                         asserts.splice( asserts.end(), type->assertions );
    605                         // expand trait instances into their members
    606                         for ( DeclarationWithType * assertion : asserts ) {
    607                                 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    608                                         // expand trait instance into all of its members
    609                                         expandAssertions( traitInst, back_inserter( type->assertions ) );
    610                                         delete traitInst;
    611                                 } else {
    612                                         // pass other assertions through
    613                                         type->assertions.push_back( assertion );
    614                                 } // if
    615                         } // for
    616                         // apply FixFunction to every assertion to check for invalid void type
    617                         for ( DeclarationWithType *& assertion : type->assertions ) {
    618                                 FixFunction fixer;
    619                                 assertion = assertion->acceptMutator( fixer );
    620                                 if ( fixer.get_isVoid() ) {
    621                                         throw SemanticError( "invalid type void in assertion of function ", func );
    622                                 } // if
    623                         } // for
    624                         // normalizeAssertions( type->assertions );
     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
    625587                } // for
    626588        }
     
    702664                } else {
    703665                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
    704                         assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->get_name().c_str() );
     666                        assertf( base != typedeclNames.end(), "Can't find typedecl name %s", typeInst->get_name().c_str() );
    705667                        typeInst->set_baseType( base->second );
    706668                } // if
     
    790752                CompoundStmt *ret = Mutator::mutate( compoundStmt );
    791753                scopeLevel -= 1;
    792                 // remove and delete decl stmts
    793                 filter( compoundStmt->kids, [](Statement * stmt) {
    794                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     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 ) ) {
    795758                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    796                                         return true;
     759                                        delete *i;
     760                                        compoundStmt->get_kids().erase( i );
    797761                                } // if
    798762                        } // if
    799                         return false;
    800                 }, true);
     763                        i = next;
     764                } // while
    801765                typedefNames.endScope();
    802766                return ret;
     
    807771        template<typename AggDecl>
    808772        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    809                 filter( aggDecl->members, isTypedef, true );
     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                }
    810782                return aggDecl;
    811783        }
     
    985957        }
    986958
    987         struct LabelFinder {
    988                 std::set< Label > & labels;
    989                 LabelFinder( std::set< Label > & labels ) : labels( labels ) {}
    990                 void previsit( Statement * stmt ) {
    991                         for ( Label & l : stmt->labels ) {
    992                                 labels.insert( l );
    993                         }
    994                 }
    995         };
    996 
    997         void LabelAddressFixer::premutate( FunctionDecl * funcDecl ) {
    998                 GuardValue( labels );
    999                 PassVisitor<LabelFinder> finder( labels );
    1000                 funcDecl->accept( finder );
    1001         }
    1002 
    1003         Expression * LabelAddressFixer::postmutate( AddressExpr * addrExpr ) {
    1004                 // convert &&label into label address
    1005                 if ( AddressExpr * inner = dynamic_cast< AddressExpr * >( addrExpr->arg ) ) {
    1006                         if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
    1007                                 if ( labels.count( nameExpr->name ) ) {
    1008                                         Label name = nameExpr->name;
    1009                                         delete addrExpr;
    1010                                         return new LabelAddressExpr( name );
    1011                                 }
    1012                         }
    1013                 }
    1014                 return addrExpr;
    1015         }
    1016 
    1017959        void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
    1018960                if ( ! dereferenceOperator ) {
Note: See TracChangeset for help on using the changeset viewer.