Changes in src/SymTab/Validate.cc [8fd52e90:c1398e4]
- File:
-
- 1 edited
-
src/SymTab/Validate.cc (modified) (68 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r8fd52e90 rc1398e4 119 119 120 120 private: 121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl ); 122 122 123 123 AggregateDecl * parentAggr = nullptr; … … 134 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 135 135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl );137 void previsit( FunctionType * func );136 void previsit( EnumDecl *aggregateDecl ); 137 void previsit( FunctionType *func ); 138 138 }; 139 139 140 140 /// Associates forward declarations of aggregates with their definitions 141 141 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 142 LinkReferenceToTypes_old( const Indexer * indexer );143 void postvisit( TypeInstType * typeInst );144 145 void postvisit( EnumInstType * enumInst );146 void postvisit( StructInstType * structInst );147 void postvisit( UnionInstType * unionInst );148 void postvisit( TraitInstType * traitInst );142 LinkReferenceToTypes_old( const Indexer *indexer ); 143 void postvisit( TypeInstType *typeInst ); 144 145 void postvisit( EnumInstType *enumInst ); 146 void postvisit( StructInstType *structInst ); 147 void postvisit( UnionInstType *unionInst ); 148 void postvisit( TraitInstType *traitInst ); 149 149 void previsit( QualifiedType * qualType ); 150 150 void postvisit( QualifiedType * qualType ); 151 151 152 void postvisit( EnumDecl * enumDecl );153 void postvisit( StructDecl * structDecl );154 void postvisit( UnionDecl * unionDecl );152 void postvisit( EnumDecl *enumDecl ); 153 void postvisit( StructDecl *structDecl ); 154 void postvisit( UnionDecl *unionDecl ); 155 155 void postvisit( TraitDecl * traitDecl ); 156 156 157 void previsit( StructDecl * structDecl );158 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl *structDecl ); 158 void previsit( UnionDecl *unionDecl ); 159 159 160 160 void renameGenericParams( std::list< TypeDecl * > & params ); 161 161 162 162 private: 163 const Indexer * local_indexer;163 const Indexer *local_indexer; 164 164 165 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 239 239 240 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl );241 void handleAggregate( AggDecl *aggregateDecl ); 242 242 243 243 void previsit( StructDecl * aggregateDecl ); … … 252 252 static void verify( std::list< Declaration * > &translationUnit ); 253 253 254 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl *funcDecl ); 255 255 }; 256 256 … … 287 287 Type::StorageClasses storageClasses; 288 288 289 void premutate( ObjectDecl * objectDecl );290 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl *objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr *compLitExpr ); 291 291 }; 292 292 … … 393 393 } 394 394 395 void validateType( Type * type, const Indexer *indexer ) {395 void validateType( Type *type, const Indexer *indexer ) { 396 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); … … 496 496 } 497 497 498 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration *decl ) { 499 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 500 500 } … … 515 515 516 516 template< typename AggDecl > 517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) { 518 518 if ( parentAggr ) { 519 519 aggregateDecl->parent = parentAggr; … … 560 560 561 561 562 bool isTypedef( Declaration * decl ) {562 bool isTypedef( Declaration *decl ) { 563 563 return dynamic_cast< TypedefDecl * >( decl ); 564 564 } … … 571 571 572 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {573 void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) { 574 574 filter( aggregateDecl->members, isTypedef, true ); 575 575 } … … 586 586 // remove and delete decl stmts 587 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {588 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 590 return true; … … 595 595 } 596 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {597 void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) { 598 598 // Set the type of each member of the enumeration to be EnumConstant 599 599 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i ); 601 601 assert( obj ); 602 602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); … … 627 627 } 628 628 629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType *func ) { 630 630 // Fix up parameters and return types 631 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 633 633 } 634 634 635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) { 636 636 if ( other_indexer ) { 637 637 local_indexer = other_indexer; … … 641 641 } 642 642 643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {644 const EnumDecl *st = local_indexer->lookupEnum( enumInst->name );643 void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) { 644 EnumDecl *st = local_indexer->lookupEnum( enumInst->name ); 645 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 646 646 if ( st ) { 647 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node647 enumInst->baseEnum = st; 648 648 } // if 649 649 if ( ! st || ! st->body ) { … … 661 661 } 662 662 663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {664 const StructDecl *st = local_indexer->lookupStruct( structInst->name );663 void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) { 664 StructDecl *st = local_indexer->lookupStruct( structInst->name ); 665 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 666 666 if ( st ) { 667 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node667 structInst->baseStruct = st; 668 668 } // if 669 669 if ( ! st || ! st->body ) { … … 674 674 } 675 675 676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {677 const UnionDecl *un = local_indexer->lookupUnion( unionInst->name );676 void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) { 677 UnionDecl *un = local_indexer->lookupUnion( unionInst->name ); 678 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 679 679 if ( un ) { 680 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node680 unionInst->baseUnion = un; 681 681 } // if 682 682 if ( ! un || ! un->body ) { … … 693 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor );695 qualType->parent->accept( *visitor ); 696 696 } 697 697 … … 762 762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 763 763 // handle other traits 764 const TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );764 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name ); 765 765 if ( ! traitDecl ) { 766 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); … … 769 769 SemanticError( traitInst, "incorrect number of trait parameters: " ); 770 770 } // if 771 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node771 traitInst->baseTrait = traitDecl; 772 772 773 773 // need to carry over the 'sized' status of each decl in the instance … … 786 786 } 787 787 788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) { 789 789 // visit enum members first so that the types of self-referencing members are updated properly 790 790 if ( enumDecl->body ) { … … 792 792 if ( fwds != forwardEnums.end() ) { 793 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 794 (* inst)->baseEnum = enumDecl;794 (*inst)->baseEnum = enumDecl; 795 795 } // for 796 796 forwardEnums.erase( fwds ); … … 834 834 } 835 835 836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) { 837 837 // visit struct members first so that the types of self-referencing members are updated properly 838 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 841 841 if ( fwds != forwardStructs.end() ) { 842 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 843 (* inst)->baseStruct = structDecl;843 (*inst)->baseStruct = structDecl; 844 844 } // for 845 845 forwardStructs.erase( fwds ); … … 848 848 } 849 849 850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {850 void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) { 851 851 if ( unionDecl->body ) { 852 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 853 853 if ( fwds != forwardUnions.end() ) { 854 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 855 (* inst)->baseUnion = unionDecl;855 (*inst)->baseUnion = unionDecl; 856 856 } // for 857 857 forwardUnions.erase( fwds ); … … 860 860 } 861 861 862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) { 863 863 // ensure generic parameter instances are renamed like the base type 864 864 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 865 if ( const NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {866 if ( const TypeDecl * typeDecl = dynamic_cast< constTypeDecl * >( namedTypeDecl ) ) {867 typeInst->set_isFtype( typeDecl-> kind== TypeDecl::Ftype );865 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 866 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { 867 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype ); 868 868 } // if 869 869 } // if … … 877 877 // expand trait instances into their members 878 878 for ( DeclarationWithType * assertion : asserts ) { 879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 880 880 // expand trait instance into all of its members 881 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 897 897 } 898 898 899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl *object ) { 900 900 // ensure that operator names only apply to functions or function pointers 901 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 905 905 } 906 906 907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl *func ) { 908 908 func->fixUniqueId(); 909 909 } … … 961 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 962 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 963 qualType->parent = qualType->parent->acceptMutator( * visitor );963 qualType->parent = qualType->parent->acceptMutator( *visitor ); 964 964 return qualType; 965 965 } … … 970 970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 971 971 if ( def != typedefNames.end() ) { 972 Type * ret = def->second.first->base->clone();972 Type *ret = def->second.first->base->clone(); 973 973 ret->location = typeInst->location; 974 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); … … 982 982 // place instance parameters on the typedef'd type 983 983 if ( ! typeInst->parameters.empty() ) { 984 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret); 985 985 if ( ! rtt ) { 986 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); … … 988 988 rtt->parameters.clear(); 989 989 cloneAll( typeInst->parameters, rtt->parameters ); 990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, *visitor ); // recursively fix typedefs on parameters 991 991 } // if 992 992 delete typeInst; … … 1043 1043 // struct screen; 1044 1044 // because the expansion of the typedef is: 1045 // void rtn( SCREEN * p ) => void rtn( struct screen *p )1045 // void rtn( SCREEN *p ) => void rtn( struct screen *p ) 1046 1046 // hence the type-name "screen" must be defined. 1047 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 1048 1048 1049 Type * designatorType = tyDecl->base->stripDeclarator();1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {1049 Type *designatorType = tyDecl->base->stripDeclarator(); 1050 if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 1051 1051 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) ); 1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {1052 } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 1053 1053 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {1054 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 1055 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 1056 } // if … … 1078 1078 1079 1079 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?1080 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 1081 1081 // replace the current object declaration with a function declaration 1082 1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); … … 1104 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1105 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1106 Type * type = nullptr;1106 Type *type = nullptr; 1107 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 1108 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 1130 1130 GuardScope( typedefNames ); 1131 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor );1132 mutateAll( aggr->parameters, *visitor ); 1133 1133 1134 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1137 1137 1138 1138 try { 1139 * i = maybeMutate( * i, *visitor );1139 *i = maybeMutate( *i, *visitor ); 1140 1140 } catch ( SemanticErrorException &e ) { 1141 1141 errors.append( e ); … … 1217 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1218 1218 if ( i < args.size() ) { 1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) ); 1220 sub.add( (*paramIter)->get_name(), expr->get_type()->clone() ); 1221 1221 } else if ( i == args.size() ) { 1222 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (*paramIter)->get_init(); 1223 1223 if ( defaultType ) { 1224 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 1225 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (*paramIter)->get_name(), defaultType->clone() ); 1226 1226 } 1227 1227 } … … 1242 1242 } 1243 1243 1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl *objectDecl ) { 1245 1245 storageClasses = objectDecl->get_storageClasses(); 1246 1246 } 1247 1247 1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) { 1249 1249 // transform [storage_class] ... (struct S){ 3, ... }; 1250 1250 // into [storage_class] struct S temp = { 3, ... }; 1251 1251 static UniqueName indexName( "_compLit" ); 1252 1252 1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );1253 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 1254 1254 compLitExpr->set_result( nullptr ); 1255 1255 compLitExpr->set_initializer( nullptr ); … … 1289 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1290 1290 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) ); 1292 1292 deleteAll( retVals ); 1293 1293 retVals.clear(); … … 1302 1302 1303 1303 void FixObjectType::previsit( ObjectDecl * objDecl ) { 1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );1304 Type *new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer ); 1305 1305 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1306 1306 objDecl->set_type( new_type ); … … 1308 1308 1309 1309 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );1310 Type *new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1311 1311 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1312 1312 funcDecl->set_type( new_type ); 1313 1313 } 1314 1314 1315 void FixObjectType::previsit( TypeDecl * typeDecl ) {1315 void FixObjectType::previsit( TypeDecl *typeDecl ) { 1316 1316 if ( typeDecl->get_base() ) { 1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );1317 Type *new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1318 1318 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1319 1319 typeDecl->set_base( new_type ); … … 1378 1378 1379 1379 namespace { 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1381 1381 /// lists by appropriate pointers 1382 1382 struct EnumAndPointerDecay_new { … … 1385 1385 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1386 1386 // build new version of object with EnumConstant 1387 ast::ptr< ast::ObjectDecl > obj = 1387 ast::ptr< ast::ObjectDecl > obj = 1388 1388 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1389 obj.get_and_mutate()->type = 1389 obj.get_and_mutate()->type = 1390 1390 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1391 1391 1392 1392 // set into decl 1393 1393 ast::EnumDecl * mut = mutate( enumDecl ); … … 1399 1399 1400 1400 static const ast::FunctionType * fixFunctionList( 1401 const ast::FunctionType * func, 1401 const ast::FunctionType * func, 1402 1402 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1403 1403 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1404 1404 ) { 1405 const auto & dwts = func->* field;1405 const auto & dwts = func->*field; 1406 1406 unsigned nvals = dwts.size(); 1407 1407 bool hasVoid = false; … … 1409 1409 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1410 1410 } 1411 1411 1412 1412 // the only case in which "void" is valid is where it is the only one in the list 1413 1413 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1414 SemanticError( 1414 SemanticError( 1415 1415 dwts.front()->location, func, "invalid type void in function type" ); 1416 1416 } … … 1418 1418 // one void is the only thing in the list, remove it 1419 1419 if ( hasVoid ) { 1420 func = ast::mutate_field( 1420 func = ast::mutate_field( 1421 1421 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1422 1422 } … … 1432 1432 1433 1433 /// expand assertions from a trait instance, performing appropriate type variable substitutions 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1436 1436 ) { 1437 1437 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1438 1438 1439 1439 // build list of trait members, substituting trait decl parameters for instance parameters 1440 ast::TypeSubstitution sub{ 1440 ast::TypeSubstitution sub{ 1441 1441 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1442 1442 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base … … 1449 1449 1450 1450 /// Associates forward declarations of aggregates with their definitions 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1453 1453 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after * they have been traversed. To enable this in the1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in *after* they have been traversed. To enable this in the 1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1459 1459 // then can have the actual mutation applied later 1460 1460 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1461 1461 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1462 1462 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1463 1463 1464 1464 const CodeLocation & location; 1465 1465 const ast::SymbolTable * localSymtab; 1466 1466 1467 1467 ForwardEnumsType forwardEnums; 1468 1468 ForwardStructsType forwardStructs; 1469 1469 ForwardUnionsType forwardUnions; 1470 1470 1471 /// true if currently in a generic type body, so that type parameter instances can be 1471 /// true if currently in a generic type body, so that type parameter instances can be 1472 1472 /// renamed appropriately 1473 1473 bool inGeneric = false; … … 1475 1475 public: 1476 1476 /// contstruct using running symbol table 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1478 1478 : location( loc ), localSymtab( &symtab ) {} 1479 1479 1480 1480 /// construct using provided symbol table 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1482 1482 : location( loc ), localSymtab( &syms ) {} 1483 1483 … … 1485 1485 // ensure generic parameter instances are renamed like the base type 1486 1486 if ( inGeneric && typeInst->base ) { 1487 typeInst = ast::mutate_field( 1487 typeInst = ast::mutate_field( 1488 1488 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1489 1489 } 1490 1490 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1494 1494 ) { 1495 1495 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); … … 1517 1517 for ( const ast::Expr * param : inst->params ) { 1518 1518 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1519 SemanticError( 1519 SemanticError( 1520 1520 location, inst, "Expression parameters for generic types are currently " 1521 1521 "unsupported: " ); … … 1571 1571 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1572 1572 if ( ! expr ) { 1573 SemanticError( 1573 SemanticError( 1574 1574 traitInst->params[i].get(), "Expression parameters for trait instances " 1575 1575 "are currently unsupported: " ); … … 1593 1593 return traitInst; 1594 1594 } 1595 1595 1596 1596 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1597 1597 1598 1598 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1599 1599 // linking only makes sense for the "oldest ancestor" of the qualified type 1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( *visitor ) ); 1602 1602 } 1603 1603 1604 1604 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1605 // visit enum members first so that the types of self-referencing members are updated 1605 // visit enum members first so that the types of self-referencing members are updated 1606 1606 // properly 1607 1607 if ( ! enumDecl->body ) return enumDecl; … … 1612 1612 auto inst = fwds.first; 1613 1613 do { 1614 // forward decl is stored * mutably* in map, can thus be updated1614 // forward decl is stored *mutably* in map, can thus be updated 1615 1615 inst->second->base = enumDecl; 1616 1616 } while ( ++inst != fwds.second ); 1617 1617 forwardEnums.erase( fwds.first, fwds.second ); 1618 1618 } 1619 1619 1620 1620 // ensure that enumerator initializers are properly set 1621 1621 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1622 1622 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1623 1623 if ( field->init ) { 1624 // need to resolve enumerator initializers early so that other passes that 1624 // need to resolve enumerator initializers early so that other passes that 1625 1625 // determine if an expression is constexpr have appropriate information 1626 1626 auto init = field->init.strict_as< ast::SingleInit >(); 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1631 1631 ast::mutate_field( init, &ast::SingleInit::value, 1632 ResolvExpr::findSingleExpression( 1632 ResolvExpr::findSingleExpression( 1633 1633 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1634 1634 symtab ) ) ) ); … … 1639 1639 } 1640 1640 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1642 1642 /// function forall parameters, e.g. the T in Box and the T in f, below 1643 1643 /// forall(otype T) … … 1657 1657 const ast::TypeDecl * td = aggr->params[i]; 1658 1658 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1661 1661 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1662 1662 } … … 1669 1669 1670 1670 void postvisit( const ast::StructDecl * structDecl ) { 1671 // visit struct members first so that the types of self-referencing members are 1671 // visit struct members first so that the types of self-referencing members are 1672 1672 // updated properly 1673 1673 if ( ! structDecl->body ) return; … … 1678 1678 auto inst = fwds.first; 1679 1679 do { 1680 // forward decl is stored * mutably* in map, can thus be updated1680 // forward decl is stored *mutably* in map, can thus be updated 1681 1681 inst->second->base = structDecl; 1682 1682 } while ( ++inst != fwds.second ); … … 1690 1690 1691 1691 void postvisit( const ast::UnionDecl * unionDecl ) { 1692 // visit union members first so that the types of self-referencing members are updated 1692 // visit union members first so that the types of self-referencing members are updated 1693 1693 // properly 1694 1694 if ( ! unionDecl->body ) return; … … 1699 1699 auto inst = fwds.first; 1700 1700 do { 1701 // forward decl is stored * mutably* in map, can thus be updated1701 // forward decl is stored *mutably* in map, can thus be updated 1702 1702 inst->second->base = unionDecl; 1703 1703 } while ( ++inst != fwds.second ); … … 1712 1712 "number of parameters: %zd", traitDecl->params.size() ); 1713 1713 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1717 1717 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1718 1718 } … … 1737 1737 traitDecl = mut; 1738 1738 } 1739 1739 1740 1740 return traitDecl; 1741 1741 } 1742 1742 }; 1743 1743 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1745 1745 /// each object and function declaration a unique ID 1746 1746 class ForallPointerDecay_new { … … 1751 1751 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1752 1752 // ensure that operator names only apply to functions or function pointers 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1755 1755 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1756 1756 ) { … … 1776 1776 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1777 1777 template< typename node_t, typename parent_t > 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1780 1780 ast::ParameterizedType::ForallList parent_t::* forallField 1781 1781 ) { 1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {1783 const ast::TypeDecl * type = (node->* forallField)[i];1782 for ( unsigned i = 0; i < (node->*forallField).size(); ++i ) { 1783 const ast::TypeDecl * type = (node->*forallField)[i]; 1784 1784 if ( type->assertions.empty() ) continue; 1785 1785 … … 1789 1789 // expand trait instances into their members 1790 1790 for ( const ast::DeclWithType * assn : type->assertions ) { 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1793 1793 if ( traitInst ) { 1794 1794 // expand trait instance to all its members … … 1831 1831 } // anonymous namespace 1832 1832 1833 const ast::Type * validateType( 1833 const ast::Type * validateType( 1834 1834 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1835 1835 ast::Pass< EnumAndPointerDecay_new > epc;
Note:
See TracChangeset
for help on using the changeset viewer.