Changes in / [4f37255:7dc2e57b]
- Location:
- src
- Files:
-
- 15 edited
-
AST/Expr.hpp (modified) (1 diff)
-
Common/PassVisitor.h (modified) (1 diff)
-
Common/PassVisitor.impl.h (modified) (60 diffs)
-
Common/PassVisitor.proto.h (modified) (3 diffs)
-
InitTweak/InitTweak.cc (modified) (15 diffs)
-
InitTweak/InitTweak.h (modified) (2 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (26 diffs)
-
ResolvExpr/ResolveAssertions.cc (modified) (10 diffs)
-
ResolvExpr/Unify.cc (modified) (1 diff)
-
ResolvExpr/typeops.h (modified) (10 diffs)
-
SymTab/Indexer.cc (modified) (22 diffs)
-
SymTab/Indexer.h (modified) (7 diffs)
-
SymTab/Mangler.cc (modified) (22 diffs)
-
SymTab/Mangler.h (modified) (1 diff)
-
SynTree/Visitor.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.hpp
r4f37255 r7dc2e57b 114 114 case Params: assertf(false, "Cannot return to resnSlots from Params"); abort(); 115 115 } 116 assertf(false, "unreachable"); 116 117 } 117 118 -
src/Common/PassVisitor.h
r4f37255 r7dc2e57b 410 410 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } 411 411 void indexerScopeLeave () { indexer_impl_leaveScope ( pass, 0 ); } 412 void indexerAddId ( DeclarationWithType* node ) { indexer_impl_addId ( pass, 0, node ); }413 void indexerAddType ( NamedTypeDecl* node ) { indexer_impl_addType ( pass, 0, node ); }412 void indexerAddId ( const DeclarationWithType * node ) { indexer_impl_addId ( pass, 0, node ); } 413 void indexerAddType ( const NamedTypeDecl * node ) { indexer_impl_addType ( pass, 0, node ); } 414 414 void indexerAddStruct ( const std::string & id ) { indexer_impl_addStruct ( pass, 0, id ); } 415 void indexerAddStruct ( StructDecl* node ) { indexer_impl_addStruct ( pass, 0, node ); }416 void indexerAddStructFwd( StructDecl* node ) { indexer_impl_addStructFwd( pass, 0, node ); }417 void indexerAddEnum ( EnumDecl* node ) { indexer_impl_addEnum ( pass, 0, node ); }415 void indexerAddStruct ( const StructDecl * node ) { indexer_impl_addStruct ( pass, 0, node ); } 416 void indexerAddStructFwd( const StructDecl * node ) { indexer_impl_addStructFwd( pass, 0, node ); } 417 void indexerAddEnum ( const EnumDecl * node ) { indexer_impl_addEnum ( pass, 0, node ); } 418 418 void indexerAddUnion ( const std::string & id ) { indexer_impl_addUnion ( pass, 0, id ); } 419 void indexerAddUnion ( UnionDecl* node ) { indexer_impl_addUnion ( pass, 0, node ); }420 void indexerAddUnionFwd ( UnionDecl* node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }421 void indexerAddTrait ( TraitDecl* node ) { indexer_impl_addTrait ( pass, 0, node ); }422 void indexerAddWith ( std::list< Expression * > & exprs,BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }419 void indexerAddUnion ( const UnionDecl * node ) { indexer_impl_addUnion ( pass, 0, node ); } 420 void indexerAddUnionFwd ( const UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 421 void indexerAddTrait ( const TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 422 void indexerAddWith ( const std::list< Expression * > & exprs, const BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); } 423 423 424 424 425 425 template< typename TreeType, typename VisitorType > 426 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );426 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ); 427 427 428 428 template< typename TreeType, typename VisitorType > 429 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor ); 429 friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ); 430 431 template< typename TreeType, typename VisitorType > 432 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor ); 430 433 }; 431 434 -
src/Common/PassVisitor.impl.h
r4f37255 r7dc2e57b 548 548 VISIT_START( node ); 549 549 550 indexerAddId( node ); 551 550 552 maybeAccept_impl( node->withExprs, *this ); 551 553 { 552 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 553 static ObjectDecl func( 554 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 555 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 556 nullptr 557 ); 558 maybeAccept_impl( node->type, *this ); 559 // function body needs to have the same scope as parameters - CompoundStmt will not enter 560 // a new scope if inFunction is true 561 ValueGuard< bool > oldInFunction( inFunction ); 562 inFunction = true; 563 maybeAccept_impl( node->statements, *this ); 564 maybeAccept_impl( node->attributes, *this ); 554 // with clause introduces a level of scope (for the with expression members). 555 // with clause exprs are added to the indexer before parameters so that parameters 556 // shadow with exprs and not the other way around. 557 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 558 indexerAddWith( node->withExprs, node ); 559 { 560 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 561 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 562 static ObjectDecl func( 563 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 564 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 565 nullptr 566 ); 567 indexerAddId( &func ); 568 maybeAccept_impl( node->type, *this ); 569 // function body needs to have the same scope as parameters - CompoundStmt will not enter 570 // a new scope if inFunction is true 571 ValueGuard< bool > oldInFunction( inFunction ); 572 inFunction = true; 573 maybeAccept_impl( node->statements, *this ); 574 maybeAccept_impl( node->attributes, *this ); 575 } 565 576 } 566 577 … … 628 639 VISIT_START( node ); 629 640 630 maybeAccept_impl( node->parameters, *this );631 maybeAccept_impl( node->members , *this );632 633 VISIT_END( node );634 }635 636 template< typename pass_type >637 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {638 MUTATE_START( node );639 640 641 // make up a forward declaration and add it before processing the members 641 642 // needs to be on the heap because addStruct saves the pointer … … 644 645 { 645 646 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 647 maybeAccept_impl( node->parameters, *this ); 648 maybeAccept_impl( node->members , *this ); 649 } 650 651 // this addition replaces the forward declaration 652 indexerAddStruct( node ); 653 654 VISIT_END( node ); 655 } 656 657 template< typename pass_type > 658 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { 659 MUTATE_START( node ); 660 661 // make up a forward declaration and add it before processing the members 662 // needs to be on the heap because addStruct saves the pointer 663 indexerAddStructFwd( node ); 664 665 { 666 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 646 667 maybeMutate_impl( node->parameters, *this ); 647 668 maybeMutate_impl( node->members , *this ); … … 677 698 VISIT_START( node ); 678 699 679 maybeAccept_impl( node->parameters, *this ); 680 maybeAccept_impl( node->members , *this ); 700 // make up a forward declaration and add it before processing the members 701 indexerAddUnionFwd( node ); 702 703 { 704 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 705 maybeAccept_impl( node->parameters, *this ); 706 maybeAccept_impl( node->members , *this ); 707 } 708 709 indexerAddUnion( node ); 681 710 682 711 VISIT_END( node ); … … 720 749 VISIT_START( node ); 721 750 751 indexerAddEnum( node ); 752 722 753 // unlike structs, traits, and unions, enums inject their members into the global scope 723 754 maybeAccept_impl( node->parameters, *this ); … … 761 792 VISIT_START( node ); 762 793 763 maybeAccept_impl( node->parameters, *this ); 764 maybeAccept_impl( node->members , *this ); 794 { 795 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 796 maybeAccept_impl( node->parameters, *this ); 797 maybeAccept_impl( node->members , *this ); 798 } 799 800 indexerAddTrait( node ); 765 801 766 802 VISIT_END( node ); … … 811 847 VISIT_START( node ); 812 848 813 maybeAccept_impl( node->parameters, *this );814 maybeAccept_impl( node->base , *this );815 maybeAccept_impl( node->assertions, *this );816 817 VISIT_END( node );818 }819 820 template< typename pass_type >821 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {822 MUTATE_START( node );823 824 849 { 825 850 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 826 maybe Mutate_impl( node->parameters, *this );827 maybe Mutate_impl( node->base , *this );851 maybeAccept_impl( node->parameters, *this ); 852 maybeAccept_impl( node->base , *this ); 828 853 } 829 854 … … 833 858 indexerAddType( node ); 834 859 860 maybeAccept_impl( node->assertions, *this ); 861 862 indexerScopedAccept( node->init, *this ); 863 864 VISIT_END( node ); 865 } 866 867 template< typename pass_type > 868 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 869 MUTATE_START( node ); 870 871 { 872 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 873 maybeMutate_impl( node->parameters, *this ); 874 maybeMutate_impl( node->base , *this ); 875 } 876 877 // see A NOTE ON THE ORDER OF TRAVERSAL, above 878 // note that assertions come after the type is added to the symtab, since they are not part of the type proper 879 // and may depend on the type itself 880 indexerAddType( node ); 881 835 882 maybeMutate_impl( node->assertions, *this ); 836 883 … … 863 910 VISIT_START( node ); 864 911 865 maybeAccept_impl( node->parameters, *this ); 866 maybeAccept_impl( node->base , *this ); 912 { 913 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 914 maybeAccept_impl( node->parameters, *this ); 915 maybeAccept_impl( node->base , *this ); 916 } 917 918 indexerAddType( node ); 919 867 920 maybeAccept_impl( node->assertions, *this ); 868 921 … … 1101 1154 void PassVisitor< pass_type >::visit( const IfStmt * node ) { 1102 1155 VISIT_START( node ); 1103 1104 maybeAccept_impl( node->initialization, *this ); 1105 visitExpression ( node->condition ); 1106 visitStatement( node->thenPart ); 1107 visitStatement( node->elsePart ); 1108 1156 { 1157 // if statements introduce a level of scope (for the initialization) 1158 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1159 maybeAccept_impl( node->initialization, *this ); 1160 visitExpression ( node->condition ); 1161 visitStatement ( node->thenPart ); 1162 visitStatement ( node->elsePart ); 1163 } 1109 1164 VISIT_END( node ); 1110 1165 } … … 1145 1200 VISIT_START( node ); 1146 1201 1147 maybeAccept_impl( node->initialization, *this ); 1148 visitExpression ( node->condition ); 1149 visitStatement( node->body ); 1202 { 1203 // while statements introduce a level of scope (for the initialization) 1204 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1205 maybeAccept_impl( node->initialization, *this ); 1206 visitExpression ( node->condition ); 1207 visitStatement ( node->body ); 1208 } 1150 1209 1151 1210 VISIT_END( node ); … … 1187 1246 void PassVisitor< pass_type >::visit( const ForStmt * node ) { 1188 1247 VISIT_START( node ); 1189 1190 maybeAccept_impl( node->initialization, *this ); 1191 visitExpression( node->condition ); 1192 visitExpression( node->increment ); 1193 visitStatement( node->body ); 1194 1248 { 1249 // for statements introduce a level of scope (for the initialization) 1250 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1251 maybeAccept_impl( node->initialization, *this ); 1252 visitExpression( node->condition ); 1253 visitExpression( node->increment ); 1254 visitStatement ( node->body ); 1255 } 1195 1256 VISIT_END( node ); 1196 1257 } … … 1408 1469 void PassVisitor< pass_type >::visit( const CatchStmt * node ) { 1409 1470 VISIT_START( node ); 1410 1411 maybeAccept_impl( node->decl, *this ); 1412 visitExpression( node->cond ); 1413 visitStatement ( node->body ); 1414 1471 { 1472 // catch statements introduce a level of scope (for the caught exception) 1473 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1474 maybeAccept_impl( node->decl, *this ); 1475 visitExpression ( node->cond ); 1476 visitStatement ( node->body ); 1477 } 1415 1478 VISIT_END( node ); 1416 1479 } … … 1543 1606 void PassVisitor< pass_type >::visit( const WithStmt * node ) { 1544 1607 VISIT_START( node ); 1545 1546 1608 maybeAccept_impl( node->exprs, *this ); 1547 maybeAccept_impl( node->stmt, *this ); 1548 1609 { 1610 // catch statements introduce a level of scope (for the caught exception) 1611 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1612 indexerAddWith( node->exprs, node ); 1613 maybeAccept_impl( node->stmt, *this ); 1614 } 1549 1615 VISIT_END( node ); 1550 1616 } … … 1648 1714 1649 1715 indexerScopedAccept( node->result , *this ); 1650 maybeAccept_impl ( node->function, *this );1651 maybeAccept_impl ( node->args , *this );1716 maybeAccept_impl ( node->function, *this ); 1717 maybeAccept_impl ( node->args , *this ); 1652 1718 1653 1719 VISIT_END( node ); … … 1658 1724 VISIT_START( node ); 1659 1725 1660 maybeAccept_impl( node->result , *this );1661 maybeAccept_impl ( node->function, *this );1662 maybeAccept_impl ( node->args , *this );1726 indexerScopedAccept( node->result , *this ); 1727 maybeAccept_impl ( node->function, *this ); 1728 maybeAccept_impl ( node->args , *this ); 1663 1729 1664 1730 VISIT_END( node ); … … 1697 1763 VISIT_START( node ); 1698 1764 1699 maybeAccept_impl( node->result, *this );1765 indexerScopedAccept( node->result, *this ); 1700 1766 1701 1767 for ( auto expr : node->args ) { … … 1735 1801 VISIT_START( node ); 1736 1802 1737 maybeAccept_impl( node->result, *this );1803 indexerScopedAccept( node->result, *this ); 1738 1804 1739 1805 VISIT_END( node ); … … 1757 1823 1758 1824 indexerScopedAccept( node->result, *this ); 1759 maybeAccept_impl ( node->arg , *this );1825 maybeAccept_impl ( node->arg , *this ); 1760 1826 1761 1827 VISIT_END( node ); … … 1766 1832 VISIT_START( node ); 1767 1833 1768 maybeAccept_impl( node->result, *this );1769 maybeAccept_impl ( node->arg , *this );1834 indexerScopedAccept( node->result, *this ); 1835 maybeAccept_impl ( node->arg , *this ); 1770 1836 1771 1837 VISIT_END( node ); … … 1799 1865 VISIT_START( node ); 1800 1866 1801 maybeAccept_impl( node->result, *this );1802 maybeAccept_impl ( node->arg , *this );1867 indexerScopedAccept( node->result, *this ); 1868 maybeAccept_impl ( node->arg , *this ); 1803 1869 1804 1870 VISIT_END( node ); … … 1823 1889 1824 1890 indexerScopedAccept( node->result, *this ); 1825 maybeAccept_impl ( node->arg, *this );1891 maybeAccept_impl ( node->arg, *this ); 1826 1892 1827 1893 VISIT_END( node ); … … 1832 1898 VISIT_START( node ); 1833 1899 1834 maybeAccept_impl( node->result, *this );1835 maybeAccept_impl ( node->arg, *this );1900 indexerScopedAccept( node->result, *this ); 1901 maybeAccept_impl ( node->arg, *this ); 1836 1902 1837 1903 VISIT_END( node ); … … 1865 1931 VISIT_START( node ); 1866 1932 1867 maybeAccept_impl( node->result, *this );1868 maybeAccept_impl ( node->arg , *this );1933 indexerScopedAccept( node->result, *this ); 1934 maybeAccept_impl ( node->arg , *this ); 1869 1935 1870 1936 VISIT_END( node ); … … 1897 1963 VISIT_START( node ); 1898 1964 1899 maybeAccept_impl( node->result, *this );1965 indexerScopedAccept( node->result, *this ); 1900 1966 1901 1967 VISIT_END( node ); … … 1929 1995 VISIT_START( node ); 1930 1996 1931 maybeAccept_impl( node->result , *this );1932 maybeAccept_impl ( node->aggregate, *this );1933 maybeAccept_impl ( node->member , *this );1997 indexerScopedAccept( node->result , *this ); 1998 maybeAccept_impl ( node->aggregate, *this ); 1999 maybeAccept_impl ( node->member , *this ); 1934 2000 1935 2001 VISIT_END( node ); … … 1964 2030 VISIT_START( node ); 1965 2031 1966 maybeAccept_impl( node->result , *this );1967 maybeAccept_impl ( node->aggregate, *this );2032 indexerScopedAccept( node->result , *this ); 2033 maybeAccept_impl ( node->aggregate, *this ); 1968 2034 1969 2035 VISIT_END( node ); … … 1996 2062 VISIT_START( node ); 1997 2063 1998 maybeAccept_impl( node->result, *this );2064 indexerScopedAccept( node->result, *this ); 1999 2065 2000 2066 VISIT_END( node ); … … 2027 2093 VISIT_START( node ); 2028 2094 2029 maybeAccept_impl( node->result , *this );2030 maybeAccept_impl ( &node->constant, *this );2095 indexerScopedAccept( node->result , *this ); 2096 maybeAccept_impl ( &node->constant, *this ); 2031 2097 2032 2098 VISIT_END( node ); … … 2066 2132 VISIT_START( node ); 2067 2133 2068 maybeAccept_impl( node->result, *this );2134 indexerScopedAccept( node->result, *this ); 2069 2135 if ( node->get_isType() ) { 2070 2136 maybeAccept_impl( node->type, *this ); … … 2111 2177 VISIT_START( node ); 2112 2178 2113 maybeAccept_impl( node->result, *this );2179 indexerScopedAccept( node->result, *this ); 2114 2180 if ( node->get_isType() ) { 2115 2181 maybeAccept_impl( node->type, *this ); … … 2152 2218 VISIT_START( node ); 2153 2219 2154 maybeAccept_impl( node->result, *this );2155 maybeAccept_impl ( node->type , *this );2220 indexerScopedAccept( node->result, *this ); 2221 maybeAccept_impl ( node->type , *this ); 2156 2222 2157 2223 VISIT_END( node ); … … 2185 2251 VISIT_START( node ); 2186 2252 2187 maybeAccept_impl( node->result, *this );2188 maybeAccept_impl ( node->type , *this );2253 indexerScopedAccept( node->result, *this ); 2254 maybeAccept_impl ( node->type , *this ); 2189 2255 2190 2256 VISIT_END( node ); … … 2218 2284 VISIT_START( node ); 2219 2285 2220 maybeAccept_impl( node->result, *this );2221 maybeAccept_impl ( node->type , *this );2286 indexerScopedAccept( node->result, *this ); 2287 maybeAccept_impl ( node->type , *this ); 2222 2288 2223 2289 VISIT_END( node ); … … 2255 2321 VISIT_START( node ); 2256 2322 2257 maybeAccept_impl( node->result, *this );2323 indexerScopedAccept( node->result, *this ); 2258 2324 if ( node->get_isType() ) { 2259 2325 maybeAccept_impl( node->type, *this ); … … 2297 2363 VISIT_START( node ); 2298 2364 2299 maybeAccept_impl( node->result, *this );2300 maybeAccept_impl ( node->arg1 , *this );2301 maybeAccept_impl ( node->arg2 , *this );2365 indexerScopedAccept( node->result, *this ); 2366 maybeAccept_impl ( node->arg1 , *this ); 2367 maybeAccept_impl ( node->arg2 , *this ); 2302 2368 2303 2369 VISIT_END( node ); … … 2334 2400 VISIT_START( node ); 2335 2401 2336 maybeAccept_impl( node->result, *this );2337 maybeAccept_impl ( node->arg1 , *this );2338 maybeAccept_impl ( node->arg2 , *this );2339 maybeAccept_impl ( node->arg3 , *this );2402 indexerScopedAccept( node->result, *this ); 2403 maybeAccept_impl ( node->arg1 , *this ); 2404 maybeAccept_impl ( node->arg2 , *this ); 2405 maybeAccept_impl ( node->arg3 , *this ); 2340 2406 2341 2407 VISIT_END( node ); … … 2372 2438 VISIT_START( node ); 2373 2439 2374 maybeAccept_impl( node->result, *this );2375 maybeAccept_impl ( node->arg1 , *this );2376 maybeAccept_impl ( node->arg2 , *this );2440 indexerScopedAccept( node->result, *this ); 2441 maybeAccept_impl ( node->arg1 , *this ); 2442 maybeAccept_impl ( node->arg2 , *this ); 2377 2443 2378 2444 VISIT_END( node ); … … 2407 2473 VISIT_START( node ); 2408 2474 2409 maybeAccept_impl( node->result, *this );2410 maybeAccept_impl ( node->type, *this );2475 indexerScopedAccept( node->result, *this ); 2476 maybeAccept_impl ( node->type, *this ); 2411 2477 2412 2478 VISIT_END( node ); … … 2442 2508 VISIT_START( node ); 2443 2509 2444 maybeAccept_impl( node->result , *this );2445 maybeAccept_impl ( node->inout , *this );2446 maybeAccept_impl ( node->constraint, *this );2447 maybeAccept_impl ( node->operand , *this );2510 indexerScopedAccept( node->result , *this ); 2511 maybeAccept_impl ( node->inout , *this ); 2512 maybeAccept_impl ( node->constraint, *this ); 2513 maybeAccept_impl ( node->operand , *this ); 2448 2514 2449 2515 VISIT_END( node ); … … 2479 2545 VISIT_START( node ); 2480 2546 2481 maybeAccept_impl( node->result , *this );2482 maybeAccept_impl ( node->callExpr , *this );2547 indexerScopedAccept( node->result , *this ); 2548 maybeAccept_impl ( node->callExpr , *this ); 2483 2549 2484 2550 VISIT_END( node ); … … 2512 2578 VISIT_START( node ); 2513 2579 2514 maybeAccept_impl( node->result , *this );2515 maybeAccept_impl ( node->callExpr, *this );2580 indexerScopedAccept( node->result , *this ); 2581 maybeAccept_impl ( node->callExpr, *this ); 2516 2582 2517 2583 VISIT_END( node ); … … 2545 2611 VISIT_START( node ); 2546 2612 2547 maybeAccept_impl( node->result , *this );2548 maybeAccept_impl ( node->initializer, *this );2613 indexerScopedAccept( node->result , *this ); 2614 maybeAccept_impl ( node->initializer, *this ); 2549 2615 2550 2616 VISIT_END( node ); … … 2579 2645 VISIT_START( node ); 2580 2646 2581 maybeAccept_impl( node->result, *this );2582 maybeAccept_impl ( node->low , *this );2583 maybeAccept_impl ( node->high , *this );2647 indexerScopedAccept( node->result, *this ); 2648 maybeAccept_impl ( node->low , *this ); 2649 maybeAccept_impl ( node->high , *this ); 2584 2650 2585 2651 VISIT_END( node ); … … 2614 2680 VISIT_START( node ); 2615 2681 2616 maybeAccept_impl( node->result, *this );2617 maybeAccept_impl ( node->exprs , *this );2682 indexerScopedAccept( node->result, *this ); 2683 maybeAccept_impl ( node->exprs , *this ); 2618 2684 2619 2685 VISIT_END( node ); … … 2647 2713 VISIT_START( node ); 2648 2714 2649 maybeAccept_impl( node->result, *this );2650 maybeAccept_impl ( node->exprs , *this );2715 indexerScopedAccept( node->result, *this ); 2716 maybeAccept_impl ( node->exprs , *this ); 2651 2717 2652 2718 VISIT_END( node ); … … 2680 2746 VISIT_START( node ); 2681 2747 2682 maybeAccept_impl( node->result, *this );2683 maybeAccept_impl ( node->tuple , *this );2748 indexerScopedAccept( node->result, *this ); 2749 maybeAccept_impl ( node->tuple , *this ); 2684 2750 2685 2751 VISIT_END( node ); … … 2713 2779 VISIT_START( node ); 2714 2780 2715 maybeAccept_impl( node->result , *this );2781 indexerScopedAccept( node->result , *this ); 2716 2782 maybeAccept_impl( node->stmtExpr, *this ); 2717 2783 … … 2753 2819 VISIT_START( node ); 2754 2820 2755 maybeAccept_impl( node->result , *this );2756 maybeAccept_impl( node->statements , *this );2757 maybeAccept_impl( node->returnDecls, *this );2758 maybeAccept_impl( node->dtors , *this );2759 2760 VISIT_END( node );2761 }2762 2763 template< typename pass_type >2764 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {2765 MUTATE_START( node );2766 2767 2821 // don't want statements from outer CompoundStmts to be added to this StmtExpr 2768 2822 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); … … 2770 2824 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 2771 2825 2826 indexerScopedAccept( node->result , *this ); 2827 maybeAccept_impl ( node->statements , *this ); 2828 maybeAccept_impl ( node->returnDecls, *this ); 2829 maybeAccept_impl ( node->dtors , *this ); 2830 2831 VISIT_END( node ); 2832 } 2833 2834 template< typename pass_type > 2835 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 2836 MUTATE_START( node ); 2837 2838 // don't want statements from outer CompoundStmts to be added to this StmtExpr 2839 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 2840 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 2841 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 2842 2772 2843 indexerScopedMutate( node->result , *this ); 2773 2844 maybeMutate_impl ( node->statements , *this ); … … 2794 2865 VISIT_START( node ); 2795 2866 2796 maybeAccept_impl( node->result, *this );2797 maybeAccept_impl ( node->expr , *this );2867 indexerScopedAccept( node->result, *this ); 2868 maybeAccept_impl ( node->expr , *this ); 2798 2869 2799 2870 VISIT_END( node ); … … 2828 2899 VISIT_START( node ); 2829 2900 2830 maybeAccept_impl( node->result, *this );2831 maybeAccept_impl ( node->expr , *this );2901 indexerScopedAccept( node->result, *this ); 2902 maybeAccept_impl ( node->expr , *this ); 2832 2903 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 2833 2904 … … 2864 2935 VISIT_START( node ); 2865 2936 2866 maybeAccept_impl( node->result, *this );2867 maybeAccept_impl ( node->expr , *this );2868 maybeAccept_impl ( node->designation, *this );2937 indexerScopedAccept( node->result, *this ); 2938 maybeAccept_impl ( node->expr , *this ); 2939 maybeAccept_impl ( node->designation, *this ); 2869 2940 2870 2941 VISIT_END( node ); … … 2890 2961 2891 2962 indexerScopedAccept( node->result, *this ); 2892 maybeAccept_impl ( node->expr, *this );2963 maybeAccept_impl ( node->expr, *this ); 2893 2964 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2894 2965 … … 2900 2971 VISIT_START( node ); 2901 2972 2902 maybeAccept_impl( node->result, *this );2903 maybeAccept_impl ( node->expr, *this );2973 indexerScopedAccept( node->result, *this ); 2974 maybeAccept_impl ( node->expr, *this ); 2904 2975 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2905 2976 … … 2925 2996 2926 2997 indexerScopedAccept( node->result, *this ); 2927 maybeAccept_impl ( node->expr, *this );2998 maybeAccept_impl ( node->expr, *this ); 2928 2999 2929 3000 VISIT_END( node ); … … 2934 3005 VISIT_START( node ); 2935 3006 2936 maybeAccept_impl( node->result, *this );2937 maybeAccept_impl ( node->expr, *this );3007 indexerScopedAccept( node->result, *this ); 3008 maybeAccept_impl ( node->expr, *this ); 2938 3009 2939 3010 VISIT_END( node ); … … 2971 3042 VISIT_START( node ); 2972 3043 2973 maybeAccept_impl( node->result, *this );3044 indexerScopedAccept( node->result, *this ); 2974 3045 maybeAccept_impl( node->control, *this ); 2975 3046 for ( const GenericExpr::Association & assoc : node->associations ) { 2976 maybeAccept_impl( assoc.type, *this );3047 indexerScopedAccept( assoc.type, *this ); 2977 3048 maybeAccept_impl( assoc.expr, *this ); 2978 3049 } … … 3247 3318 VISIT_START( node ); 3248 3319 3249 maybeAccept_impl( node->forall , *this ); 3250 maybeAccept_impl( node->parameters, *this ); 3320 indexerAddStruct( node->name ); 3321 3322 { 3323 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3324 maybeAccept_impl( node->forall , *this ); 3325 maybeAccept_impl( node->parameters, *this ); 3326 } 3251 3327 3252 3328 VISIT_END( node ); … … 3289 3365 VISIT_START( node ); 3290 3366 3291 maybeAccept_impl( node->forall , *this ); 3292 maybeAccept_impl( node->parameters, *this ); 3367 indexerAddStruct( node->name ); 3368 3369 { 3370 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3371 maybeAccept_impl( node->forall , *this ); 3372 maybeAccept_impl( node->parameters, *this ); 3373 } 3293 3374 3294 3375 VISIT_END( node ); -
src/Common/PassVisitor.proto.h
r4f37255 r7dc2e57b 229 229 230 230 231 INDEXER_FUNC1( addId , DeclarationWithType * );232 INDEXER_FUNC1( addType , NamedTypeDecl * );233 INDEXER_FUNC1( addStruct , StructDecl * );234 INDEXER_FUNC1( addEnum , EnumDecl * );235 INDEXER_FUNC1( addUnion , UnionDecl * );236 INDEXER_FUNC1( addTrait , TraitDecl * );237 INDEXER_FUNC2( addWith , std::list< Expression * > &,BaseSyntaxNode * );231 INDEXER_FUNC1( addId , const DeclarationWithType * ); 232 INDEXER_FUNC1( addType , const NamedTypeDecl * ); 233 INDEXER_FUNC1( addStruct , const StructDecl * ); 234 INDEXER_FUNC1( addEnum , const EnumDecl * ); 235 INDEXER_FUNC1( addUnion , const UnionDecl * ); 236 INDEXER_FUNC1( addTrait , const TraitDecl * ); 237 INDEXER_FUNC2( addWith , const std::list< Expression * > &, const BaseSyntaxNode * ); 238 238 239 239 #undef INDEXER_FUNC1 … … 241 241 242 242 template<typename pass_type> 243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 244 244 StructDecl * fwd = new StructDecl( decl->name ); 245 245 cloneAll( decl->parameters, fwd->parameters ); … … 251 251 252 252 template<typename pass_type> 253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 254 254 UnionDecl * fwd = new UnionDecl( decl->name ); 255 255 cloneAll( decl->parameters, fwd->parameters ); -
src/InitTweak/InitTweak.cc
r4f37255 r7dc2e57b 318 318 virtual ~ExpanderImpl() = default; 319 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 320 virtual ast::ptr< ast::Stmt > buildListInit( 320 virtual ast::ptr< ast::Stmt > buildListInit( 321 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 322 }; … … 324 324 namespace { 325 325 template< typename Out > 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 328 328 const ast::Init * init, Out & out 329 329 ) { 330 330 const CodeLocation & loc = init->location; 331 331 332 auto cond = new ast::UntypedExpr{ 332 auto cond = new ast::UntypedExpr{ 333 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 334 335 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 336 splice( callExpr->args, args ); … … 338 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 339 340 out.emplace_back( new ast::ExprStmt{ 340 out.emplace_back( new ast::ExprStmt{ 341 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 342 } … … 344 344 template< typename Out > 345 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 347 const ast::Init * init, Out & out 348 348 ) { … … 371 371 372 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 373 ast::Label switchLabel{ 374 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 375 376 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 377 for ( const ast::Init * init : *listInit ) { … … 381 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 383 stmts.emplace_back( 384 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); … … 398 398 return makeInitList( init ); 399 399 } 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 403 403 ) override { 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 408 // statement consuming all of expander's elements 409 409 … … 427 427 ExprImpl_new( const ast::Expr * a ) : arg( a ) {} 428 428 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 431 431 ) override { 432 432 if ( ! arg ) return {}; … … 437 437 // go through indices and layer on subscript exprs ?[?] 438 438 ++it; 439 expr = new ast::UntypedExpr{ 439 expr = new ast::UntypedExpr{ 440 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 441 } 442 442 return { expr }; 443 443 } 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 448 448 return {}; 449 449 } … … 464 464 } 465 465 466 /// builds statement which has the same semantics as a C-style list initializer (for array 466 /// builds statement which has the same semantics as a C-style list initializer (for array 467 467 /// initializers) using callExpr as the base expression to perform initialization 468 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { … … 668 668 669 669 const ast::DeclWithType * func = getCalledFunction( appExpr->func ); 670 assertf( func, 670 assertf( func, 671 671 "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() ); 672 673 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 674 // autogenerated ctor/dtor will call all member dtors, and some members may have a 672 673 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 674 // autogenerated ctor/dtor will call all member dtors, and some members may have a 675 675 // user-defined dtor 676 676 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr; … … 707 707 return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){ 708 708 if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 709 const ast::FunctionType * funcType = 709 const ast::FunctionType * funcType = 710 710 GenPoly::getFunctionType( appExpr->func->result ); 711 711 assert( funcType ); … … 997 997 bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); } 998 998 999 FunctionDecl * isCopyFunction(Declaration * decl, const std::string & fname ) {1000 FunctionDecl * function = dynamic_cast<FunctionDecl * >( decl );999 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) { 1000 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl ); 1001 1001 if ( ! function ) return nullptr; 1002 1002 if ( function->name != fname ) return nullptr; … … 1022 1022 if ( ! t1 ) return false; 1023 1023 const ast::Type * t2 = ftype->params.back()->get_type(); 1024 1024 1025 1025 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); 1026 1026 } 1027 1027 1028 FunctionDecl * isAssignment(Declaration * decl ) {1028 const FunctionDecl * isAssignment( const Declaration * decl ) { 1029 1029 return isCopyFunction( decl, "?=?" ); 1030 1030 } 1031 FunctionDecl * isDestructor(Declaration * decl ) {1032 if ( isDestructor( decl-> get_name()) ) {1033 return dynamic_cast< FunctionDecl * >( decl );1031 const FunctionDecl * isDestructor( const Declaration * decl ) { 1032 if ( isDestructor( decl->name ) ) { 1033 return dynamic_cast< const FunctionDecl * >( decl ); 1034 1034 } 1035 1035 return nullptr; 1036 1036 } 1037 FunctionDecl * isDefaultConstructor(Declaration * decl ) {1037 const FunctionDecl * isDefaultConstructor( const Declaration * decl ) { 1038 1038 if ( isConstructor( decl->name ) ) { 1039 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {1039 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 1040 1040 if ( func->type->parameters.size() == 1 ) { 1041 1041 return func; … … 1045 1045 return nullptr; 1046 1046 } 1047 FunctionDecl * isCopyConstructor(Declaration * decl ) {1047 const FunctionDecl * isCopyConstructor( const Declaration * decl ) { 1048 1048 return isCopyFunction( decl, "?{}" ); 1049 1049 } -
src/InitTweak/InitTweak.h
r4f37255 r7dc2e57b 26 26 // helper functions for initialization 27 27 namespace InitTweak { 28 FunctionDecl * isAssignment(Declaration * decl );29 FunctionDecl * isDestructor(Declaration * decl );30 FunctionDecl * isDefaultConstructor(Declaration * decl );31 FunctionDecl * isCopyConstructor(Declaration * decl );32 FunctionDecl * isCopyFunction(Declaration * decl, const std::string & fname );28 const FunctionDecl * isAssignment( const Declaration * decl ); 29 const FunctionDecl * isDestructor( const Declaration * decl ); 30 const FunctionDecl * isDefaultConstructor( const Declaration * decl ); 31 const FunctionDecl * isCopyConstructor( const Declaration * decl ); 32 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ); 33 33 bool isCopyFunction( const ast::FunctionDecl * decl ); 34 34 … … 153 153 InitExpander_new & operator++ (); 154 154 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 157 157 /// Mutates callExpr 158 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); -
src/ResolvExpr/AlternativeFinder.cc
r4f37255 r7dc2e57b 336 336 } 337 337 338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 339 339 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 341 341 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 342 342 } // if … … 344 344 345 345 template< typename StructOrUnionType > 346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 347 347 std::list< Declaration* > members; 348 348 aggInst->lookup( name, members ); 349 349 350 350 for ( Declaration * decl : members ) { 351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 352 352 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 353 353 // can't construct in place and use vector::back … … 362 362 } 363 363 364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ) {364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) { 365 365 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 366 366 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 368 368 std::string tmp; 369 369 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 370 alternatives.push_back( Alternative{ 370 alternatives.push_back( Alternative{ 371 371 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 372 372 } // if … … 374 374 } 375 375 376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) { 377 377 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 378 378 } … … 475 475 } 476 476 477 // specialization cost of return types can't be accounted for directly, it disables 477 // specialization cost of return types can't be accounted for directly, it disables 478 478 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 479 479 // … … 1226 1226 // count one safe conversion for each value that is thrown away 1227 1227 thisCost.incSafe( discardedValues ); 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1230 1230 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1231 1231 inferParameters( newAlt, back_inserter( candidates ) ); … … 1328 1328 if ( sizeofExpr->get_isType() ) { 1329 1329 Type * newType = sizeofExpr->get_type()->clone(); 1330 alternatives.push_back( Alternative{ 1330 alternatives.push_back( Alternative{ 1331 1331 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1332 1332 } else { … … 1343 1343 Alternative &choice = winners.front(); 1344 1344 referenceToRvalueConversion( choice.expr, choice.cost ); 1345 alternatives.push_back( Alternative{ 1345 alternatives.push_back( Alternative{ 1346 1346 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1347 1347 } // if … … 1351 1351 if ( alignofExpr->get_isType() ) { 1352 1352 Type * newType = alignofExpr->get_type()->clone(); 1353 alternatives.push_back( Alternative{ 1353 alternatives.push_back( Alternative{ 1354 1354 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1355 1355 } else { … … 1366 1366 Alternative &choice = winners.front(); 1367 1367 referenceToRvalueConversion( choice.expr, choice.cost ); 1368 alternatives.push_back( Alternative{ 1368 alternatives.push_back( Alternative{ 1369 1369 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1370 1370 } // if … … 1377 1377 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1378 1378 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1379 alternatives.push_back( Alternative{ 1379 alternatives.push_back( Alternative{ 1380 1380 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1381 1381 renameTypes( alternatives.back().expr ); … … 1405 1405 1406 1406 namespace { 1407 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {1407 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1408 1408 // assume no polymorphism 1409 1409 // assume no implicit conversions 1410 assert( function-> get_parameters().size() == 1 );1410 assert( function->parameters.size() == 1 ); 1411 1411 PRINT( 1412 1412 std::cerr << "resolvAttr: funcDecl is "; … … 1418 1418 const SymTab::Indexer & indexer = finder.get_indexer(); 1419 1419 AltList & alternatives = finder.get_alternatives(); 1420 if ( typesCompatibleIgnoreQualifiers( argType, function-> get_parameters().front()->get_type(), indexer, env ) ) {1420 if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) { 1421 1421 Cost cost = Cost::zero; 1422 1422 Expression * newExpr = data.combine( cost ); 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1425 1425 AssertionList{}, Cost::zero, cost } ); 1426 1426 for ( DeclarationWithType * retVal : function->returnVals ) { … … 1431 1431 } 1432 1432 1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) { 1434 1434 // assume no 'pointer-to-attribute' 1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1436 1436 assert( nameExpr ); 1437 1437 std::list< SymTab::Indexer::IdData > attrList; … … 1439 1439 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1440 1440 for ( auto & data : attrList ) { 1441 DeclarationWithType * id = data.id;1441 const DeclarationWithType * id = data.id; 1442 1442 // check if the type is function 1443 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {1443 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) { 1444 1444 // assume exactly one parameter 1445 if ( function-> get_parameters().size() == 1 ) {1445 if ( function->parameters.size() == 1 ) { 1446 1446 if ( attrExpr->get_isType() ) { 1447 1447 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); … … 1462 1462 Cost cost = Cost::zero; 1463 1463 Expression * newExpr = data.combine( cost ); 1464 alternatives.push_back( Alternative{ 1464 alternatives.push_back( Alternative{ 1465 1465 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1466 1466 renameTypes( alternatives.back().expr ); … … 1469 1469 } 1470 1470 1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) { 1472 1472 AlternativeFinder firstFinder( indexer, env ); 1473 1473 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1486 1486 cloneAll( second.need, need ); 1487 1487 1488 LogicalExpr *newExpr = new LogicalExpr{ 1488 LogicalExpr *newExpr = new LogicalExpr{ 1489 1489 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1492 1492 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1493 1493 } … … 1522 1522 cloneAll( third.need, need ); 1523 1523 AssertionSet have; 1524 1524 1525 1525 // unify true and false types, then infer parameters to produce new alternatives 1526 1526 Type* commonType = nullptr; 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1528 1528 need, have, openVars, indexer, commonType ) ) { 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1530 1530 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1531 1531 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1532 1532 // convert both options to the conditional result type 1533 1533 Cost cost = first.cost + second.cost + third.cost; 1534 cost += computeExpressionConversionCost( 1534 cost += computeExpressionConversionCost( 1535 1535 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1536 cost += computeExpressionConversionCost( 1536 cost += computeExpressionConversionCost( 1537 1537 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1538 1538 // output alternative 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1541 1541 AssertionList( need.begin(), need.end() ), cost }; 1542 1542 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1553 1553 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1554 1554 for ( const Alternative & alt : secondFinder.alternatives ) { 1555 alternatives.push_back( Alternative{ 1555 alternatives.push_back( Alternative{ 1556 1556 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1557 1557 } // for … … 1579 1579 1580 1580 Type* commonType = nullptr; 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1582 1582 openVars, indexer, commonType ) ) { 1583 RangeExpr * newExpr = 1583 RangeExpr * newExpr = 1584 1584 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1585 1585 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1588 1588 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1589 1589 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1612 1612 cloneAll( alt.need, need ); 1613 1613 } 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1617 1617 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1618 1618 } // for … … 1633 1633 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1634 1634 for ( Alternative & alt : finder.alternatives ) { 1635 alternatives.push_back( Alternative{ 1635 alternatives.push_back( Alternative{ 1636 1636 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1637 1637 } … … 1685 1685 cloneAll( alt.need, need ); 1686 1686 AssertionSet have; 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1689 1689 // those are open vars? 1690 1690 PRINT( 1691 1691 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1692 1692 ) 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1697 1697 // types to cast to. 1698 1698 int discardedValues = alt.expr->result->size() - toType->size(); 1699 1699 if ( discardedValues < 0 ) continue; 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1702 1702 // atomic type (e.g. (int)([1, 2, 3])) 1703 1703 1704 1704 // unification run for side-effects 1705 1705 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); … … 1710 1710 // count one safe conversion for each value that is thrown away 1711 1711 thisCost.incSafe( discardedValues ); 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1716 1716 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1717 1717 inferParameters( newAlt, back_inserter( candidates ) ); -
src/ResolvExpr/ResolveAssertions.cc
r4f37255 r7dc2e57b 197 197 } 198 198 if ( i == b.size() /* && i < a.size() */ ) return 1; 199 199 200 200 int c = a[i].compare( b[i] ); 201 201 if ( c != 0 ) return c; … … 220 220 221 221 /// Initial resolution state for an alternative 222 ResnState( Alternative & a, SymTab::Indexer& indexer )222 ResnState( Alternative & a, SymTab::Indexer & indexer ) 223 223 : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) { 224 224 need.swap( a.need ); … … 226 226 227 227 /// Updated resolution state with new need-list 228 ResnState( ResnState && o, IterateFlag )228 ResnState( ResnState && o, IterateFlag ) 229 229 : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(), 230 230 inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) { … … 234 234 235 235 /// Binds a single assertion, updating resolution state 236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative& alt,237 AssnCandidate & match, InferCache& inferred ) {238 239 DeclarationWithType* candidate = match.cdata.id;240 assertf( candidate-> get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost );236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt, 237 AssnCandidate & match, InferCache & inferred ) { 238 239 const DeclarationWithType * candidate = match.cdata.id; 240 assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost ); 243 243 delete varExpr->result; 244 244 varExpr->result = match.adjType->clone(); … … 247 247 // place newly-inferred assertion in proper place in cache 248 248 inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{ 249 candidate-> get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),249 candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(), 250 250 varExpr }; 251 251 } 252 252 253 253 /// Adds a captured assertion to the symbol table 254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer &indexer ) {254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) { 255 255 for ( auto& i : assertSet ) { 256 256 if ( i.second.isUsed ) { … … 264 264 265 265 /// Resolve a single assertion, in context 266 bool resolveAssertion( AssertionItem & assn, ResnState& resn ) {266 bool resolveAssertion( AssertionItem & assn, ResnState & resn ) { 267 267 // skip unused assertions 268 268 if ( ! assn.info.isUsed ) return true; … … 274 274 // find the candidates that unify with the desired type 275 275 CandidateList matches; 276 for ( const auto & cdata : candidates ) {277 DeclarationWithType* candidate = cdata.id;276 for ( const auto & cdata : candidates ) { 277 const DeclarationWithType * candidate = cdata.id; 278 278 279 279 // build independent unification context for candidate … … 281 281 TypeEnvironment newEnv{ resn.alt.env }; 282 282 OpenVarSet newOpenVars{ resn.alt.openVars }; 283 Type * adjType = candidate->get_type()->clone();283 Type * adjType = candidate->get_type()->clone(); 284 284 adjustExprType( adjType, newEnv, resn.indexer ); 285 285 renameTyVars( adjType ); … … 370 370 return resKey; 371 371 } 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 374 374 /// threshold. 375 375 void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) { … … 406 406 ResnList resns{ ResnState{ alt, root_indexer } }; 407 407 ResnList new_resns{}; 408 408 409 409 // Pruning thresholds by result type of the output alternatives. 410 410 // Alternatives *should* be generated in sorted order, so no need to retroactively prune -
src/ResolvExpr/Unify.cc
r4f37255 r7dc2e57b 102 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 103 104 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {104 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 105 105 TypeEnvironment newEnv; 106 106 OpenVarSet openVars, closedVars; // added closedVars 107 107 AssertionSet needAssertions, haveAssertions; 108 Type * newFirst = first->clone(), *newSecond = second->clone();108 Type * newFirst = first->clone(), * newSecond = second->clone(); 109 109 env.apply( newFirst ); 110 110 env.apply( newSecond ); -
src/ResolvExpr/typeops.h
r4f37255 r7dc2e57b 28 28 #include "SynTree/SynTree.h" 29 29 #include "SynTree/Type.h" 30 #include "SymTab/Indexer.h" 30 31 namespace SymTab { 32 class Indexer; 33 } 31 34 32 35 namespace ResolvExpr { … … 60 63 // in AdjustExprType.cc 61 64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function 62 void adjustExprType( Type *& type, const TypeEnvironment &env, const SymTab::Indexer &indexer );65 void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 63 66 64 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer … … 66 69 67 70 template< typename ForwardIterator > 68 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) { 69 72 while ( begin != end ) { 70 73 adjustExprType( *begin++, env, indexer ); … … 77 80 78 81 // in CastCost.cc 79 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment &env );82 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 80 83 Cost castCost( 81 84 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, … … 83 86 84 87 // in ConversionCost.cc 85 Cost conversionCost( const Type * src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );88 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 86 89 Cost conversionCost( 87 90 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, … … 89 92 90 93 // in AlternativeFinder.cc 91 Cost computeConversionCost( Type * actualType, Type *formalType,92 const SymTab::Indexer & indexer, const TypeEnvironment &env );94 Cost computeConversionCost( Type * actualType, Type * formalType, 95 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 93 96 94 97 // in PtrsAssignable.cc 95 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );98 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env ); 96 99 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 97 100 const ast::TypeEnvironment & env ); 98 101 99 102 // in PtrsCastable.cc 100 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer &indexer );103 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 101 104 int ptrsCastable( 102 105 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, … … 104 107 105 108 // in Unify.cc 106 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );107 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment &env );108 109 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {109 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 110 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 111 112 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 110 113 TypeEnvironment env; 111 114 return typesCompatible( t1, t2, indexer, env ); 112 115 } 113 116 114 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {117 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 115 118 TypeEnvironment env; 116 119 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); … … 131 134 132 135 // in CommonType.cc 133 Type * commonType( Type * type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );136 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars ); 134 137 ast::ptr< ast::Type > commonType( 135 138 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, … … 137 140 138 141 // in PolyCost.cc 139 int polyCost( Type * type, const TypeEnvironment &env, const SymTab::Indexer &indexer );142 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 140 143 int polyCost( 141 144 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 142 145 143 146 // in SpecCost.cc 144 int specCost( Type * type );147 int specCost( Type * type ); 145 148 int specCost( const ast::Type * type ); 146 149 147 150 // in Occurs.cc 148 bool occurs( Type * type, std::string varName, const TypeEnvironment &env );151 bool occurs( Type * type, std::string varName, const TypeEnvironment & env ); 149 152 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 150 153 151 154 template<typename Iter> 152 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {155 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) { 153 156 while ( begin != end ) { 154 157 if ( occurs( ty, *begin, env ) ) return true; … … 197 200 198 201 // in TypeEnvironment.cc 199 bool isFtype( Type * type );202 bool isFtype( Type * type ); 200 203 } // namespace ResolvExpr 201 204 -
src/SymTab/Indexer.cc
r4f37255 r7dc2e57b 188 188 } 189 189 190 bool isFunction( DeclarationWithType * decl ) {190 bool isFunction( const DeclarationWithType * decl ) { 191 191 return GenPoly::getFunctionType( decl->get_type() ); 192 192 } 193 193 194 bool isObject( DeclarationWithType * decl ) {194 bool isObject( const DeclarationWithType * decl ) { 195 195 return ! isFunction( decl ); 196 196 } 197 197 198 bool isDefinition( DeclarationWithType * decl ) {199 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {198 bool isDefinition( const DeclarationWithType * decl ) { 199 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 200 200 // a function is a definition if it has a body 201 201 return func->statements; … … 209 209 210 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, DeclarationWithType * added,212 Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {211 const Indexer::IdData & existing, const DeclarationWithType * added, 212 Indexer::OnConflict handleConflicts, const BaseSyntaxNode * deleteStmt ) { 213 213 // if we're giving the same name mangling to things of different types then there is 214 214 // something wrong … … 274 274 } 275 275 276 bool Indexer::hasIncompatibleCDecl( 277 const std::string & id, const std::string &mangleName ) const { 276 bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const { 278 277 if ( ! idTable ) return false; 279 278 … … 295 294 296 295 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 297 std::string getOtypeKey( FunctionDecl * function ) {296 std::string getOtypeKey( const FunctionDecl * function ) { 298 297 auto& params = function->type->parameters; 299 298 assert( ! params.empty() ); … … 306 305 /// gets the declaration for the function acting on a type specified by otype key, 307 306 /// nullptr if none such 308 FunctionDecl * getFunctionForOtype(DeclarationWithType * decl, const std::string& otypeKey ) {309 FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl );307 const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) { 308 const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ); 310 309 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 311 310 return func; 312 311 } 313 312 314 bool Indexer::removeSpecialOverrides( 315 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 313 bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 316 314 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 317 315 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, … … 324 322 325 323 // only relevant on function declarations 326 FunctionDecl * function = dynamic_cast<FunctionDecl * >( data.id );324 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id ); 327 325 if ( ! function ) return true; 328 326 // only need to perform this check for constructors, destructors, and assignment functions … … 343 341 for ( const auto& entry : * mangleTable ) { 344 342 // skip decls that aren't functions or are for the wrong type 345 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );343 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 346 344 if ( ! decl ) continue; 347 345 … … 382 380 for ( const auto& entry : * mangleTable ) { 383 381 // skip decls that aren't functions or are for the wrong type 384 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );382 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 385 383 if ( ! decl ) continue; 386 384 … … 410 408 for ( const auto& entry : * mangleTable ) { 411 409 // skip decls that aren't functions or are for the wrong type 412 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );410 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 413 411 if ( ! decl ) continue; 414 412 … … 433 431 } 434 432 435 void Indexer::addId( 436 DeclarationWithType * decl, OnConflict handleConflicts, Expression * baseExpr, 437 BaseSyntaxNode * deleteStmt ) { 433 void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr, 434 const BaseSyntaxNode * deleteStmt ) { 438 435 ++* stats().add_calls; 439 436 const std::string &name = decl->name; … … 508 505 } 509 506 510 void Indexer::addId( DeclarationWithType * decl,Expression * baseExpr ) {507 void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) { 511 508 // default handling of conflicts is to raise an error 512 509 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 513 510 } 514 511 515 void Indexer::addDeletedId( DeclarationWithType * decl,BaseSyntaxNode * deleteStmt ) {512 void Indexer::addDeletedId( const DeclarationWithType * decl, const BaseSyntaxNode * deleteStmt ) { 516 513 // default handling of conflicts is to raise an error 517 514 addId( decl, OnConflict::error(), nullptr, deleteStmt ); 518 515 } 519 516 520 bool addedTypeConflicts( NamedTypeDecl * existing,NamedTypeDecl * added ) {517 bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) { 521 518 if ( existing->base == nullptr ) { 522 519 return false; … … 535 532 } 536 533 537 void Indexer::addType( NamedTypeDecl * decl ) {534 void Indexer::addType( const NamedTypeDecl * decl ) { 538 535 ++* stats().add_calls; 539 536 const std::string & id = decl->name; … … 554 551 } 555 552 556 bool addedDeclConflicts( AggregateDecl * existing,AggregateDecl * added ) {553 bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) { 557 554 if ( ! existing->body ) { 558 555 return false; … … 567 564 } 568 565 569 void Indexer::addStruct( StructDecl * decl ) {566 void Indexer::addStruct( const StructDecl * decl ) { 570 567 ++* stats().add_calls; 571 568 const std::string & id = decl->name; … … 586 583 } 587 584 588 void Indexer::addEnum( EnumDecl * decl ) {585 void Indexer::addEnum( const EnumDecl * decl ) { 589 586 ++* stats().add_calls; 590 587 const std::string & id = decl->name; … … 609 606 } 610 607 611 void Indexer::addUnion( UnionDecl * decl ) {608 void Indexer::addUnion( const UnionDecl * decl ) { 612 609 ++* stats().add_calls; 613 610 const std::string & id = decl->name; … … 628 625 } 629 626 630 void Indexer::addTrait( TraitDecl * decl ) {627 void Indexer::addTrait( const TraitDecl * decl ) { 631 628 ++* stats().add_calls; 632 629 const std::string & id = decl->name; … … 647 644 } 648 645 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 650 OnConflict handleConflicts ) { 646 void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) { 651 647 for ( Declaration * decl : aggr->members ) { 652 648 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 653 649 addId( dwt, handleConflicts, expr ); 654 650 if ( dwt->name == "" ) { 655 Type * t = dwt->get_type()->stripReferences();656 if ( dynamic_cast< StructInstType *>( t ) || dynamic_cast<UnionInstType *>( t ) ) {651 const Type * t = dwt->get_type()->stripReferences(); 652 if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) { 657 653 Expression * base = expr->clone(); 658 654 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? … … 665 661 } 666 662 667 void Indexer::addWith( std::list< Expression * > & withExprs,BaseSyntaxNode * withStmt ) {668 for ( Expression * expr : withExprs ) {663 void Indexer::addWith( const std::list< Expression * > & withExprs, const BaseSyntaxNode * withStmt ) { 664 for ( const Expression * expr : withExprs ) { 669 665 if ( expr->result ) { 670 666 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); … … 689 685 } 690 686 691 void Indexer::addFunctionType( FunctionType * ftype ) {687 void Indexer::addFunctionType( const FunctionType * ftype ) { 692 688 addTypes( ftype->forall ); 693 689 addIds( ftype->returnVals ); … … 700 696 Expression * base = baseExpr->clone(); 701 697 ResolvExpr::referenceToRvalueConversion( base, cost ); 702 ret = new MemberExpr( id, base );698 ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base ); 703 699 // xxx - this introduces hidden environments, for now remove them. 704 700 // std::swap( base->env, ret->env ); … … 706 702 base->env = nullptr; 707 703 } else { 708 ret = new VariableExpr( id);709 } 710 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt);704 ret = new VariableExpr( const_cast<DeclarationWithType *>(id) ); 705 } 706 if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<BaseSyntaxNode *>(deleteStmt) ); 711 707 return ret; 712 708 } -
src/SymTab/Indexer.h
r4f37255 r7dc2e57b 40 40 41 41 struct IdData { 42 DeclarationWithType * id = nullptr;43 Expression * baseExpr = nullptr; // WithExpr42 const DeclarationWithType * id = nullptr; 43 const Expression * baseExpr = nullptr; // WithExpr 44 44 45 45 /// non-null if this declaration is deleted 46 BaseSyntaxNode * deleteStmt = nullptr;46 const BaseSyntaxNode * deleteStmt = nullptr; 47 47 /// scope of identifier 48 48 unsigned long scope = 0; … … 51 51 IdData() = default; 52 52 IdData( 53 DeclarationWithType * id, Expression * baseExpr,BaseSyntaxNode * deleteStmt,53 const DeclarationWithType * id, const Expression * baseExpr, const BaseSyntaxNode * deleteStmt, 54 54 unsigned long scope ) 55 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 IdData( const IdData& o, BaseSyntaxNode * deleteStmt )56 IdData( const IdData& o, const BaseSyntaxNode * deleteStmt ) 57 57 : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {} 58 58 … … 82 82 const EnumDecl * globalLookupEnum( const std::string & id ) const; 83 83 84 void addId( DeclarationWithType * decl,Expression * baseExpr = nullptr );85 void addDeletedId( DeclarationWithType * decl,BaseSyntaxNode * deleteStmt );84 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr ); 85 void addDeletedId( const DeclarationWithType * decl, const BaseSyntaxNode * deleteStmt ); 86 86 87 void addType( NamedTypeDecl * decl );87 void addType( const NamedTypeDecl * decl ); 88 88 void addStruct( const std::string & id ); 89 void addStruct( StructDecl * decl );90 void addEnum( EnumDecl * decl );89 void addStruct( const StructDecl * decl ); 90 void addEnum( const EnumDecl * decl ); 91 91 void addUnion( const std::string & id ); 92 void addUnion( UnionDecl * decl );93 void addTrait( TraitDecl * decl );92 void addUnion( const UnionDecl * decl ); 93 void addTrait( const TraitDecl * decl ); 94 94 95 95 /// adds all of the IDs from WithStmt exprs 96 void addWith( std::list< Expression * > & withExprs,BaseSyntaxNode * withStmt );96 void addWith( const std::list< Expression * > & withExprs, const BaseSyntaxNode * withStmt ); 97 97 98 98 /// convenience function for adding a list of Ids to the indexer … … 103 103 104 104 /// convenience function for adding all of the declarations in a function type to the indexer 105 void addFunctionType( FunctionType * ftype );105 void addFunctionType( const FunctionType * ftype ); 106 106 107 107 private: … … 109 109 template<typename Decl> 110 110 struct Scoped { 111 Decl * decl; ///< declaration111 const Decl * decl; ///< declaration 112 112 unsigned long scope; ///< scope of this declaration 113 113 114 Scoped( Decl * d, unsigned long s) : decl(d), scope(s) {}114 Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {} 115 115 }; 116 116 … … 144 144 /// Removes matching autogenerated constructors and destructors so that they will not be 145 145 /// selected. If returns false, passed decl should not be added. 146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr& mangleTable );146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); 147 147 148 148 /// Options for handling identifier conflicts … … 152 152 Delete ///< Delete the earlier version with the delete statement 153 153 } mode; 154 BaseSyntaxNode * deleteStmt; ///< Statement that deletes this expression154 const BaseSyntaxNode * deleteStmt; ///< Statement that deletes this expression 155 155 156 156 private: 157 157 OnConflict() : mode(Error), deleteStmt(nullptr) {} 158 OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}158 OnConflict( const BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {} 159 159 public: 160 160 OnConflict( const OnConflict& ) = default; 161 161 162 162 static OnConflict error() { return {}; } 163 static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }163 static OnConflict deleteWith( const BaseSyntaxNode * d ) { return { d }; } 164 164 }; 165 165 166 166 /// true if the existing identifier conflicts with the added identifier 167 167 bool addedIdConflicts( 168 const IdData & existing,DeclarationWithType * added, OnConflict handleConflicts,169 BaseSyntaxNode * deleteStmt );168 const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts, 169 const BaseSyntaxNode * deleteStmt ); 170 170 171 171 /// common code for addId, addDeletedId, etc. 172 void addId( 173 DeclarationWithType * decl, OnConflict handleConflicts, 174 Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 172 void addId(const DeclarationWithType * decl, OnConflict handleConflicts, 173 const Expression * baseExpr = nullptr, const BaseSyntaxNode * deleteStmt = nullptr ); 175 174 176 175 /// adds all of the members of the Aggregate (addWith helper) 177 void addMembers( AggregateDecl * aggr,Expression * expr, OnConflict handleConflicts );176 void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ); 178 177 179 178 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 180 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const;179 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 181 180 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 182 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const;181 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 183 182 }; 184 183 } // namespace SymTab -
src/SymTab/Mangler.cc
r4f37255 r7dc2e57b 42 42 Mangler_old( const Mangler_old & ) = delete; 43 43 44 void previsit( BaseSyntaxNode * ) { visit_children = false; }45 46 void postvisit( ObjectDecl * declaration );47 void postvisit( FunctionDecl * declaration );48 void postvisit( TypeDecl * declaration );49 50 void postvisit( VoidType * voidType );51 void postvisit( BasicType * basicType );52 void postvisit( PointerType * pointerType );53 void postvisit( ArrayType * arrayType );54 void postvisit( ReferenceType * refType );55 void postvisit( FunctionType * functionType );56 void postvisit( StructInstType * aggregateUseType );57 void postvisit( UnionInstType * aggregateUseType );58 void postvisit( EnumInstType * aggregateUseType );59 void postvisit( TypeInstType * aggregateUseType );60 void postvisit( TraitInstType * inst );61 void postvisit( TupleType * tupleType );62 void postvisit( VarArgsType * varArgsType );63 void postvisit( ZeroType * zeroType );64 void postvisit( OneType * oneType );65 void postvisit( QualifiedType * qualType );44 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 45 46 void postvisit( const ObjectDecl * declaration ); 47 void postvisit( const FunctionDecl * declaration ); 48 void postvisit( const TypeDecl * declaration ); 49 50 void postvisit( const VoidType * voidType ); 51 void postvisit( const BasicType * basicType ); 52 void postvisit( const PointerType * pointerType ); 53 void postvisit( const ArrayType * arrayType ); 54 void postvisit( const ReferenceType * refType ); 55 void postvisit( const FunctionType * functionType ); 56 void postvisit( const StructInstType * aggregateUseType ); 57 void postvisit( const UnionInstType * aggregateUseType ); 58 void postvisit( const EnumInstType * aggregateUseType ); 59 void postvisit( const TypeInstType * aggregateUseType ); 60 void postvisit( const TraitInstType * inst ); 61 void postvisit( const TupleType * tupleType ); 62 void postvisit( const VarArgsType * varArgsType ); 63 void postvisit( const ZeroType * zeroType ); 64 void postvisit( const OneType * oneType ); 65 void postvisit( const QualifiedType * qualType ); 66 66 67 67 std::string get_mangleName() { return mangleName.str(); } … … 79 79 80 80 public: 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 82 int nextVarNum, const VarMapType& varNums ); 83 83 84 84 private: 85 void mangleDecl( DeclarationWithType *declaration );86 void mangleRef( ReferenceToType *refType, std::string prefix );87 88 void printQualifiers( Type *type );85 void mangleDecl( const DeclarationWithType * declaration ); 86 void mangleRef( const ReferenceToType * refType, std::string prefix ); 87 88 void printQualifiers( const Type *type ); 89 89 }; // Mangler_old 90 90 } // namespace 91 91 92 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 93 93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams ); 94 94 maybeAccept( decl, mangler ); … … 96 96 } 97 97 98 std::string mangleType( Type * ty ) {98 std::string mangleType( const Type * ty ) { 99 99 PassVisitor<Mangler_old> mangler( false, true, true ); 100 100 maybeAccept( ty, mangler ); … … 102 102 } 103 103 104 std::string mangleConcrete( Type * ty ) {104 std::string mangleConcrete( const Type * ty ) { 105 105 PassVisitor<Mangler_old> mangler( false, false, false ); 106 106 maybeAccept( ty, mangler ); … … 110 110 namespace { 111 111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 114 114 mangleGenericParams( mangleGenericParams ) {} 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 117 117 int nextVarNum, const VarMapType& varNums ) 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 120 120 mangleGenericParams( mangleGenericParams ) {} 121 121 122 void Mangler_old::mangleDecl( DeclarationWithType * declaration ) {122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) { 123 123 bool wasTopLevel = isTopLevel; 124 124 if ( isTopLevel ) { … … 150 150 } 151 151 152 void Mangler_old::postvisit( ObjectDecl * declaration ) {152 void Mangler_old::postvisit( const ObjectDecl * declaration ) { 153 153 mangleDecl( declaration ); 154 154 } 155 155 156 void Mangler_old::postvisit( FunctionDecl * declaration ) {156 void Mangler_old::postvisit( const FunctionDecl * declaration ) { 157 157 mangleDecl( declaration ); 158 158 } 159 159 160 void Mangler_old::postvisit( VoidType * voidType ) {160 void Mangler_old::postvisit( const VoidType * voidType ) { 161 161 printQualifiers( voidType ); 162 162 mangleName << Encoding::void_t; 163 163 } 164 164 165 void Mangler_old::postvisit( BasicType * basicType ) {165 void Mangler_old::postvisit( const BasicType * basicType ) { 166 166 printQualifiers( basicType ); 167 assertf( basicType-> get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind());168 mangleName << Encoding::basicTypes[ basicType-> get_kind()];169 } 170 171 void Mangler_old::postvisit( PointerType * pointerType ) {167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); 168 mangleName << Encoding::basicTypes[ basicType->kind ]; 169 } 170 171 void Mangler_old::postvisit( const PointerType * pointerType ) { 172 172 printQualifiers( pointerType ); 173 173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers … … 176 176 } 177 177 178 void Mangler_old::postvisit( ArrayType * arrayType ) {178 void Mangler_old::postvisit( const ArrayType * arrayType ) { 179 179 // TODO: encode dimension 180 180 printQualifiers( arrayType ); … … 183 183 } 184 184 185 void Mangler_old::postvisit( ReferenceType * refType ) {185 void Mangler_old::postvisit( const ReferenceType * refType ) { 186 186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 187 187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 202 202 } 203 203 204 void Mangler_old::postvisit( FunctionType * functionType ) {204 void Mangler_old::postvisit( const FunctionType * functionType ) { 205 205 printQualifiers( functionType ); 206 206 mangleName << Encoding::function; … … 219 219 } 220 220 221 void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) {221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) { 222 222 printQualifiers( refType ); 223 223 … … 225 225 226 226 if ( mangleGenericParams ) { 227 std::list< Expression* >& params = refType->parameters;227 const std::list< Expression* > & params = refType->parameters; 228 228 if ( ! params.empty() ) { 229 229 mangleName << "_"; 230 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param) {231 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString( *param));230 for ( const Expression * param : params ) { 231 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param ); 232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 233 233 maybeAccept( paramType->type, *visitor ); 234 234 } … … 238 238 } 239 239 240 void Mangler_old::postvisit( StructInstType * aggregateUseType ) {240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) { 241 241 mangleRef( aggregateUseType, Encoding::struct_t ); 242 242 } 243 243 244 void Mangler_old::postvisit( UnionInstType * aggregateUseType ) {244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) { 245 245 mangleRef( aggregateUseType, Encoding::union_t ); 246 246 } 247 247 248 void Mangler_old::postvisit( EnumInstType * aggregateUseType ) {248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) { 249 249 mangleRef( aggregateUseType, Encoding::enum_t ); 250 250 } 251 251 252 void Mangler_old::postvisit( TypeInstType * typeInst ) {252 void Mangler_old::postvisit( const TypeInstType * typeInst ) { 253 253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 254 254 if ( varNum == varNums.end() ) { … … 266 266 } 267 267 268 void Mangler_old::postvisit( TraitInstType * inst ) {268 void Mangler_old::postvisit( const TraitInstType * inst ) { 269 269 printQualifiers( inst ); 270 270 mangleName << inst->name.size() << inst->name; 271 271 } 272 272 273 void Mangler_old::postvisit( TupleType * tupleType ) {273 void Mangler_old::postvisit( const TupleType * tupleType ) { 274 274 printQualifiers( tupleType ); 275 275 mangleName << Encoding::tuple << tupleType->types.size(); … … 277 277 } 278 278 279 void Mangler_old::postvisit( VarArgsType * varArgsType ) {279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) { 280 280 printQualifiers( varArgsType ); 281 281 static const std::string vargs = "__builtin_va_list"; … … 283 283 } 284 284 285 void Mangler_old::postvisit( ZeroType * ) {285 void Mangler_old::postvisit( const ZeroType * ) { 286 286 mangleName << Encoding::zero; 287 287 } 288 288 289 void Mangler_old::postvisit( OneType * ) {289 void Mangler_old::postvisit( const OneType * ) { 290 290 mangleName << Encoding::one; 291 291 } 292 292 293 void Mangler_old::postvisit( QualifiedType * qualType ) {293 void Mangler_old::postvisit( const QualifiedType * qualType ) { 294 294 bool inqual = inQualifiedType; 295 295 if (! inqual ) { … … 307 307 } 308 308 309 void Mangler_old::postvisit( TypeDecl * decl ) {309 void Mangler_old::postvisit( const TypeDecl * decl ) { 310 310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 311 311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. … … 314 314 // aside from the assert false. 315 315 assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl)); 316 assertf( decl-> get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind());317 mangleName << Encoding::typeVariables[ decl-> get_kind()] << ( decl->name.length() ) << decl->name;316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 317 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name; 318 318 } 319 319 … … 324 324 } 325 325 326 void Mangler_old::printQualifiers( Type * type ) {326 void Mangler_old::printQualifiers( const Type * type ) { 327 327 // skip if not including qualifiers 328 328 if ( typeMode ) return; 329 if ( ! type-> get_forall().empty() ) {329 if ( ! type->forall.empty() ) { 330 330 std::list< std::string > assertionNames; 331 331 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 332 332 mangleName << Encoding::forall; 333 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i) {334 switch ( (*i)->get_kind()) {333 for ( const TypeDecl * i : type->forall ) { 334 switch ( i->kind ) { 335 335 case TypeDecl::Dtype: 336 336 dcount++; … … 345 345 assert( false ); 346 346 } // switch 347 varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind());348 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert) {349 PassVisitor<Mangler_old> sub_mangler( 347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind ); 348 for ( const DeclarationWithType * assert : i->assertions ) { 349 PassVisitor<Mangler_old> sub_mangler( 350 350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 351 (*assert)->accept( sub_mangler );351 assert->accept( sub_mangler ); 352 352 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 353 353 acount++; … … 436 436 437 437 private: 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 439 439 int nextVarNum, const VarMapType& varNums ); 440 440 friend class ast::Pass<Mangler_new>; … … 457 457 namespace { 458 458 Mangler_new::Mangler_new( Mangle::Mode mode ) 459 : nextVarNum( 0 ), isTopLevel( true ), 459 : nextVarNum( 0 ), isTopLevel( true ), 460 460 mangleOverridable ( ! mode.no_overrideable ), 461 typeMode ( mode.type ), 461 typeMode ( mode.type ), 462 462 mangleGenericParams( ! mode.no_generic_params ) {} 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 465 465 int nextVarNum, const VarMapType& varNums ) 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 468 468 mangleGenericParams( mangleGenericParams ) {} 469 469 … … 693 693 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 694 694 for ( const ast::DeclWithType * assert : decl->assertions ) { 695 ast::Pass<Mangler_new> sub_mangler( 695 ast::Pass<Mangler_new> sub_mangler( 696 696 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 697 697 assert->accept( sub_mangler ); -
src/SymTab/Mangler.h
r4f37255 r7dc2e57b 40 40 namespace Mangler { 41 41 /// Mangle syntax tree object; primary interface to clients 42 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );42 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 43 43 44 44 /// Mangle a type name; secondary interface 45 std::string mangleType( Type* ty );45 std::string mangleType( const Type * ty ); 46 46 /// Mangle ignoring generic type parameters 47 std::string mangleConcrete( Type* ty );47 std::string mangleConcrete( const Type * ty ); 48 48 49 49 namespace Encoding { -
src/SynTree/Visitor.h
r4f37255 r7dc2e57b 222 222 223 223 template< typename TreeType, typename VisitorType > 224 inline void maybeAccept( TreeType * tree, VisitorType &visitor ) {224 inline void maybeAccept( TreeType * tree, VisitorType & visitor ) { 225 225 if ( tree ) { 226 226 tree->accept( visitor ); … … 228 228 } 229 229 230 template< typename TreeType, typename VisitorType > 231 inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) { 232 if ( tree ) { 233 tree->accept( visitor ); 234 } 235 } 236 230 237 template< typename Container, typename VisitorType > 231 inline void acceptAll( Container & container, VisitorType &visitor ) {238 inline void acceptAll( Container & container, VisitorType & visitor ) { 232 239 SemanticErrorException errors; 233 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i) {240 for ( auto * i : container ) { 234 241 try { 235 if ( *i ) { 236 (*i)->accept( visitor ); 242 if ( i ) { 243 i->accept( visitor ); 244 } 245 } catch( SemanticErrorException & e ) { 246 errors.append( e ); 247 } 248 } 249 if ( ! errors.isEmpty() ) { 250 throw errors; 251 } 252 } 253 254 template< typename Container, typename VisitorType > 255 inline void acceptAll( const Container & container, VisitorType & visitor ) { 256 SemanticErrorException errors; 257 for ( const auto * i : container ) { 258 try { 259 if ( i ) { 260 i->accept( visitor ); 237 261 } 238 262 } catch( SemanticErrorException &e ) {
Note:
See TracChangeset
for help on using the changeset viewer.