Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r0b0f1dd r4bda2cf  
    351351        namespace {
    352352                template< typename DWTList >
    353                 void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    354                         // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    355                         // entirely. other fix ups are handled by the FixFunction class
    356                         typedef typename DWTList::iterator DWTIterator;
    357                         DWTIterator begin( dwts.begin() ), end( dwts.end() );
    358                         if ( begin == end ) return;
    359                         PassVisitor<FixFunction> fixer;
    360                         DWTIterator i = begin;
    361                         *i = (*i)->acceptMutator( fixer );
    362                         if ( fixer.pass.isVoid ) {
    363                                 DWTIterator j = i;
    364                                 ++i;
    365                                 delete *j;
    366                                 dwts.erase( j );
    367                                 if ( i != end ) {
    368                                         throw SemanticError( func, "invalid type void in function type " );
    369                                 } // if
    370                         } else {
    371                                 ++i;
    372                                 for ( ; i != end; ++i ) {
    373                                         PassVisitor<FixFunction> fixer;
    374                                         *i = (*i)->acceptMutator( fixer );
    375                                         if ( fixer.pass.isVoid ) {
    376                                                 throw SemanticError( func, "invalid type void in function type " );
    377                                         } // if
    378                                 } // for
    379                         } // if
     353                void fixFunctionList( DWTList & dwts, bool isVarArgs, FunctionType * func ) {
     354                        auto nvals = dwts.size();
     355                        bool containsVoid = false;
     356                        for ( auto & dwt : dwts ) {
     357                                // fix each DWT and record whether a void was found
     358                                containsVoid |= fixFunction( dwt );
     359                        }
     360
     361                        // the only case in which "void" is valid is where it is the only one in the list
     362                        if ( containsVoid && ( nvals > 1 || isVarArgs ) ) {
     363                                throw SemanticError( "invalid type void in function type ", func );
     364                        }
     365
     366                        // one void is the only thing in the list; remove it.
     367                        if ( containsVoid ) {
     368                                delete dwts.front();
     369                                dwts.clear();
     370                        }
    380371                }
    381372        }
     
    383374        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    384375                // Fix up parameters and return types
    385                 fixFunctionList( func->get_parameters(), func );
    386                 fixFunctionList( func->get_returnVals(), func );
     376                fixFunctionList( func->parameters, func->isVarArgs, func );
     377                fixFunctionList( func->returnVals, false, func );
    387378        }
    388379
     
    411402                for ( Expression * param : inst->parameters ) {
    412403                        if ( ! dynamic_cast< TypeExpr * >( param ) ) {
    413                                 throw SemanticError( inst, "Expression parameters for generic types are currently unsupported: " );
     404                                throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );
    414405                        }
    415406                }
     
    511502                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    512503                if ( ! traitDecl ) {
    513                         throw SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
     504                        throw SemanticError( "use of undeclared trait " + traitInst->name );
    514505                } // if
    515506                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    516                         throw SemanticError( traitInst, "incorrect number of trait parameters: " );
     507                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    517508                } // if
    518509                traitInst->baseTrait = traitDecl;
     
    522513                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
    523514                        if ( ! expr ) {
    524                                 throw SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " );
     515                                throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) );
    525516                        }
    526517                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
     
    626617                        // apply FixFunction to every assertion to check for invalid void type
    627618                        for ( DeclarationWithType *& assertion : type->assertions ) {
    628                                 PassVisitor<FixFunction> fixer;
    629                                 assertion = assertion->acceptMutator( fixer );
    630                                 if ( fixer.pass.isVoid ) {
    631                                         throw SemanticError( node, "invalid type void in assertion of function " );
     619                                bool isVoid = fixFunction( assertion );
     620                                if ( isVoid ) {
     621                                        throw SemanticError( "invalid type void in assertion of function ", node );
    632622                                } // if
    633623                        } // for
     
    673663                // were cast to void.
    674664                if ( ! returnStmt->get_expr() && returnVals.size() != 0 ) {
    675                         throw SemanticError( returnStmt, "Non-void function returns no values: " );
     665                        throw SemanticError( "Non-void function returns no values: " , returnStmt );
    676666                }
    677667        }
     
    714704                                ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
    715705                                if ( ! rtt ) {
    716                                         throw SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
     706                                        throw SemanticError("Cannot apply type parameters to base type of " + typeInst->name);
    717707                                }
    718708                                rtt->get_parameters().clear();
     
    752742                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    753743                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    754                                 throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
     744                                throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
    755745                        }
    756746                        // Cannot redefine VLA typedefs. Note: this is slightly incorrect, because our notion of VLAs
     
    759749                        // to fix this corner case likely outweighs the utility of allowing it.
    760750                        if ( isVariableLength( t1 ) || isVariableLength( t2 ) ) {
    761                                 throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
     751                                throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
    762752                        }
    763753                } else {
     
    857847                                type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
    858848                        } // if
    859                         TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
     849                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    860850                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    861851                } // if
     
    908898                if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
    909899                        if ( params.size() == 0 ) {
    910                                 throw SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
     900                                throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
    911901                        }
    912902                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    913903                        if ( ! refType ) {
    914                                 throw SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
     904                                throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl );
    915905                        }
    916906                        if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
    917                                 throw SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
     907                                throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
    918908                        }
    919909                }
     
    950940
    951941                        sub.apply( inst );
    952                         if ( args.size() < params->size() ) throw SemanticError( inst, "Too few type arguments in generic type " );
    953                         if ( args.size() > params->size() ) throw SemanticError( inst, "Too many type arguments in generic type " );
     942                        if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst );
     943                        if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst );
    954944                }
    955945        }
Note: See TracChangeset for help on using the changeset viewer.