Changes in src/SymTab/Validate.cc [c8e4d2f8:c1ed2ee]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
rc8e4d2f8 rc1ed2ee 46 46 #include <utility> // for pair 47 47 48 #include "AST/Decl.hpp" 49 #include "AST/Node.hpp" 50 #include "AST/Pass.hpp" 51 #include "AST/SymbolTable.hpp" 52 #include "AST/Type.hpp" 48 53 #include "CodeGen/CodeGenerator.h" // for genName 49 54 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign … … 124 129 125 130 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 126 struct EnumAndPointerDecay {131 struct EnumAndPointerDecay_old { 127 132 void previsit( EnumDecl *aggregateDecl ); 128 133 void previsit( FunctionType *func ); … … 130 135 131 136 /// Associates forward declarations of aggregates with their definitions 132 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {133 LinkReferenceToTypes ( const Indexer *indexer );137 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 138 LinkReferenceToTypes_old( const Indexer *indexer ); 134 139 void postvisit( TypeInstType *typeInst ); 135 140 … … 165 170 166 171 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 167 struct ForallPointerDecay final {172 struct ForallPointerDecay_old final { 168 173 void previsit( ObjectDecl * object ); 169 174 void previsit( FunctionDecl * func ); … … 290 295 291 296 void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) { 292 PassVisitor<EnumAndPointerDecay > epc;293 PassVisitor<LinkReferenceToTypes > lrt( nullptr );294 PassVisitor<ForallPointerDecay > fpd;297 PassVisitor<EnumAndPointerDecay_old> epc; 298 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr ); 299 PassVisitor<ForallPointerDecay_old> fpd; 295 300 PassVisitor<CompoundLiteral> compoundliteral; 296 301 PassVisitor<ValidateGenericParameters> genericParams; … … 305 310 ReplaceTypedef::replaceTypedef( translationUnit ); 306 311 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 307 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling312 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling 308 313 } 309 314 { … … 314 319 }); 315 320 Stats::Time::TimeBlock("Fix Qualified Types", [&]() { 316 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes , because aggregate members are accessed321 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 317 322 }); 318 323 Stats::Time::TimeBlock("Hoist Structs", [&]() { … … 326 331 Stats::Heap::newPass("validate-C"); 327 332 Stats::Time::BlockGuard guard("validate-C"); 328 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes 333 acceptAll( translationUnit, genericParams ); // check as early as possible - can't happen before LinkReferenceToTypes_old 329 334 VerifyCtorDtorAssign::verify( translationUnit ); // must happen before autogen, because autogen examines existing ctor/dtors 330 335 ReturnChecker::checkFunctionReturns( translationUnit ); … … 344 349 }); 345 350 Stats::Time::TimeBlock("Generate Autogen routines", [&]() { 346 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay 351 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old 347 352 }); 348 353 } … … 385 390 386 391 void validateType( Type *type, const Indexer *indexer ) { 387 PassVisitor<EnumAndPointerDecay > epc;388 PassVisitor<LinkReferenceToTypes > lrt( indexer );389 PassVisitor<ForallPointerDecay > fpd;392 PassVisitor<EnumAndPointerDecay_old> epc; 393 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); 394 PassVisitor<ForallPointerDecay_old> fpd; 390 395 type->accept( epc ); 391 396 type->accept( lrt ); … … 586 591 } 587 592 588 void EnumAndPointerDecay ::previsit( EnumDecl *enumDecl ) {593 void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) { 589 594 // Set the type of each member of the enumeration to be EnumConstant 590 595 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { … … 618 623 } 619 624 620 void EnumAndPointerDecay ::previsit( FunctionType *func ) {625 void EnumAndPointerDecay_old::previsit( FunctionType *func ) { 621 626 // Fix up parameters and return types 622 627 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 624 629 } 625 630 626 LinkReferenceToTypes ::LinkReferenceToTypes( const Indexer *other_indexer ) {631 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) { 627 632 if ( other_indexer ) { 628 633 local_indexer = other_indexer; … … 632 637 } 633 638 634 void LinkReferenceToTypes ::postvisit( EnumInstType *enumInst ) {639 void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) { 635 640 EnumDecl *st = local_indexer->lookupEnum( enumInst->name ); 636 641 // it's not a semantic error if the enum is not found, just an implicit forward declaration … … 652 657 } 653 658 654 void LinkReferenceToTypes ::postvisit( StructInstType *structInst ) {659 void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) { 655 660 StructDecl *st = local_indexer->lookupStruct( structInst->name ); 656 661 // it's not a semantic error if the struct is not found, just an implicit forward declaration … … 665 670 } 666 671 667 void LinkReferenceToTypes ::postvisit( UnionInstType *unionInst ) {672 void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) { 668 673 UnionDecl *un = local_indexer->lookupUnion( unionInst->name ); 669 674 // it's not a semantic error if the union is not found, just an implicit forward declaration … … 678 683 } 679 684 680 void LinkReferenceToTypes ::previsit( QualifiedType * ) {685 void LinkReferenceToTypes_old::previsit( QualifiedType * ) { 681 686 visit_children = false; 682 687 } 683 688 684 void LinkReferenceToTypes ::postvisit( QualifiedType * qualType ) {689 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 685 690 // linking only makes sense for the 'oldest ancestor' of the qualified type 686 691 qualType->parent->accept( *visitor ); … … 729 734 } 730 735 731 void LinkReferenceToTypes ::postvisit( TraitDecl * traitDecl ) {736 void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) { 732 737 if ( traitDecl->name == "sized" ) { 733 738 // "sized" is a special trait - flick the sized status on for the type variable … … 751 756 } 752 757 753 void LinkReferenceToTypes ::postvisit( TraitInstType * traitInst ) {758 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 754 759 // handle other traits 755 760 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name ); … … 777 782 } 778 783 779 void LinkReferenceToTypes ::postvisit( EnumDecl *enumDecl ) {784 void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) { 780 785 // visit enum members first so that the types of self-referencing members are updated properly 781 786 if ( enumDecl->body ) { … … 799 804 } 800 805 801 void LinkReferenceToTypes ::renameGenericParams( std::list< TypeDecl * > & params ) {806 void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) { 802 807 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 803 808 // forall(otype T) … … 817 822 } 818 823 819 void LinkReferenceToTypes ::previsit( StructDecl * structDecl ) {824 void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) { 820 825 renameGenericParams( structDecl->parameters ); 821 826 } 822 827 823 void LinkReferenceToTypes ::previsit( UnionDecl * unionDecl ) {828 void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) { 824 829 renameGenericParams( unionDecl->parameters ); 825 830 } 826 831 827 void LinkReferenceToTypes ::postvisit( StructDecl *structDecl ) {832 void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) { 828 833 // visit struct members first so that the types of self-referencing members are updated properly 829 834 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 839 844 } 840 845 841 void LinkReferenceToTypes ::postvisit( UnionDecl *unionDecl ) {846 void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) { 842 847 if ( unionDecl->body ) { 843 848 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); … … 851 856 } 852 857 853 void LinkReferenceToTypes ::postvisit( TypeInstType *typeInst ) {858 void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) { 854 859 // ensure generic parameter instances are renamed like the base type 855 860 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; … … 888 893 } 889 894 890 void ForallPointerDecay ::previsit( ObjectDecl *object ) {895 void ForallPointerDecay_old::previsit( ObjectDecl *object ) { 891 896 // ensure that operator names only apply to functions or function pointers 892 897 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 896 901 } 897 902 898 void ForallPointerDecay ::previsit( FunctionDecl *func ) {903 void ForallPointerDecay_old::previsit( FunctionDecl *func ) { 899 904 func->fixUniqueId(); 900 905 } 901 906 902 void ForallPointerDecay ::previsit( FunctionType * ftype ) {907 void ForallPointerDecay_old::previsit( FunctionType * ftype ) { 903 908 forallFixer( ftype->forall, ftype ); 904 909 } 905 910 906 void ForallPointerDecay ::previsit( StructDecl * aggrDecl ) {911 void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) { 907 912 forallFixer( aggrDecl->parameters, aggrDecl ); 908 913 } 909 914 910 void ForallPointerDecay ::previsit( UnionDecl * aggrDecl ) {915 void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) { 911 916 forallFixer( aggrDecl->parameters, aggrDecl ); 912 917 } … … 1368 1373 } 1369 1374 1370 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1371 #warning unimplemented 1372 (void)type; (void)symtab; 1373 assert(false); 1374 return nullptr; 1375 } 1375 namespace { 1376 /// Replaces enum types by int, and function/array types in function parameter and return 1377 /// lists by appropriate pointers 1378 struct EnumAndPointerDecay_new { 1379 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { 1380 // set the type of each member of the enumeration to be EnumConstant 1381 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1382 // build new version of object with EnumConstant 1383 ast::ptr< ast::ObjectDecl > obj = 1384 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1385 obj.get_and_mutate()->type = 1386 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1387 1388 // set into decl 1389 ast::EnumDecl * mut = mutate( enumDecl ); 1390 mut->members[i] = obj.get(); 1391 enumDecl = mut; 1392 } 1393 return enumDecl; 1394 } 1395 1396 static const ast::FunctionType * fixFunctionList( 1397 const ast::FunctionType * func, 1398 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1399 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1400 ) { 1401 const auto & dwts = func->*field; 1402 unsigned nvals = dwts.size(); 1403 bool hasVoid = false; 1404 for ( unsigned i = 0; i < nvals; ++i ) { 1405 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1406 } 1407 1408 // the only case in which "void" is valid is where it is the only one in the list 1409 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1410 SemanticError( 1411 dwts.front()->location, func, "invalid type void in function type" ); 1412 } 1413 1414 // one void is the only thing in the list, remove it 1415 if ( hasVoid ) { 1416 func = ast::mutate_field( 1417 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1418 } 1419 1420 return func; 1421 } 1422 1423 const ast::FunctionType * previsit( const ast::FunctionType * func ) { 1424 func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs ); 1425 return fixFunctionList( func, &ast::FunctionType::returns ); 1426 } 1427 }; 1428 1429 /// Associates forward declarations of aggregates with their definitions 1430 struct LinkReferenceToTypes_new final 1431 : public ast::WithSymbolTable, public ast::WithGuards, public 1432 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1433 1434 const ast::SymbolTable * localSyms; 1435 1436 LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {} 1437 1438 #warning incomplete 1439 }; 1440 1441 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1442 /// each object and function declaration a unique ID 1443 struct ForallPointerDecay_new { 1444 #warning incomplete 1445 }; 1446 } // anonymous namespace 1447 1448 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1449 ast::Pass< EnumAndPointerDecay_new > epc; 1450 ast::Pass< LinkReferenceToTypes_new > lrt{ symtab }; 1451 ast::Pass< ForallPointerDecay_new > fpd; 1452 1453 return type->accept( epc )->accept( lrt )->accept( fpd ); 1454 } 1455 1376 1456 } // namespace SymTab 1377 1457
Note: See TracChangeset
for help on using the changeset viewer.