Changes in src/SymTab/Validate.cc [9939dc3:7c919559]
- File:
-
- 1 edited
-
src/SymTab/Validate.cc (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r9939dc3 r7c919559 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 763 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 764 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); 765 // it's not a semantic error if the struct is not found, just an implicit forward declaration 766 if ( st ) { 767 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node 768 } // if 769 if ( ! st || ! st->body ) { 770 // use of forward declaration 771 forwardStructs[ structInst->name ].push_back( structInst ); 772 } // if 773 } 774 775 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 776 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name ); 777 // it's not a semantic error if the union is not found, just an implicit forward declaration 778 if ( un ) { 779 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node 780 } // if 781 if ( ! un || ! un->body ) { 782 // use of forward declaration 783 forwardUnions[ unionInst->name ].push_back( unionInst ); 784 } // if 785 } 786 787 void LinkReferenceToTypes_old::previsit( QualifiedType * ) { 788 visit_children = false; 789 } 790 791 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 792 // linking only makes sense for the 'oldest ancestor' of the qualified type 793 qualType->parent->accept( * visitor ); 794 } 795 796 template< typename Decl > 797 void normalizeAssertions( std::list< Decl * > & assertions ) { 798 // ensure no duplicate trait members after the clone 799 auto pred = [](Decl * d1, Decl * d2) { 800 // only care if they're equal 801 DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 ); 802 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 803 if ( dwt1 && dwt2 ) { 804 if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 805 // std::cerr << "=========== equal:" << std::endl; 806 // std::cerr << "d1: " << d1 << std::endl; 807 // std::cerr << "d2: " << d2 << std::endl; 808 return false; 809 } 810 } 811 return d1 < d2; 812 }; 813 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred ); 814 // if ( unique_members.size() != assertions.size() ) { 815 // std::cerr << "============different" << std::endl; 816 // std::cerr << unique_members.size() << " " << assertions.size() << std::endl; 817 // } 818 819 std::list< Decl * > order; 820 order.splice( order.end(), assertions ); 821 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) { 822 return unique_members.count( decl ); 823 }); 824 } 825 615 826 // expand assertions from trait instance, performing the appropriate type variable substitutions 616 827 template< typename Iterator > … … 625 836 } 626 837 838 void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) { 839 if ( traitDecl->name == "sized" ) { 840 // "sized" is a special trait - flick the sized status on for the type variable 841 assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() ); 842 TypeDecl * td = traitDecl->parameters.front(); 843 td->set_sized( true ); 844 } 845 846 // move assertions from type parameters into the body of the trait 847 for ( TypeDecl * td : traitDecl->parameters ) { 848 for ( DeclarationWithType * assert : td->assertions ) { 849 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) { 850 expandAssertions( inst, back_inserter( traitDecl->members ) ); 851 } else { 852 traitDecl->members.push_back( assert->clone() ); 853 } 854 } 855 deleteAll( td->assertions ); 856 td->assertions.clear(); 857 } // for 858 } 859 860 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 861 // handle other traits 862 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name ); 863 if ( ! traitDecl ) { 864 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); 865 } // if 866 if ( traitDecl->parameters.size() != traitInst->parameters.size() ) { 867 SemanticError( traitInst, "incorrect number of trait parameters: " ); 868 } // if 869 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node 870 871 // need to carry over the 'sized' status of each decl in the instance 872 for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) { 873 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 874 if ( ! expr ) { 875 SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " ); 876 } 877 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 878 TypeDecl * formalDecl = std::get<0>(p); 879 TypeDecl * instDecl = inst->baseType; 880 if ( formalDecl->get_sized() ) instDecl->set_sized( true ); 881 } 882 } 883 // normalizeAssertions( traitInst->members ); 884 } 885 886 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 887 // visit enum members first so that the types of self-referencing members are updated properly 888 if ( enumDecl->body ) { 889 ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name ); 890 if ( fwds != forwardEnums.end() ) { 891 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 892 (* inst)->baseEnum = enumDecl; 893 } // for 894 forwardEnums.erase( fwds ); 895 } // if 896 } // if 897 } 898 899 void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) { 900 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 901 // forall(otype T) 902 // struct Box { 903 // T x; 904 // }; 905 // forall(otype T) 906 // void f(Box(T) b) { 907 // ... 908 // } 909 // The T in Box and the T in f are different, so internally the naming must reflect that. 910 GuardValue( inGeneric ); 911 inGeneric = ! params.empty(); 912 for ( TypeDecl * td : params ) { 913 td->name = "__" + td->name + "_generic_"; 914 } 915 } 916 917 void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) { 918 renameGenericParams( structDecl->parameters ); 919 } 920 921 void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) { 922 renameGenericParams( unionDecl->parameters ); 923 } 924 925 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 926 // visit struct members first so that the types of self-referencing members are updated properly 927 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) 928 if ( structDecl->body ) { 929 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name ); 930 if ( fwds != forwardStructs.end() ) { 931 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 932 (* inst)->baseStruct = structDecl; 933 } // for 934 forwardStructs.erase( fwds ); 935 } // if 936 } // if 937 } 938 939 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 940 if ( unionDecl->body ) { 941 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 942 if ( fwds != forwardUnions.end() ) { 943 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 944 (* inst)->baseUnion = unionDecl; 945 } // for 946 forwardUnions.erase( fwds ); 947 } // if 948 } // if 949 } 950 951 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 952 // ensure generic parameter instances are renamed like the base type 953 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 954 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 955 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 956 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 957 } // if 958 } // if 959 } 960 627 961 ResolveEnumInitializers::ResolveEnumInitializers( const Indexer * other_indexer ) : WithIndexer( true ) { 628 962 if ( other_indexer ) { … … 640 974 // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information. 641 975 SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init ); 642 if ( !enumDecl->base || dynamic_cast<BasicType *>(enumDecl->base)) 643 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer ); 644 else { 645 if (dynamic_cast<PointerType *>(enumDecl->base)) { 646 auto typePtr = dynamic_cast<PointerType *>(enumDecl->base); 647 ResolvExpr::findSingleExpression( init->value, 648 new PointerType( Type::Qualifiers(), typePtr->base ), indexer ); 649 } else { 650 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer ); 651 } 652 } 976 ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer ); 653 977 } 654 978 } 655 656 979 } // if 657 980 } … … 740 1063 } 741 1064 1065 void TraitExpander_old::previsit( FunctionType * ftype ) { 1066 expandTraits( ftype->forall ); 1067 } 1068 1069 void TraitExpander_old::previsit( StructDecl * aggrDecl ) { 1070 expandTraits( aggrDecl->parameters ); 1071 } 1072 1073 void TraitExpander_old::previsit( UnionDecl * aggrDecl ) { 1074 expandTraits( aggrDecl->parameters ); 1075 } 1076 1077 void AssertionFixer_old::previsit( FunctionType * ftype ) { 1078 fixAssertions( ftype->forall, ftype ); 1079 } 1080 1081 void AssertionFixer_old::previsit( StructDecl * aggrDecl ) { 1082 fixAssertions( aggrDecl->parameters, aggrDecl ); 1083 } 1084 1085 void AssertionFixer_old::previsit( UnionDecl * aggrDecl ) { 1086 fixAssertions( aggrDecl->parameters, aggrDecl ); 1087 } 1088 1089 void CheckOperatorTypes_old::previsit( ObjectDecl * object ) { 1090 // ensure that operator names only apply to functions or function pointers 1091 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { 1092 SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." ) ); 1093 } 1094 } 1095 1096 void FixUniqueIds_old::previsit( DeclarationWithType * decl ) { 1097 decl->fixUniqueId(); 1098 } 1099 742 1100 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { 743 1101 PassVisitor<ReturnChecker> checker; … … 882 1240 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 883 1241 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 884 // declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) ); 885 if (enumDecl->baseEnum) { 886 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) ); 887 } else { 888 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 889 } 1242 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 890 1243 } // if 891 1244 return tyDecl->clone();
Note:
See TracChangeset
for help on using the changeset viewer.