Changeset 7870799
- Timestamp:
- Jul 12, 2019, 10:49:02 AM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- ef5b828
- Parents:
- ee6dbae
- Location:
- src
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
ree6dbae r7870799 1355 1355 ast::Node * node = nullptr; 1356 1356 /// cache of nodes that might be referenced by readonly<> for de-duplication 1357 std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};1357 std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {}; 1358 1358 1359 1359 // Local Utilities: … … 1422 1422 to<std::vector>::from( make_labels( std::move( labels ) ) ) 1423 1423 1424 static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }1424 static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; } 1425 1425 1426 1426 /// returns true and sets `node` if in cache 1427 bool inCache( BaseSyntaxNode * old ) {1427 bool inCache( const BaseSyntaxNode * old ) { 1428 1428 auto it = cache.find( old ); 1429 1429 if ( it == cache.end() ) return false; … … 1434 1434 // Now all the visit functions: 1435 1435 1436 virtual void visit( ObjectDecl * old ) override final {1436 virtual void visit( const ObjectDecl * old ) override final { 1437 1437 auto&& type = GET_ACCEPT_1(type, Type); 1438 1438 auto&& init = GET_ACCEPT_1(init, Init); … … 1465 1465 } 1466 1466 1467 virtual void visit( FunctionDecl * old ) override final {1467 virtual void visit( const FunctionDecl * old ) override final { 1468 1468 if ( inCache( old ) ) return; 1469 1469 auto decl = new ast::FunctionDecl{ … … 1498 1498 } 1499 1499 1500 virtual void visit( StructDecl * old ) override final {1500 virtual void visit( const StructDecl * old ) override final { 1501 1501 if ( inCache( old ) ) return; 1502 1502 auto decl = new ast::StructDecl( … … 1523 1523 } 1524 1524 1525 virtual void visit( UnionDecl * old ) override final {1525 virtual void visit( const UnionDecl * old ) override final { 1526 1526 if ( inCache( old ) ) return; 1527 1527 auto decl = new ast::UnionDecl( … … 1543 1543 } 1544 1544 1545 virtual void visit( EnumDecl * old ) override final {1545 virtual void visit( const EnumDecl * old ) override final { 1546 1546 if ( inCache( old ) ) return; 1547 1547 auto decl = new ast::EnumDecl( … … 1563 1563 } 1564 1564 1565 virtual void visit( TraitDecl * old ) override final {1565 virtual void visit( const TraitDecl * old ) override final { 1566 1566 if ( inCache( old ) ) return; 1567 1567 auto decl = new ast::TraitDecl( … … 1583 1583 } 1584 1584 1585 virtual void visit( TypeDecl * old ) override final {1585 virtual void visit( const TypeDecl * old ) override final { 1586 1586 if ( inCache( old ) ) return; 1587 1587 auto decl = new ast::TypeDecl{ … … 1603 1603 } 1604 1604 1605 virtual void visit( TypedefDecl * old ) override final {1605 virtual void visit( const TypedefDecl * old ) override final { 1606 1606 auto decl = new ast::TypedefDecl( 1607 1607 old->location, … … 1620 1620 } 1621 1621 1622 virtual void visit( AsmDecl * old ) override final {1622 virtual void visit( const AsmDecl * old ) override final { 1623 1623 auto decl = new ast::AsmDecl{ 1624 1624 old->location, … … 1632 1632 } 1633 1633 1634 virtual void visit( StaticAssertDecl * old ) override final {1634 virtual void visit( const StaticAssertDecl * old ) override final { 1635 1635 auto decl = new ast::StaticAssertDecl{ 1636 1636 old->location, … … 1645 1645 } 1646 1646 1647 virtual void visit( CompoundStmt * old ) override final {1647 virtual void visit( const CompoundStmt * old ) override final { 1648 1648 if ( inCache( old ) ) return; 1649 1649 auto stmt = new ast::CompoundStmt( … … 1657 1657 } 1658 1658 1659 virtual void visit( ExprStmt * old ) override final {1659 virtual void visit( const ExprStmt * old ) override final { 1660 1660 if ( inCache( old ) ) return; 1661 1661 this->node = new ast::ExprStmt( … … 1667 1667 } 1668 1668 1669 virtual void visit( AsmStmt * old ) override final {1669 virtual void visit( const AsmStmt * old ) override final { 1670 1670 if ( inCache( old ) ) return; 1671 1671 this->node = new ast::AsmStmt( … … 1682 1682 } 1683 1683 1684 virtual void visit( DirectiveStmt * old ) override final {1684 virtual void visit( const DirectiveStmt * old ) override final { 1685 1685 if ( inCache( old ) ) return; 1686 1686 this->node = new ast::DirectiveStmt( … … 1692 1692 } 1693 1693 1694 virtual void visit( IfStmt * old ) override final {1694 virtual void visit( const IfStmt * old ) override final { 1695 1695 if ( inCache( old ) ) return; 1696 1696 this->node = new ast::IfStmt( … … 1705 1705 } 1706 1706 1707 virtual void visit( SwitchStmt * old ) override final {1707 virtual void visit( const SwitchStmt * old ) override final { 1708 1708 if ( inCache( old ) ) return; 1709 1709 this->node = new ast::SwitchStmt( … … 1716 1716 } 1717 1717 1718 virtual void visit( CaseStmt * old ) override final {1718 virtual void visit( const CaseStmt * old ) override final { 1719 1719 if ( inCache( old ) ) return; 1720 1720 this->node = new ast::CaseStmt( … … 1727 1727 } 1728 1728 1729 virtual void visit( WhileStmt * old ) override final {1729 virtual void visit( const WhileStmt * old ) override final { 1730 1730 if ( inCache( old ) ) return; 1731 1731 this->node = new ast::WhileStmt( … … 1740 1740 } 1741 1741 1742 virtual void visit( ForStmt * old ) override final {1742 virtual void visit( const ForStmt * old ) override final { 1743 1743 if ( inCache( old ) ) return; 1744 1744 this->node = new ast::ForStmt( … … 1753 1753 } 1754 1754 1755 virtual void visit( BranchStmt * old ) override final {1755 virtual void visit( const BranchStmt * old ) override final { 1756 1756 if ( inCache( old ) ) return; 1757 1757 if (old->computedTarget) { … … 1790 1790 } 1791 1791 1792 virtual void visit( ReturnStmt * old ) override final {1792 virtual void visit( const ReturnStmt * old ) override final { 1793 1793 if ( inCache( old ) ) return; 1794 1794 this->node = new ast::ReturnStmt( … … 1800 1800 } 1801 1801 1802 virtual void visit( ThrowStmt * old ) override final {1802 virtual void visit( const ThrowStmt * old ) override final { 1803 1803 if ( inCache( old ) ) return; 1804 1804 ast::ExceptionKind kind; … … 1824 1824 } 1825 1825 1826 virtual void visit( TryStmt * old ) override final {1826 virtual void visit( const TryStmt * old ) override final { 1827 1827 if ( inCache( old ) ) return; 1828 1828 this->node = new ast::TryStmt( … … 1836 1836 } 1837 1837 1838 virtual void visit( CatchStmt * old ) override final {1838 virtual void visit( const CatchStmt * old ) override final { 1839 1839 if ( inCache( old ) ) return; 1840 1840 ast::ExceptionKind kind; … … 1861 1861 } 1862 1862 1863 virtual void visit( FinallyStmt * old ) override final {1863 virtual void visit( const FinallyStmt * old ) override final { 1864 1864 if ( inCache( old ) ) return; 1865 1865 this->node = new ast::FinallyStmt( … … 1871 1871 } 1872 1872 1873 virtual void visit( WaitForStmt * old ) override final {1873 virtual void visit( const WaitForStmt * old ) override final { 1874 1874 if ( inCache( old ) ) return; 1875 1875 ast::WaitForStmt * stmt = new ast::WaitForStmt( … … 1903 1903 } 1904 1904 1905 virtual void visit( WithStmt * old ) override final {1905 virtual void visit( const WithStmt * old ) override final { 1906 1906 if ( inCache( old ) ) return; 1907 1907 this->node = new ast::WithStmt( … … 1914 1914 } 1915 1915 1916 virtual void visit( NullStmt * old ) override final {1916 virtual void visit( const NullStmt * old ) override final { 1917 1917 if ( inCache( old ) ) return; 1918 1918 this->node = new ast::NullStmt( … … 1923 1923 } 1924 1924 1925 virtual void visit( DeclStmt * old ) override final {1925 virtual void visit( const DeclStmt * old ) override final { 1926 1926 if ( inCache( old ) ) return; 1927 1927 this->node = new ast::DeclStmt( … … 1933 1933 } 1934 1934 1935 virtual void visit( ImplicitCtorDtorStmt * old ) override final {1935 virtual void visit( const ImplicitCtorDtorStmt * old ) override final { 1936 1936 if ( inCache( old ) ) return; 1937 1937 auto stmt = new ast::ImplicitCtorDtorStmt( … … 1990 1990 } 1991 1991 1992 ast::Expr * visitBaseExpr_SkipResultType( Expression * old, ast::Expr * nw) {1992 ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) { 1993 1993 1994 1994 nw->env = convertTypeSubstitution(old->env); … … 2000 2000 } 2001 2001 2002 ast::Expr * visitBaseExpr( Expression * old, ast::Expr * nw) {2002 ast::Expr * visitBaseExpr( const Expression * old, ast::Expr * nw) { 2003 2003 2004 2004 nw->result = GET_ACCEPT_1(result, Type); … … 2006 2006 } 2007 2007 2008 virtual void visit( ApplicationExpr * old ) override final {2008 virtual void visit( const ApplicationExpr * old ) override final { 2009 2009 this->node = visitBaseExpr( old, 2010 2010 new ast::ApplicationExpr( … … 2016 2016 } 2017 2017 2018 virtual void visit( UntypedExpr * old ) override final {2018 virtual void visit( const UntypedExpr * old ) override final { 2019 2019 this->node = visitBaseExpr( old, 2020 2020 new ast::UntypedExpr( … … 2026 2026 } 2027 2027 2028 virtual void visit( NameExpr * old ) override final {2028 virtual void visit( const NameExpr * old ) override final { 2029 2029 this->node = visitBaseExpr( old, 2030 2030 new ast::NameExpr( … … 2035 2035 } 2036 2036 2037 virtual void visit( CastExpr * old ) override final {2037 virtual void visit( const CastExpr * old ) override final { 2038 2038 this->node = visitBaseExpr( old, 2039 2039 new ast::CastExpr( … … 2045 2045 } 2046 2046 2047 virtual void visit( KeywordCastExpr * old) override final {2047 virtual void visit( const KeywordCastExpr * old) override final { 2048 2048 ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS; 2049 2049 switch (old->target) { … … 2070 2070 } 2071 2071 2072 virtual void visit( VirtualCastExpr * old ) override final {2072 virtual void visit( const VirtualCastExpr * old ) override final { 2073 2073 this->node = visitBaseExpr_SkipResultType( old, 2074 2074 new ast::VirtualCastExpr( … … 2080 2080 } 2081 2081 2082 virtual void visit( AddressExpr * old ) override final {2082 virtual void visit( const AddressExpr * old ) override final { 2083 2083 this->node = visitBaseExpr( old, 2084 2084 new ast::AddressExpr( … … 2089 2089 } 2090 2090 2091 virtual void visit( LabelAddressExpr * old ) override final {2091 virtual void visit( const LabelAddressExpr * old ) override final { 2092 2092 this->node = visitBaseExpr( old, 2093 2093 new ast::LabelAddressExpr( … … 2098 2098 } 2099 2099 2100 virtual void visit( UntypedMemberExpr * old ) override final {2100 virtual void visit( const UntypedMemberExpr * old ) override final { 2101 2101 this->node = visitBaseExpr( old, 2102 2102 new ast::UntypedMemberExpr( … … 2108 2108 } 2109 2109 2110 virtual void visit( MemberExpr * old ) override final {2110 virtual void visit( const MemberExpr * old ) override final { 2111 2111 this->node = visitBaseExpr( old, 2112 2112 new ast::MemberExpr( … … 2118 2118 } 2119 2119 2120 virtual void visit( VariableExpr * old ) override final {2120 virtual void visit( const VariableExpr * old ) override final { 2121 2121 auto expr = new ast::VariableExpr( 2122 2122 old->location … … 2129 2129 } 2130 2130 2131 virtual void visit( ConstantExpr * old ) override final {2131 virtual void visit( const ConstantExpr * old ) override final { 2132 2132 ast::ConstantExpr *rslt = new ast::ConstantExpr( 2133 2133 old->location, 2134 2134 GET_ACCEPT_1(result, Type), 2135 old->constant. get_value(),2135 old->constant.rep, 2136 2136 old->constant.ival 2137 2137 ); 2138 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant. get_type());2138 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.type ); 2139 2139 this->node = visitBaseExpr( old, rslt ); 2140 2140 } 2141 2141 2142 virtual void visit( SizeofExpr * old ) override final {2142 virtual void visit( const SizeofExpr * old ) override final { 2143 2143 assert (old->expr || old->type); 2144 2144 assert (! (old->expr && old->type)); … … 2161 2161 } 2162 2162 2163 virtual void visit( AlignofExpr * old ) override final {2163 virtual void visit( const AlignofExpr * old ) override final { 2164 2164 assert (old->expr || old->type); 2165 2165 assert (! (old->expr && old->type)); … … 2182 2182 } 2183 2183 2184 virtual void visit( UntypedOffsetofExpr * old ) override final {2184 virtual void visit( const UntypedOffsetofExpr * old ) override final { 2185 2185 this->node = visitBaseExpr( old, 2186 2186 new ast::UntypedOffsetofExpr( … … 2192 2192 } 2193 2193 2194 virtual void visit( OffsetofExpr * old ) override final {2194 virtual void visit( const OffsetofExpr * old ) override final { 2195 2195 this->node = visitBaseExpr( old, 2196 2196 new ast::OffsetofExpr( … … 2202 2202 } 2203 2203 2204 virtual void visit( OffsetPackExpr * old ) override final {2204 virtual void visit( const OffsetPackExpr * old ) override final { 2205 2205 this->node = visitBaseExpr( old, 2206 2206 new ast::OffsetPackExpr( … … 2211 2211 } 2212 2212 2213 virtual void visit( LogicalExpr * old ) override final {2213 virtual void visit( const LogicalExpr * old ) override final { 2214 2214 this->node = visitBaseExpr( old, 2215 2215 new ast::LogicalExpr( … … 2224 2224 } 2225 2225 2226 virtual void visit( ConditionalExpr * old ) override final {2226 virtual void visit( const ConditionalExpr * old ) override final { 2227 2227 this->node = visitBaseExpr( old, 2228 2228 new ast::ConditionalExpr( … … 2235 2235 } 2236 2236 2237 virtual void visit( CommaExpr * old ) override final {2237 virtual void visit( const CommaExpr * old ) override final { 2238 2238 this->node = visitBaseExpr( old, 2239 2239 new ast::CommaExpr( … … 2245 2245 } 2246 2246 2247 virtual void visit( TypeExpr * old ) override final {2247 virtual void visit( const TypeExpr * old ) override final { 2248 2248 this->node = visitBaseExpr( old, 2249 2249 new ast::TypeExpr( … … 2254 2254 } 2255 2255 2256 virtual void visit( AsmExpr * old ) override final {2256 virtual void visit( const AsmExpr * old ) override final { 2257 2257 this->node = visitBaseExpr( old, 2258 2258 new ast::AsmExpr( … … 2265 2265 } 2266 2266 2267 virtual void visit( ImplicitCopyCtorExpr * old ) override final {2267 virtual void visit( const ImplicitCopyCtorExpr * old ) override final { 2268 2268 auto rslt = new ast::ImplicitCopyCtorExpr( 2269 2269 old->location, … … 2274 2274 } 2275 2275 2276 virtual void visit( ConstructorExpr * old ) override final {2276 virtual void visit( const ConstructorExpr * old ) override final { 2277 2277 this->node = visitBaseExpr( old, 2278 2278 new ast::ConstructorExpr( … … 2283 2283 } 2284 2284 2285 virtual void visit( CompoundLiteralExpr * old ) override final {2285 virtual void visit( const CompoundLiteralExpr * old ) override final { 2286 2286 this->node = visitBaseExpr_SkipResultType( old, 2287 2287 new ast::CompoundLiteralExpr( … … 2293 2293 } 2294 2294 2295 virtual void visit( RangeExpr * old ) override final {2295 virtual void visit( const RangeExpr * old ) override final { 2296 2296 this->node = visitBaseExpr( old, 2297 2297 new ast::RangeExpr( … … 2303 2303 } 2304 2304 2305 virtual void visit( UntypedTupleExpr * old ) override final {2305 virtual void visit( const UntypedTupleExpr * old ) override final { 2306 2306 this->node = visitBaseExpr( old, 2307 2307 new ast::UntypedTupleExpr( … … 2312 2312 } 2313 2313 2314 virtual void visit( TupleExpr * old ) override final {2314 virtual void visit( const TupleExpr * old ) override final { 2315 2315 this->node = visitBaseExpr( old, 2316 2316 new ast::TupleExpr( … … 2321 2321 } 2322 2322 2323 virtual void visit( TupleIndexExpr * old ) override final {2323 virtual void visit( const TupleIndexExpr * old ) override final { 2324 2324 this->node = visitBaseExpr( old, 2325 2325 new ast::TupleIndexExpr( … … 2331 2331 } 2332 2332 2333 virtual void visit( TupleAssignExpr * old ) override final {2333 virtual void visit( const TupleAssignExpr * old ) override final { 2334 2334 this->node = visitBaseExpr_SkipResultType( old, 2335 2335 new ast::TupleAssignExpr( … … 2341 2341 } 2342 2342 2343 virtual void visit( StmtExpr * old ) override final {2343 virtual void visit( const StmtExpr * old ) override final { 2344 2344 auto rslt = new ast::StmtExpr( 2345 2345 old->location, … … 2352 2352 } 2353 2353 2354 virtual void visit( UniqueExpr * old ) override final {2354 virtual void visit( const UniqueExpr * old ) override final { 2355 2355 auto rslt = new ast::UniqueExpr( 2356 2356 old->location, … … 2364 2364 } 2365 2365 2366 virtual void visit( UntypedInitExpr * old ) override final {2366 virtual void visit( const UntypedInitExpr * old ) override final { 2367 2367 std::deque<ast::InitAlternative> initAlts; 2368 2368 for (auto ia : old->initAlts) { … … 2381 2381 } 2382 2382 2383 virtual void visit( InitExpr * old ) override final {2383 virtual void visit( const InitExpr * old ) override final { 2384 2384 this->node = visitBaseExpr( old, 2385 2385 new ast::InitExpr( … … 2391 2391 } 2392 2392 2393 virtual void visit( DeletedExpr * old ) override final {2393 virtual void visit( const DeletedExpr * old ) override final { 2394 2394 this->node = visitBaseExpr( old, 2395 2395 new ast::DeletedExpr( … … 2403 2403 } 2404 2404 2405 virtual void visit( DefaultArgExpr * old ) override final {2405 virtual void visit( const DefaultArgExpr * old ) override final { 2406 2406 this->node = visitBaseExpr( old, 2407 2407 new ast::DefaultArgExpr( … … 2412 2412 } 2413 2413 2414 virtual void visit( GenericExpr * old ) override final {2414 virtual void visit( const GenericExpr * old ) override final { 2415 2415 std::vector<ast::GenericExpr::Association> associations; 2416 2416 for (auto association : old->associations) { … … 2429 2429 } 2430 2430 2431 void visitType( Type * old, ast::Type * type ) {2431 void visitType( const Type * old, ast::Type * type ) { 2432 2432 // Some types do this in their constructor so add a check. 2433 2433 if ( !old->attributes.empty() && type->attributes.empty() ) { … … 2437 2437 } 2438 2438 2439 virtual void visit( VoidType * old ) override final {2439 virtual void visit( const VoidType * old ) override final { 2440 2440 visitType( old, new ast::VoidType{ cv( old ) } ); 2441 2441 } 2442 2442 2443 virtual void visit( BasicType * old ) override final {2443 virtual void visit( const BasicType * old ) override final { 2444 2444 auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) }; 2445 2445 // I believe this should always be a BasicType. … … 2450 2450 } 2451 2451 2452 virtual void visit( PointerType * old ) override final {2452 virtual void visit( const PointerType * old ) override final { 2453 2453 visitType( old, new ast::PointerType{ 2454 2454 GET_ACCEPT_1( base, Type ), … … 2460 2460 } 2461 2461 2462 virtual void visit( ArrayType * old ) override final {2462 virtual void visit( const ArrayType * old ) override final { 2463 2463 visitType( old, new ast::ArrayType{ 2464 2464 GET_ACCEPT_1( base, Type ), … … 2470 2470 } 2471 2471 2472 virtual void visit( ReferenceType * old ) override final {2472 virtual void visit( const ReferenceType * old ) override final { 2473 2473 visitType( old, new ast::ReferenceType{ 2474 2474 GET_ACCEPT_1( base, Type ), … … 2477 2477 } 2478 2478 2479 virtual void visit( QualifiedType * old ) override final {2479 virtual void visit( const QualifiedType * old ) override final { 2480 2480 visitType( old, new ast::QualifiedType{ 2481 2481 GET_ACCEPT_1( parent, Type ), … … 2485 2485 } 2486 2486 2487 virtual void visit( FunctionType * old ) override final {2487 virtual void visit( const FunctionType * old ) override final { 2488 2488 auto ty = new ast::FunctionType { 2489 2489 (ast::ArgumentFlag)old->isVarArgs, … … 2496 2496 } 2497 2497 2498 void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {2498 void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) { 2499 2499 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2500 2500 ty->params = GET_ACCEPT_V( parameters, Expr ); … … 2503 2503 } 2504 2504 2505 virtual void visit( StructInstType * old ) override final {2505 virtual void visit( const StructInstType * old ) override final { 2506 2506 ast::StructInstType * ty; 2507 2507 if ( old->baseStruct ) { … … 2521 2521 } 2522 2522 2523 virtual void visit( UnionInstType * old ) override final {2523 virtual void visit( const UnionInstType * old ) override final { 2524 2524 ast::UnionInstType * ty; 2525 2525 if ( old->baseUnion ) { … … 2539 2539 } 2540 2540 2541 virtual void visit( EnumInstType * old ) override final {2541 virtual void visit( const EnumInstType * old ) override final { 2542 2542 ast::EnumInstType * ty; 2543 2543 if ( old->baseEnum ) { … … 2557 2557 } 2558 2558 2559 virtual void visit( TraitInstType * old ) override final {2559 virtual void visit( const TraitInstType * old ) override final { 2560 2560 ast::TraitInstType * ty; 2561 2561 if ( old->baseTrait ) { … … 2575 2575 } 2576 2576 2577 virtual void visit( TypeInstType * old ) override final {2577 virtual void visit( const TypeInstType * old ) override final { 2578 2578 ast::TypeInstType * ty; 2579 2579 if ( old->baseType ) { … … 2595 2595 } 2596 2596 2597 virtual void visit( TupleType * old ) override final {2597 virtual void visit( const TupleType * old ) override final { 2598 2598 visitType( old, new ast::TupleType{ 2599 2599 GET_ACCEPT_V( types, Type ), … … 2603 2603 } 2604 2604 2605 virtual void visit( TypeofType * old ) override final {2605 virtual void visit( const TypeofType * old ) override final { 2606 2606 visitType( old, new ast::TypeofType{ 2607 2607 GET_ACCEPT_1( expr, Expr ), … … 2611 2611 } 2612 2612 2613 virtual void visit( AttrType * ) override final {2613 virtual void visit( const AttrType * ) override final { 2614 2614 assertf( false, "AttrType deprecated in new AST." ); 2615 2615 } 2616 2616 2617 virtual void visit( VarArgsType * old ) override final {2617 virtual void visit( const VarArgsType * old ) override final { 2618 2618 visitType( old, new ast::VarArgsType{ cv( old ) } ); 2619 2619 } 2620 2620 2621 virtual void visit( ZeroType * old ) override final {2621 virtual void visit( const ZeroType * old ) override final { 2622 2622 visitType( old, new ast::ZeroType{ cv( old ) } ); 2623 2623 } 2624 2624 2625 virtual void visit( OneType * old ) override final {2625 virtual void visit( const OneType * old ) override final { 2626 2626 visitType( old, new ast::OneType{ cv( old ) } ); 2627 2627 } 2628 2628 2629 virtual void visit( GlobalScopeType * old ) override final {2629 virtual void visit( const GlobalScopeType * old ) override final { 2630 2630 visitType( old, new ast::GlobalScopeType{} ); 2631 2631 } 2632 2632 2633 virtual void visit( Designation * old ) override final {2633 virtual void visit( const Designation * old ) override final { 2634 2634 this->node = new ast::Designation( 2635 2635 old->location, … … 2638 2638 } 2639 2639 2640 virtual void visit( SingleInit * old ) override final {2640 virtual void visit( const SingleInit * old ) override final { 2641 2641 this->node = new ast::SingleInit( 2642 2642 old->location, … … 2646 2646 } 2647 2647 2648 virtual void visit( ListInit * old ) override final {2648 virtual void visit( const ListInit * old ) override final { 2649 2649 this->node = new ast::ListInit( 2650 2650 old->location, … … 2655 2655 } 2656 2656 2657 virtual void visit( ConstructorInit * old ) override final {2657 virtual void visit( const ConstructorInit * old ) override final { 2658 2658 this->node = new ast::ConstructorInit( 2659 2659 old->location, … … 2664 2664 } 2665 2665 2666 virtual void visit( Constant * ) override final {2666 virtual void visit( const Constant * ) override final { 2667 2667 // Handled in visit( ConstantEpxr * ). 2668 2668 // In the new tree, Constant fields are inlined into containing ConstantExpression. … … 2670 2670 } 2671 2671 2672 virtual void visit( Attribute * old ) override final {2672 virtual void visit( const Attribute * old ) override final { 2673 2673 this->node = new ast::Attribute( 2674 2674 old->name, … … 2677 2677 } 2678 2678 2679 virtual void visit( AttrExpr * ) override final {2679 virtual void visit( const AttrExpr * ) override final { 2680 2680 assertf( false, "AttrExpr deprecated in new AST." ); 2681 2681 } -
src/AST/Expr.hpp
ree6dbae r7870799 47 47 48 48 ParamEntry() : decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {} 49 ParamEntry( 50 UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 49 ParamEntry( 50 UniqueId id, const Decl * declptr, const Type * actual, const Type * formal, 51 51 const Expr * e ) 52 52 : decl( id ), declptr( declptr ), actualType( actual ), formalType( formal ), expr( e ) {} … … 112 112 case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough 113 113 case Slots: return data.resnSlots; 114 case Params: assert (!"Cannot return to resnSlots from Params");114 case Params: assertf(false, "Cannot return to resnSlots from Params"); abort(); 115 115 } 116 return *((ResnSlots*)nullptr);117 116 } 118 117 … … 121 120 return data.resnSlots; 122 121 } 123 assert (!"Mode was not already resnSlots");124 return *((ResnSlots*)nullptr);122 assertf(false, "Mode was not already resnSlots"); 123 abort(); 125 124 } 126 125 … … 131 130 case Params: return data.inferParams; 132 131 } 133 assert(!"unreachable"); 134 return *((InferredParams*)nullptr); 132 assertf(false, "unreachable"); 135 133 } 136 134 … … 139 137 return data.inferParams; 140 138 } 141 assert (!"Mode was not already Params");142 return *((InferredParams*)nullptr);139 assertf(false, "Mode was not already Params"); 140 abort(); 143 141 } 144 142 145 143 void set_inferParams( InferredParams && ps ) { 146 144 switch(mode) { 147 case Slots: 145 case Slots: 148 146 data.resnSlots.~ResnSlots(); 149 147 // fallthrough 150 case Empty: 148 case Empty: 151 149 new(&data.inferParams) InferredParams{ std::move( ps ) }; 152 150 mode = Params; … … 172 170 data.inferParams[p.first] = std::move(p.second); 173 171 } 174 } else assert (!"invalid mode");172 } else assertf(false, "invalid mode"); 175 173 } 176 174 }; … … 384 382 385 383 ConstantExpr( 386 const CodeLocation & loc, const Type * ty, const std::string & r, 384 const CodeLocation & loc, const Type * ty, const std::string & r, 387 385 std::optional<unsigned long long> i ) 388 386 : Expr( loc, ty ), rep( r ), ival( i ) {} -
src/Common/PassVisitor.h
ree6dbae r7870799 60 60 61 61 virtual void visit( ObjectDecl * objectDecl ) override final; 62 virtual void visit( const ObjectDecl * objectDecl ) override final; 62 63 virtual void visit( FunctionDecl * functionDecl ) override final; 64 virtual void visit( const FunctionDecl * functionDecl ) override final; 63 65 virtual void visit( StructDecl * aggregateDecl ) override final; 66 virtual void visit( const StructDecl * aggregateDecl ) override final; 64 67 virtual void visit( UnionDecl * aggregateDecl ) override final; 68 virtual void visit( const UnionDecl * aggregateDecl ) override final; 65 69 virtual void visit( EnumDecl * aggregateDecl ) override final; 70 virtual void visit( const EnumDecl * aggregateDecl ) override final; 66 71 virtual void visit( TraitDecl * aggregateDecl ) override final; 72 virtual void visit( const TraitDecl * aggregateDecl ) override final; 67 73 virtual void visit( TypeDecl * typeDecl ) override final; 74 virtual void visit( const TypeDecl * typeDecl ) override final; 68 75 virtual void visit( TypedefDecl * typeDecl ) override final; 76 virtual void visit( const TypedefDecl * typeDecl ) override final; 69 77 virtual void visit( AsmDecl * asmDecl ) override final; 78 virtual void visit( const AsmDecl * asmDecl ) override final; 70 79 virtual void visit( StaticAssertDecl * assertDecl ) override final; 80 virtual void visit( const StaticAssertDecl * assertDecl ) override final; 71 81 72 82 virtual void visit( CompoundStmt * compoundStmt ) override final; 83 virtual void visit( const CompoundStmt * compoundStmt ) override final; 73 84 virtual void visit( ExprStmt * exprStmt ) override final; 85 virtual void visit( const ExprStmt * exprStmt ) override final; 74 86 virtual void visit( AsmStmt * asmStmt ) override final; 87 virtual void visit( const AsmStmt * asmStmt ) override final; 75 88 virtual void visit( DirectiveStmt * dirStmt ) override final; 89 virtual void visit( const DirectiveStmt * dirStmt ) override final; 76 90 virtual void visit( IfStmt * ifStmt ) override final; 91 virtual void visit( const IfStmt * ifStmt ) override final; 77 92 virtual void visit( WhileStmt * whileStmt ) override final; 93 virtual void visit( const WhileStmt * whileStmt ) override final; 78 94 virtual void visit( ForStmt * forStmt ) override final; 95 virtual void visit( const ForStmt * forStmt ) override final; 79 96 virtual void visit( SwitchStmt * switchStmt ) override final; 97 virtual void visit( const SwitchStmt * switchStmt ) override final; 80 98 virtual void visit( CaseStmt * caseStmt ) override final; 99 virtual void visit( const CaseStmt * caseStmt ) override final; 81 100 virtual void visit( BranchStmt * branchStmt ) override final; 101 virtual void visit( const BranchStmt * branchStmt ) override final; 82 102 virtual void visit( ReturnStmt * returnStmt ) override final; 103 virtual void visit( const ReturnStmt * returnStmt ) override final; 83 104 virtual void visit( ThrowStmt * throwStmt ) override final; 105 virtual void visit( const ThrowStmt * throwStmt ) override final; 84 106 virtual void visit( TryStmt * tryStmt ) override final; 107 virtual void visit( const TryStmt * tryStmt ) override final; 85 108 virtual void visit( CatchStmt * catchStmt ) override final; 109 virtual void visit( const CatchStmt * catchStmt ) override final; 86 110 virtual void visit( FinallyStmt * finallyStmt ) override final; 111 virtual void visit( const FinallyStmt * finallyStmt ) override final; 87 112 virtual void visit( WaitForStmt * waitforStmt ) override final; 113 virtual void visit( const WaitForStmt * waitforStmt ) override final; 88 114 virtual void visit( WithStmt * withStmt ) override final; 115 virtual void visit( const WithStmt * withStmt ) override final; 89 116 virtual void visit( NullStmt * nullStmt ) override final; 117 virtual void visit( const NullStmt * nullStmt ) override final; 90 118 virtual void visit( DeclStmt * declStmt ) override final; 119 virtual void visit( const DeclStmt * declStmt ) override final; 91 120 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final; 121 virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final; 92 122 93 123 virtual void visit( ApplicationExpr * applicationExpr ) override final; 124 virtual void visit( const ApplicationExpr * applicationExpr ) override final; 94 125 virtual void visit( UntypedExpr * untypedExpr ) override final; 126 virtual void visit( const UntypedExpr * untypedExpr ) override final; 95 127 virtual void visit( NameExpr * nameExpr ) override final; 128 virtual void visit( const NameExpr * nameExpr ) override final; 96 129 virtual void visit( CastExpr * castExpr ) override final; 130 virtual void visit( const CastExpr * castExpr ) override final; 97 131 virtual void visit( KeywordCastExpr * castExpr ) override final; 132 virtual void visit( const KeywordCastExpr * castExpr ) override final; 98 133 virtual void visit( VirtualCastExpr * castExpr ) override final; 134 virtual void visit( const VirtualCastExpr * castExpr ) override final; 99 135 virtual void visit( AddressExpr * addressExpr ) override final; 136 virtual void visit( const AddressExpr * addressExpr ) override final; 100 137 virtual void visit( LabelAddressExpr * labAddressExpr ) override final; 138 virtual void visit( const LabelAddressExpr * labAddressExpr ) override final; 101 139 virtual void visit( UntypedMemberExpr * memberExpr ) override final; 140 virtual void visit( const UntypedMemberExpr * memberExpr ) override final; 102 141 virtual void visit( MemberExpr * memberExpr ) override final; 142 virtual void visit( const MemberExpr * memberExpr ) override final; 103 143 virtual void visit( VariableExpr * variableExpr ) override final; 144 virtual void visit( const VariableExpr * variableExpr ) override final; 104 145 virtual void visit( ConstantExpr * constantExpr ) override final; 146 virtual void visit( const ConstantExpr * constantExpr ) override final; 105 147 virtual void visit( SizeofExpr * sizeofExpr ) override final; 148 virtual void visit( const SizeofExpr * sizeofExpr ) override final; 106 149 virtual void visit( AlignofExpr * alignofExpr ) override final; 150 virtual void visit( const AlignofExpr * alignofExpr ) override final; 107 151 virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final; 152 virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final; 108 153 virtual void visit( OffsetofExpr * offsetofExpr ) override final; 154 virtual void visit( const OffsetofExpr * offsetofExpr ) override final; 109 155 virtual void visit( OffsetPackExpr * offsetPackExpr ) override final; 156 virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final; 110 157 virtual void visit( AttrExpr * attrExpr ) override final; 158 virtual void visit( const AttrExpr * attrExpr ) override final; 111 159 virtual void visit( LogicalExpr * logicalExpr ) override final; 160 virtual void visit( const LogicalExpr * logicalExpr ) override final; 112 161 virtual void visit( ConditionalExpr * conditionalExpr ) override final; 162 virtual void visit( const ConditionalExpr * conditionalExpr ) override final; 113 163 virtual void visit( CommaExpr * commaExpr ) override final; 164 virtual void visit( const CommaExpr * commaExpr ) override final; 114 165 virtual void visit( TypeExpr * typeExpr ) override final; 166 virtual void visit( const TypeExpr * typeExpr ) override final; 115 167 virtual void visit( AsmExpr * asmExpr ) override final; 168 virtual void visit( const AsmExpr * asmExpr ) override final; 116 169 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final; 170 virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final; 117 171 virtual void visit( ConstructorExpr * ctorExpr ) override final; 172 virtual void visit( const ConstructorExpr * ctorExpr ) override final; 118 173 virtual void visit( CompoundLiteralExpr * compLitExpr ) override final; 174 virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final; 119 175 virtual void visit( RangeExpr * rangeExpr ) override final; 176 virtual void visit( const RangeExpr * rangeExpr ) override final; 120 177 virtual void visit( UntypedTupleExpr * tupleExpr ) override final; 178 virtual void visit( const UntypedTupleExpr * tupleExpr ) override final; 121 179 virtual void visit( TupleExpr * tupleExpr ) override final; 180 virtual void visit( const TupleExpr * tupleExpr ) override final; 122 181 virtual void visit( TupleIndexExpr * tupleExpr ) override final; 182 virtual void visit( const TupleIndexExpr * tupleExpr ) override final; 123 183 virtual void visit( TupleAssignExpr * assignExpr ) override final; 184 virtual void visit( const TupleAssignExpr * assignExpr ) override final; 124 185 virtual void visit( StmtExpr * stmtExpr ) override final; 186 virtual void visit( const StmtExpr * stmtExpr ) override final; 125 187 virtual void visit( UniqueExpr * uniqueExpr ) override final; 188 virtual void visit( const UniqueExpr * uniqueExpr ) override final; 126 189 virtual void visit( UntypedInitExpr * initExpr ) override final; 190 virtual void visit( const UntypedInitExpr * initExpr ) override final; 127 191 virtual void visit( InitExpr * initExpr ) override final; 192 virtual void visit( const InitExpr * initExpr ) override final; 128 193 virtual void visit( DeletedExpr * delExpr ) override final; 194 virtual void visit( const DeletedExpr * delExpr ) override final; 129 195 virtual void visit( DefaultArgExpr * argExpr ) override final; 196 virtual void visit( const DefaultArgExpr * argExpr ) override final; 130 197 virtual void visit( GenericExpr * genExpr ) override final; 198 virtual void visit( const GenericExpr * genExpr ) override final; 131 199 132 200 virtual void visit( VoidType * basicType ) override final; 201 virtual void visit( const VoidType * basicType ) override final; 133 202 virtual void visit( BasicType * basicType ) override final; 203 virtual void visit( const BasicType * basicType ) override final; 134 204 virtual void visit( PointerType * pointerType ) override final; 205 virtual void visit( const PointerType * pointerType ) override final; 135 206 virtual void visit( ArrayType * arrayType ) override final; 207 virtual void visit( const ArrayType * arrayType ) override final; 136 208 virtual void visit( ReferenceType * referenceType ) override final; 209 virtual void visit( const ReferenceType * referenceType ) override final; 137 210 virtual void visit( QualifiedType * qualType ) override final; 211 virtual void visit( const QualifiedType * qualType ) override final; 138 212 virtual void visit( FunctionType * functionType ) override final; 213 virtual void visit( const FunctionType * functionType ) override final; 139 214 virtual void visit( StructInstType * aggregateUseType ) override final; 215 virtual void visit( const StructInstType * aggregateUseType ) override final; 140 216 virtual void visit( UnionInstType * aggregateUseType ) override final; 217 virtual void visit( const UnionInstType * aggregateUseType ) override final; 141 218 virtual void visit( EnumInstType * aggregateUseType ) override final; 219 virtual void visit( const EnumInstType * aggregateUseType ) override final; 142 220 virtual void visit( TraitInstType * aggregateUseType ) override final; 221 virtual void visit( const TraitInstType * aggregateUseType ) override final; 143 222 virtual void visit( TypeInstType * aggregateUseType ) override final; 223 virtual void visit( const TypeInstType * aggregateUseType ) override final; 144 224 virtual void visit( TupleType * tupleType ) override final; 225 virtual void visit( const TupleType * tupleType ) override final; 145 226 virtual void visit( TypeofType * typeofType ) override final; 227 virtual void visit( const TypeofType * typeofType ) override final; 146 228 virtual void visit( AttrType * attrType ) override final; 229 virtual void visit( const AttrType * attrType ) override final; 147 230 virtual void visit( VarArgsType * varArgsType ) override final; 231 virtual void visit( const VarArgsType * varArgsType ) override final; 148 232 virtual void visit( ZeroType * zeroType ) override final; 233 virtual void visit( const ZeroType * zeroType ) override final; 149 234 virtual void visit( OneType * oneType ) override final; 235 virtual void visit( const OneType * oneType ) override final; 150 236 virtual void visit( GlobalScopeType * globalType ) override final; 237 virtual void visit( const GlobalScopeType * globalType ) override final; 151 238 152 239 virtual void visit( Designation * designation ) override final; 240 virtual void visit( const Designation * designation ) override final; 153 241 virtual void visit( SingleInit * singleInit ) override final; 242 virtual void visit( const SingleInit * singleInit ) override final; 154 243 virtual void visit( ListInit * listInit ) override final; 244 virtual void visit( const ListInit * listInit ) override final; 155 245 virtual void visit( ConstructorInit * ctorInit ) override final; 246 virtual void visit( const ConstructorInit * ctorInit ) override final; 156 247 157 248 virtual void visit( Constant * constant ) override final; 249 virtual void visit( const Constant * constant ) override final; 158 250 159 251 virtual void visit( Attribute * attribute ) override final; 252 virtual void visit( const Attribute * attribute ) override final; 160 253 161 254 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final; … … 265 358 266 359 template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 360 template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor ); 267 361 template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor ); 268 362 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor ); 363 template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor ); 269 364 template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator ); 270 365 template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor ); 366 template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor ); 271 367 template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator ); 272 368 273 369 template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); } 370 template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); } 274 371 template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); } 372 template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); } 275 373 276 374 template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); } … … 286 384 void visitStatementList ( std::list< Statement* > &statements ); 287 385 void mutateStatementList( std::list< Statement* > &statements ); 386 void visitStatementList ( const std::list< Statement * > & statements ); 288 387 289 388 template< typename func_t > … … 291 390 Statement * visitStatement ( Statement * stmt ); 292 391 Statement * mutateStatement( Statement * stmt ); 392 void visitStatement ( const Statement * stmt ); 293 393 294 394 template< typename func_t > … … 296 396 Expression * visitExpression ( Expression * expr ); 297 397 Expression * mutateExpression( Expression * expr ); 398 void visitExpression ( const Expression * expr ); 298 399 299 400 -
src/Common/PassVisitor.impl.h
ree6dbae r7870799 80 80 81 81 template< typename pass_type > 82 inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) { 83 SemanticErrorException errors; 84 85 pass_visitor_stats.depth++; 86 pass_visitor_stats.max->push(pass_visitor_stats.depth); 87 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 88 for ( const Declaration * decl : decls ) { 89 try { 90 // run visitor on declaration 91 maybeAccept_impl( decl, visitor ); 92 } 93 catch( SemanticErrorException &e ) { 94 errors.append( e ); 95 } 96 } 97 pass_visitor_stats.depth--; 98 if ( ! errors.isEmpty() ) { 99 throw errors; 100 } 101 } 102 103 template< typename pass_type > 82 104 inline void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_type >& mutator ) { 83 105 DeclList_t* beforeDecls = mutator.get_beforeDecls(); … … 117 139 } 118 140 141 template< typename TreeType, typename pass_type > 142 inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) { 143 if ( ! visitor.get_visit_children() ) return; 144 if ( tree ) { 145 tree->accept( visitor ); 146 } 147 } 148 119 149 template< typename Container, typename pass_type > 120 150 inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) { … … 129 159 if ( *i ) { 130 160 (*i)->accept( visitor ); 161 } 162 } catch( SemanticErrorException &e ) { 163 errors.append( e ); 164 } 165 } 166 pass_visitor_stats.depth--; 167 if ( ! errors.isEmpty() ) { 168 throw errors; 169 } 170 } 171 172 template< typename Container, typename pass_type > 173 inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) { 174 if ( ! visitor.get_visit_children() ) return; 175 SemanticErrorException errors; 176 177 pass_visitor_stats.depth++; 178 pass_visitor_stats.max->push(pass_visitor_stats.depth); 179 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 180 for ( const auto & i : container ) { 181 try { 182 if ( i ) { 183 i->accept( visitor ); 131 184 } 132 185 } catch( SemanticErrorException &e ) { … … 227 280 228 281 template< typename pass_type > 282 void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) { 283 if ( ! get_visit_children() ) return; 284 SemanticErrorException errors; 285 286 pass_visitor_stats.depth++; 287 pass_visitor_stats.max->push(pass_visitor_stats.depth); 288 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 289 for ( const Statement * i : statements ) { 290 try { 291 maybeAccept_impl( i, *this ); 292 } catch ( SemanticErrorException &e ) { 293 errors.append( e ); 294 } 295 } 296 pass_visitor_stats.depth--; 297 if ( !errors.isEmpty() ) { throw errors; } 298 } 299 300 template< typename pass_type > 229 301 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { 230 302 handleStatementList( statements, [this]( Statement *& stmt) { … … 275 347 276 348 template< typename pass_type > 349 void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) { 350 if ( ! get_visit_children() ) return; 351 352 // don't want statements from outer CompoundStmts to be added to this CompoundStmt 353 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 354 355 maybeAccept_impl( stmt, *this ); 356 } 357 358 template< typename pass_type > 277 359 Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { 278 360 return handleStatement( stmt, [this]( Statement * stmt ) { … … 306 388 307 389 template< typename pass_type > 390 void PassVisitor< pass_type >::visitExpression( const Expression * expr ) { 391 if ( ! get_visit_children() ) return; 392 if( !expr ) return; 393 394 auto env_ptr = get_env_ptr(); 395 if ( env_ptr && expr->get_env() ) { 396 *env_ptr = expr->get_env(); 397 } 398 399 maybeAccept_impl( expr, *this ); 400 } 401 402 template< typename pass_type > 308 403 Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { 309 404 return handleExpression(expr, [this]( Expression * expr ) { … … 315 410 template< typename TreeType, typename VisitorType > 316 411 inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) { 412 if ( ! visitor.get_visit_children() ) return; 413 auto guard = makeFuncGuard( 414 [&visitor]() { visitor.indexerScopeEnter(); }, 415 [&visitor]() { visitor.indexerScopeLeave(); } 416 ); 417 maybeAccept_impl( tree, visitor ); 418 } 419 420 template< typename TreeType, typename VisitorType > 421 inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) { 317 422 if ( ! visitor.get_visit_children() ) return; 318 423 auto guard = makeFuncGuard( … … 372 477 373 478 indexerAddId( node ); 479 480 VISIT_END( node ); 481 } 482 483 template< typename pass_type > 484 void PassVisitor< pass_type >::visit( const ObjectDecl * node ) { 485 VISIT_START( node ); 486 487 maybeAccept_impl( node->type , *this ); 488 maybeAccept_impl( node->init , *this ); 489 maybeAccept_impl( node->bitfieldWidth, *this ); 490 maybeAccept_impl( node->attributes , *this ); 374 491 375 492 VISIT_END( node ); … … 428 545 429 546 template< typename pass_type > 547 void PassVisitor< pass_type >::visit( const FunctionDecl * node ) { 548 VISIT_START( node ); 549 550 maybeAccept_impl( node->withExprs, *this ); 551 { 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 ); 565 } 566 567 VISIT_END( node ); 568 } 569 570 template< typename pass_type > 430 571 DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) { 431 572 MUTATE_START( node ); … … 484 625 485 626 template< typename pass_type > 627 void PassVisitor< pass_type >::visit( const StructDecl * node ) { 628 VISIT_START( node ); 629 630 maybeAccept_impl( node->parameters, *this ); 631 maybeAccept_impl( node->members , *this ); 632 633 VISIT_END( node ); 634 } 635 636 template< typename pass_type > 486 637 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { 487 638 MUTATE_START( node ); … … 522 673 VISIT_END( node ); 523 674 } 675 template< typename pass_type > 676 void PassVisitor< pass_type >::visit( const UnionDecl * node ) { 677 VISIT_START( node ); 678 679 maybeAccept_impl( node->parameters, *this ); 680 maybeAccept_impl( node->members , *this ); 681 682 VISIT_END( node ); 683 } 524 684 525 685 template< typename pass_type > … … 557 717 558 718 template< typename pass_type > 719 void PassVisitor< pass_type >::visit( const EnumDecl * node ) { 720 VISIT_START( node ); 721 722 // unlike structs, traits, and unions, enums inject their members into the global scope 723 maybeAccept_impl( node->parameters, *this ); 724 maybeAccept_impl( node->members , *this ); 725 726 VISIT_END( node ); 727 } 728 729 template< typename pass_type > 559 730 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) { 560 731 MUTATE_START( node ); … … 587 758 588 759 template< typename pass_type > 760 void PassVisitor< pass_type >::visit( const TraitDecl * node ) { 761 VISIT_START( node ); 762 763 maybeAccept_impl( node->parameters, *this ); 764 maybeAccept_impl( node->members , *this ); 765 766 VISIT_END( node ); 767 } 768 769 template< typename pass_type > 589 770 Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) { 590 771 MUTATE_START( node ); … … 625 806 } 626 807 808 809 template< typename pass_type > 810 void PassVisitor< pass_type >::visit( const TypeDecl * node ) { 811 VISIT_START( node ); 812 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 627 820 template< typename pass_type > 628 821 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { … … 667 860 668 861 template< typename pass_type > 862 void PassVisitor< pass_type >::visit( const TypedefDecl * node ) { 863 VISIT_START( node ); 864 865 maybeAccept_impl( node->parameters, *this ); 866 maybeAccept_impl( node->base , *this ); 867 maybeAccept_impl( node->assertions, *this ); 868 869 VISIT_END( node ); 870 } 871 872 template< typename pass_type > 669 873 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) { 670 874 MUTATE_START( node ); … … 695 899 696 900 template< typename pass_type > 901 void PassVisitor< pass_type >::visit( const AsmDecl * node ) { 902 VISIT_START( node ); 903 904 maybeAccept_impl( node->stmt, *this ); 905 906 VISIT_END( node ); 907 } 908 909 template< typename pass_type > 697 910 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) { 698 911 MUTATE_START( node ); … … 710 923 711 924 node->condition = visitExpression( node->condition ); 925 maybeAccept_impl( node->message, *this ); 926 927 VISIT_END( node ); 928 } 929 930 template< typename pass_type > 931 void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) { 932 VISIT_START( node ); 933 934 visitExpression( node->condition ); 712 935 maybeAccept_impl( node->message, *this ); 713 936 … … 742 965 743 966 template< typename pass_type > 967 void PassVisitor< pass_type >::visit( const CompoundStmt * node ) { 968 VISIT_START( node ); 969 { 970 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 971 ValueGuard< bool > oldInFunction( inFunction ); 972 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } ); 973 auto guard2 = makeFuncGuard( [this]() { call_beginScope(); }, [this]() { call_endScope(); } ); 974 inFunction = false; 975 visitStatementList( node->kids ); 976 } 977 VISIT_END( node ); 978 } 979 980 template< typename pass_type > 744 981 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { 745 982 MUTATE_START( node ); … … 767 1004 768 1005 template< typename pass_type > 1006 void PassVisitor< pass_type >::visit( const ExprStmt * node ) { 1007 VISIT_START( node ); 1008 1009 visitExpression( node->expr ); 1010 1011 VISIT_END( node ); 1012 } 1013 1014 template< typename pass_type > 769 1015 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) { 770 1016 MUTATE_START( node ); … … 790 1036 791 1037 template< typename pass_type > 1038 void PassVisitor< pass_type >::visit( const AsmStmt * node ) { 1039 VISIT_START( node ) 1040 1041 maybeAccept_impl( node->instruction, *this ); 1042 maybeAccept_impl( node->output, *this ); 1043 maybeAccept_impl( node->input, *this ); 1044 maybeAccept_impl( node->clobber, *this ); 1045 1046 VISIT_END( node ); 1047 } 1048 1049 template< typename pass_type > 792 1050 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 793 1051 MUTATE_START( node ); … … 811 1069 812 1070 template< typename pass_type > 1071 void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) { 1072 VISIT_START( node ) 1073 1074 VISIT_END( node ); 1075 } 1076 1077 template< typename pass_type > 813 1078 Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) { 814 1079 MUTATE_START( node ); … … 825 1090 // if statements introduce a level of scope (for the initialization) 826 1091 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 827 maybeAccept_impl( node-> get_initialization(), *this );1092 maybeAccept_impl( node->initialization, *this ); 828 1093 visitExpression ( node->condition ); 829 1094 node->thenPart = visitStatement( node->thenPart ); … … 834 1099 835 1100 template< typename pass_type > 1101 void PassVisitor< pass_type >::visit( const IfStmt * node ) { 1102 VISIT_START( node ); 1103 1104 maybeAccept_impl( node->initialization, *this ); 1105 visitExpression ( node->condition ); 1106 visitStatement( node->thenPart ); 1107 visitStatement( node->elsePart ); 1108 1109 VISIT_END( node ); 1110 } 1111 1112 template< typename pass_type > 836 1113 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 837 1114 MUTATE_START( node ); … … 839 1116 // if statements introduce a level of scope (for the initialization) 840 1117 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 841 maybeMutate_impl( node-> get_initialization(), *this );1118 maybeMutate_impl( node->initialization, *this ); 842 1119 node->condition = mutateExpression( node->condition ); 843 1120 node->thenPart = mutateStatement ( node->thenPart ); … … 860 1137 node->body = visitStatement( node->body ); 861 1138 } 1139 1140 VISIT_END( node ); 1141 } 1142 1143 template< typename pass_type > 1144 void PassVisitor< pass_type >::visit( const WhileStmt * node ) { 1145 VISIT_START( node ); 1146 1147 maybeAccept_impl( node->initialization, *this ); 1148 visitExpression ( node->condition ); 1149 visitStatement( node->body ); 862 1150 863 1151 VISIT_END( node ); … … 897 1185 898 1186 template< typename pass_type > 1187 void PassVisitor< pass_type >::visit( const ForStmt * node ) { 1188 VISIT_START( node ); 1189 1190 maybeAccept_impl( node->initialization, *this ); 1191 visitExpression( node->condition ); 1192 visitExpression( node->increment ); 1193 visitStatement( node->body ); 1194 1195 VISIT_END( node ); 1196 } 1197 1198 template< typename pass_type > 899 1199 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { 900 1200 MUTATE_START( node ); … … 923 1223 924 1224 template< typename pass_type > 1225 void PassVisitor< pass_type >::visit( const SwitchStmt * node ) { 1226 VISIT_START( node ); 1227 1228 visitExpression ( node->condition ); 1229 visitStatementList( node->statements ); 1230 1231 VISIT_END( node ); 1232 } 1233 1234 template< typename pass_type > 925 1235 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { 926 1236 MUTATE_START( node ); … … 945 1255 946 1256 template< typename pass_type > 1257 void PassVisitor< pass_type >::visit( const CaseStmt * node ) { 1258 VISIT_START( node ); 1259 1260 visitExpression ( node->condition ); 1261 visitStatementList( node->stmts ); 1262 1263 VISIT_END( node ); 1264 } 1265 1266 template< typename pass_type > 947 1267 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { 948 1268 MUTATE_START( node ); … … 963 1283 964 1284 template< typename pass_type > 1285 void PassVisitor< pass_type >::visit( const BranchStmt * node ) { 1286 VISIT_START( node ); 1287 VISIT_END( node ); 1288 } 1289 1290 template< typename pass_type > 965 1291 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 966 1292 MUTATE_START( node ); … … 980 1306 981 1307 template< typename pass_type > 1308 void PassVisitor< pass_type >::visit( const ReturnStmt * node ) { 1309 VISIT_START( node ); 1310 1311 visitExpression( node->expr ); 1312 1313 VISIT_END( node ); 1314 } 1315 1316 template< typename pass_type > 982 1317 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { 983 1318 MUTATE_START( node ); … … 990 1325 //-------------------------------------------------------------------------- 991 1326 // ThrowStmt 992 993 1327 template< typename pass_type > 994 1328 void PassVisitor< pass_type >::visit( ThrowStmt * node ) { … … 1002 1336 1003 1337 template< typename pass_type > 1338 void PassVisitor< pass_type >::visit( const ThrowStmt * node ) { 1339 VISIT_START( node ); 1340 1341 maybeAccept_impl( node->expr, *this ); 1342 maybeAccept_impl( node->target, *this ); 1343 1344 VISIT_END( node ); 1345 } 1346 1347 template< typename pass_type > 1004 1348 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { 1005 1349 MUTATE_START( node ); … … 1015 1359 template< typename pass_type > 1016 1360 void PassVisitor< pass_type >::visit( TryStmt * node ) { 1361 VISIT_START( node ); 1362 1363 maybeAccept_impl( node->block , *this ); 1364 maybeAccept_impl( node->handlers , *this ); 1365 maybeAccept_impl( node->finallyBlock, *this ); 1366 1367 VISIT_END( node ); 1368 } 1369 1370 template< typename pass_type > 1371 void PassVisitor< pass_type >::visit( const TryStmt * node ) { 1017 1372 VISIT_START( node ); 1018 1373 … … 1051 1406 1052 1407 template< typename pass_type > 1408 void PassVisitor< pass_type >::visit( const CatchStmt * node ) { 1409 VISIT_START( node ); 1410 1411 maybeAccept_impl( node->decl, *this ); 1412 visitExpression( node->cond ); 1413 visitStatement ( node->body ); 1414 1415 VISIT_END( node ); 1416 } 1417 1418 template< typename pass_type > 1053 1419 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { 1054 1420 MUTATE_START( node ); … … 1075 1441 1076 1442 template< typename pass_type > 1443 void PassVisitor< pass_type >::visit( const FinallyStmt * node ) { 1444 VISIT_START( node ); 1445 1446 maybeAccept_impl( node->block, *this ); 1447 1448 VISIT_END( node ); 1449 } 1450 1451 template< typename pass_type > 1077 1452 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { 1078 1453 MUTATE_START( node ); … … 1107 1482 1108 1483 template< typename pass_type > 1484 void PassVisitor< pass_type >::visit( const WaitForStmt * node ) { 1485 VISIT_START( node ); 1486 1487 for( auto & clause : node->clauses ) { 1488 maybeAccept_impl( clause.target.function, *this ); 1489 maybeAccept_impl( clause.target.arguments, *this ); 1490 1491 maybeAccept_impl( clause.statement, *this ); 1492 maybeAccept_impl( clause.condition, *this ); 1493 } 1494 1495 maybeAccept_impl( node->timeout.time, *this ); 1496 maybeAccept_impl( node->timeout.statement, *this ); 1497 maybeAccept_impl( node->timeout.condition, *this ); 1498 maybeAccept_impl( node->orelse.statement, *this ); 1499 maybeAccept_impl( node->orelse.condition, *this ); 1500 1501 VISIT_END( node ); 1502 } 1503 1504 template< typename pass_type > 1109 1505 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) { 1110 1506 MUTATE_START( node ); … … 1130 1526 1131 1527 //-------------------------------------------------------------------------- 1132 // NullStmt1528 // WithStmt 1133 1529 template< typename pass_type > 1134 1530 void PassVisitor< pass_type >::visit( WithStmt * node ) { … … 1145 1541 1146 1542 template< typename pass_type > 1543 void PassVisitor< pass_type >::visit( const WithStmt * node ) { 1544 VISIT_START( node ); 1545 1546 maybeAccept_impl( node->exprs, *this ); 1547 maybeAccept_impl( node->stmt, *this ); 1548 1549 VISIT_END( node ); 1550 } 1551 1552 template< typename pass_type > 1147 1553 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1148 1554 MUTATE_START( node ); … … 1166 1572 1167 1573 template< typename pass_type > 1574 void PassVisitor< pass_type >::visit( const NullStmt * node ) { 1575 VISIT_START( node ); 1576 VISIT_END( node ); 1577 } 1578 1579 template< typename pass_type > 1168 1580 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1169 1581 MUTATE_START( node ); … … 1183 1595 1184 1596 template< typename pass_type > 1597 void PassVisitor< pass_type >::visit( const DeclStmt * node ) { 1598 VISIT_START( node ); 1599 1600 maybeAccept_impl( node->decl, *this ); 1601 1602 VISIT_END( node ); 1603 } 1604 1605 template< typename pass_type > 1185 1606 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1186 1607 MUTATE_START( node ); … … 1195 1616 template< typename pass_type > 1196 1617 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) { 1618 VISIT_START( node ); 1619 1620 maybeAccept_impl( node->callStmt, *this ); 1621 1622 VISIT_END( node ); 1623 } 1624 1625 template< typename pass_type > 1626 void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) { 1197 1627 VISIT_START( node ); 1198 1628 … … 1220 1650 maybeAccept_impl ( node->function, *this ); 1221 1651 maybeAccept_impl ( node->args , *this ); 1652 1653 VISIT_END( node ); 1654 } 1655 1656 template< typename pass_type > 1657 void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) { 1658 VISIT_START( node ); 1659 1660 maybeAccept_impl( node->result , *this ); 1661 maybeAccept_impl( node->function, *this ); 1662 maybeAccept_impl( node->args , *this ); 1222 1663 1223 1664 VISIT_END( node ); … … 1253 1694 1254 1695 template< typename pass_type > 1696 void PassVisitor< pass_type >::visit( const UntypedExpr * node ) { 1697 VISIT_START( node ); 1698 1699 maybeAccept_impl( node->result, *this ); 1700 1701 for ( auto expr : node->args ) { 1702 visitExpression( expr ); 1703 } 1704 1705 VISIT_END( node ); 1706 } 1707 1708 template< typename pass_type > 1255 1709 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 1256 1710 MUTATE_START( node ); … … 1278 1732 1279 1733 template< typename pass_type > 1734 void PassVisitor< pass_type >::visit( const NameExpr * node ) { 1735 VISIT_START( node ); 1736 1737 maybeAccept_impl( node->result, *this ); 1738 1739 VISIT_END( node ); 1740 } 1741 1742 template< typename pass_type > 1280 1743 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) { 1281 1744 MUTATE_START( node ); … … 1295 1758 indexerScopedAccept( node->result, *this ); 1296 1759 maybeAccept_impl ( node->arg , *this ); 1760 1761 VISIT_END( node ); 1762 } 1763 1764 template< typename pass_type > 1765 void PassVisitor< pass_type >::visit( const CastExpr * node ) { 1766 VISIT_START( node ); 1767 1768 maybeAccept_impl( node->result, *this ); 1769 maybeAccept_impl( node->arg , *this ); 1297 1770 1298 1771 VISIT_END( node ); … … 1323 1796 1324 1797 template< typename pass_type > 1798 void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) { 1799 VISIT_START( node ); 1800 1801 maybeAccept_impl( node->result, *this ); 1802 maybeAccept_impl( node->arg , *this ); 1803 1804 VISIT_END( node ); 1805 } 1806 1807 template< typename pass_type > 1325 1808 Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) { 1326 1809 MUTATE_START( node ); … … 1346 1829 1347 1830 template< typename pass_type > 1831 void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) { 1832 VISIT_START( node ); 1833 1834 maybeAccept_impl( node->result, *this ); 1835 maybeAccept_impl( node->arg, *this ); 1836 1837 VISIT_END( node ); 1838 } 1839 1840 template< typename pass_type > 1348 1841 Expression * PassVisitor< pass_type >::mutate( VirtualCastExpr * node ) { 1349 1842 MUTATE_START( node ); … … 1369 1862 1370 1863 template< typename pass_type > 1864 void PassVisitor< pass_type >::visit( const AddressExpr * node ) { 1865 VISIT_START( node ); 1866 1867 maybeAccept_impl( node->result, *this ); 1868 maybeAccept_impl( node->arg , *this ); 1869 1870 VISIT_END( node ); 1871 } 1872 1873 template< typename pass_type > 1371 1874 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) { 1372 1875 MUTATE_START( node ); … … 1391 1894 1392 1895 template< typename pass_type > 1896 void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) { 1897 VISIT_START( node ); 1898 1899 maybeAccept_impl( node->result, *this ); 1900 1901 VISIT_END( node ); 1902 } 1903 1904 template< typename pass_type > 1393 1905 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) { 1394 1906 MUTATE_START( node ); … … 1409 1921 maybeAccept_impl ( node->aggregate, *this ); 1410 1922 maybeAccept_impl ( node->member , *this ); 1923 1924 VISIT_END( node ); 1925 } 1926 1927 template< typename pass_type > 1928 void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) { 1929 VISIT_START( node ); 1930 1931 maybeAccept_impl( node->result , *this ); 1932 maybeAccept_impl( node->aggregate, *this ); 1933 maybeAccept_impl( node->member , *this ); 1411 1934 1412 1935 VISIT_END( node ); … … 1438 1961 1439 1962 template< typename pass_type > 1963 void PassVisitor< pass_type >::visit( const MemberExpr * node ) { 1964 VISIT_START( node ); 1965 1966 maybeAccept_impl( node->result , *this ); 1967 maybeAccept_impl( node->aggregate, *this ); 1968 1969 VISIT_END( node ); 1970 } 1971 1972 template< typename pass_type > 1440 1973 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) { 1441 1974 MUTATE_START( node ); … … 1460 1993 1461 1994 template< typename pass_type > 1995 void PassVisitor< pass_type >::visit( const VariableExpr * node ) { 1996 VISIT_START( node ); 1997 1998 maybeAccept_impl( node->result, *this ); 1999 2000 VISIT_END( node ); 2001 } 2002 2003 template< typename pass_type > 1462 2004 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) { 1463 2005 MUTATE_START( node ); … … 1477 2019 indexerScopedAccept( node->result , *this ); 1478 2020 maybeAccept_impl ( &node->constant, *this ); 2021 2022 VISIT_END( node ); 2023 } 2024 2025 template< typename pass_type > 2026 void PassVisitor< pass_type >::visit( const ConstantExpr * node ) { 2027 VISIT_START( node ); 2028 2029 maybeAccept_impl( node->result , *this ); 2030 maybeAccept_impl( &node->constant, *this ); 1479 2031 1480 2032 VISIT_END( node ); … … 1501 2053 1502 2054 indexerScopedAccept( node->result, *this ); 2055 if ( node->get_isType() ) { 2056 maybeAccept_impl( node->type, *this ); 2057 } else { 2058 maybeAccept_impl( node->expr, *this ); 2059 } 2060 2061 VISIT_END( node ); 2062 } 2063 2064 template< typename pass_type > 2065 void PassVisitor< pass_type >::visit( const SizeofExpr * node ) { 2066 VISIT_START( node ); 2067 2068 maybeAccept_impl( node->result, *this ); 1503 2069 if ( node->get_isType() ) { 1504 2070 maybeAccept_impl( node->type, *this ); … … 1542 2108 1543 2109 template< typename pass_type > 2110 void PassVisitor< pass_type >::visit( const AlignofExpr * node ) { 2111 VISIT_START( node ); 2112 2113 maybeAccept_impl( node->result, *this ); 2114 if ( node->get_isType() ) { 2115 maybeAccept_impl( node->type, *this ); 2116 } else { 2117 maybeAccept_impl( node->expr, *this ); 2118 } 2119 2120 VISIT_END( node ); 2121 } 2122 2123 template< typename pass_type > 1544 2124 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) { 1545 2125 MUTATE_START( node ); … … 1569 2149 1570 2150 template< typename pass_type > 2151 void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) { 2152 VISIT_START( node ); 2153 2154 maybeAccept_impl( node->result, *this ); 2155 maybeAccept_impl( node->type , *this ); 2156 2157 VISIT_END( node ); 2158 } 2159 2160 template< typename pass_type > 1571 2161 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) { 1572 2162 MUTATE_START( node ); … … 1592 2182 1593 2183 template< typename pass_type > 2184 void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) { 2185 VISIT_START( node ); 2186 2187 maybeAccept_impl( node->result, *this ); 2188 maybeAccept_impl( node->type , *this ); 2189 2190 VISIT_END( node ); 2191 } 2192 2193 template< typename pass_type > 1594 2194 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) { 1595 2195 MUTATE_START( node ); … … 1615 2215 1616 2216 template< typename pass_type > 2217 void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) { 2218 VISIT_START( node ); 2219 2220 maybeAccept_impl( node->result, *this ); 2221 maybeAccept_impl( node->type , *this ); 2222 2223 VISIT_END( node ); 2224 } 2225 2226 template< typename pass_type > 1617 2227 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) { 1618 2228 MUTATE_START( node ); … … 1632 2242 1633 2243 indexerScopedAccept( node->result, *this ); 2244 if ( node->get_isType() ) { 2245 maybeAccept_impl( node->type, *this ); 2246 } else { 2247 maybeAccept_impl( node->expr, *this ); 2248 } 2249 2250 VISIT_END( node ); 2251 } 2252 2253 template< typename pass_type > 2254 void PassVisitor< pass_type >::visit( const AttrExpr * node ) { 2255 VISIT_START( node ); 2256 2257 maybeAccept_impl( node->result, *this ); 1634 2258 if ( node->get_isType() ) { 1635 2259 maybeAccept_impl( node->type, *this ); … … 1670 2294 1671 2295 template< typename pass_type > 2296 void PassVisitor< pass_type >::visit( const LogicalExpr * node ) { 2297 VISIT_START( node ); 2298 2299 maybeAccept_impl( node->result, *this ); 2300 maybeAccept_impl( node->arg1 , *this ); 2301 maybeAccept_impl( node->arg2 , *this ); 2302 2303 VISIT_END( node ); 2304 } 2305 2306 template< typename pass_type > 1672 2307 Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) { 1673 2308 MUTATE_START( node ); … … 1691 2326 maybeAccept_impl ( node->arg2 , *this ); 1692 2327 maybeAccept_impl ( node->arg3 , *this ); 2328 2329 VISIT_END( node ); 2330 } 2331 2332 template< typename pass_type > 2333 void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) { 2334 VISIT_START( node ); 2335 2336 maybeAccept_impl( node->result, *this ); 2337 maybeAccept_impl( node->arg1 , *this ); 2338 maybeAccept_impl( node->arg2 , *this ); 2339 maybeAccept_impl( node->arg3 , *this ); 1693 2340 1694 2341 VISIT_END( node ); … … 1722 2369 1723 2370 template< typename pass_type > 2371 void PassVisitor< pass_type >::visit( const CommaExpr * node ) { 2372 VISIT_START( node ); 2373 2374 maybeAccept_impl( node->result, *this ); 2375 maybeAccept_impl( node->arg1 , *this ); 2376 maybeAccept_impl( node->arg2 , *this ); 2377 2378 VISIT_END( node ); 2379 } 2380 2381 template< typename pass_type > 1724 2382 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) { 1725 2383 MUTATE_START( node ); … … 1746 2404 1747 2405 template< typename pass_type > 2406 void PassVisitor< pass_type >::visit( const TypeExpr * node ) { 2407 VISIT_START( node ); 2408 2409 maybeAccept_impl( node->result, *this ); 2410 maybeAccept_impl( node->type, *this ); 2411 2412 VISIT_END( node ); 2413 } 2414 2415 template< typename pass_type > 1748 2416 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) { 1749 2417 MUTATE_START( node ); … … 1766 2434 maybeAccept_impl ( node->constraint, *this ); 1767 2435 maybeAccept_impl ( node->operand , *this ); 2436 2437 VISIT_END( node ); 2438 } 2439 2440 template< typename pass_type > 2441 void PassVisitor< pass_type >::visit( const AsmExpr * node ) { 2442 VISIT_START( node ); 2443 2444 maybeAccept_impl( node->result , *this ); 2445 maybeAccept_impl( node->inout , *this ); 2446 maybeAccept_impl( node->constraint, *this ); 2447 maybeAccept_impl( node->operand , *this ); 1768 2448 1769 2449 VISIT_END( node ); … … 1796 2476 1797 2477 template< typename pass_type > 2478 void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) { 2479 VISIT_START( node ); 2480 2481 maybeAccept_impl( node->result , *this ); 2482 maybeAccept_impl( node->callExpr , *this ); 2483 2484 VISIT_END( node ); 2485 } 2486 2487 template< typename pass_type > 1798 2488 Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) { 1799 2489 MUTATE_START( node ); … … 1819 2509 1820 2510 template< typename pass_type > 2511 void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) { 2512 VISIT_START( node ); 2513 2514 maybeAccept_impl( node->result , *this ); 2515 maybeAccept_impl( node->callExpr, *this ); 2516 2517 VISIT_END( node ); 2518 } 2519 2520 template< typename pass_type > 1821 2521 Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) { 1822 2522 MUTATE_START( node ); … … 1842 2542 1843 2543 template< typename pass_type > 2544 void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) { 2545 VISIT_START( node ); 2546 2547 maybeAccept_impl( node->result , *this ); 2548 maybeAccept_impl( node->initializer, *this ); 2549 2550 VISIT_END( node ); 2551 } 2552 2553 template< typename pass_type > 1844 2554 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) { 1845 2555 MUTATE_START( node ); … … 1861 2571 maybeAccept_impl ( node->low , *this ); 1862 2572 maybeAccept_impl ( node->high , *this ); 2573 2574 VISIT_END( node ); 2575 } 2576 2577 template< typename pass_type > 2578 void PassVisitor< pass_type >::visit( const RangeExpr * node ) { 2579 VISIT_START( node ); 2580 2581 maybeAccept_impl( node->result, *this ); 2582 maybeAccept_impl( node->low , *this ); 2583 maybeAccept_impl( node->high , *this ); 1863 2584 1864 2585 VISIT_END( node ); … … 1890 2611 1891 2612 template< typename pass_type > 2613 void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) { 2614 VISIT_START( node ); 2615 2616 maybeAccept_impl( node->result, *this ); 2617 maybeAccept_impl( node->exprs , *this ); 2618 2619 VISIT_END( node ); 2620 } 2621 2622 template< typename pass_type > 1892 2623 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) { 1893 2624 MUTATE_START( node ); … … 1913 2644 1914 2645 template< typename pass_type > 2646 void PassVisitor< pass_type >::visit( const TupleExpr * node ) { 2647 VISIT_START( node ); 2648 2649 maybeAccept_impl( node->result, *this ); 2650 maybeAccept_impl( node->exprs , *this ); 2651 2652 VISIT_END( node ); 2653 } 2654 2655 template< typename pass_type > 1915 2656 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) { 1916 2657 MUTATE_START( node ); … … 1936 2677 1937 2678 template< typename pass_type > 2679 void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) { 2680 VISIT_START( node ); 2681 2682 maybeAccept_impl( node->result, *this ); 2683 maybeAccept_impl( node->tuple , *this ); 2684 2685 VISIT_END( node ); 2686 } 2687 2688 template< typename pass_type > 1938 2689 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) { 1939 2690 MUTATE_START( node ); … … 1954 2705 indexerScopedAccept( node->result , *this ); 1955 2706 maybeAccept_impl ( node->stmtExpr, *this ); 2707 2708 VISIT_END( node ); 2709 } 2710 2711 template< typename pass_type > 2712 void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) { 2713 VISIT_START( node ); 2714 2715 maybeAccept_impl( node->result , *this ); 2716 maybeAccept_impl( node->stmtExpr, *this ); 1956 2717 1957 2718 VISIT_END( node ); … … 1989 2750 1990 2751 template< typename pass_type > 2752 void PassVisitor< pass_type >::visit( const StmtExpr * node ) { 2753 VISIT_START( node ); 2754 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 > 1991 2764 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 1992 2765 MUTATE_START( node ); … … 2018 2791 2019 2792 template< typename pass_type > 2793 void PassVisitor< pass_type >::visit( const UniqueExpr * node ) { 2794 VISIT_START( node ); 2795 2796 maybeAccept_impl( node->result, *this ); 2797 maybeAccept_impl( node->expr , *this ); 2798 2799 VISIT_END( node ); 2800 } 2801 2802 template< typename pass_type > 2020 2803 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { 2021 2804 MUTATE_START( node ); … … 2036 2819 indexerScopedAccept( node->result, *this ); 2037 2820 maybeAccept_impl ( node->expr , *this ); 2821 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 2822 2823 VISIT_END( node ); 2824 } 2825 2826 template< typename pass_type > 2827 void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) { 2828 VISIT_START( node ); 2829 2830 maybeAccept_impl( node->result, *this ); 2831 maybeAccept_impl( node->expr , *this ); 2038 2832 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 2039 2833 … … 2067 2861 2068 2862 template< typename pass_type > 2863 void PassVisitor< pass_type >::visit( const InitExpr * node ) { 2864 VISIT_START( node ); 2865 2866 maybeAccept_impl( node->result, *this ); 2867 maybeAccept_impl( node->expr , *this ); 2868 maybeAccept_impl( node->designation, *this ); 2869 2870 VISIT_END( node ); 2871 } 2872 2873 template< typename pass_type > 2069 2874 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) { 2070 2875 MUTATE_START( node ); … … 2092 2897 2093 2898 template< typename pass_type > 2899 void PassVisitor< pass_type >::visit( const DeletedExpr * node ) { 2900 VISIT_START( node ); 2901 2902 maybeAccept_impl( node->result, *this ); 2903 maybeAccept_impl( node->expr, *this ); 2904 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2905 2906 VISIT_END( node ); 2907 } 2908 2909 template< typename pass_type > 2094 2910 Expression * PassVisitor< pass_type >::mutate( DeletedExpr * node ) { 2095 2911 MUTATE_START( node ); … … 2109 2925 2110 2926 indexerScopedAccept( node->result, *this ); 2927 maybeAccept_impl( node->expr, *this ); 2928 2929 VISIT_END( node ); 2930 } 2931 2932 template< typename pass_type > 2933 void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) { 2934 VISIT_START( node ); 2935 2936 maybeAccept_impl( node->result, *this ); 2111 2937 maybeAccept_impl( node->expr, *this ); 2112 2938 … … 2135 2961 for ( GenericExpr::Association & assoc : node->associations ) { 2136 2962 indexerScopedAccept( assoc.type, *this ); 2963 maybeAccept_impl( assoc.expr, *this ); 2964 } 2965 2966 VISIT_END( node ); 2967 } 2968 2969 template< typename pass_type > 2970 void PassVisitor< pass_type >::visit( const GenericExpr * node ) { 2971 VISIT_START( node ); 2972 2973 maybeAccept_impl( node->result, *this ); 2974 maybeAccept_impl( node->control, *this ); 2975 for ( const GenericExpr::Association & assoc : node->associations ) { 2976 maybeAccept_impl( assoc.type, *this ); 2137 2977 maybeAccept_impl( assoc.expr, *this ); 2138 2978 } … … 2168 3008 2169 3009 template< typename pass_type > 3010 void PassVisitor< pass_type >::visit( const VoidType * node ) { 3011 VISIT_START( node ); 3012 3013 maybeAccept_impl( node->forall, *this ); 3014 3015 VISIT_END( node ); 3016 } 3017 3018 template< typename pass_type > 2170 3019 Type * PassVisitor< pass_type >::mutate( VoidType * node ) { 2171 3020 MUTATE_START( node ); … … 2180 3029 template< typename pass_type > 2181 3030 void PassVisitor< pass_type >::visit( BasicType * node ) { 3031 VISIT_START( node ); 3032 3033 maybeAccept_impl( node->forall, *this ); 3034 3035 VISIT_END( node ); 3036 } 3037 3038 template< typename pass_type > 3039 void PassVisitor< pass_type >::visit( const BasicType * node ) { 2182 3040 VISIT_START( node ); 2183 3041 … … 2210 3068 2211 3069 template< typename pass_type > 3070 void PassVisitor< pass_type >::visit( const PointerType * node ) { 3071 VISIT_START( node ); 3072 3073 maybeAccept_impl( node->forall, *this ); 3074 // xxx - should PointerType visit/mutate dimension? 3075 maybeAccept_impl( node->base, *this ); 3076 3077 VISIT_END( node ); 3078 } 3079 3080 template< typename pass_type > 2212 3081 Type * PassVisitor< pass_type >::mutate( PointerType * node ) { 2213 3082 MUTATE_START( node ); … … 2234 3103 2235 3104 template< typename pass_type > 3105 void PassVisitor< pass_type >::visit( const ArrayType * node ) { 3106 VISIT_START( node ); 3107 3108 maybeAccept_impl( node->forall, *this ); 3109 maybeAccept_impl( node->dimension, *this ); 3110 maybeAccept_impl( node->base, *this ); 3111 3112 VISIT_END( node ); 3113 } 3114 3115 template< typename pass_type > 2236 3116 Type * PassVisitor< pass_type >::mutate( ArrayType * node ) { 2237 3117 MUTATE_START( node ); … … 2257 3137 2258 3138 template< typename pass_type > 3139 void PassVisitor< pass_type >::visit( const ReferenceType * node ) { 3140 VISIT_START( node ); 3141 3142 maybeAccept_impl( node->forall, *this ); 3143 maybeAccept_impl( node->base, *this ); 3144 3145 VISIT_END( node ); 3146 } 3147 3148 template< typename pass_type > 2259 3149 Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) { 2260 3150 MUTATE_START( node ); … … 2280 3170 2281 3171 template< typename pass_type > 3172 void PassVisitor< pass_type >::visit( const QualifiedType * node ) { 3173 VISIT_START( node ); 3174 3175 maybeAccept_impl( node->forall, *this ); 3176 maybeAccept_impl( node->parent, *this ); 3177 maybeAccept_impl( node->child, *this ); 3178 3179 VISIT_END( node ); 3180 } 3181 3182 template< typename pass_type > 2282 3183 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) { 2283 3184 MUTATE_START( node ); … … 2294 3195 template< typename pass_type > 2295 3196 void PassVisitor< pass_type >::visit( FunctionType * node ) { 3197 VISIT_START( node ); 3198 3199 maybeAccept_impl( node->forall, *this ); 3200 maybeAccept_impl( node->returnVals, *this ); 3201 maybeAccept_impl( node->parameters, *this ); 3202 3203 VISIT_END( node ); 3204 } 3205 3206 template< typename pass_type > 3207 void PassVisitor< pass_type >::visit( const FunctionType * node ) { 2296 3208 VISIT_START( node ); 2297 3209 … … 2332 3244 2333 3245 template< typename pass_type > 3246 void PassVisitor< pass_type >::visit( const StructInstType * node ) { 3247 VISIT_START( node ); 3248 3249 maybeAccept_impl( node->forall , *this ); 3250 maybeAccept_impl( node->parameters, *this ); 3251 3252 VISIT_END( node ); 3253 } 3254 3255 template< typename pass_type > 2334 3256 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) { 2335 3257 MUTATE_START( node ); … … 2364 3286 2365 3287 template< typename pass_type > 3288 void PassVisitor< pass_type >::visit( const UnionInstType * node ) { 3289 VISIT_START( node ); 3290 3291 maybeAccept_impl( node->forall , *this ); 3292 maybeAccept_impl( node->parameters, *this ); 3293 3294 VISIT_END( node ); 3295 } 3296 3297 template< typename pass_type > 2366 3298 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) { 2367 3299 MUTATE_START( node ); … … 2391 3323 2392 3324 template< typename pass_type > 3325 void PassVisitor< pass_type >::visit( const EnumInstType * node ) { 3326 VISIT_START( node ); 3327 3328 maybeAccept_impl( node->forall, *this ); 3329 maybeAccept_impl( node->parameters, *this ); 3330 3331 VISIT_END( node ); 3332 } 3333 3334 template< typename pass_type > 2393 3335 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) { 2394 3336 MUTATE_START( node ); … … 2413 3355 2414 3356 template< typename pass_type > 3357 void PassVisitor< pass_type >::visit( const TraitInstType * node ) { 3358 VISIT_START( node ); 3359 3360 maybeAccept_impl( node->forall , *this ); 3361 maybeAccept_impl( node->parameters, *this ); 3362 3363 VISIT_END( node ); 3364 } 3365 3366 template< typename pass_type > 2415 3367 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) { 2416 3368 MUTATE_START( node ); … … 2426 3378 template< typename pass_type > 2427 3379 void PassVisitor< pass_type >::visit( TypeInstType * node ) { 3380 VISIT_START( node ); 3381 3382 maybeAccept_impl( node->forall , *this ); 3383 maybeAccept_impl( node->parameters, *this ); 3384 3385 VISIT_END( node ); 3386 } 3387 3388 template< typename pass_type > 3389 void PassVisitor< pass_type >::visit( const TypeInstType * node ) { 2428 3390 VISIT_START( node ); 2429 3391 … … 2458 3420 2459 3421 template< typename pass_type > 3422 void PassVisitor< pass_type >::visit( const TupleType * node ) { 3423 VISIT_START( node ); 3424 3425 maybeAccept_impl( node->forall, *this ); 3426 maybeAccept_impl( node->types, *this ); 3427 maybeAccept_impl( node->members, *this ); 3428 3429 VISIT_END( node ); 3430 } 3431 3432 template< typename pass_type > 2460 3433 Type * PassVisitor< pass_type >::mutate( TupleType * node ) { 2461 3434 MUTATE_START( node ); … … 2472 3445 template< typename pass_type > 2473 3446 void PassVisitor< pass_type >::visit( TypeofType * node ) { 3447 VISIT_START( node ); 3448 3449 assert( node->expr ); 3450 maybeAccept_impl( node->expr, *this ); 3451 3452 VISIT_END( node ); 3453 } 3454 3455 template< typename pass_type > 3456 void PassVisitor< pass_type >::visit( const TypeofType * node ) { 2474 3457 VISIT_START( node ); 2475 3458 … … 2508 3491 2509 3492 template< typename pass_type > 3493 void PassVisitor< pass_type >::visit( const AttrType * node ) { 3494 VISIT_START( node ); 3495 3496 if ( node->isType ) { 3497 assert( node->type ); 3498 maybeAccept_impl( node->type, *this ); 3499 } else { 3500 assert( node->expr ); 3501 maybeAccept_impl( node->expr, *this ); 3502 } // if 3503 3504 VISIT_END( node ); 3505 } 3506 3507 template< typename pass_type > 2510 3508 Type * PassVisitor< pass_type >::mutate( AttrType * node ) { 2511 3509 MUTATE_START( node ); … … 2534 3532 2535 3533 template< typename pass_type > 3534 void PassVisitor< pass_type >::visit( const VarArgsType * node ) { 3535 VISIT_START( node ); 3536 3537 maybeAccept_impl( node->forall, *this ); 3538 3539 VISIT_END( node ); 3540 } 3541 3542 template< typename pass_type > 2536 3543 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) { 2537 3544 MUTATE_START( node ); … … 2554 3561 2555 3562 template< typename pass_type > 3563 void PassVisitor< pass_type >::visit( const ZeroType * node ) { 3564 VISIT_START( node ); 3565 3566 maybeAccept_impl( node->forall, *this ); 3567 3568 VISIT_END( node ); 3569 } 3570 3571 template< typename pass_type > 2556 3572 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) { 2557 3573 MUTATE_START( node ); … … 2574 3590 2575 3591 template< typename pass_type > 3592 void PassVisitor< pass_type >::visit( const OneType * node ) { 3593 VISIT_START( node ); 3594 3595 maybeAccept_impl( node->forall, *this ); 3596 3597 VISIT_END( node ); 3598 } 3599 3600 template< typename pass_type > 2576 3601 Type * PassVisitor< pass_type >::mutate( OneType * node ) { 2577 3602 MUTATE_START( node ); … … 2594 3619 2595 3620 template< typename pass_type > 3621 void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) { 3622 VISIT_START( node ); 3623 3624 maybeAccept_impl( node->forall, *this ); 3625 3626 VISIT_END( node ); 3627 } 3628 3629 template< typename pass_type > 2596 3630 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) { 2597 3631 MUTATE_START( node ); … … 2614 3648 2615 3649 template< typename pass_type > 3650 void PassVisitor< pass_type >::visit( const Designation * node ) { 3651 VISIT_START( node ); 3652 3653 maybeAccept_impl( node->designators, *this ); 3654 3655 VISIT_END( node ); 3656 } 3657 3658 template< typename pass_type > 2616 3659 Designation * PassVisitor< pass_type >::mutate( Designation * node ) { 2617 3660 MUTATE_START( node ); … … 2634 3677 2635 3678 template< typename pass_type > 3679 void PassVisitor< pass_type >::visit( const SingleInit * node ) { 3680 VISIT_START( node ); 3681 3682 visitExpression( node->value ); 3683 3684 VISIT_END( node ); 3685 } 3686 3687 template< typename pass_type > 2636 3688 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { 2637 3689 MUTATE_START( node ); … … 2646 3698 template< typename pass_type > 2647 3699 void PassVisitor< pass_type >::visit( ListInit * node ) { 3700 VISIT_START( node ); 3701 3702 maybeAccept_impl( node->designations, *this ); 3703 maybeAccept_impl( node->initializers, *this ); 3704 3705 VISIT_END( node ); 3706 } 3707 3708 template< typename pass_type > 3709 void PassVisitor< pass_type >::visit( const ListInit * node ) { 2648 3710 VISIT_START( node ); 2649 3711 … … 2678 3740 2679 3741 template< typename pass_type > 3742 void PassVisitor< pass_type >::visit( const ConstructorInit * node ) { 3743 VISIT_START( node ); 3744 3745 maybeAccept_impl( node->ctor, *this ); 3746 maybeAccept_impl( node->dtor, *this ); 3747 maybeAccept_impl( node->init, *this ); 3748 3749 VISIT_END( node ); 3750 } 3751 3752 template< typename pass_type > 2680 3753 Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) { 2681 3754 MUTATE_START( node ); … … 2698 3771 2699 3772 template< typename pass_type > 3773 void PassVisitor< pass_type >::visit( const Constant * node ) { 3774 VISIT_START( node ); 3775 3776 VISIT_END( node ); 3777 } 3778 3779 template< typename pass_type > 2700 3780 Constant * PassVisitor< pass_type >::mutate( Constant * node ) { 2701 3781 MUTATE_START( node ); … … 2708 3788 template< typename pass_type > 2709 3789 void PassVisitor< pass_type >::visit( Attribute * node ) { 3790 VISIT_START( node ); 3791 3792 maybeAccept_impl( node->parameters, *this ); 3793 3794 VISIT_END( node ); 3795 } 3796 3797 template< typename pass_type > 3798 void PassVisitor< pass_type >::visit( const Attribute * node ) { 2710 3799 VISIT_START( node ); 2711 3800 -
src/Common/PassVisitor.proto.h
ree6dbae r7870799 118 118 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {} 119 119 120 template<typename pass_type, typename node_type> 121 static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) { 122 pass.previsit( node ); 123 } 124 125 template<typename pass_type, typename node_type> 126 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {} 127 128 129 template<typename pass_type, typename node_type> 130 static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) { 131 pass.postvisit( node ); 132 } 133 134 template<typename pass_type, typename node_type> 135 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {} 136 120 137 //--------------------------------------------------------- 121 138 // Mutate … … 200 217 pass.indexer.func( arg ); \ 201 218 } \ 202 \ 203 template<typename pass_type> \ 204 static inline void indexer_impl_##func ( pass_type &, long, type ) { } \ 219 template<typename pass_type> \ 220 static inline void indexer_impl_##func ( pass_type &, long, type ) { } 205 221 206 222 #define INDEXER_FUNC2( func, type1, type2 ) \ … … 209 225 pass.indexer.func( arg1, arg2 ); \ 210 226 } \ 211 \212 227 template<typename pass_type> \ 213 228 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { } … … 233 248 234 249 template<typename pass_type> 235 static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}250 static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {} 236 251 237 252 template<typename pass_type> … … 243 258 244 259 template<typename pass_type> 245 static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {}260 static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {} 246 261 247 262 template<typename pass_type> -
src/ResolvExpr/CastCost.cc
ree6dbae r7870799 37 37 struct CastCost_old : public ConversionCost { 38 38 public: 39 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );39 CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 40 40 41 41 using ConversionCost::previsit; 42 42 using ConversionCost::postvisit; 43 void postvisit( BasicType * basicType );44 void postvisit( PointerType * pointerType );43 void postvisit( const BasicType * basicType ); 44 void postvisit( const PointerType * pointerType ); 45 45 }; 46 46 47 Cost castCost( Type *src,Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {48 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {49 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst-> get_name()) ) {47 Cost castCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 48 if ( const TypeInstType *destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 49 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { 50 50 if ( eqvClass->type ) { 51 51 return castCost( src, eqvClass->type, indexer, env ); … … 53 53 return Cost::infinity; 54 54 } 55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst-> get_name()) ) {55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) { 56 56 // all typedefs should be gone by this point 57 TypeDecl *type = strict_dynamic_cast<TypeDecl* >( namedType );57 const TypeDecl * type = strict_dynamic_cast< const TypeDecl* >( namedType ); 58 58 if ( type->base ) { 59 59 return castCost( src, type->base, indexer, env ) + Cost::safe; … … 74 74 PRINT( std::cerr << "compatible!" << std::endl; ) 75 75 return Cost::zero; 76 } else if ( dynamic_cast< VoidType* >( dest ) ) {76 } else if ( dynamic_cast< const VoidType* >( dest ) ) { 77 77 return Cost::safe; 78 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {78 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 79 79 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 80 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {80 return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 81 81 return ptrsCastable( t1, t2, env, indexer ); 82 82 }); 83 83 } else { 84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment & ))84 PassVisitor<CastCost_old> converter( 85 dest, indexer, env, 86 (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & )) 87 87 castCost ); 88 88 src->accept( converter ); … … 96 96 } 97 97 98 CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )98 CastCost_old::CastCost_old( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 99 99 : ConversionCost( dest, indexer, env, costFunc ) { 100 100 } 101 101 102 void CastCost_old::postvisit( BasicType *basicType ) {103 PointerType *destAsPointer = dynamic_cast<PointerType* >( dest );102 void CastCost_old::postvisit( const BasicType *basicType ) { 103 const PointerType *destAsPointer = dynamic_cast< const PointerType* >( dest ); 104 104 if ( destAsPointer && basicType->isInteger() ) { 105 105 // necessary for, e.g. unsigned long => void* … … 110 110 } 111 111 112 void CastCost_old::postvisit( PointerType *pointerType ) {113 if ( PointerType *destAsPtr = dynamic_cast<PointerType* >( dest ) ) {114 if ( pointerType-> get_qualifiers() <= destAsPtr->get_qualifiers()&& typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {112 void CastCost_old::postvisit( const PointerType *pointerType ) { 113 if ( const PointerType *destAsPtr = dynamic_cast< const PointerType* >( dest ) ) { 114 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 115 115 cost = Cost::safe; 116 116 } else { … … 125 125 } // if 126 126 } // if 127 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {127 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 128 128 if ( destAsBasic->isInteger() ) { 129 129 // necessary for, e.g. void* => unsigned long … … 138 138 using ConversionCost_new::postvisit; 139 139 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 140 CastCost_new( 141 const ast::Type * dst, const ast::SymbolTable & symtab, 142 142 const ast::TypeEnvironment & env, CostCalculation costFunc ) 143 143 : ConversionCost_new( dst, symtab, env, costFunc ) {} … … 182 182 } // anonymous namespace 183 183 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 184 Cost castCost( 185 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 186 const ast::TypeEnvironment & env 187 187 ) { 188 188 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 220 220 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 221 221 #warning cast on ptrsCastable artifact of having two functions, remove when port done 222 return convertToReferenceCost( 223 src, refType, symtab, env, 224 ( int (*)( 225 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 222 return convertToReferenceCost( 223 src, refType, symtab, env, 224 ( int (*)( 225 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 226 226 const ast::TypeEnvironment & ) 227 227 ) ptrsCastable ); … … 229 229 #warning cast on castCost artifact of having two functions, remove when port done 230 230 ast::Pass< CastCost_new > converter{ 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 231 dst, symtab, env, 232 ( Cost (*)( 233 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 234 234 const ast::TypeEnvironment & ) 235 235 ) castCost }; -
src/ResolvExpr/ConversionCost.cc
ree6dbae r7870799 46 46 #endif 47 47 48 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {49 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {48 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 49 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 50 50 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 51 51 if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) { … … 55 55 return Cost::infinity; 56 56 } 57 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 58 58 PRINT( std::cerr << " found" << std::endl; ) 59 TypeDecl *type = dynamic_cast<TypeDecl* >( namedType );59 const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType ); 60 60 // all typedefs should be gone by this point 61 61 assert( type ); … … 77 77 PRINT( std::cerr << "compatible!" << std::endl; ) 78 78 return Cost::zero; 79 } else if ( dynamic_cast< VoidType* >( dest ) ) {79 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 80 80 return Cost::safe; 81 } else if ( ReferenceType * refType = dynamic_cast<ReferenceType * > ( dest ) ) {81 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { 82 82 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 83 return convertToReferenceCost( src, refType, indexer, env, []( Type * t1,Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){83 return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){ 84 84 return ptrsAssignable( t1, t2, env ); 85 85 }); 86 86 } else { 87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)( Type*,Type*, const SymTab::Indexer&, const TypeEnvironment&))87 PassVisitor<ConversionCost> converter( 88 dest, indexer, env, 89 (Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&)) 90 90 conversionCost ); 91 91 src->accept( converter ); … … 98 98 } 99 99 100 Cost convertToReferenceCost( Type * src,Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {100 Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 101 101 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; ) 102 102 if ( diff > 0 ) { 103 103 // TODO: document this 104 Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );104 Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func ); 105 105 cost.incReference(); 106 106 return cost; 107 107 } else if ( diff < -1 ) { 108 108 // TODO: document this 109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );109 Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func ); 110 110 cost.incReference(); 111 111 return cost; 112 112 } else if ( diff == 0 ) { 113 ReferenceType * srcAsRef = dynamic_cast<ReferenceType * >( src );114 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );113 const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src ); 114 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 115 115 if ( srcAsRef && destAsRef ) { // pointer-like conversions between references 116 116 PRINT( std::cerr << "converting between references" << std::endl; ) 117 Type::Qualifiers tq1 = srcAsRef->base-> get_qualifiers();118 Type::Qualifiers tq2 = destAsRef->base-> get_qualifiers();117 Type::Qualifiers tq1 = srcAsRef->base->tq; 118 Type::Qualifiers tq2 = destAsRef->base->tq; 119 119 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) { 120 120 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 137 137 } else { 138 138 PRINT( std::cerr << "reference to rvalue conversion" << std::endl; ) 139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)( Type*,Type*, const SymTab::Indexer&, const TypeEnvironment&))139 PassVisitor<ConversionCost> converter( 140 dest, indexer, env, 141 (Cost (*)(const Type*, const Type*, const SymTab::Indexer&, const TypeEnvironment&)) 142 142 conversionCost ); 143 143 src->accept( converter ); … … 145 145 } // if 146 146 } else { 147 ReferenceType * destAsRef = dynamic_cast<ReferenceType * >( dest );147 const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest ); 148 148 assert( diff == -1 && destAsRef ); 149 149 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) … … 156 156 ) 157 157 // lvalue-to-reference conversion: cv lvalue T => cv T & 158 if ( src-> get_qualifiers() == destAsRef->base->get_qualifiers()) {158 if ( src->tq == destAsRef->base->tq ) { 159 159 return Cost::reference; // cost needs to be non-zero to add cast 160 } if ( src-> get_qualifiers() < destAsRef->base->get_qualifiers()) {160 } if ( src->tq < destAsRef->base->tq ) { 161 161 return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same 162 162 } else { … … 178 178 } 179 179 180 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {180 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 181 181 int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth(); 182 182 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func ); … … 185 185 } 186 186 187 ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )187 ConversionCost::ConversionCost( const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 188 188 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 189 189 } … … 193 193 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves) 194 194 _Bool 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 195 char signed char unsigned char 196 signed short int unsigned short int 197 signed int unsigned int 198 signed long int unsigned long int 199 signed long long int unsigned long long int 200 __int128 unsigned __int128 201 _Float16 _Float16 _Complex 202 _Float32 _Float32 _Complex 203 float float _Complex 204 _Float32x _Float32x _Complex 205 _Float64 _Float64 _Complex 206 double double _Complex 207 _Float64x _Float64x _Complex 208 208 __float80 209 _Float128 _Float128 _Complex 209 _Float128 _Float128 _Complex 210 210 __float128 211 long double long double _Complex 212 _Float128x _Float128x _Complex 211 long double long double _Complex 212 _Float128x _Float128x _Complex 213 213 */ 214 214 // GENERATED END … … 309 309 ); 310 310 311 void ConversionCost::postvisit( VoidType * ) {311 void ConversionCost::postvisit( const VoidType * ) { 312 312 cost = Cost::infinity; 313 313 } 314 314 315 void ConversionCost::postvisit( BasicType *basicType) {316 if ( BasicType *destAsBasic = dynamic_cast<BasicType* >( dest ) ) {317 int tableResult = costMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()];315 void ConversionCost::postvisit(const BasicType *basicType) { 316 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) { 317 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 318 318 if ( tableResult == -1 ) { 319 319 cost = Cost::unsafe; … … 321 321 cost = Cost::zero; 322 322 cost.incSafe( tableResult ); 323 cost.incSign( signMatrix[ basicType-> get_kind() ][ destAsBasic->get_kind()] );324 } // if 325 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {323 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] ); 324 } // if 325 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) { 326 326 // xxx - not positive this is correct, but appears to allow casting int => enum 327 327 cost = Cost::unsafe; … … 330 330 } 331 331 332 void ConversionCost::postvisit( PointerType * pointerType ) {333 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {332 void ConversionCost::postvisit( const PointerType * pointerType ) { 333 if ( const PointerType *destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 334 334 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 335 Type::Qualifiers tq1 = pointerType->base-> get_qualifiers();336 Type::Qualifiers tq2 = destAsPtr->base-> get_qualifiers();335 Type::Qualifiers tq1 = pointerType->base->tq; 336 Type::Qualifiers tq2 = destAsPtr->base->tq; 337 337 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 338 338 PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; ) … … 363 363 } 364 364 365 void ConversionCost::postvisit( ArrayType * ) {}366 367 void ConversionCost::postvisit( ReferenceType * refType ) {365 void ConversionCost::postvisit( const ArrayType * ) {} 366 367 void ConversionCost::postvisit( const ReferenceType * refType ) { 368 368 // Note: dest can never be a reference, since it would have been caught in an earlier check 369 assert( ! dynamic_cast< ReferenceType * >( dest ) );369 assert( ! dynamic_cast< const ReferenceType * >( dest ) ); 370 370 // convert reference to rvalue: cv T1 & => T2 371 371 // recursively compute conversion cost from T1 to T2. 372 372 // cv can be safely dropped because of 'implicit dereference' behavior. 373 373 cost = costFunc( refType->base, dest, indexer, env ); 374 if ( refType->base-> get_qualifiers() == dest->get_qualifiers()) {374 if ( refType->base->tq == dest->tq ) { 375 375 cost.incReference(); // prefer exact qualifiers 376 } else if ( refType->base-> get_qualifiers() < dest->get_qualifiers()) {376 } else if ( refType->base->tq < dest->tq ) { 377 377 cost.incSafe(); // then gaining qualifiers 378 378 } else { … … 382 382 } 383 383 384 void ConversionCost::postvisit( FunctionType * ) {}385 386 void ConversionCost::postvisit( StructInstType * inst ) {387 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {384 void ConversionCost::postvisit( const FunctionType * ) {} 385 386 void ConversionCost::postvisit( const StructInstType * inst ) { 387 if ( const StructInstType *destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 388 388 if ( inst->name == destAsInst->name ) { 389 389 cost = Cost::zero; … … 392 392 } 393 393 394 void ConversionCost::postvisit( UnionInstType * inst ) {395 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {394 void ConversionCost::postvisit( const UnionInstType * inst ) { 395 if ( const UnionInstType *destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 396 396 if ( inst->name == destAsInst->name ) { 397 397 cost = Cost::zero; … … 400 400 } 401 401 402 void ConversionCost::postvisit( EnumInstType * ) {402 void ConversionCost::postvisit( const EnumInstType * ) { 403 403 static Type::Qualifiers q; 404 404 static BasicType integer( q, BasicType::SignedInt ); … … 409 409 } 410 410 411 void ConversionCost::postvisit( TraitInstType * ) {}412 413 void ConversionCost::postvisit( TypeInstType *inst ) {411 void ConversionCost::postvisit( const TraitInstType * ) {} 412 413 void ConversionCost::postvisit( const TypeInstType *inst ) { 414 414 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) { 415 415 cost = costFunc( eqvClass->type, dest, indexer, env ); 416 } else if ( TypeInstType *destAsInst = dynamic_cast<TypeInstType* >( dest ) ) {416 } else if ( const TypeInstType *destAsInst = dynamic_cast< const TypeInstType* >( dest ) ) { 417 417 if ( inst->name == destAsInst->name ) { 418 418 cost = Cost::zero; 419 419 } 420 420 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) { 421 TypeDecl *type = dynamic_cast<TypeDecl* >( namedType );421 const TypeDecl *type = dynamic_cast< const TypeDecl* >( namedType ); 422 422 // all typedefs should be gone by this point 423 423 assert( type ); … … 428 428 } 429 429 430 void ConversionCost::postvisit( TupleType * tupleType ) {430 void ConversionCost::postvisit( const TupleType * tupleType ) { 431 431 Cost c = Cost::zero; 432 if ( TupleType * destAsTuple = dynamic_cast<TupleType * >( dest ) ) {432 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) { 433 433 std::list< Type * >::const_iterator srcIt = tupleType->types.begin(); 434 434 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); … … 448 448 } 449 449 450 void ConversionCost::postvisit( VarArgsType * ) {451 if ( dynamic_cast< VarArgsType* >( dest ) ) {452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( ZeroType * ) {457 if ( dynamic_cast< ZeroType * >( dest ) ) {458 cost = Cost::zero; 459 } else if ( BasicType *destAsBasic = dynamic_cast<BasicType* >( dest ) ) {450 void ConversionCost::postvisit( const VarArgsType * ) { 451 if ( dynamic_cast< const VarArgsType* >( dest ) ) { 452 cost = Cost::zero; 453 } 454 } 455 456 void ConversionCost::postvisit( const ZeroType * ) { 457 if ( dynamic_cast< const ZeroType * >( dest ) ) { 458 cost = Cost::zero; 459 } else if ( const BasicType *destAsBasic = dynamic_cast< const BasicType* >( dest ) ) { 460 460 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 462 462 if ( tableResult == -1 ) { 463 463 cost = Cost::unsafe; … … 465 465 cost = Cost::zero; 466 466 cost.incSafe( tableResult + 1 ); 467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );468 } // if 469 } else if ( dynamic_cast< PointerType* >( dest ) ) {467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 468 } // if 469 } else if ( dynamic_cast< const PointerType* >( dest ) ) { 470 470 cost = Cost::zero; 471 471 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation … … 473 473 } 474 474 475 void ConversionCost::postvisit( OneType * ) {476 if ( dynamic_cast< OneType * >( dest ) ) {477 cost = Cost::zero; 478 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {475 void ConversionCost::postvisit( const OneType * ) { 476 if ( dynamic_cast< const OneType * >( dest ) ) { 477 cost = Cost::zero; 478 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 479 479 // copied from visit(BasicType*) for signed int, but +1 for safe conversions 480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 481 481 if ( tableResult == -1 ) { 482 482 cost = Cost::unsafe; … … 484 484 cost = Cost::zero; 485 485 cost.incSafe( tableResult + 1 ); 486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()] );486 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 487 487 } // if 488 488 } // if -
src/ResolvExpr/ConversionCost.h
ree6dbae r7870799 33 33 class TypeEnvironment; 34 34 35 typedef std::function<Cost( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;35 typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction; 36 36 struct ConversionCost : public WithShortCircuiting { 37 37 public: 38 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );38 ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction ); 39 39 40 40 Cost get_cost() const { return cost; } 41 41 42 void previsit( BaseSyntaxNode * ) { visit_children = false; }42 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 43 43 44 void postvisit( VoidType * voidType );45 void postvisit( BasicType * basicType );46 void postvisit( PointerType * pointerType );47 void postvisit( ArrayType * arrayType );48 void postvisit( ReferenceType * refType );49 void postvisit( FunctionType * functionType );50 void postvisit( StructInstType * aggregateUseType );51 void postvisit( UnionInstType * aggregateUseType );52 void postvisit( EnumInstType * aggregateUseType );53 void postvisit( TraitInstType * aggregateUseType );54 void postvisit( TypeInstType * aggregateUseType );55 void postvisit( TupleType * tupleType );56 void postvisit( VarArgsType * varArgsType );57 void postvisit( ZeroType * zeroType );58 void postvisit( OneType * oneType );44 void postvisit( const VoidType * voidType ); 45 void postvisit( const BasicType * basicType ); 46 void postvisit( const PointerType * pointerType ); 47 void postvisit( const ArrayType * arrayType ); 48 void postvisit( const ReferenceType * refType ); 49 void postvisit( const FunctionType * functionType ); 50 void postvisit( const StructInstType * aggregateUseType ); 51 void postvisit( const UnionInstType * aggregateUseType ); 52 void postvisit( const EnumInstType * aggregateUseType ); 53 void postvisit( const TraitInstType * aggregateUseType ); 54 void postvisit( const TypeInstType * aggregateUseType ); 55 void postvisit( const TupleType * tupleType ); 56 void postvisit( const VarArgsType * varArgsType ); 57 void postvisit( const ZeroType * zeroType ); 58 void postvisit( const OneType * oneType ); 59 59 protected: 60 Type *dest;60 const Type * dest; 61 61 const SymTab::Indexer &indexer; 62 62 Cost cost; … … 65 65 }; 66 66 67 typedef std::function<int( Type *,Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;68 Cost convertToReferenceCost( Type * src,ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );67 typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction; 68 Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ); 69 69 70 70 // Some function pointer types, differ in return type. -
src/ResolvExpr/PtrsAssignable.cc
ree6dbae r7870799 27 27 namespace ResolvExpr { 28 28 struct PtrsAssignable : public WithShortCircuiting { 29 PtrsAssignable( Type *dest, const TypeEnvironment &env );29 PtrsAssignable( const Type * dest, const TypeEnvironment &env ); 30 30 31 31 int get_result() const { return result; } 32 32 33 void previsit( Type * ) { visit_children = false; }34 35 void postvisit( VoidType * voidType );36 void postvisit( BasicType * basicType );37 void postvisit( PointerType * pointerType );38 void postvisit( ArrayType * arrayType );39 void postvisit( FunctionType * functionType );40 void postvisit( StructInstType * inst );41 void postvisit( UnionInstType * inst );42 void postvisit( EnumInstType * inst );43 void postvisit( TraitInstType * inst );44 void postvisit( TypeInstType * inst );45 void postvisit( TupleType * tupleType );46 void postvisit( VarArgsType * varArgsType );47 void postvisit( ZeroType * zeroType );48 void postvisit( OneType * oneType );33 void previsit( const Type * ) { visit_children = false; } 34 35 void postvisit( const VoidType * voidType ); 36 void postvisit( const BasicType * basicType ); 37 void postvisit( const PointerType * pointerType ); 38 void postvisit( const ArrayType * arrayType ); 39 void postvisit( const FunctionType * functionType ); 40 void postvisit( const StructInstType * inst ); 41 void postvisit( const UnionInstType * inst ); 42 void postvisit( const EnumInstType * inst ); 43 void postvisit( const TraitInstType * inst ); 44 void postvisit( const TypeInstType * inst ); 45 void postvisit( const TupleType * tupleType ); 46 void postvisit( const VarArgsType * varArgsType ); 47 void postvisit( const ZeroType * zeroType ); 48 void postvisit( const OneType * oneType ); 49 49 private: 50 Type *dest;50 const Type * dest; 51 51 int result; 52 52 const TypeEnvironment &env; 53 53 }; 54 54 55 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {55 int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) { 56 56 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 57 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {57 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 58 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 59 59 return ptrsAssignable( src, eqvClass->type, env ); 60 60 } // if 61 61 } // if 62 if ( dynamic_cast< VoidType* >( dest ) ) {62 if ( dynamic_cast< const VoidType* >( dest ) ) { 63 63 // void * = T * for any T is unsafe 64 64 // xxx - this should be safe, but that currently breaks the build … … 71 71 } 72 72 73 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}74 75 void PtrsAssignable::postvisit( VoidType * ) {73 PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 74 75 void PtrsAssignable::postvisit( const VoidType * ) { 76 76 // T * = void * is disallowed - this is a change from C, where any 77 77 // void * can be assigned or passed to a non-void pointer without a cast. 78 78 } 79 79 80 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType) {}82 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType) {}83 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType) {}84 85 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst) {}86 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst) {}87 88 void PtrsAssignable::postvisit( EnumInstType * ) {89 if ( dynamic_cast< BasicType* >( dest ) ) {80 void PtrsAssignable::postvisit( const BasicType * ) {} 81 void PtrsAssignable::postvisit( const PointerType * ) {} 82 void PtrsAssignable::postvisit( const ArrayType * ) {} 83 void PtrsAssignable::postvisit( const FunctionType * ) {} 84 85 void PtrsAssignable::postvisit( const StructInstType * ) {} 86 void PtrsAssignable::postvisit( const UnionInstType * ) {} 87 88 void PtrsAssignable::postvisit( const EnumInstType * ) { 89 if ( dynamic_cast< const BasicType* >( dest ) ) { 90 90 // int * = E *, etc. is safe. This isn't technically correct, as each 91 91 // enum has one basic type that it is compatible with, an that type can … … 97 97 } 98 98 99 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst) {}100 void PtrsAssignable::postvisit( TypeInstType *inst ) {101 if ( const EqvClass * eqvClass = env.lookup( inst->get_name()) ) {99 void PtrsAssignable::postvisit( const TraitInstType * ) {} 100 void PtrsAssignable::postvisit( const TypeInstType * inst ) { 101 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 102 102 if ( eqvClass->type ) { 103 103 // T * = S * for any S depends on the type bound to T … … 107 107 } 108 108 109 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType) {}110 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType) {}111 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType) {}112 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType) {}109 void PtrsAssignable::postvisit( const TupleType * ) {} 110 void PtrsAssignable::postvisit( const VarArgsType * ) {} 111 void PtrsAssignable::postvisit( const ZeroType * ) {} 112 void PtrsAssignable::postvisit( const OneType * ) {} 113 113 114 114 // TODO: Get rid of the `_new` suffix when the old version is removed. -
src/ResolvExpr/PtrsCastable.cc
ree6dbae r7870799 29 29 struct PtrsCastable_old : public WithShortCircuiting { 30 30 public: 31 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );31 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 32 32 33 33 int get_result() const { return result; } 34 34 35 void previsit( Type * ) { visit_children = false; }36 37 void postvisit( VoidType * voidType );38 void postvisit( BasicType * basicType );39 void postvisit( PointerType * pointerType );40 void postvisit( ArrayType * arrayType );41 void postvisit( FunctionType * functionType );42 void postvisit( StructInstType * inst );43 void postvisit( UnionInstType * inst );44 void postvisit( EnumInstType * inst );45 void postvisit( TraitInstType * inst );46 void postvisit( TypeInstType * inst );47 void postvisit( TupleType * tupleType );48 void postvisit( VarArgsType * varArgsType );49 void postvisit( ZeroType * zeroType );50 void postvisit( OneType * oneType );35 void previsit( const Type * ) { visit_children = false; } 36 37 void postvisit( const VoidType * voidType ); 38 void postvisit( const BasicType * basicType ); 39 void postvisit( const PointerType * pointerType ); 40 void postvisit( const ArrayType * arrayType ); 41 void postvisit( const FunctionType * functionType ); 42 void postvisit( const StructInstType * inst ); 43 void postvisit( const UnionInstType * inst ); 44 void postvisit( const EnumInstType * inst ); 45 void postvisit( const TraitInstType * inst ); 46 void postvisit( const TypeInstType * inst ); 47 void postvisit( const TupleType * tupleType ); 48 void postvisit( const VarArgsType * varArgsType ); 49 void postvisit( const ZeroType * zeroType ); 50 void postvisit( const OneType * oneType ); 51 51 private: 52 Type *dest;52 const Type * dest; 53 53 int result; 54 54 const TypeEnvironment &env; … … 57 57 58 58 namespace { 59 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {60 if ( dynamic_cast< FunctionType* >( src ) ) {59 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 60 if ( dynamic_cast< const FunctionType* >( src ) ) { 61 61 return -1; 62 } else if ( TypeInstType *typeInst = dynamic_cast<TypeInstType* >( src ) ) {63 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name()) ) {64 if ( TypeDecl *tyDecl = dynamic_cast<TypeDecl* >( ntDecl ) ) {65 if ( tyDecl-> get_kind()== TypeDecl::Ftype ) {62 } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) { 63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) { 64 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) { 65 if ( tyDecl->kind == TypeDecl::Ftype ) { 66 66 return -1; 67 67 } // if 68 68 } //if 69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 70 70 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 71 71 return -1; … … 75 75 return 1; 76 76 } 77 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {77 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 78 78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast 79 79 } 80 80 } 81 81 82 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {83 if ( TypeInstType *destAsTypeInst = dynamic_cast<TypeInstType* >( dest ) ) {84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {82 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) { 84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) { 85 85 // xxx - should this be ptrsCastable? 86 86 return ptrsAssignable( src, eqvClass->type, env ); 87 87 } // if 88 88 } // if 89 if ( dynamic_cast< VoidType* >( dest ) ) {89 if ( dynamic_cast< const VoidType* >( dest ) ) { 90 90 return objectCast( src, env, indexer ); 91 91 } else { … … 96 96 } 97 97 98 PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )98 PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) 99 99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) { 100 100 } 101 101 102 void PtrsCastable_old::postvisit( VoidType * ) {103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( BasicType * ) {107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( PointerType * ) {111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( ArrayType * ) {115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( FunctionType * ) {102 void PtrsCastable_old::postvisit( const VoidType * ) { 103 result = objectCast( dest, env, indexer ); 104 } 105 106 void PtrsCastable_old::postvisit( const BasicType * ) { 107 result = objectCast( dest, env, indexer ); 108 } 109 110 void PtrsCastable_old::postvisit( const PointerType * ) { 111 result = objectCast( dest, env, indexer ); 112 } 113 114 void PtrsCastable_old::postvisit( const ArrayType * ) { 115 result = objectCast( dest, env, indexer ); 116 } 117 118 void PtrsCastable_old::postvisit( const FunctionType * ) { 119 119 // result = -1; 120 120 result = functionCast( dest, env, indexer ); 121 121 } 122 122 123 void PtrsCastable_old::postvisit( StructInstType * ) {124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( UnionInstType * ) {128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( EnumInstType * ) {132 if ( dynamic_cast< EnumInstType* >( dest ) ) {123 void PtrsCastable_old::postvisit( const StructInstType * ) { 124 result = objectCast( dest, env, indexer ); 125 } 126 127 void PtrsCastable_old::postvisit( const UnionInstType * ) { 128 result = objectCast( dest, env, indexer ); 129 } 130 131 void PtrsCastable_old::postvisit( const EnumInstType * ) { 132 if ( dynamic_cast< const EnumInstType * >( dest ) ) { 133 133 result = 1; 134 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {135 if ( bt-> get_kind()== BasicType::SignedInt ) {134 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) { 135 if ( bt->kind == BasicType::SignedInt ) { 136 136 result = 0; 137 137 } else { … … 143 143 } 144 144 145 void PtrsCastable_old::postvisit( TraitInstType * ) {}146 147 void PtrsCastable_old::postvisit( TypeInstType *inst ) {145 void PtrsCastable_old::postvisit( const TraitInstType * ) {} 146 147 void PtrsCastable_old::postvisit( const TypeInstType *inst ) { 148 148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 149 149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 150 150 } 151 151 152 void PtrsCastable_old::postvisit( TupleType * ) {153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( VarArgsType * ) {157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( ZeroType * ) {161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( OneType * ) {152 void PtrsCastable_old::postvisit( const TupleType * ) { 153 result = objectCast( dest, env, indexer ); 154 } 155 156 void PtrsCastable_old::postvisit( const VarArgsType * ) { 157 result = objectCast( dest, env, indexer ); 158 } 159 160 void PtrsCastable_old::postvisit( const ZeroType * ) { 161 result = objectCast( dest, env, indexer ); 162 } 163 164 void PtrsCastable_old::postvisit( const OneType * ) { 165 165 result = objectCast( dest, env, indexer ); 166 166 } … … 168 168 namespace { 169 169 // can this type be cast to an object (1 for yes, -1 for no) 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 170 int objectCast( 171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 172 172 ) { 173 173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) { … … 191 191 192 192 // can this type be cast to a function (inverse of objectCast) 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 193 int functionCast( 194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 195 195 ) { 196 196 return -1 * objectCast( src, env, symtab ); … … 204 204 int result; 205 205 206 PtrsCastable_new( 206 PtrsCastable_new( 207 207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 208 208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {} … … 278 278 } // anonymous namespace 279 279 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 280 int ptrsCastable( 281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 282 const ast::TypeEnvironment & env 283 283 ) { 284 284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { -
src/ResolvExpr/Unify.cc
ree6dbae r7870799 97 97 bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ); 98 98 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 99 bool unifyExact( 100 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 101 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 102 102 WidenMode widen, const ast::SymbolTable & symtab ); 103 103 … … 121 121 } 122 122 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 123 bool typesCompatible( 124 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 125 125 const ast::TypeEnvironment & env ) { 126 126 ast::TypeEnvironment newEnv; … … 135 135 findOpenVars( newSecond, open, closed, need, have, FirstOpen ); 136 136 137 return unifyExact( 137 return unifyExact( 138 138 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 139 139 } 140 140 141 bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {141 bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 142 142 TypeEnvironment newEnv; 143 143 OpenVarSet openVars; … … 163 163 } 164 164 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 165 bool typesCompatibleIgnoreQualifiers( 166 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 167 167 const ast::TypeEnvironment & env ) { 168 168 ast::TypeEnvironment newEnv; 169 169 ast::OpenVarSet open; 170 170 ast::AssertionSet need, have; 171 171 172 172 ast::ptr<ast::Type> newFirst{ first }, newSecond{ second }; 173 173 env.apply( newFirst ); … … 176 176 reset_qualifiers( newSecond ); 177 177 178 return unifyExact( 178 return unifyExact( 179 179 newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab ); 180 180 } … … 490 490 491 491 // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 492 if ( 493 (flatFunc->parameters.size() == flatOther->parameters.size() && 494 flatFunc->returnVals.size() == flatOther->returnVals.size()) 495 || flatFunc->isTtype() 496 || flatOther->isTtype() 497 497 ) { 498 498 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { … … 711 711 bool result; 712 712 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 713 Unify_new( 714 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 715 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 716 716 const ast::SymbolTable & symtab ) 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 717 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 718 718 symtab(symtab), result(false) {} 719 719 720 720 void previsit( const ast::Node * ) { visit_children = false; } 721 721 722 722 void postvisit( const ast::VoidType * ) { 723 723 result = dynamic_cast< const ast::VoidType * >( type2 ); … … 732 732 void postvisit( const ast::PointerType * pointer ) { 733 733 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 734 result = unifyExact( 735 pointer->base, pointer2->base, tenv, need, have, open, 736 736 noWiden(), symtab ); 737 737 } … … 742 742 if ( ! array2 ) return; 743 743 744 // to unify, array types must both be VLA or both not VLA and both must have a 744 // to unify, array types must both be VLA or both not VLA and both must have a 745 745 // dimension expression or not have a dimension 746 746 if ( array->isVarLen != array2->isVarLen ) return; 747 if ( ! array->isVarLen && ! array2->isVarLen 747 if ( ! array->isVarLen && ! array2->isVarLen 748 748 && array->dimension && array2->dimension ) { 749 749 auto ce1 = array->dimension.as< ast::ConstantExpr >(); … … 751 751 752 752 // see C11 Reference Manual 6.7.6.2.6 753 // two array types with size specifiers that are integer constant expressions are 753 // two array types with size specifiers that are integer constant expressions are 754 754 // compatible if both size specifiers have the same constant value 755 755 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return; 756 756 } 757 757 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 758 result = unifyExact( 759 array->base, array2->base, tenv, need, have, open, noWiden(), 760 760 symtab ); 761 761 } … … 763 763 void postvisit( const ast::ReferenceType * ref ) { 764 764 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 765 result = unifyExact( 766 ref->base, ref2->base, tenv, need, have, open, noWiden(), 767 767 symtab ); 768 768 } … … 771 771 private: 772 772 /// Replaces ttype variables with their bound types. 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 773 /// If this isn't done when satifying ttype assertions, then argument lists can have 774 774 /// different size and structure when they should be compatible. 775 775 struct TtypeExpander_new : public ast::WithShortCircuiting { … … 800 800 auto types = flatten( d->get_type() ); 801 801 for ( ast::ptr< ast::Type > & t : types ) { 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 802 // outermost const, volatile, _Atomic qualifiers in parameters should not play 803 // a role in the unification of function types, since they do not determine 804 804 // whether a function is callable. 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 805 // NOTE: **must** consider at least mutex qualifier, since functions can be 806 // overloaded on outermost mutex and a mutex function has different 807 807 // requirements than a non-mutex function 808 808 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); … … 818 818 std::vector< ast::ptr< ast::Type > > types; 819 819 while ( crnt != end ) { 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 820 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 821 821 // that this results in a flat tuple 822 822 flatten( (*crnt)->get_type(), types ); … … 829 829 830 830 template< typename Iter > 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 static bool unifyDeclList( 832 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 833 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 834 834 const ast::SymbolTable & symtab 835 835 ) { … … 843 843 if ( isTuple1 && ! isTuple2 ) { 844 844 // combine remainder of list2, then unify 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 845 return unifyExact( 846 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 847 847 noWiden(), symtab ); 848 848 } else if ( ! isTuple1 && isTuple2 ) { 849 849 // combine remainder of list1, then unify 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 850 return unifyExact( 851 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 852 852 noWiden(), symtab ); 853 853 } 854 854 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 855 if ( ! unifyExact( 856 t1, t2, env, need, have, open, noWiden(), symtab ) 857 857 ) return false; 858 858 … … 860 860 } 861 861 862 // May get to the end of one argument list before the other. This is only okay if the 862 // May get to the end of one argument list before the other. This is only okay if the 863 863 // other is a ttype 864 864 if ( crnt1 != end1 ) { … … 866 866 const ast::Type * t1 = (*crnt1)->get_type(); 867 867 if ( ! Tuples::isTtype( t1 ) ) return false; 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 868 return unifyExact( 869 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 870 870 noWiden(), symtab ); 871 871 } else if ( crnt2 != end2 ) { … … 873 873 const ast::Type * t2 = (*crnt2)->get_type(); 874 874 if ( ! Tuples::isTtype( t2 ) ) return false; 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 875 return unifyExact( 876 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 877 877 noWiden(), symtab ); 878 878 } … … 881 881 } 882 882 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 static bool unifyDeclList( 884 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 885 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 886 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 887 887 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 888 888 ) { 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 889 return unifyDeclList( 890 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 891 891 symtab ); 892 892 } … … 900 900 901 901 /// mark all assertions in `type` used in both `assn1` and `assn2` 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 902 static void markAssertions( 903 ast::AssertionSet & assn1, ast::AssertionSet & assn2, 904 const ast::ParameterizedType * type 905 905 ) { 906 906 for ( const auto & tyvar : type->forall ) { … … 918 918 919 919 if ( func->isVarArgs != func2->isVarArgs ) return; 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 920 921 // Flatten the parameter lists for both functions so that tuple structure does not 922 922 // affect unification. Does not actually mutate function parameters. 923 923 auto params = flattenList( func->params, tenv ); 924 924 auto params2 = flattenList( func2->params, tenv ); 925 925 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 926 // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 927 927 // where the ttype is to prevent errors 928 if ( 928 if ( 929 929 ( params.size() != params2.size() || func->returns.size() != func2->returns.size() ) 930 930 && ! func->isTtype() … … 933 933 934 934 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 935 if ( ! unifyDeclList( 935 if ( ! unifyDeclList( 936 936 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 937 937 938 938 markAssertions( have, need, func ); 939 939 markAssertions( have, need, func2 ); … … 941 941 result = true; 942 942 } 943 943 944 944 private: 945 945 template< typename RefType > … … 953 953 /// Creates a tuple type based on a list of TypeExpr 954 954 template< typename Iter > 955 static const ast::Type * tupleFromExprs( 955 static const ast::Type * tupleFromExprs( 956 956 const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs 957 957 ) { … … 973 973 const RefType * inst2 = handleRefType( inst, other ); 974 974 if ( ! inst2 ) return; 975 975 976 976 // check that parameters of types unify, if any 977 977 const std::vector< ast::ptr< ast::Expr > > & params = inst->params; … … 1002 1002 } 1003 1003 1004 if ( ! unifyExact( 1004 if ( ! unifyExact( 1005 1005 pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) { 1006 1006 result = false; … … 1038 1038 private: 1039 1039 /// Creates a tuple type based on a list of Type 1040 static ast::ptr< ast::Type > tupleFromTypes( 1040 static ast::ptr< ast::Type > tupleFromTypes( 1041 1041 const std::vector< ast::ptr< ast::Type > > & tys 1042 1042 ) { 1043 1043 std::vector< ast::ptr< ast::Type > > out; 1044 1044 for ( const ast::Type * ty : tys ) { 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1045 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 1046 1046 // that this results in a flat tuple 1047 1047 flatten( ty, out ); … … 1051 1051 } 1052 1052 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1053 static bool unifyList( 1054 const std::vector< ast::ptr< ast::Type > > & list1, 1055 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1056 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1057 1057 const ast::SymbolTable & symtab 1058 1058 ) { … … 1068 1068 if ( isTuple1 && ! isTuple2 ) { 1069 1069 // combine entirety of list2, then unify 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1070 return unifyExact( 1071 t1, tupleFromTypes( list2 ), env, need, have, open, 1072 1072 noWiden(), symtab ); 1073 1073 } else if ( ! isTuple1 && isTuple2 ) { 1074 1074 // combine entirety of list1, then unify 1075 1075 return unifyExact( 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1076 tupleFromTypes( list1 ), t2, env, need, have, open, 1077 1077 noWiden(), symtab ); 1078 1078 } 1079 1079 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1080 if ( ! unifyExact( 1081 t1, t2, env, need, have, open, noWiden(), symtab ) 1082 1082 ) return false; 1083 1083 … … 1089 1089 const ast::Type * t1 = *crnt1; 1090 1090 if ( ! Tuples::isTtype( t1 ) ) return false; 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1091 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1092 1092 // from Rob's code 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1093 return unifyExact( 1094 t1, tupleFromTypes( list2 ), env, need, have, open, 1095 1095 noWiden(), symtab ); 1096 1096 } else if ( crnt2 != list2.end() ) { … … 1098 1098 const ast::Type * t2 = *crnt2; 1099 1099 if ( ! Tuples::isTtype( t2 ) ) return false; 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1100 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 1101 1101 // from Rob's code 1102 1102 return unifyExact( 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1103 tupleFromTypes( list1 ), t2, env, need, have, open, 1104 1104 noWiden(), symtab ); 1105 1105 } … … 1133 1133 void postvisit( const ast::OneType * ) { 1134 1134 result = dynamic_cast< const ast::OneType * >( type2 ); 1135 } 1135 } 1136 1136 1137 1137 private: … … 1140 1140 }; 1141 1141 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1142 bool unify( 1143 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1144 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1145 1145 ast::OpenVarSet & open, const ast::SymbolTable & symtab 1146 1146 ) { … … 1149 1149 } 1150 1150 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1151 bool unify( 1152 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1153 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1154 ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 1155 1155 ) { 1156 1156 ast::OpenVarSet closed; 1157 1157 findOpenVars( type1, open, closed, need, have, FirstClosed ); 1158 1158 findOpenVars( type2, open, closed, need, have, FirstOpen ); 1159 return unifyInexact( 1159 return unifyInexact( 1160 1160 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common ); 1161 1161 } 1162 1162 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1163 bool unifyExact( 1164 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1165 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1166 1166 WidenMode widen, const ast::SymbolTable & symtab 1167 1167 ) { … … 1170 1170 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1171 1171 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1172 ast::OpenVarSet::const_iterator 1173 entry1 = var1 ? open.find( var1->name ) : open.end(), 1174 1174 entry2 = var2 ? open.find( var2->name ) : open.end(); 1175 1175 bool isopen1 = entry1 != open.end(); … … 1178 1178 if ( isopen1 && isopen2 ) { 1179 1179 if ( entry1->second.kind != entry2->second.kind ) return false; 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1180 return env.bindVarToVar( 1181 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 1182 1182 open, widen, symtab ); 1183 1183 } else if ( isopen1 ) { … … 1192 1192 } 1193 1193 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1194 bool unifyInexact( 1195 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 1198 ast::ptr<ast::Type> & common 1199 1199 ) { 1200 1200 ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers; 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1201 1202 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 1203 1203 // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1 1204 1204 ast::ptr<ast::Type> t1{ type1 }, t2{ type2 }; 1205 1205 reset_qualifiers( t1 ); 1206 1206 reset_qualifiers( t2 ); 1207 1207 1208 1208 if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) { 1209 1209 t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones -
src/ResolvExpr/typeops.h
ree6dbae r7870799 73 73 74 74 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 75 const ast::Type * adjustExprType( 75 const ast::Type * adjustExprType( 76 76 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 77 77 78 78 // in CastCost.cc 79 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );80 Cost castCost( 81 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 79 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 80 Cost castCost( 81 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 82 82 const ast::TypeEnvironment & env ); 83 83 84 84 // in ConversionCost.cc 85 Cost conversionCost( Type *src,Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 85 Cost conversionCost( const Type *src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 86 Cost conversionCost( 87 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 88 88 const ast::TypeEnvironment & env ); 89 89 90 90 // in AlternativeFinder.cc 91 Cost computeConversionCost( Type *actualType, Type *formalType, 91 Cost computeConversionCost( Type *actualType, Type *formalType, 92 92 const SymTab::Indexer &indexer, const TypeEnvironment &env ); 93 93 94 94 // in PtrsAssignable.cc 95 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );95 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment &env ); 96 96 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 97 97 const ast::TypeEnvironment & env ); 98 98 99 99 // in PtrsCastable.cc 100 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );101 int ptrsCastable( 102 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 100 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 101 int ptrsCastable( 102 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 103 103 const ast::TypeEnvironment & env ); 104 104 105 105 // in Unify.cc 106 106 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 107 bool typesCompatibleIgnoreQualifiers( Type *,Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );107 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 108 108 109 109 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) { … … 112 112 } 113 113 114 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {114 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer &indexer ) { 115 115 TypeEnvironment env; 116 116 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 117 117 } 118 118 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 121 121 const ast::TypeEnvironment & env = {} ); 122 122 123 123 bool typesCompatibleIgnoreQualifiers( 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 125 125 const ast::TypeEnvironment & env = {} ); 126 126 … … 133 133 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 134 134 ast::ptr< ast::Type > commonType( 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 136 136 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 137 137 138 138 // in PolyCost.cc 139 139 int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 140 int polyCost( 140 int polyCost( 141 141 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 142 142 … … 149 149 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 150 150 151 template<typename Iter> 151 template<typename Iter> 152 152 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) { 153 153 while ( begin != end ) { … … 176 176 177 177 /// flatten tuple type into existing list of types 178 static inline void flatten( 179 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 178 static inline void flatten( 179 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 180 180 ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 182 182 for ( const ast::Type * t : tupleType->types ) { 183 183 flatten( t, out ); -
src/SymTab/Validate.h
ree6dbae r7870799 19 19 #include <list> // for list 20 20 21 classCodeLocation;22 class Declaration;23 class Type;21 struct CodeLocation; 22 class Declaration; 23 class Type; 24 24 25 25 namespace ast { … … 35 35 void validateType( Type *type, const Indexer *indexer ); 36 36 37 const ast::Type * validateType( 37 const ast::Type * validateType( 38 38 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ); 39 39 } // namespace SymTab -
src/SynTree/Attribute.h
ree6dbae r7870799 50 50 Attribute * clone() const override { return new Attribute( *this ); } 51 51 virtual void accept( Visitor & v ) override { v.visit( this ); } 52 virtual void accept( Visitor & v ) const override { v.visit( this ); } 52 53 virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 53 54 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/BaseSyntaxNode.h
ree6dbae r7870799 32 32 BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; } 33 33 BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default; 34 34 35 35 virtual ~BaseSyntaxNode() {} 36 36 37 37 virtual BaseSyntaxNode * clone() const = 0; 38 38 virtual void accept( Visitor & v ) = 0; 39 virtual void accept( Visitor & v ) const = 0; 39 40 virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0; 40 41 /// Notes: -
src/SynTree/Constant.h
ree6dbae r7870799 33 33 virtual ~Constant(); 34 34 35 virtual Constant * clone() const { return new Constant( *this ); }35 virtual Constant * clone() const override { return new Constant( *this ); } 36 36 37 37 Type * get_type() { return type; } … … 51 51 static Constant null( Type * ptrtype = nullptr ); 52 52 53 virtual void accept( Visitor & v ) { v.visit( this ); } 54 virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); } 55 virtual void print( std::ostream & os, Indenter indent = 0 ) const; 56 private: 53 virtual void accept( Visitor & v ) override { v.visit( this ); } 54 virtual void accept( Visitor & v ) const override { v.visit( this ); } 55 virtual Constant * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 56 virtual void print( std::ostream & os, Indenter indent = 0 ) const override; 57 57 58 Type * type; 58 59 std::string rep; 59 60 std::optional<unsigned long long> ival; 60 61 friend class ConverterOldToNew;62 61 }; 63 62 -
src/SynTree/Declaration.h
ree6dbae r7870799 63 63 void fixUniqueId( void ); 64 64 virtual Declaration *clone() const override = 0; 65 virtual void accept( Visitor &v ) override = 0; 65 virtual void accept( Visitor & v ) override = 0; 66 virtual void accept( Visitor & v ) const override = 0; 66 67 virtual Declaration *acceptMutator( Mutator &m ) override = 0; 67 68 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; … … 139 140 140 141 virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); } 141 virtual void accept( Visitor &v ) override { v.visit( this ); } 142 virtual void accept( Visitor & v ) override { v.visit( this ); } 143 virtual void accept( Visitor & v ) const override { v.visit( this ); } 142 144 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 143 145 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 169 171 170 172 virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); } 171 virtual void accept( Visitor &v ) override { v.visit( this ); } 173 virtual void accept( Visitor & v ) override { v.visit( this ); } 174 virtual void accept( Visitor & v ) const override { v.visit( this ); } 172 175 virtual DeclarationWithType *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 173 176 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 238 241 239 242 virtual TypeDecl *clone() const override { return new TypeDecl( *this ); } 240 virtual void accept( Visitor &v ) override { v.visit( this ); } 243 virtual void accept( Visitor & v ) override { v.visit( this ); } 244 virtual void accept( Visitor & v ) const override { v.visit( this ); } 241 245 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 242 246 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 256 260 257 261 virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); } 258 virtual void accept( Visitor &v ) override { v.visit( this ); } 262 virtual void accept( Visitor & v ) override { v.visit( this ); } 263 virtual void accept( Visitor & v ) const override { v.visit( this ); } 259 264 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 260 265 private: … … 300 305 301 306 virtual StructDecl *clone() const override { return new StructDecl( *this ); } 302 virtual void accept( Visitor &v ) override { v.visit( this ); } 307 virtual void accept( Visitor & v ) override { v.visit( this ); } 308 virtual void accept( Visitor & v ) const override { v.visit( this ); } 303 309 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 304 310 DeclarationNode::Aggregate kind; … … 314 320 315 321 virtual UnionDecl *clone() const override { return new UnionDecl( *this ); } 316 virtual void accept( Visitor &v ) override { v.visit( this ); } 322 virtual void accept( Visitor & v ) override { v.visit( this ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); } 317 324 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 318 325 private: … … 329 336 330 337 virtual EnumDecl *clone() const override { return new EnumDecl( *this ); } 331 virtual void accept( Visitor &v ) override { v.visit( this ); } 338 virtual void accept( Visitor & v ) override { v.visit( this ); } 339 virtual void accept( Visitor & v ) const override { v.visit( this ); } 332 340 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 333 341 private: … … 345 353 346 354 virtual TraitDecl *clone() const override { return new TraitDecl( *this ); } 347 virtual void accept( Visitor &v ) override { v.visit( this ); } 355 virtual void accept( Visitor & v ) override { v.visit( this ); } 356 virtual void accept( Visitor & v ) const override { v.visit( this ); } 348 357 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 349 358 private: … … 363 372 364 373 virtual AsmDecl *clone() const override { return new AsmDecl( *this ); } 365 virtual void accept( Visitor &v ) override { v.visit( this ); } 374 virtual void accept( Visitor & v ) override { v.visit( this ); } 375 virtual void accept( Visitor & v ) const override { v.visit( this ); } 366 376 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 367 377 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 379 389 380 390 virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 381 virtual void accept( Visitor &v ) override { v.visit( this ); } 391 virtual void accept( Visitor & v ) override { v.visit( this ); } 392 virtual void accept( Visitor & v ) const override { v.visit( this ); } 382 393 virtual StaticAssertDecl * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 383 394 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Expression.h
ree6dbae r7870799 82 82 virtual Expression * clone() const override = 0; 83 83 virtual void accept( Visitor & v ) override = 0; 84 virtual void accept( Visitor & v ) const override = 0; 84 85 virtual Expression * acceptMutator( Mutator & m ) override = 0; 85 86 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 101 102 std::list<Expression *>& get_args() { return args; } 102 103 103 virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); } 104 virtual void accept( Visitor & v ) { v.visit( this ); } 105 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 106 virtual void print( std::ostream & os, Indenter indent = {} ) const; 104 virtual ApplicationExpr * clone() const override { return new ApplicationExpr( * this ); } 105 virtual void accept( Visitor & v ) override { v.visit( this ); } 106 virtual void accept( Visitor & v ) const override { v.visit( this ); } 107 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 108 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 107 109 }; 108 110 … … 129 131 static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 ); 130 132 131 virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); } 132 virtual void accept( Visitor & v ) { v.visit( this ); } 133 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 134 virtual void print( std::ostream & os, Indenter indent = {} ) const; 133 virtual UntypedExpr * clone() const override { return new UntypedExpr( * this ); } 134 virtual void accept( Visitor & v ) override { v.visit( this ); } 135 virtual void accept( Visitor & v ) const override { v.visit( this ); } 136 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 137 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 135 138 }; 136 139 … … 147 150 void set_name( std::string newValue ) { name = newValue; } 148 151 149 virtual NameExpr * clone() const { return new NameExpr( * this ); } 150 virtual void accept( Visitor & v ) { v.visit( this ); } 151 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 152 virtual void print( std::ostream & os, Indenter indent = {} ) const; 152 virtual NameExpr * clone() const override { return new NameExpr( * this ); } 153 virtual void accept( Visitor & v ) override { v.visit( this ); } 154 virtual void accept( Visitor & v ) const override { v.visit( this ); } 155 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 156 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 153 157 }; 154 158 … … 168 172 void set_arg(Expression * newValue ) { arg = newValue; } 169 173 170 virtual AddressExpr * clone() const { return new AddressExpr( * this ); } 171 virtual void accept( Visitor & v ) { v.visit( this ); } 172 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 173 virtual void print( std::ostream & os, Indenter indent = {} ) const; 174 virtual AddressExpr * clone() const override { return new AddressExpr( * this ); } 175 virtual void accept( Visitor & v ) override { v.visit( this ); } 176 virtual void accept( Visitor & v ) const override { v.visit( this ); } 177 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 178 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 174 179 }; 175 180 … … 184 189 virtual ~LabelAddressExpr(); 185 190 186 virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); } 187 virtual void accept( Visitor & v ) { v.visit( this ); } 188 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 189 virtual void print( std::ostream & os, Indenter indent = {} ) const; 191 virtual LabelAddressExpr * clone() const override { return new LabelAddressExpr( * this ); } 192 virtual void accept( Visitor & v ) override { v.visit( this ); } 193 virtual void accept( Visitor & v ) const override { v.visit( this ); } 194 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 195 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 190 196 }; 191 197 … … 205 211 void set_arg( Expression * newValue ) { arg = newValue; } 206 212 207 virtual CastExpr * clone() const { return new CastExpr( * this ); } 208 virtual void accept( Visitor & v ) { v.visit( this ); } 209 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 210 virtual void print( std::ostream & os, Indenter indent = {} ) const; 213 virtual CastExpr * clone() const override { return new CastExpr( * this ); } 214 virtual void accept( Visitor & v ) override { v.visit( this ); } 215 virtual void accept( Visitor & v ) const override { v.visit( this ); } 216 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 217 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 211 218 }; 212 219 … … 225 232 const std::string & targetString() const; 226 233 227 virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); } 228 virtual void accept( Visitor & v ) { v.visit( this ); } 229 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 230 virtual void print( std::ostream & os, Indenter indent = {} ) const; 234 virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); } 235 virtual void accept( Visitor & v ) override { v.visit( this ); } 236 virtual void accept( Visitor & v ) const override { v.visit( this ); } 237 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 238 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 231 239 }; 232 240 … … 243 251 void set_arg( Expression * newValue ) { arg = newValue; } 244 252 245 virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); } 246 virtual void accept( Visitor & v ) { v.visit( this ); } 247 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 248 virtual void print( std::ostream & os, Indenter indent = {} ) const; 253 virtual VirtualCastExpr * clone() const override { return new VirtualCastExpr( * this ); } 254 virtual void accept( Visitor & v ) override { v.visit( this ); } 255 virtual void accept( Visitor & v ) const override { v.visit( this ); } 256 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 257 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 249 258 }; 250 259 … … 264 273 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 265 274 266 virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); } 267 virtual void accept( Visitor & v ) { v.visit( this ); } 268 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 269 virtual void print( std::ostream & os, Indenter indent = {} ) const; 275 virtual UntypedMemberExpr * clone() const override { return new UntypedMemberExpr( * this ); } 276 virtual void accept( Visitor & v ) override { v.visit( this ); } 277 virtual void accept( Visitor & v ) const override { v.visit( this ); } 278 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 279 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 270 280 }; 271 281 … … 286 296 void set_aggregate( Expression * newValue ) { aggregate = newValue; } 287 297 288 virtual MemberExpr * clone() const { return new MemberExpr( * this ); } 289 virtual void accept( Visitor & v ) { v.visit( this ); } 290 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 291 virtual void print( std::ostream & os, Indenter indent = {} ) const; 298 virtual MemberExpr * clone() const override { return new MemberExpr( * this ); } 299 virtual void accept( Visitor & v ) override { v.visit( this ); } 300 virtual void accept( Visitor & v ) const override { v.visit( this ); } 301 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 302 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 292 303 }; 293 304 … … 308 319 static VariableExpr * functionPointer( FunctionDecl * decl ); 309 320 310 virtual VariableExpr * clone() const { return new VariableExpr( * this ); } 311 virtual void accept( Visitor & v ) { v.visit( this ); } 312 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 313 virtual void print( std::ostream & os, Indenter indent = {} ) const; 321 virtual VariableExpr * clone() const override { return new VariableExpr( * this ); } 322 virtual void accept( Visitor & v ) override { v.visit( this ); }