Changeset 4bda2cf
- Timestamp:
- Feb 9, 2018, 10:06:16 AM (7 years ago)
- 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)
- Location:
- src/SymTab
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/FixFunction.cc
rff878b7 r4bda2cf 36 36 } 37 37 38 // xxx - this passes on void[], e.g. 39 // void foo(void [10]); 40 // does not cause an error 41 38 42 Type * FixFunction::postmutate(ArrayType *arrayType) { 39 43 // need to recursively mutate the base type in order for multi-dimensional arrays to work. … … 62 66 void FixFunction::premutate(ZeroType *) { visit_children = false; } 63 67 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 } 64 74 } // namespace SymTab 65 75 -
src/SymTab/FixFunction.h
rff878b7 r4bda2cf 47 47 bool isVoid; 48 48 }; 49 50 bool fixFunction( DeclarationWithType *& ); 49 51 } // namespace SymTab 50 52 -
src/SymTab/Validate.cc
rff878b7 r4bda2cf 351 351 namespace { 352 352 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 } 380 371 } 381 372 } … … 383 374 void EnumAndPointerDecay::previsit( FunctionType *func ) { 384 375 // 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 ); 387 378 } 388 379 … … 626 617 // apply FixFunction to every assertion to check for invalid void type 627 618 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 ) { 631 621 throw SemanticError( "invalid type void in assertion of function ", node ); 632 622 } // if
Note: See TracChangeset
for help on using the changeset viewer.