Changes in src/SymTab/Validate.cc [9939dc3:9e7236f4]
- File:
-
- 1 edited
-
src/SymTab/Validate.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r9939dc3 r9e7236f4 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 17 14:36:00 202213 // Update Count : 36 612 // Last Modified On : Fri Nov 12 11:00:00 2021 13 // Update Count : 364 14 14 // 15 15 … … 74 74 #include "ResolvExpr/ResolveTypeof.h" // for resolveTypeof 75 75 #include "SymTab/Autogen.h" // for SizeType 76 #include "SymTab/ValidateType.h" // for decayEnumsAndPointers, decayFo...77 76 #include "SynTree/LinkageSpec.h" // for C 78 77 #include "SynTree/Attribute.h" // for noAttributes, Attribute … … 135 134 }; 136 135 136 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 137 struct EnumAndPointerDecay_old { 138 void previsit( EnumDecl * aggregateDecl ); 139 void previsit( FunctionType * func ); 140 }; 141 142 /// Associates forward declarations of aggregates with their definitions 143 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 144 LinkReferenceToTypes_old( const Indexer * indexer ); 145 void postvisit( TypeInstType * typeInst ); 146 147 void postvisit( EnumInstType * enumInst ); 148 void postvisit( StructInstType * structInst ); 149 void postvisit( UnionInstType * unionInst ); 150 void postvisit( TraitInstType * traitInst ); 151 void previsit( QualifiedType * qualType ); 152 void postvisit( QualifiedType * qualType ); 153 154 void postvisit( EnumDecl * enumDecl ); 155 void postvisit( StructDecl * structDecl ); 156 void postvisit( UnionDecl * unionDecl ); 157 void postvisit( TraitDecl * traitDecl ); 158 159 void previsit( StructDecl * structDecl ); 160 void previsit( UnionDecl * unionDecl ); 161 162 void renameGenericParams( std::list< TypeDecl * > & params ); 163 164 private: 165 const Indexer * local_indexer; 166 167 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; 168 typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType; 169 typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType; 170 ForwardEnumsType forwardEnums; 171 ForwardStructsType forwardStructs; 172 ForwardUnionsType forwardUnions; 173 /// true if currently in a generic type body, so that type parameter instances can be renamed appropriately 174 bool inGeneric = false; 175 }; 176 137 177 /// Does early resolution on the expressions that give enumeration constants their values 138 178 struct ResolveEnumInitializers final : public WithIndexer, public WithGuards, public WithVisitorRef<ResolveEnumInitializers>, public WithShortCircuiting { … … 152 192 void previsit( StructDecl * aggrDecl ); 153 193 void previsit( UnionDecl * aggrDecl ); 194 }; 195 196 // These structs are the sub-sub-passes of ForallPointerDecay_old. 197 198 struct TraitExpander_old final { 199 void previsit( FunctionType * ); 200 void previsit( StructDecl * ); 201 void previsit( UnionDecl * ); 202 }; 203 204 struct AssertionFixer_old final { 205 void previsit( FunctionType * ); 206 void previsit( StructDecl * ); 207 void previsit( UnionDecl * ); 208 }; 209 210 struct CheckOperatorTypes_old final { 211 void previsit( ObjectDecl * ); 212 }; 213 214 struct FixUniqueIds_old final { 215 void previsit( DeclarationWithType * ); 154 216 }; 155 217 … … 295 357 296 358 void validate_A( std::list< Declaration * > & translationUnit ) { 359 PassVisitor<EnumAndPointerDecay_old> epc; 297 360 PassVisitor<HoistTypeDecls> hoistDecls; 298 361 { … … 303 366 ReplaceTypedef::replaceTypedef( translationUnit ); 304 367 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen 305 decayEnumsAndPointers( translationUnit); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling368 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 306 369 } 307 370 } 308 371 309 372 void validate_B( std::list< Declaration * > & translationUnit ) { 373 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr ); 310 374 PassVisitor<FixQualifiedTypes> fixQual; 311 375 { 312 376 Stats::Heap::newPass("validate-B"); 313 377 Stats::Time::BlockGuard guard("validate-B"); 314 //linkReferenceToTypes( translationUnit );378 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions 315 379 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed 316 380 HoistStruct::hoistStruct( translationUnit ); … … 343 407 }); 344 408 } 409 } 410 411 static void decayForallPointers( std::list< Declaration * > & translationUnit ) { 412 PassVisitor<TraitExpander_old> te; 413 acceptAll( translationUnit, te ); 414 PassVisitor<AssertionFixer_old> af; 415 acceptAll( translationUnit, af ); 416 PassVisitor<CheckOperatorTypes_old> cot; 417 acceptAll( translationUnit, cot ); 418 PassVisitor<FixUniqueIds_old> fui; 419 acceptAll( translationUnit, fui ); 345 420 } 346 421 … … 421 496 } 422 497 498 void validateType( Type * type, const Indexer * indexer ) { 499 PassVisitor<EnumAndPointerDecay_old> epc; 500 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); 501 PassVisitor<TraitExpander_old> te; 502 PassVisitor<AssertionFixer_old> af; 503 PassVisitor<CheckOperatorTypes_old> cot; 504 PassVisitor<FixUniqueIds_old> fui; 505 type->accept( epc ); 506 type->accept( lrt ); 507 type->accept( te ); 508 type->accept( af ); 509 type->accept( cot ); 510 type->accept( fui ); 511 } 512 423 513 void HoistTypeDecls::handleType( Type * type ) { 424 514 // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here … … 613 703 } 614 704 705 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) { 706 // Set the type of each member of the enumeration to be EnumConstant 707 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 708 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i ); 709 assert( obj ); 710 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); 711 } // for 712 } 713 714 namespace { 715 template< typename DWTList > 716 void fixFunctionList( DWTList & dwts, bool isVarArgs, FunctionType * func ) { 717 auto nvals = dwts.size(); 718 bool containsVoid = false; 719 for ( auto & dwt : dwts ) { 720 // fix each DWT and record whether a void was found 721 containsVoid |= fixFunction( dwt ); 722 } 723 724 // the only case in which "void" is valid is where it is the only one in the list 725 if ( containsVoid && ( nvals > 1 || isVarArgs ) ) { 726 SemanticError( func, "invalid type void in function type " ); 727 } 728 729 // one void is the only thing in the list; remove it. 730 if ( containsVoid ) { 731 delete dwts.front(); 732 dwts.clear(); 733 } 734 } 735 } 736 737 void EnumAndPointerDecay_old::previsit( FunctionType * func ) { 738 // Fix up parameters and return types 739 fixFunctionList( func->parameters, func->isVarArgs, func ); 740 fixFunctionList( func->returnVals, false, func ); 741 } 742 743 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) : WithIndexer( false ) { 744 if ( other_indexer ) { 745 local_indexer = other_indexer; 746 } else { 747 local_indexer = &indexer; 748 } // if 749 } 750 751 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) { 752 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name ); 753 // it's not a semantic error if the enum is not found, just an implicit forward declaration 754 if ( st ) { 755 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node 756 } // if 757 if ( ! st || ! st->body ) { 758 // use of forward declaration 759 forwardEnums[ enumInst->name ].push_back( enumInst ); 760 } // if 761 } 762 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 763 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); 764 // it's not a semantic error if the struct is not found, just an implicit forward declaration 765 if ( st ) { 766 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node 767 } // if 768 if ( ! st || ! st->body ) { 769 // use of forward declaration 770 forwardStructs[ structInst->name ].push_back( structInst ); 771 } // if 772 } 773 774 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 775 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name ); 776 // it's not a semantic error if the union is not found, just an implicit forward declaration 777 if ( un ) { 778 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node 779 } // if 780 if ( ! un || ! un->body ) { 781 // use of forward declaration 782 forwardUnions[ unionInst->name ].push_back( unionInst ); 783 } // if 784 } 785 786 void LinkReferenceToTypes_old::previsit( QualifiedType * ) { 787 visit_children = false; 788 } 789 790 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 791 // linking only makes sense for the 'oldest ancestor' of the qualified type 792 qualType->parent->accept( * visitor ); 793 } 794 795 template< typename Decl > 796 void normalizeAssertions( std::list< Decl * > & assertions ) { 797 // ensure no duplicate trait members after the clone 798 auto pred = [](Decl * d1, Decl * d2) { 799 // only care if they're equal 800 DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 ); 801 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 802 if ( dwt1 && dwt2 ) { 803 if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 804 // std::cerr << "=========== equal:" << std::endl; 805 // std::cerr << "d1: " << d1 << std::endl; 806 // std::cerr << "d2: " << d2 << std::endl; 807 return false; 808 } 809 } 810 return d1 < d2; 811 }; 812 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred ); 813 // if ( unique_members.size() != assertions.size() ) { 814 // std::cerr << "============different" << std::endl; 815 // std::cerr << unique_members.size() << " " << assertions.size() << std::endl; 816 // } 817 818 std::list< Decl * > order; 819 order.splice( order.end(), assertions ); 820 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) { 821 return unique_members.count( decl ); 822 }); 823 } 824 615 825 // expand assertions from trait instance, performing the appropriate type variable substitutions 616 826 template< typename Iterator > … … 623 833 // substitute trait decl parameters for instance parameters 624 834 applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out ); 835 } 836 837 void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) { 838 if ( traitDecl->name == "sized" ) { 839 // "sized" is a special trait - flick the sized status on for the type variable 840 assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() ); 841 TypeDecl * td = traitDecl->parameters.front(); 842 td->set_sized( true ); 843 } 844 845 // move assertions from type parameters into the body of the trait 846 for ( TypeDecl * td : traitDecl->parameters ) { 847 for ( DeclarationWithType * assert : td->assertions ) { 848 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) { 849 expandAssertions( inst, back_inserter( traitDecl->members ) ); 850 } else { 851 traitDecl->members.push_back( assert->clone() ); 852 } 853 } 854 deleteAll( td->assertions ); 855 td->assertions.clear(); 856 } // for 857 } 858 859 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 860 // handle other traits 861 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name ); 862 if ( ! traitDecl ) { 863 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); 864 } // if 865 if ( traitDecl->parameters.size() != traitInst->parameters.size() ) { 866 SemanticError( traitInst, "incorrect number of trait parameters: " ); 867 } // if 868 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node 869 870 // need to carry over the 'sized' status of each decl in the instance 871 for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) { 872 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 873 if ( ! expr ) { 874 SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " ); 875 } 876 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 877 TypeDecl * formalDecl = std::get<0>(p); 878 TypeDecl * instDecl = inst->baseType; 879 if ( formalDecl->get_sized() ) instDecl->set_sized( true ); 880 } 881 } 882 // normalizeAssertions( traitInst->members ); 883 } 884 885 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 886 // visit enum members first so that the types of self-referencing members are updated properly 887 // Replace the enum base; right now it works only for StructEnum 888 if ( enumDecl->base && dynamic_cast<TypeInstType*>(enumDecl->base) ) { 889 std::string baseName = static_cast<TypeInstType*>(enumDecl->base)->name; 890 const StructDecl * st = local_indexer->lookupStruct( baseName ); 891 if ( st ) { 892 enumDecl->base = new StructInstType(Type::Qualifiers(),const_cast<StructDecl *>(st)); // Just linking in the node 893 } 894 } 895 if ( enumDecl->body ) { 896 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name ); 897 if ( fwds != forwardEnums.end() ) { 898 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 899 (* inst)->baseEnum = enumDecl; 900 } // for 901 forwardEnums.erase( fwds ); 902 } // if 903 } // if 904 } 905 906 void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) { 907 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 908 // forall(otype T) 909 // struct Box { 910 // T x; 911 // }; 912 // forall(otype T) 913 // void f(Box(T) b) { 914 // ... 915 // } 916 // The T in Box and the T in f are different, so internally the naming must reflect that. 917 GuardValue( inGeneric ); 918 inGeneric = ! params.empty(); 919 for ( TypeDecl * td : params ) { 920 td->name = "__" + td->name + "_generic_"; 921 } 922 } 923 924 void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) { 925 renameGenericParams( structDecl->parameters ); 926 } 927 928 void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) { 929 renameGenericParams( unionDecl->parameters ); 930 } 931 932 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 933 // visit struct members first so that the types of self-referencing members are updated properly 934 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) 935 if ( structDecl->body ) { 936 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name ); 937 if ( fwds != forwardStructs.end() ) { 938 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 939 (* inst)->baseStruct = structDecl; 940 } // for 941 forwardStructs.erase( fwds ); 942 } // if 943 } // if 944 } 945 946 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 947 if ( unionDecl->body ) { 948 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 949 if ( fwds != forwardUnions.end() ) { 950 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 951 (* inst)->baseUnion = unionDecl; 952 } // for 953 forwardUnions.erase( fwds ); 954 } // if 955 } // if 956 } 957 958 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 959 // ensure generic parameter instances are renamed like the base type 960 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 961 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 962 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 963 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 964 } // if 965 } // if 625 966 } 626 967 … … 651 992 } 652 993 } 994 653 995 } 654 996 } … … 738 1080 void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) { 739 1081 forallFixer( aggrDecl->parameters, aggrDecl ); 1082 } 1083 1084 void TraitExpander_old::previsit( FunctionType * ftype ) { 1085 expandTraits( ftype->forall ); 1086 } 1087 1088 void TraitExpander_old::previsit( StructDecl * aggrDecl ) { 1089 expandTraits( aggrDecl->parameters ); 1090 } 1091 1092 void TraitExpander_old::previsit( UnionDecl * aggrDecl ) { 1093 expandTraits( aggrDecl->parameters ); 1094 } 1095 1096 void AssertionFixer_old::previsit( FunctionType * ftype ) { 1097 fixAssertions( ftype->forall, ftype ); 1098 } 1099 1100 void AssertionFixer_old::previsit( StructDecl * aggrDecl ) { 1101 fixAssertions( aggrDecl->parameters, aggrDecl ); 1102 } 1103 1104 void AssertionFixer_old::previsit( UnionDecl * aggrDecl ) { 1105 fixAssertions( aggrDecl->parameters, aggrDecl ); 1106 } 1107 1108 void CheckOperatorTypes_old::previsit( ObjectDecl * object ) { 1109 // ensure that operator names only apply to functions or function pointers 1110 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { 1111 SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." ) ); 1112 } 1113 } 1114 1115 void FixUniqueIds_old::previsit( DeclarationWithType * decl ) { 1116 decl->fixUniqueId(); 740 1117 } 741 1118
Note:
See TracChangeset
for help on using the changeset viewer.