Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r4bda2cf r0b0f1dd  
    351351        namespace {
    352352                template< typename DWTList >
    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                         }
     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
    371380                }
    372381        }
     
    374383        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    375384                // Fix up parameters and return types
    376                 fixFunctionList( func->parameters, func->isVarArgs, func );
    377                 fixFunctionList( func->returnVals, false, func );
     385                fixFunctionList( func->get_parameters(), func );
     386                fixFunctionList( func->get_returnVals(), func );
    378387        }
    379388
     
    402411                for ( Expression * param : inst->parameters ) {
    403412                        if ( ! dynamic_cast< TypeExpr * >( param ) ) {
    404                                 throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );
     413                                throw SemanticError( inst, "Expression parameters for generic types are currently unsupported: " );
    405414                        }
    406415                }
     
    502511                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    503512                if ( ! traitDecl ) {
    504                         throw SemanticError( "use of undeclared trait " + traitInst->name );
     513                        throw SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
    505514                } // if
    506515                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    507                         throw SemanticError( "incorrect number of trait parameters: ", traitInst );
     516                        throw SemanticError( traitInst, "incorrect number of trait parameters: " );
    508517                } // if
    509518                traitInst->baseTrait = traitDecl;
     
    513522                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
    514523                        if ( ! expr ) {
    515                                 throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) );
     524                                throw SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " );
    516525                        }
    517526                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
     
    617626                        // apply FixFunction to every assertion to check for invalid void type
    618627                        for ( DeclarationWithType *& assertion : type->assertions ) {
    619                                 bool isVoid = fixFunction( assertion );
    620                                 if ( isVoid ) {
    621                                         throw SemanticError( "invalid type void in assertion of function ", node );
     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 " );
    622632                                } // if
    623633                        } // for
     
    663673                // were cast to void.
    664674                if ( ! returnStmt->get_expr() && returnVals.size() != 0 ) {
    665                         throw SemanticError( "Non-void function returns no values: " , returnStmt );
     675                        throw SemanticError( returnStmt, "Non-void function returns no values: " );
    666676                }
    667677        }
     
    704714                                ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
    705715                                if ( ! rtt ) {
    706                                         throw SemanticError("Cannot apply type parameters to base type of " + typeInst->name);
     716                                        throw SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
    707717                                }
    708718                                rtt->get_parameters().clear();
     
    742752                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    743753                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    744                                 throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
     754                                throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
    745755                        }
    746756                        // Cannot redefine VLA typedefs. Note: this is slightly incorrect, because our notion of VLAs
     
    749759                        // to fix this corner case likely outweighs the utility of allowing it.
    750760                        if ( isVariableLength( t1 ) || isVariableLength( t2 ) ) {
    751                                 throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
     761                                throw SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
    752762                        }
    753763                } else {
     
    847857                                type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
    848858                        } // if
    849                         TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type, aggDecl->get_linkage() ) );
     859                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    850860                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    851861                } // if
     
    898908                if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
    899909                        if ( params.size() == 0 ) {
    900                                 throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
     910                                throw SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
    901911                        }
    902912                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    903913                        if ( ! refType ) {
    904                                 throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl );
     914                                throw SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
    905915                        }
    906916                        if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
    907                                 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     917                                throw SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
    908918                        }
    909919                }
     
    940950
    941951                        sub.apply( inst );
    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 );
     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 " );
    944954                }
    945955        }
Note: See TracChangeset for help on using the changeset viewer.