Changeset 4bda2cf for src/SymTab


Ignore:
Timestamp:
Feb 9, 2018, 10:06:16 AM (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:
b8a52f5
Parents:
ff878b7
git-author:
Rob Schluntz <rschlunt@…> (02/08/18 16:25:33)
git-committer:
Rob Schluntz <rschlunt@…> (02/09/18 10:06:16)
Message:

Refactor FixFunction?, add error for void foo(void, ...)

Location:
src/SymTab
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/FixFunction.cc

    rff878b7 r4bda2cf  
    3636        }
    3737
     38        // xxx - this passes on void[], e.g.
     39        //   void foo(void [10]);
     40        // does not cause an error
     41
    3842        Type * FixFunction::postmutate(ArrayType *arrayType) {
    3943                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
     
    6266        void FixFunction::premutate(ZeroType *) { visit_children = false; }
    6367        void FixFunction::premutate(OneType *) { visit_children = false; }
     68
     69        bool fixFunction( DeclarationWithType *& dwt ) {
     70                PassVisitor<FixFunction> fixer;
     71                dwt = dwt->acceptMutator( fixer );
     72                return fixer.pass.isVoid;
     73        }
    6474} // namespace SymTab
    6575
  • src/SymTab/FixFunction.h

    rff878b7 r4bda2cf  
    4747                bool isVoid;
    4848        };
     49
     50        bool fixFunction( DeclarationWithType *& );
    4951} // namespace SymTab
    5052
  • src/SymTab/Validate.cc

    rff878b7 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( "invalid type void in function type ", func );
    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( "invalid type void in function type ", func );
    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
     
    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 ) {
     619                                bool isVoid = fixFunction( assertion );
     620                                if ( isVoid ) {
    631621                                        throw SemanticError( "invalid type void in assertion of function ", node );
    632622                                } // if
Note: See TracChangeset for help on using the changeset viewer.