Changes in src/SymTab/Validate.cc [b3b2077:9facf3b]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
rb3b2077 r9facf3b 61 61 #include <algorithm> 62 62 #include "InitTweak/InitTweak.h" 63 #include "CodeGen/CodeGenerator.h" 63 64 64 65 #define debugPrint( x ) if ( doDebug ) { std::cout << x; } 65 66 66 67 namespace SymTab { 67 class HoistStruct : public Visitor {68 class HoistStruct final : public Visitor { 68 69 public: 69 70 /// Flattens nested struct types … … 86 87 }; 87 88 89 /// Fix return types so that every function returns exactly one value 90 class ReturnTypeFixer final : public Visitor { 91 public: 92 93 typedef Visitor Parent; 94 using Parent::visit; 95 96 static void fix( std::list< Declaration * > &translationUnit ); 97 98 virtual void visit( FunctionDecl * functionDecl ); 99 100 virtual void visit( FunctionType * ftype ); 101 }; 102 88 103 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 89 class EnumAndPointerDecayPass : public Visitor {104 class EnumAndPointerDecayPass final : public Visitor { 90 105 typedef Visitor Parent; 91 106 virtual void visit( EnumDecl *aggregateDecl ); … … 94 109 95 110 /// Associates forward declarations of aggregates with their definitions 96 class Pass2: public Indexer {111 class LinkReferenceToTypes final : public Indexer { 97 112 typedef Indexer Parent; 98 113 public: 99 Pass2( bool doDebug, const Indexer *indexer );114 LinkReferenceToTypes( bool doDebug, const Indexer *indexer ); 100 115 private: 101 virtual void visit( StructInstType *structInst ); 102 virtual void visit( UnionInstType *unionInst ); 103 virtual void visit( TraitInstType *contextInst ); 104 virtual void visit( StructDecl *structDecl ); 105 virtual void visit( UnionDecl *unionDecl ); 106 virtual void visit( TypeInstType *typeInst ); 116 using Indexer::visit; 117 void visit( StructInstType *structInst ) final; 118 void visit( UnionInstType *unionInst ) final; 119 void visit( TraitInstType *contextInst ) final; 120 void visit( StructDecl *structDecl ) final; 121 void visit( UnionDecl *unionDecl ) final; 122 void visit( TypeInstType *typeInst ) final; 107 123 108 124 const Indexer *indexer; … … 182 198 }; 183 199 184 class CompoundLiteral : public GenPoly::DeclMutator {200 class CompoundLiteral final : public GenPoly::DeclMutator { 185 201 DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass; 186 202 187 virtual DeclarationWithType * mutate( ObjectDecl *objectDecl ); 188 virtual Expression *mutate( CompoundLiteralExpr *compLitExpr ); 203 using GenPoly::DeclMutator::mutate; 204 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final; 205 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final; 189 206 }; 190 207 191 208 void validate( std::list< Declaration * > &translationUnit, bool doDebug ) { 192 209 EnumAndPointerDecayPass epc; 193 Pass2 pass2( doDebug, 0 );210 LinkReferenceToTypes lrt( doDebug, 0 ); 194 211 Pass3 pass3( 0 ); 195 212 CompoundLiteral compoundliteral; … … 197 214 EliminateTypedef::eliminateTypedef( translationUnit ); 198 215 HoistStruct::hoistStruct( translationUnit ); 216 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 199 217 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass 200 218 acceptAll( translationUnit, epc ); 201 acceptAll( translationUnit, pass2);219 acceptAll( translationUnit, lrt ); 202 220 ReturnChecker::checkFunctionReturns( translationUnit ); 203 221 compoundliteral.mutateDeclarationList( translationUnit ); … … 208 226 void validateType( Type *type, const Indexer *indexer ) { 209 227 EnumAndPointerDecayPass epc; 210 Pass2 pass2( false, indexer );228 LinkReferenceToTypes lrt( false, indexer ); 211 229 Pass3 pass3( indexer ); 212 230 type->accept( epc ); 213 type->accept( pass2);231 type->accept( lrt ); 214 232 type->accept( pass3 ); 215 233 } … … 322 340 } 323 341 324 Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {342 LinkReferenceToTypes::LinkReferenceToTypes( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) { 325 343 if ( other_indexer ) { 326 344 indexer = other_indexer; … … 330 348 } 331 349 332 void Pass2::visit( StructInstType *structInst ) {350 void LinkReferenceToTypes::visit( StructInstType *structInst ) { 333 351 Parent::visit( structInst ); 334 352 StructDecl *st = indexer->lookupStruct( structInst->get_name() ); … … 344 362 } 345 363 346 void Pass2::visit( UnionInstType *unionInst ) {364 void LinkReferenceToTypes::visit( UnionInstType *unionInst ) { 347 365 Parent::visit( unionInst ); 348 366 UnionDecl *un = indexer->lookupUnion( unionInst->get_name() ); … … 357 375 } 358 376 359 void Pass2::visit( TraitInstType *contextInst ) {377 void LinkReferenceToTypes::visit( TraitInstType *contextInst ) { 360 378 Parent::visit( contextInst ); 379 if ( contextInst->get_name() == "sized" ) { 380 // "sized" is a special trait with no members - just flick the sized status on for the type variable 381 if ( contextInst->get_parameters().size() != 1 ) { 382 throw SemanticError( "incorrect number of context parameters: ", contextInst ); 383 } 384 TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() ); 385 TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() ); 386 TypeDecl * decl = inst->get_baseType(); 387 decl->set_sized( true ); 388 // since "sized" is special, the next few steps don't apply 389 return; 390 } 361 391 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() ); 362 392 if ( ! ctx ) { … … 384 414 } 385 415 386 void Pass2::visit( StructDecl *structDecl ) {416 void LinkReferenceToTypes::visit( StructDecl *structDecl ) { 387 417 // visit struct members first so that the types of self-referencing members are updated properly 388 418 Parent::visit( structDecl ); … … 398 428 } 399 429 400 void Pass2::visit( UnionDecl *unionDecl ) {430 void LinkReferenceToTypes::visit( UnionDecl *unionDecl ) { 401 431 Parent::visit( unionDecl ); 402 432 if ( ! unionDecl->get_members().empty() ) { … … 411 441 } 412 442 413 void Pass2::visit( TypeInstType *typeInst ) {443 void LinkReferenceToTypes::visit( TypeInstType *typeInst ) { 414 444 if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) { 415 445 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { … … 582 612 583 613 typedeclNames[ typeDecl->get_name() ] = typeDecl; 584 return typeDecl;614 return Mutator::mutate( typeDecl ); 585 615 } 586 616 … … 652 682 void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 653 683 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 654 Type *type ;684 Type *type = nullptr; 655 685 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 656 686 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 733 763 return new VariableExpr( newtempvar ); 734 764 } 765 766 void ReturnTypeFixer::fix( std::list< Declaration * > &translationUnit ) { 767 ReturnTypeFixer fixer; 768 acceptAll( translationUnit, fixer ); 769 } 770 771 void ReturnTypeFixer::visit( FunctionDecl * functionDecl ) { 772 Parent::visit( functionDecl ); 773 FunctionType * ftype = functionDecl->get_functionType(); 774 std::list< DeclarationWithType * > & retVals = ftype->get_returnVals(); 775 assertf( retVals.size() == 0 || retVals.size() == 1, "Function %s has too many return values: %d", functionDecl->get_name().c_str(), retVals.size() ); 776 if ( retVals.size() == 1 ) { 777 // ensure all function return values have a name - use the name of the function to disambiguate (this also provides a nice bit of help for debugging) 778 // ensure other return values have a name 779 DeclarationWithType * ret = retVals.front(); 780 if ( ret->get_name() == "" ) { 781 ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) ); 782 } 783 } 784 } 785 786 void ReturnTypeFixer::visit( FunctionType * ftype ) { 787 // xxx - need to handle named return values - this information needs to be saved somehow 788 // so that resolution has access to the names. 789 // Note that this pass needs to happen early so that other passes which look for tuple types 790 // find them in all of the right places, including function return types. 791 std::list< DeclarationWithType * > & retVals = ftype->get_returnVals(); 792 if ( retVals.size() > 1 ) { 793 // generate a single return parameter which is the tuple of all of the return values 794 TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 795 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 796 ObjectDecl * newRet = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) ); 797 deleteAll( retVals ); 798 retVals.clear(); 799 retVals.push_back( newRet ); 800 } 801 } 735 802 } // namespace SymTab 736 803
Note: See TracChangeset
for help on using the changeset viewer.