- Timestamp:
- Jul 19, 2019, 2:16:01 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 4eb43fa
- Parents:
- 1f1c102 (diff), 8ac3b0e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 53 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r1f1c102 rf53acdf8 518 518 } 519 519 520 const ast:: Stmt* visit( const ast::WithStmt * node ) override final {520 const ast::Decl * visit( const ast::WithStmt * node ) override final { 521 521 if ( inCache( node ) ) return nullptr; 522 522 auto stmt = new WithStmt( … … 524 524 get<Statement>().accept1( node->stmt ) 525 525 ); 526 return stmtPostamble( stmt, node ); 526 declPostamble( stmt, node ); 527 return nullptr; 527 528 } 528 529 … … 1039 1040 get<Expression>().accept1(node->expr), 1040 1041 inCache(node->deleteStmt) ? 1041 this->node:1042 get< BaseSyntaxNode>().accept1(node->deleteStmt)1042 strict_dynamic_cast<Declaration*>(this->node) : 1043 get<Declaration>().accept1(node->deleteStmt) 1043 1044 ) 1044 1045 ); … … 1355 1356 ast::Node * node = nullptr; 1356 1357 /// cache of nodes that might be referenced by readonly<> for de-duplication 1357 std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};1358 std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {}; 1358 1359 1359 1360 // Local Utilities: … … 1422 1423 to<std::vector>::from( make_labels( std::move( labels ) ) ) 1423 1424 1424 static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }1425 static ast::CV::Qualifiers cv( const Type * ty ) { return { ty->tq.val }; } 1425 1426 1426 1427 /// returns true and sets `node` if in cache 1427 bool inCache( BaseSyntaxNode * old ) {1428 bool inCache( const BaseSyntaxNode * old ) { 1428 1429 auto it = cache.find( old ); 1429 1430 if ( it == cache.end() ) return false; … … 1434 1435 // Now all the visit functions: 1435 1436 1436 virtual void visit( ObjectDecl * old ) override final {1437 virtual void visit( const ObjectDecl * old ) override final { 1437 1438 auto&& type = GET_ACCEPT_1(type, Type); 1438 1439 auto&& init = GET_ACCEPT_1(init, Init); … … 1465 1466 } 1466 1467 1467 virtual void visit( FunctionDecl * old ) override final {1468 virtual void visit( const FunctionDecl * old ) override final { 1468 1469 if ( inCache( old ) ) return; 1469 1470 auto decl = new ast::FunctionDecl{ … … 1498 1499 } 1499 1500 1500 virtual void visit( StructDecl * old ) override final {1501 virtual void visit( const StructDecl * old ) override final { 1501 1502 if ( inCache( old ) ) return; 1502 1503 auto decl = new ast::StructDecl( … … 1523 1524 } 1524 1525 1525 virtual void visit( UnionDecl * old ) override final {1526 virtual void visit( const UnionDecl * old ) override final { 1526 1527 if ( inCache( old ) ) return; 1527 1528 auto decl = new ast::UnionDecl( … … 1543 1544 } 1544 1545 1545 virtual void visit( EnumDecl * old ) override final {1546 virtual void visit( const EnumDecl * old ) override final { 1546 1547 if ( inCache( old ) ) return; 1547 1548 auto decl = new ast::EnumDecl( … … 1563 1564 } 1564 1565 1565 virtual void visit( TraitDecl * old ) override final {1566 virtual void visit( const TraitDecl * old ) override final { 1566 1567 if ( inCache( old ) ) return; 1567 1568 auto decl = new ast::TraitDecl( … … 1583 1584 } 1584 1585 1585 virtual void visit( TypeDecl * old ) override final {1586 virtual void visit( const TypeDecl * old ) override final { 1586 1587 if ( inCache( old ) ) return; 1587 1588 auto decl = new ast::TypeDecl{ … … 1603 1604 } 1604 1605 1605 virtual void visit( TypedefDecl * old ) override final {1606 virtual void visit( const TypedefDecl * old ) override final { 1606 1607 auto decl = new ast::TypedefDecl( 1607 1608 old->location, … … 1620 1621 } 1621 1622 1622 virtual void visit( AsmDecl * old ) override final {1623 virtual void visit( const AsmDecl * old ) override final { 1623 1624 auto decl = new ast::AsmDecl{ 1624 1625 old->location, … … 1632 1633 } 1633 1634 1634 virtual void visit( StaticAssertDecl * old ) override final {1635 virtual void visit( const StaticAssertDecl * old ) override final { 1635 1636 auto decl = new ast::StaticAssertDecl{ 1636 1637 old->location, … … 1645 1646 } 1646 1647 1647 virtual void visit( CompoundStmt * old ) override final {1648 virtual void visit( const CompoundStmt * old ) override final { 1648 1649 if ( inCache( old ) ) return; 1649 1650 auto stmt = new ast::CompoundStmt( … … 1657 1658 } 1658 1659 1659 virtual void visit( ExprStmt * old ) override final {1660 virtual void visit( const ExprStmt * old ) override final { 1660 1661 if ( inCache( old ) ) return; 1661 1662 this->node = new ast::ExprStmt( … … 1667 1668 } 1668 1669 1669 virtual void visit( AsmStmt * old ) override final {1670 virtual void visit( const AsmStmt * old ) override final { 1670 1671 if ( inCache( old ) ) return; 1671 1672 this->node = new ast::AsmStmt( … … 1682 1683 } 1683 1684 1684 virtual void visit( DirectiveStmt * old ) override final {1685 virtual void visit( const DirectiveStmt * old ) override final { 1685 1686 if ( inCache( old ) ) return; 1686 1687 this->node = new ast::DirectiveStmt( … … 1692 1693 } 1693 1694 1694 virtual void visit( IfStmt * old ) override final {1695 virtual void visit( const IfStmt * old ) override final { 1695 1696 if ( inCache( old ) ) return; 1696 1697 this->node = new ast::IfStmt( … … 1705 1706 } 1706 1707 1707 virtual void visit( SwitchStmt * old ) override final {1708 virtual void visit( const SwitchStmt * old ) override final { 1708 1709 if ( inCache( old ) ) return; 1709 1710 this->node = new ast::SwitchStmt( … … 1716 1717 } 1717 1718 1718 virtual void visit( CaseStmt * old ) override final {1719 virtual void visit( const CaseStmt * old ) override final { 1719 1720 if ( inCache( old ) ) return; 1720 1721 this->node = new ast::CaseStmt( … … 1727 1728 } 1728 1729 1729 virtual void visit( WhileStmt * old ) override final {1730 virtual void visit( const WhileStmt * old ) override final { 1730 1731 if ( inCache( old ) ) return; 1731 1732 this->node = new ast::WhileStmt( … … 1740 1741 } 1741 1742 1742 virtual void visit( ForStmt * old ) override final {1743 virtual void visit( const ForStmt * old ) override final { 1743 1744 if ( inCache( old ) ) return; 1744 1745 this->node = new ast::ForStmt( … … 1753 1754 } 1754 1755 1755 virtual void visit( BranchStmt * old ) override final {1756 virtual void visit( const BranchStmt * old ) override final { 1756 1757 if ( inCache( old ) ) return; 1757 1758 if (old->computedTarget) { … … 1790 1791 } 1791 1792 1792 virtual void visit( ReturnStmt * old ) override final {1793 virtual void visit( const ReturnStmt * old ) override final { 1793 1794 if ( inCache( old ) ) return; 1794 1795 this->node = new ast::ReturnStmt( … … 1800 1801 } 1801 1802 1802 virtual void visit( ThrowStmt * old ) override final {1803 virtual void visit( const ThrowStmt * old ) override final { 1803 1804 if ( inCache( old ) ) return; 1804 1805 ast::ExceptionKind kind; … … 1824 1825 } 1825 1826 1826 virtual void visit( TryStmt * old ) override final {1827 virtual void visit( const TryStmt * old ) override final { 1827 1828 if ( inCache( old ) ) return; 1828 1829 this->node = new ast::TryStmt( … … 1836 1837 } 1837 1838 1838 virtual void visit( CatchStmt * old ) override final {1839 virtual void visit( const CatchStmt * old ) override final { 1839 1840 if ( inCache( old ) ) return; 1840 1841 ast::ExceptionKind kind; … … 1861 1862 } 1862 1863 1863 virtual void visit( FinallyStmt * old ) override final {1864 virtual void visit( const FinallyStmt * old ) override final { 1864 1865 if ( inCache( old ) ) return; 1865 1866 this->node = new ast::FinallyStmt( … … 1871 1872 } 1872 1873 1873 virtual void visit( WaitForStmt * old ) override final {1874 virtual void visit( const WaitForStmt * old ) override final { 1874 1875 if ( inCache( old ) ) return; 1875 1876 ast::WaitForStmt * stmt = new ast::WaitForStmt( … … 1903 1904 } 1904 1905 1905 virtual void visit( WithStmt * old ) override final {1906 virtual void visit( const WithStmt * old ) override final { 1906 1907 if ( inCache( old ) ) return; 1907 1908 this->node = new ast::WithStmt( 1908 1909 old->location, 1909 1910 GET_ACCEPT_V(exprs, Expr), 1910 GET_ACCEPT_1(stmt, Stmt), 1911 GET_LABELS_V(old->labels) 1911 GET_ACCEPT_1(stmt, Stmt) 1912 1912 ); 1913 1913 cache.emplace( old, this->node ); 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( … … 2397 2397 GET_ACCEPT_1(expr, Expr), 2398 2398 inCache(old->deleteStmt) ? 2399 this->node:2400 GET_ACCEPT_1(deleteStmt, Node)2401 ) 2402 ); 2403 } 2404 2405 virtual void visit( DefaultArgExpr * old ) override final {2399 strict_dynamic_cast<ast::Decl*>(this->node) : 2400 GET_ACCEPT_1(deleteStmt, Decl) 2401 ) 2402 ); 2403 } 2404 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/Decl.hpp
r1f1c102 rf53acdf8 102 102 ptr<Expr> bitfieldWidth; 103 103 104 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 105 const Init * init = nullptr, Storage::Classes storage = {}, 106 Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 104 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 105 const Init * init = nullptr, Storage::Classes storage = {}, 106 Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr, 107 107 std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} ) 108 108 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), … … 323 323 }; 324 324 325 /// With statement `with (...) ...` 326 class WithStmt final : public Decl { 327 public: 328 std::vector<ptr<Expr>> exprs; 329 ptr<Stmt> stmt; 330 331 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt ) 332 : Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {} 333 334 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } 335 private: 336 WithStmt * clone() const override { return new WithStmt{ *this }; } 337 MUTATE_FRIEND 338 }; 339 325 340 class AsmDecl : public Decl { 326 341 public: -
src/AST/Expr.hpp
r1f1c102 rf53acdf8 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);116 assertf(false, "unreachable"); 117 117 } 118 118 … … 121 121 return data.resnSlots; 122 122 } 123 assert (!"Mode was not already resnSlots");124 return *((ResnSlots*)nullptr);123 assertf(false, "Mode was not already resnSlots"); 124 abort(); 125 125 } 126 126 … … 131 131 case Params: return data.inferParams; 132 132 } 133 assert(!"unreachable"); 134 return *((InferredParams*)nullptr); 133 assertf(false, "unreachable"); 135 134 } 136 135 … … 139 138 return data.inferParams; 140 139 } 141 assert (!"Mode was not already Params");142 return *((InferredParams*)nullptr);140 assertf(false, "Mode was not already Params"); 141 abort(); 143 142 } 144 143 145 144 void set_inferParams( InferredParams && ps ) { 146 145 switch(mode) { 147 case Slots: 146 case Slots: 148 147 data.resnSlots.~ResnSlots(); 149 148 // fallthrough 150 case Empty: 149 case Empty: 151 150 new(&data.inferParams) InferredParams{ std::move( ps ) }; 152 151 mode = Params; … … 172 171 data.inferParams[p.first] = std::move(p.second); 173 172 } 174 } else assert (!"invalid mode");173 } else assertf(false, "invalid mode"); 175 174 } 176 175 }; … … 384 383 385 384 ConstantExpr( 386 const CodeLocation & loc, const Type * ty, const std::string & r, 385 const CodeLocation & loc, const Type * ty, const std::string & r, 387 386 std::optional<unsigned long long> i ) 388 387 : Expr( loc, ty ), rep( r ), ival( i ) {} … … 770 769 public: 771 770 ptr<Expr> expr; 772 readonly< Node> deleteStmt;773 774 DeletedExpr( const CodeLocation & loc, const Expr * e, const Node* del )771 readonly<Decl> deleteStmt; 772 773 DeletedExpr( const CodeLocation & loc, const Expr * e, const Decl * del ) 775 774 : Expr( loc, e->result ), expr( e ), deleteStmt( del ) { assert( expr->result ); } 776 775 -
src/AST/Pass.hpp
r1f1c102 rf53acdf8 115 115 const ast::Stmt * visit( const ast::FinallyStmt * ) override final; 116 116 const ast::Stmt * visit( const ast::WaitForStmt * ) override final; 117 const ast:: Stmt* visit( const ast::WithStmt * ) override final;117 const ast::Decl * visit( const ast::WithStmt * ) override final; 118 118 const ast::NullStmt * visit( const ast::NullStmt * ) override final; 119 119 const ast::Stmt * visit( const ast::DeclStmt * ) override final; -
src/AST/Pass.impl.hpp
r1f1c102 rf53acdf8 909 909 // WithStmt 910 910 template< typename pass_t > 911 const ast:: Stmt* ast::Pass< pass_t >::visit( const ast::WithStmt * node ) {911 const ast::Decl * ast::Pass< pass_t >::visit( const ast::WithStmt * node ) { 912 912 VISIT_START( node ); 913 913 -
src/AST/Print.cpp
r1f1c102 rf53acdf8 37 37 } 38 38 39 class Printer : public Visitor {39 class Printer final : public Visitor { 40 40 public: 41 41 ostream & os; … … 272 272 273 273 public: 274 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {274 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final { 275 275 if ( ! node->name.empty() ) os << node->name << ": "; 276 276 … … 314 314 } 315 315 316 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {316 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final { 317 317 if ( !node->name.empty() ) os << node->name << ": "; 318 318 … … 342 342 } 343 343 344 virtual const ast::Decl * visit( const ast::StructDecl * node ) {344 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final { 345 345 print(node); 346 346 return node; 347 347 } 348 348 349 virtual const ast::Decl * visit( const ast::UnionDecl * node ) {349 virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final { 350 350 print(node); 351 351 return node; 352 352 } 353 353 354 virtual const ast::Decl * visit( const ast::EnumDecl * node ) {354 virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final { 355 355 print(node); 356 356 return node; 357 357 } 358 358 359 virtual const ast::Decl * visit( const ast::TraitDecl * node ) {359 virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final { 360 360 print(node); 361 361 return node; 362 362 } 363 363 364 virtual const ast::Decl * visit( const ast::TypeDecl * node ) {364 virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final { 365 365 preprint( node ); 366 366 if ( ! short_mode && node->init ) { … … 374 374 } 375 375 376 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {377 preprint( node ); 378 return node; 379 } 380 381 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {376 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final { 377 preprint( node ); 378 return node; 379 } 380 381 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final { 382 382 safe_print( node->stmt ); 383 383 return node; 384 384 } 385 385 386 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {386 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final { 387 387 os << "Static Assert with condition: "; 388 388 ++indent; … … 396 396 } 397 397 398 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {398 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final { 399 399 os << "Compound Statement:" << endl; 400 400 ++indent; … … 404 404 } 405 405 406 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {406 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final { 407 407 ++indent; 408 408 os << "Expression Statement:" << endl << indent; … … 412 412 } 413 413 414 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {414 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final { 415 415 os << "Assembler Statement:" << endl; 416 416 ++indent; … … 433 433 } 434 434 435 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {435 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final { 436 436 os << "GCC Directive: " << node->directive << endl; 437 437 return node; 438 438 } 439 439 440 virtual const ast::Stmt * visit( const ast::IfStmt * node ) {440 virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final { 441 441 os << "If on condition:" << endl; 442 442 ++indent; … … 473 473 } 474 474 475 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {475 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) override final { 476 476 if ( node->isDoWhile ) { os << "Do-"; } 477 477 os << "While on condition:" << endl; … … 490 490 } 491 491 492 virtual const ast::Stmt * visit( const ast::ForStmt * node ) {492 virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final { 493 493 os << "For Statement" << endl; 494 494 … … 532 532 } 533 533 534 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {534 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final { 535 535 os << "Switch on condition: "; 536 536 safe_print( node->cond ); … … 546 546 } 547 547 548 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {548 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) override final { 549 549 if ( node->isDefault() ) { 550 550 os << indent << "Default "; … … 565 565 } 566 566 567 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {567 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final { 568 568 os << "Branch (" << node->kindName() << ")" << endl; 569 569 ++indent; … … 586 586 } 587 587 588 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {588 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final { 589 589 os << "Return Statement, returning"; 590 590 if ( node->expr ) { … … 601 601 } 602 602 603 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {603 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final { 604 604 if ( node->target ) os << "Non-Local "; 605 605 … … 621 621 } 622 622 623 virtual const ast::Stmt * visit( const ast::TryStmt * node ) {623 virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final { 624 624 ++indent; 625 625 os << "Try Statement" << endl << indent-1 … … 642 642 } 643 643 644 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {644 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) override final { 645 645 os << "Catch "; 646 646 switch ( node->kind ) { … … 667 667 } 668 668 669 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {669 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) override final { 670 670 os << "Finally Statement" << endl; 671 671 os << indent << "... with block:" << endl; … … 678 678 } 679 679 680 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {680 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final { 681 681 os << "Waitfor Statement" << endl; 682 682 indent += 2; … … 732 732 } 733 733 734 virtual const ast:: Stmt * visit( const ast::WithStmt * node ){734 virtual const ast::Decl * visit( const ast::WithStmt * node ) override final { 735 735 os << "With statement" << endl; 736 736 os << indent << "... with expressions:" << endl; … … 744 744 } 745 745 746 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {746 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final { 747 747 os << "Null Statement" << endl; 748 748 print( node->labels ); … … 751 751 } 752 752 753 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {753 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final { 754 754 os << "Declaration of "; 755 755 safe_print( node->decl ); … … 758 758 } 759 759 760 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {760 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final { 761 761 os << "Implicit Ctor Dtor Statement" << endl; 762 762 os << indent << "... with Ctor/Dtor: "; … … 769 769 } 770 770 771 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {771 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final { 772 772 ++indent; 773 773 os << "Application of" << endl << indent; … … 784 784 } 785 785 786 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {786 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final { 787 787 ++indent; 788 788 os << "Applying untyped:" << endl; … … 797 797 } 798 798 799 virtual const ast::Expr * visit( const ast::NameExpr * node ) {799 virtual const ast::Expr * visit( const ast::NameExpr * node ) override final { 800 800 os << "Name: " << node->name; 801 801 postprint( node ); … … 804 804 } 805 805 806 virtual const ast::Expr * visit( const ast::AddressExpr * node ) {806 virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final { 807 807 os << "Address of:" << endl; 808 808 ++indent; … … 815 815 } 816 816 817 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {817 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final { 818 818 os << "Address of label:" << node->arg; 819 819 … … 821 821 } 822 822 823 virtual const ast::Expr * visit( const ast::CastExpr * node ) {823 virtual const ast::Expr * visit( const ast::CastExpr * node ) override final { 824 824 ++indent; 825 825 os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent; … … 841 841 } 842 842 843 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {843 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final { 844 844 ++indent; 845 845 os << "Keyword Cast of:" << endl << indent; … … 852 852 } 853 853 854 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {854 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final { 855 855 ++indent; 856 856 os << "Virtual Cast of:" << endl << indent; … … 869 869 } 870 870 871 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {871 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final { 872 872 ++indent; 873 873 os << "Untyped Member Expression, with field: " << endl << indent; … … 881 881 } 882 882 883 virtual const ast::Expr * visit( const ast::MemberExpr * node ) {883 virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final { 884 884 ++indent; 885 885 os << "Member Expression, with field:" << endl << indent; … … 893 893 } 894 894 895 virtual const ast::Expr * visit( const ast::VariableExpr * node ) {895 virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final { 896 896 os << "Variable Expression: "; 897 897 short_print( node->var ); … … 901 901 } 902 902 903 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {903 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final { 904 904 os << "Constant Expression (" << node->rep; 905 905 if ( node->result ) { … … 913 913 } 914 914 915 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {915 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final { 916 916 os << "Sizeof Expression on: "; 917 917 ++indent; … … 924 924 } 925 925 926 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {926 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final { 927 927 os << "Alignof Expression on: "; 928 928 ++indent; … … 935 935 } 936 936 937 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {937 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final { 938 938 os << "Untyped Offsetof Expression on member " << node->member << " of "; 939 939 ++indent; … … 945 945 } 946 946 947 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {947 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final { 948 948 os << "Offsetof Expression on member " << node->member->name << " of "; 949 949 ++indent; … … 955 955 } 956 956 957 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {957 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final { 958 958 os << "Offset Pack Expression on: "; 959 959 ++indent; … … 965 965 } 966 966 967 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {967 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final { 968 968 os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: "; 969 969 safe_print( node->arg1 ); … … 975 975 } 976 976 977 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {977 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final { 978 978 ++indent; 979 979 os << "Conditional expression on:" << endl << indent; … … 989 989 } 990 990 991 virtual const ast::Expr * visit( const ast::CommaExpr * node ) {991 virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final { 992 992 ++indent; 993 993 os << "Comma Expression:" << endl << indent; … … 1001 1001 } 1002 1002 1003 virtual const ast::Expr * visit( const ast::TypeExpr * node ) {1003 virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final { 1004 1004 safe_print( node->type ); 1005 1005 postprint( node ); … … 1008 1008 } 1009 1009 1010 virtual const ast::Expr * visit( const ast::AsmExpr * node ) {1010 virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final { 1011 1011 os << "Asm Expression:" << endl; 1012 1012 ++indent; … … 1019 1019 } 1020 1020 1021 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {1021 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final { 1022 1022 ++indent; 1023 1023 os << "Implicit Copy Constructor Expression:" << endl << indent; … … 1029 1029 } 1030 1030 1031 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {1031 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final { 1032 1032 os << "Constructor Expression:" << endl << indent+1; 1033 1033 indent += 2; … … 1039 1039 } 1040 1040 1041 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {1041 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final { 1042 1042 ++indent; 1043 1043 os << "Compound Literal Expression: " << endl << indent; … … 1051 1051 } 1052 1052 1053 virtual const ast::Expr * visit( const ast::RangeExpr * node ) {1053 virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final { 1054 1054 os << "Range Expression: "; 1055 1055 safe_print( node->low ); … … 1061 1061 } 1062 1062 1063 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {1063 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final { 1064 1064 os << "Untyped Tuple:" << endl; 1065 1065 ++indent; … … 1071 1071 } 1072 1072 1073 virtual const ast::Expr * visit( const ast::TupleExpr * node ) {1073 virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final { 1074 1074 os << "Tuple:" << endl; 1075 1075 ++indent; … … 1081 1081 } 1082 1082 1083 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {1083 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final { 1084 1084 os << "Tuple Index Expression, with tuple:" << endl; 1085 1085 ++indent; … … 1093 1093 } 1094 1094 1095 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {1095 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final { 1096 1096 os << "Tuple Assignment Expression, with stmt expr:" << endl; 1097 1097 ++indent; … … 1104 1104 } 1105 1105 1106 virtual const ast::Expr * visit( const ast::StmtExpr * node ) {1106 virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final { 1107 1107 ++indent; 1108 1108 os << "Statement Expression:" << endl << indent; … … 1122 1122 } 1123 1123 1124 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {1124 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final { 1125 1125 ++indent; 1126 1126 os << "Unique Expression with id: " << node->id << endl << indent; … … 1136 1136 } 1137 1137 1138 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {1138 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final { 1139 1139 ++indent; 1140 1140 os << "Untyped Init Expression" << endl << indent; … … 1152 1152 } 1153 1153 1154 virtual const ast::Expr * visit( const ast::InitExpr * node ) {1154 virtual const ast::Expr * visit( const ast::InitExpr * node ) override final { 1155 1155 ++indent; 1156 1156 os << "Init Expression" << endl << indent; … … 1163 1163 } 1164 1164 1165 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {1165 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final { 1166 1166 ++indent; 1167 1167 os << "Deleted Expression" << endl << indent; … … 1174 1174 } 1175 1175 1176 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {1176 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final { 1177 1177 ++indent; 1178 1178 os << "Default Argument Expression" << endl << indent; … … 1183 1183 } 1184 1184 1185 virtual const ast::Expr * visit( const ast::GenericExpr * node ) {1185 virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final { 1186 1186 ++indent; 1187 1187 os << "C11 _Generic Expression" << endl << indent; … … 1206 1206 } 1207 1207 1208 virtual const ast::Type * visit( const ast::VoidType * node ) {1208 virtual const ast::Type * visit( const ast::VoidType * node ) override final { 1209 1209 preprint( node ); 1210 1210 os << "void"; … … 1212 1212 } 1213 1213 1214 virtual const ast::Type * visit( const ast::BasicType * node ) {1214 virtual const ast::Type * visit( const ast::BasicType * node ) override final { 1215 1215 preprint( node ); 1216 1216 os << ast::BasicType::typeNames[ node->kind ]; … … 1218 1218 } 1219 1219 1220 virtual const ast::Type * visit( const ast::PointerType * node ) {1220 virtual const ast::Type * visit( const ast::PointerType * node ) override final { 1221 1221 preprint( node ); 1222 1222 if ( ! node->isArray() ) { … … 1241 1241 } 1242 1242 1243 virtual const ast::Type * visit( const ast::ArrayType * node ) {1243 virtual const ast::Type * visit( const ast::ArrayType * node ) override final { 1244 1244 preprint( node ); 1245 1245 if ( node->isStatic ) { … … 1265 1265 } 1266 1266 1267 virtual const ast::Type * visit( const ast::ReferenceType * node ) {1267 virtual const ast::Type * visit( const ast::ReferenceType * node ) override final { 1268 1268 preprint( node ); 1269 1269 os << "reference to "; … … 1273 1273 } 1274 1274 1275 virtual const ast::Type * visit( const ast::QualifiedType * node ) {1275 virtual const ast::Type * visit( const ast::QualifiedType * node ) override final { 1276 1276 preprint( node ); 1277 1277 ++indent; … … 1286 1286 } 1287 1287 1288 virtual const ast::Type * visit( const ast::FunctionType * node ) {1288 virtual const ast::Type * visit( const ast::FunctionType * node ) override final { 1289 1289 preprint( node ); 1290 1290 … … 1315 1315 } 1316 1316 1317 virtual const ast::Type * visit( const ast::StructInstType * node ) {1317 virtual const ast::Type * visit( const ast::StructInstType * node ) override final { 1318 1318 preprint( node ); 1319 1319 os << "instance of struct " << node->name; … … 1326 1326 } 1327 1327 1328 virtual const ast::Type * visit( const ast::UnionInstType * node ) {1328 virtual const ast::Type * visit( const ast::UnionInstType * node ) override final { 1329 1329 preprint( node ); 1330 1330 os << "instance of union " << node->name; … … 1337 1337 } 1338 1338 1339 virtual const ast::Type * visit( const ast::EnumInstType * node ) {1339 virtual const ast::Type * visit( const ast::EnumInstType * node ) override final { 1340 1340 preprint( node ); 1341 1341 os << "instance of enum " << node->name; … … 1348 1348 } 1349 1349 1350 virtual const ast::Type * visit( const ast::TraitInstType * node ) {1350 virtual const ast::Type * visit( const ast::TraitInstType * node ) override final { 1351 1351 preprint( node ); 1352 1352 os << "instance of trait " << node->name; … … 1356 1356 } 1357 1357 1358 virtual const ast::Type * visit( const ast::TypeInstType * node ) {1358 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final { 1359 1359 preprint( node ); 1360 1360 os << "instance of type " << node->name … … 1365 1365 } 1366 1366 1367 virtual const ast::Type * visit( const ast::TupleType * node ) {1367 virtual const ast::Type * visit( const ast::TupleType * node ) override final { 1368 1368 preprint( node ); 1369 1369 os << "tuple of types" << endl; … … 1375 1375 } 1376 1376 1377 virtual const ast::Type * visit( const ast::TypeofType * node ) {1377 virtual const ast::Type * visit( const ast::TypeofType * node ) override final { 1378 1378 preprint( node ); 1379 1379 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; } … … 1384 1384 } 1385 1385 1386 virtual const ast::Type * visit( const ast::VarArgsType * node ) {1386 virtual const ast::Type * visit( const ast::VarArgsType * node ) override final { 1387 1387 preprint( node ); 1388 1388 os << "builtin var args pack"; … … 1390 1390 } 1391 1391 1392 virtual const ast::Type * visit( const ast::ZeroType * node ) {1392 virtual const ast::Type * visit( const ast::ZeroType * node ) override final { 1393 1393 preprint( node ); 1394 1394 os << "zero_t"; … … 1396 1396 } 1397 1397 1398 virtual const ast::Type * visit( const ast::OneType * node ) {1398 virtual const ast::Type * visit( const ast::OneType * node ) override final { 1399 1399 preprint( node ); 1400 1400 os << "one_t"; … … 1402 1402 } 1403 1403 1404 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {1404 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final { 1405 1405 preprint( node ); 1406 1406 os << "Global Scope Type"; … … 1408 1408 } 1409 1409 1410 virtual const ast::Designation * visit( const ast::Designation * node ) {1410 virtual const ast::Designation * visit( const ast::Designation * node ) override final { 1411 1411 if ( node->designators.empty() ) return node; 1412 1412 os << "... designated by: " << endl; … … 1421 1421 } 1422 1422 1423 virtual const ast::Init * visit( const ast::SingleInit * node ) {1423 virtual const ast::Init * visit( const ast::SingleInit * node ) override final { 1424 1424 os << "Simple Initializer: "; 1425 1425 safe_print( node->value ); … … 1427 1427 } 1428 1428 1429 virtual const ast::Init * visit( const ast::ListInit * node ) {1429 virtual const ast::Init * visit( const ast::ListInit * node ) override final { 1430 1430 os << "Compound initializer: " << endl; 1431 1431 ++indent; … … 1445 1445 } 1446 1446 1447 virtual const ast::Init * visit( const ast::ConstructorInit * node ) {1447 virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final { 1448 1448 os << "Constructor initializer: " << endl; 1449 1449 if ( node->ctor ) { … … 1470 1470 } 1471 1471 1472 virtual const ast::Attribute * visit( const ast::Attribute * node ) {1472 virtual const ast::Attribute * visit( const ast::Attribute * node ) override final { 1473 1473 if ( node->empty() ) return node; 1474 1474 os << "Attribute with name: " << node->name; … … 1481 1481 } 1482 1482 1483 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {1483 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final { 1484 1484 os << indent << "Types:" << endl; 1485 1485 for ( const auto& i : *node ) { -
src/AST/Stmt.hpp
r1f1c102 rf53acdf8 380 380 }; 381 381 382 /// With statement `with (...) ...`383 class WithStmt final : public Stmt {384 public:385 std::vector<ptr<Expr>> exprs;386 ptr<Stmt> stmt;387 388 WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt,389 std::vector<Label> && labels = {} )390 : Stmt(loc, std::move(labels)), exprs(std::move(exprs)), stmt(stmt) {}391 392 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }393 private:394 WithStmt * clone() const override { return new WithStmt{ *this }; }395 MUTATE_FRIEND396 };397 398 382 /// Any declaration in a (compound) statement. 399 383 class DeclStmt final : public Stmt { -
src/AST/SymbolTable.cpp
r1f1c102 rf53acdf8 73 73 74 74 SymbolTable::SymbolTable() 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 76 76 prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; } 77 77 … … 171 171 } 172 172 173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Node* deleter ) {173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) { 174 174 // default handling of conflicts is to raise an error 175 175 addId( decl, OnConflict::error(), nullptr, deleter ); … … 189 189 } 190 190 } 191 // does not need to be added to the table if both existing and added have a base that are 191 // does not need to be added to the table if both existing and added have a base that are 192 192 // the same 193 193 return true; … … 209 209 const std::string &id = decl->name; 210 210 211 if ( ! typeTable ) { 211 if ( ! typeTable ) { 212 212 typeTable = TypeTable::new_ptr(); 213 213 } else { 214 214 ++*stats().map_lookups; 215 215 auto existing = typeTable->find( id ); 216 if ( existing != typeTable->end() 217 && existing->second.scope == scope 216 if ( existing != typeTable->end() 217 && existing->second.scope == scope 218 218 && addedTypeConflicts( existing->second.decl, decl ) ) return; 219 219 } 220 220 221 221 lazyInitScope(); 222 222 ++*stats().map_mutations; … … 237 237 ++*stats().map_lookups; 238 238 auto existing = structTable->find( id ); 239 if ( existing != structTable->end() 240 && existing->second.scope == scope 239 if ( existing != structTable->end() 240 && existing->second.scope == scope 241 241 && addedDeclConflicts( existing->second.decl, decl ) ) return; 242 242 } … … 256 256 ++*stats().map_lookups; 257 257 auto existing = enumTable->find( id ); 258 if ( existing != enumTable->end() 259 && existing->second.scope == scope 258 if ( existing != enumTable->end() 259 && existing->second.scope == scope 260 260 && addedDeclConflicts( existing->second.decl, decl ) ) return; 261 261 } 262 262 263 263 lazyInitScope(); 264 264 ++*stats().map_mutations; … … 279 279 ++*stats().map_lookups; 280 280 auto existing = unionTable->find( id ); 281 if ( existing != unionTable->end() 282 && existing->second.scope == scope 281 if ( existing != unionTable->end() 282 && existing->second.scope == scope 283 283 && addedDeclConflicts( existing->second.decl, decl ) ) return; 284 284 } … … 298 298 ++*stats().map_lookups; 299 299 auto existing = traitTable->find( id ); 300 if ( existing != traitTable->end() 301 && existing->second.scope == scope 300 if ( existing != traitTable->end() 301 && existing->second.scope == scope 302 302 && addedDeclConflicts( existing->second.decl, decl ) ) return; 303 303 } … … 309 309 310 310 311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node* withStmt ) {311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) { 312 312 for ( const Expr * expr : withExprs ) { 313 313 if ( ! expr->result ) continue; 314 314 const Type * resTy = expr->result->stripReferences(); 315 315 auto aggrType = dynamic_cast< const ReferenceToType * >( resTy ); 316 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 316 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 317 317 toString( expr->result ).c_str() ); 318 318 const AggregateDecl * aggr = aggrType->aggr(); 319 assertf( aggr, "WithStmt has null aggregate from type: %s", 319 assertf( aggr, "WithStmt has null aggregate from type: %s", 320 320 toString( expr->result ).c_str() ); 321 321 322 322 addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) ); 323 323 } … … 373 373 } 374 374 375 /// gets the declaration for the function acting on a type specified by otype key, 375 /// gets the declaration for the function acting on a type specified by otype key, 376 376 /// nullptr if none such 377 const FunctionDecl * getFunctionForOtype( 377 const FunctionDecl * getFunctionForOtype( 378 378 const DeclWithType * decl, const std::string & otypeKey ) { 379 379 auto func = dynamic_cast< const FunctionDecl * >( decl ); … … 383 383 } 384 384 385 bool SymbolTable::removeSpecialOverrides( 385 bool SymbolTable::removeSpecialOverrides( 386 386 SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) { 387 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 388 // determine the set of ctor/dtor/assign that can be used by the requester. In particular, 389 // if the user defines a default ctor, then the generated default ctor is unavailable, 390 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 391 // field ctors are available. If the user defines any ctor then the generated default ctor 392 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 393 // anything that looks like a copy constructor, then the generated copy constructor is 387 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 388 // determine the set of ctor/dtor/assign that can be used by the requester. In particular, 389 // if the user defines a default ctor, then the generated default ctor is unavailable, 390 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 391 // field ctors are available. If the user defines any ctor then the generated default ctor 392 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 393 // anything that looks like a copy constructor, then the generated copy constructor is 394 394 // unavailable, and likewise for the assignment operator. 395 395 … … 450 450 // if this is the first user-defined function, delete non-user-defined overloads 451 451 std::vector< MangleTable::value_type > deleted; 452 452 453 453 for ( const auto& entry : *mangleTable ) { 454 454 // skip decls that aren't functions or are for the wrong type … … 489 489 if ( dataIsCopyFunc ) { 490 490 // remove current function if exists a user-defined copy function 491 // since the signatures for copy functions don't need to match exactly, using 491 // since the signatures for copy functions don't need to match exactly, using 492 492 // a delete statement is the wrong approach 493 493 if ( InitTweak::isCopyFunction( decl ) ) return false; … … 499 499 } 500 500 } 501 501 502 502 // nothing (more) to fix, return true 503 503 return true; … … 525 525 526 526 bool SymbolTable::addedIdConflicts( 527 const SymbolTable::IdData & existing, const DeclWithType * added, 528 SymbolTable::OnConflict handleConflicts, const Node* deleter ) {529 // if we're giving the same name mangling to things of different types then there is something 527 const SymbolTable::IdData & existing, const DeclWithType * added, 528 SymbolTable::OnConflict handleConflicts, const Decl * deleter ) { 529 // if we're giving the same name mangling to things of different types then there is something 530 530 // wrong 531 531 assert( (isObject( added ) && isObject( existing.id ) ) 532 532 || ( isFunction( added ) && isFunction( existing.id ) ) ); 533 533 534 534 if ( existing.id->linkage.is_overrideable ) { 535 535 // new definition shadows the autogenerated one, even at the same scope 536 536 return false; 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 539 539 added->get_type(), existing.id->get_type(), SymbolTable{} ) ) { 540 540 541 541 // it is a conflict if one declaration is deleted and the other is not 542 542 if ( deleter && ! existing.deleter ) { … … 555 555 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 556 556 if ( handleConflicts.mode == OnConflict::Error ) { 557 SemanticError( added, 558 isFunction( added ) ? 559 "duplicate function definition for " : 557 SemanticError( added, 558 isFunction( added ) ? 559 "duplicate function definition for " : 560 560 "duplicate object definition for " ); 561 561 } … … 572 572 } 573 573 574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Node* deleter ) {574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Decl * deleter ) { 577 577 ++*stats().add_calls; 578 578 const std::string &name = decl->name; … … 581 581 std::string mangleName; 582 582 if ( decl->linkage.is_overrideable ) { 583 // mangle the name without including the appropriate suffix, so overridable routines 583 // mangle the name without including the appropriate suffix, so overridable routines 584 584 // are placed into the same "bucket" as their user defined versions. 585 585 mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } ); … … 588 588 } 589 589 590 // this ensures that no two declarations with the same unmangled name at the same scope 590 // this ensures that no two declarations with the same unmangled name at the same scope 591 591 // both have C linkage 592 592 if ( decl->linkage.is_mangled ) { … … 596 596 } 597 597 } else { 598 // NOTE: only correct if name mangling is completely isomorphic to C 598 // NOTE: only correct if name mangling is completely isomorphic to C 599 599 // type-compatibility, which it may not be. 600 600 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 628 628 idTable = idTable->set( 629 629 name, 630 mangleTable->set( 631 mangleName, 630 mangleTable->set( 631 mangleName, 632 632 IdData{ existing->second, handleConflicts.deleter } ) ); 633 633 } … … 647 647 } 648 648 649 void SymbolTable::addMembers( 649 void SymbolTable::addMembers( 650 650 const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) { 651 651 for ( const Decl * decl : aggr->members ) { … … 655 655 const Type * t = dwt->get_type()->stripReferences(); 656 656 if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) { 657 if ( ! dynamic_cast<const StructInstType *>(rty) 657 if ( ! dynamic_cast<const StructInstType *>(rty) 658 658 && ! dynamic_cast<const UnionInstType *>(rty) ) continue; 659 659 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; 660 660 const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost ); 661 addMembers( 661 addMembers( 662 662 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts ); 663 663 } … … 680 680 if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true; 681 681 } 682 682 683 683 return false; 684 684 } -
src/AST/SymbolTable.hpp
r1f1c102 rf53acdf8 37 37 readonly<DeclWithType> id = nullptr; ///< Identifier of declaration 38 38 readonly<Expr> baseExpr = nullptr; ///< Implied containing aggregate (from WithExpr) 39 readonly< Node> deleter = nullptr; ///< Node deleting this declaration (if non-null)39 readonly<Decl> deleter = nullptr; ///< Node deleting this declaration (if non-null) 40 40 unsigned long scope = 0; ///< Scope of identifier 41 41 42 42 IdData() = default; 43 IdData( const DeclWithType * i, const Expr * base, const Node * del, unsigned long s )43 IdData( const DeclWithType * i, const Expr * base, const Decl * del, unsigned long s ) 44 44 : id( i ), baseExpr( base ), deleter( del ), scope( s ) {} 45 45 46 46 /// Modify an existing node with a new deleter 47 IdData( const IdData & o, const Node* del )47 IdData( const IdData & o, const Decl * del ) 48 48 : id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {} 49 49 … … 58 58 struct scoped { 59 59 readonly<D> decl; ///< wrapped declaration 60 unsigned long scope; ///< scope of this declaration 60 unsigned long scope; ///< scope of this declaration 61 61 62 62 scoped(const D * d, unsigned long s) : decl(d), scope(s) {} … … 88 88 ~SymbolTable(); 89 89 90 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 90 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 91 91 // tell the indexer explicitly when scopes begin and end 92 92 void enterScope(); … … 118 118 void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr ); 119 119 /// Adds a deleted identifier declaration to the symbol table 120 void addDeletedId( const DeclWithType * decl, const Node* deleter );120 void addDeletedId( const DeclWithType * decl, const Decl * deleter ); 121 121 122 122 /// Adds a type to the symbol table … … 136 136 137 137 /// adds all of the IDs from WithStmt exprs 138 void addWith( const std::vector< ptr<Expr> > & withExprs, const Node* withStmt );138 void addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ); 139 139 140 140 /// convenience function for adding a list of Ids to the indexer … … 154 154 const SymbolTable * atScope( unsigned long i ) const; 155 155 156 /// Removes matching autogenerated constructors and destructors so that they will not be 156 /// Removes matching autogenerated constructors and destructors so that they will not be 157 157 /// selected. If returns false, passed decl should not be added. 158 158 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); … … 164 164 Delete ///< Delete the earlier version with the delete statement 165 165 } mode; 166 const Node* deleter; ///< Statement that deletes this expression166 const Decl * deleter; ///< Statement that deletes this expression 167 167 168 168 private: 169 169 OnConflict() : mode(Error), deleter(nullptr) {} 170 OnConflict( const Node* d ) : mode(Delete), deleter(d) {}170 OnConflict( const Decl * d ) : mode(Delete), deleter(d) {} 171 171 public: 172 172 OnConflict( const OnConflict& ) = default; 173 173 174 174 static OnConflict error() { return {}; } 175 static OnConflict deleteWith( const Node* d ) { return { d }; }175 static OnConflict deleteWith( const Decl * d ) { return { d }; } 176 176 }; 177 177 178 178 /// true if the existing identifier conflicts with the added identifier 179 179 bool addedIdConflicts( 180 const IdData & existing, const DeclWithType * added, OnConflict handleConflicts, 181 const Node* deleter );180 const IdData & existing, const DeclWithType * added, OnConflict handleConflicts, 181 const Decl * deleter ); 182 182 183 183 /// common code for addId, addDeletedId, etc. 184 void addId( 185 const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 186 const Node* deleter = nullptr );184 void addId( 185 const DeclWithType * decl, OnConflict handleConflicts, const Expr * baseExpr = nullptr, 186 const Decl * deleter = nullptr ); 187 187 188 188 /// adds all of the members of the Aggregate (addWith helper) -
src/AST/Type.hpp
r1f1c102 rf53acdf8 35 35 36 36 template< typename T > class Pass; 37 class ForallSubstitutor; 37 38 struct ForallSubstitutor; 38 39 39 40 class Type : public Node { … … 167 168 static const char *typeNames[]; 168 169 169 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 170 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 170 171 : Type(q, std::move(as)), kind(k) {} 171 172 … … 274 275 public: 275 276 using ForallList = std::vector<ptr<TypeDecl>>; 276 277 277 278 ForallList forall; 278 279 … … 338 339 bool hoistType = false; 339 340 340 ReferenceToType( 341 ReferenceToType( 341 342 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 342 343 : ParameterizedType(q, std::move(as)), params(), name(n) {} … … 359 360 readonly<StructDecl> base; 360 361 361 StructInstType( 362 StructInstType( 362 363 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 363 364 : ReferenceToType( n, q, std::move(as) ), base() {} 364 365 365 StructInstType( 366 StructInstType( 366 367 const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 367 368 … … 381 382 readonly<UnionDecl> base; 382 383 383 UnionInstType( 384 UnionInstType( 384 385 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 385 386 : ReferenceToType( n, q, std::move(as) ), base() {} 386 387 387 UnionInstType( 388 UnionInstType( 388 389 const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 389 390 … … 403 404 readonly<EnumDecl> base; 404 405 405 EnumInstType( 406 EnumInstType( 406 407 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 407 408 : ReferenceToType( n, q, std::move(as) ), base() {} 408 409 409 EnumInstType( 410 EnumInstType( 410 411 const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 411 412 … … 425 426 readonly<TraitDecl> base; 426 427 427 TraitInstType( 428 TraitInstType( 428 429 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 429 430 : ReferenceToType( n, q, std::move(as) ), base() {} 430 431 TraitInstType( 431 432 TraitInstType( 432 433 const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 433 434 … … 449 450 TypeVar::Kind kind; 450 451 451 TypeInstType( 452 TypeInstType( 452 453 const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 453 454 std::vector<ptr<Attribute>> && as = {} ) 454 455 : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {} 455 456 TypeInstType( 456 457 TypeInstType( 457 458 const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 458 459 std::vector<ptr<Attribute>> && as = {} ) -
src/AST/Visitor.hpp
r1f1c102 rf53acdf8 48 48 virtual const ast::Stmt * visit( const ast::FinallyStmt * ) = 0; 49 49 virtual const ast::Stmt * visit( const ast::WaitForStmt * ) = 0; 50 virtual const ast:: Stmt* visit( const ast::WithStmt * ) = 0;50 virtual const ast::Decl * visit( const ast::WithStmt * ) = 0; 51 51 virtual const ast::NullStmt * visit( const ast::NullStmt * ) = 0; 52 52 virtual const ast::Stmt * visit( const ast::DeclStmt * ) = 0; -
src/Common/PassVisitor.h
r1f1c102 rf53acdf8 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; … … 186 279 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 187 280 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 188 virtual Statement* mutate( WithStmt * withStmt ) override final;281 virtual Declaration * mutate( WithStmt * withStmt ) override final; 189 282 virtual NullStmt * mutate( NullStmt * nullStmt ) override final; 190 283 virtual Statement * mutate( DeclStmt * declStmt ) 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 … … 309 410 void indexerScopeEnter () { indexer_impl_enterScope ( pass, 0 ); } 310 411 void indexerScopeLeave () { indexer_impl_leaveScope ( pass, 0 ); } 311 void indexerAddId ( DeclarationWithType* node ) { indexer_impl_addId ( pass, 0, node ); }312 void indexerAddType ( NamedTypeDecl* node ) { indexer_impl_addType ( pass, 0, node ); }412 void indexerAddId ( const DeclarationWithType * node ) { indexer_impl_addId ( pass, 0, node ); } 413 void indexerAddType ( const NamedTypeDecl * node ) { indexer_impl_addType ( pass, 0, node ); } 313 414 void indexerAddStruct ( const std::string & id ) { indexer_impl_addStruct ( pass, 0, id ); } 314 void indexerAddStruct ( StructDecl* node ) { indexer_impl_addStruct ( pass, 0, node ); }315 void indexerAddStructFwd( StructDecl* node ) { indexer_impl_addStructFwd( pass, 0, node ); }316 void indexerAddEnum ( EnumDecl* node ) { indexer_impl_addEnum ( pass, 0, node ); }415 void indexerAddStruct ( const StructDecl * node ) { indexer_impl_addStruct ( pass, 0, node ); } 416 void indexerAddStructFwd( const StructDecl * node ) { indexer_impl_addStructFwd( pass, 0, node ); } 417 void indexerAddEnum ( const EnumDecl * node ) { indexer_impl_addEnum ( pass, 0, node ); } 317 418 void indexerAddUnion ( const std::string & id ) { indexer_impl_addUnion ( pass, 0, id ); } 318 void indexerAddUnion ( UnionDecl* node ) { indexer_impl_addUnion ( pass, 0, node ); }319 void indexerAddUnionFwd ( UnionDecl* node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }320 void indexerAddTrait ( TraitDecl* node ) { indexer_impl_addTrait ( pass, 0, node ); }321 void indexerAddWith ( std::list< Expression * > & exprs, BaseSyntaxNode* withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }419 void indexerAddUnion ( const UnionDecl * node ) { indexer_impl_addUnion ( pass, 0, node ); } 420 void indexerAddUnionFwd ( const UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 421 void indexerAddTrait ( const TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 422 void indexerAddWith ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); } 322 423 323 424 324 425 template< typename TreeType, typename VisitorType > 325 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );426 friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ); 326 427 327 428 template< typename TreeType, typename VisitorType > 328 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor ); 429 friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ); 430 431 template< typename TreeType, typename VisitorType > 432 friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor ); 329 433 }; 330 434 -
src/Common/PassVisitor.impl.h
r1f1c102 rf53acdf8 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 indexerAddId( node ); 551 552 maybeAccept_impl( node->withExprs, *this ); 553 { 554 // with clause introduces a level of scope (for the with expression members). 555 // with clause exprs are added to the indexer before parameters so that parameters 556 // shadow with exprs and not the other way around. 557 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 558 indexerAddWith( node->withExprs, node ); 559 { 560 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 561 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 562 static ObjectDecl func( 563 "__func__", noStorageClasses, LinkageSpec::C, nullptr, 564 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ), 565 nullptr 566 ); 567 indexerAddId( &func ); 568 maybeAccept_impl( node->type, *this ); 569 // function body needs to have the same scope as parameters - CompoundStmt will not enter 570 // a new scope if inFunction is true 571 ValueGuard< bool > oldInFunction( inFunction ); 572 inFunction = true; 573 maybeAccept_impl( node->statements, *this ); 574 maybeAccept_impl( node->attributes, *this ); 575 } 576 } 577 578 VISIT_END( node ); 579 } 580 581 template< typename pass_type > 430 582 DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) { 431 583 MUTATE_START( node ); … … 484 636 485 637 template< typename pass_type > 486 Declaration * PassVisitor< pass_type >::mutate(StructDecl * node ) {487 MUTATE_START( node );638 void PassVisitor< pass_type >::visit( const StructDecl * node ) { 639 VISIT_START( node ); 488 640 489 641 // make up a forward declaration and add it before processing the members … … 493 645 { 494 646 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 647 maybeAccept_impl( node->parameters, *this ); 648 maybeAccept_impl( node->members , *this ); 649 } 650 651 // this addition replaces the forward declaration 652 indexerAddStruct( node ); 653 654 VISIT_END( node ); 655 } 656 657 template< typename pass_type > 658 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { 659 MUTATE_START( node ); 660 661 // make up a forward declaration and add it before processing the members 662 // needs to be on the heap because addStruct saves the pointer 663 indexerAddStructFwd( node ); 664 665 { 666 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 495 667 maybeMutate_impl( node->parameters, *this ); 496 668 maybeMutate_impl( node->members , *this ); … … 522 694 VISIT_END( node ); 523 695 } 696 template< typename pass_type > 697 void PassVisitor< pass_type >::visit( const UnionDecl * node ) { 698 VISIT_START( node ); 699 700 // make up a forward declaration and add it before processing the members 701 indexerAddUnionFwd( node ); 702 703 { 704 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 705 maybeAccept_impl( node->parameters, *this ); 706 maybeAccept_impl( node->members , *this ); 707 } 708 709 indexerAddUnion( node ); 710 711 VISIT_END( node ); 712 } 524 713 525 714 template< typename pass_type > … … 557 746 558 747 template< typename pass_type > 748 void PassVisitor< pass_type >::visit( const EnumDecl * node ) { 749 VISIT_START( node ); 750 751 indexerAddEnum( node ); 752 753 // unlike structs, traits, and unions, enums inject their members into the global scope 754 maybeAccept_impl( node->parameters, *this ); 755 maybeAccept_impl( node->members , *this ); 756 757 VISIT_END( node ); 758 } 759 760 template< typename pass_type > 559 761 Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) { 560 762 MUTATE_START( node ); … … 573 775 template< typename pass_type > 574 776 void PassVisitor< pass_type >::visit( TraitDecl * node ) { 777 VISIT_START( node ); 778 779 { 780 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 781 maybeAccept_impl( node->parameters, *this ); 782 maybeAccept_impl( node->members , *this ); 783 } 784 785 indexerAddTrait( node ); 786 787 VISIT_END( node ); 788 } 789 790 template< typename pass_type > 791 void PassVisitor< pass_type >::visit( const TraitDecl * node ) { 575 792 VISIT_START( node ); 576 793 … … 625 842 } 626 843 627 template< typename pass_type > 628 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 629 MUTATE_START( node ); 844 845 template< typename pass_type > 846 void PassVisitor< pass_type >::visit( const TypeDecl * node ) { 847 VISIT_START( node ); 630 848 631 849 { 632 850 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 633 maybe Mutate_impl( node->parameters, *this );634 maybe Mutate_impl( node->base , *this );851 maybeAccept_impl( node->parameters, *this ); 852 maybeAccept_impl( node->base , *this ); 635 853 } 636 854 … … 640 858 indexerAddType( node ); 641 859 860 maybeAccept_impl( node->assertions, *this ); 861 862 indexerScopedAccept( node->init, *this ); 863 864 VISIT_END( node ); 865 } 866 867 template< typename pass_type > 868 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 869 MUTATE_START( node ); 870 871 { 872 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 873 maybeMutate_impl( node->parameters, *this ); 874 maybeMutate_impl( node->base , *this ); 875 } 876 877 // see A NOTE ON THE ORDER OF TRAVERSAL, above 878 // note that assertions come after the type is added to the symtab, since they are not part of the type proper 879 // and may depend on the type itself 880 indexerAddType( node ); 881 642 882 maybeMutate_impl( node->assertions, *this ); 643 883 … … 667 907 668 908 template< typename pass_type > 909 void PassVisitor< pass_type >::visit( const TypedefDecl * node ) { 910 VISIT_START( node ); 911 912 { 913 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 914 maybeAccept_impl( node->parameters, *this ); 915 maybeAccept_impl( node->base , *this ); 916 } 917 918 indexerAddType( node ); 919 920 maybeAccept_impl( node->assertions, *this ); 921 922 VISIT_END( node ); 923 } 924 925 template< typename pass_type > 669 926 Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) { 670 927 MUTATE_START( node ); … … 695 952 696 953 template< typename pass_type > 954 void PassVisitor< pass_type >::visit( const AsmDecl * node ) { 955 VISIT_START( node ); 956 957 maybeAccept_impl( node->stmt, *this ); 958 959 VISIT_END( node ); 960 } 961 962 template< typename pass_type > 697 963 AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) { 698 964 MUTATE_START( node ); … … 710 976 711 977 node->condition = visitExpression( node->condition ); 978 maybeAccept_impl( node->message, *this ); 979 980 VISIT_END( node ); 981 } 982 983 template< typename pass_type > 984 void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) { 985 VISIT_START( node ); 986 987 visitExpression( node->condition ); 712 988 maybeAccept_impl( node->message, *this ); 713 989 … … 742 1018 743 1019 template< typename pass_type > 1020 void PassVisitor< pass_type >::visit( const CompoundStmt * node ) { 1021 VISIT_START( node ); 1022 { 1023 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 1024 ValueGuard< bool > oldInFunction( inFunction ); 1025 auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } ); 1026 auto guard2 = makeFuncGuard( [this]() { call_beginScope(); }, [this]() { call_endScope(); } ); 1027 inFunction = false; 1028 visitStatementList( node->kids ); 1029 } 1030 VISIT_END( node ); 1031 } 1032 1033 template< typename pass_type > 744 1034 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { 745 1035 MUTATE_START( node ); … … 767 1057 768 1058 template< typename pass_type > 1059 void PassVisitor< pass_type >::visit( const ExprStmt * node ) { 1060 VISIT_START( node ); 1061 1062 visitExpression( node->expr ); 1063 1064 VISIT_END( node ); 1065 } 1066 1067 template< typename pass_type > 769 1068 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) { 770 1069 MUTATE_START( node ); … … 790 1089 791 1090 template< typename pass_type > 1091 void PassVisitor< pass_type >::visit( const AsmStmt * node ) { 1092 VISIT_START( node ) 1093 1094 maybeAccept_impl( node->instruction, *this ); 1095 maybeAccept_impl( node->output, *this ); 1096 maybeAccept_impl( node->input, *this ); 1097 maybeAccept_impl( node->clobber, *this ); 1098 1099 VISIT_END( node ); 1100 } 1101 1102 template< typename pass_type > 792 1103 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { 793 1104 MUTATE_START( node ); … … 811 1122 812 1123 template< typename pass_type > 1124 void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) { 1125 VISIT_START( node ) 1126 1127 VISIT_END( node ); 1128 } 1129 1130 template< typename pass_type > 813 1131 Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) { 814 1132 MUTATE_START( node ); … … 825 1143 // if statements introduce a level of scope (for the initialization) 826 1144 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 827 maybeAccept_impl( node-> get_initialization(), *this );1145 maybeAccept_impl( node->initialization, *this ); 828 1146 visitExpression ( node->condition ); 829 1147 node->thenPart = visitStatement( node->thenPart ); … … 834 1152 835 1153 template< typename pass_type > 836 Statement * PassVisitor< pass_type >::mutate(IfStmt * node ) {837 MUTATE_START( node );1154 void PassVisitor< pass_type >::visit( const IfStmt * node ) { 1155 VISIT_START( node ); 838 1156 { 839 1157 // if statements introduce a level of scope (for the initialization) 840 1158 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 841 maybeMutate_impl( node->get_initialization(), *this ); 1159 maybeAccept_impl( node->initialization, *this ); 1160 visitExpression ( node->condition ); 1161 visitStatement ( node->thenPart ); 1162 visitStatement ( node->elsePart ); 1163 } 1164 VISIT_END( node ); 1165 } 1166 1167 template< typename pass_type > 1168 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { 1169 MUTATE_START( node ); 1170 { 1171 // if statements introduce a level of scope (for the initialization) 1172 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1173 maybeMutate_impl( node->initialization, *this ); 842 1174 node->condition = mutateExpression( node->condition ); 843 1175 node->thenPart = mutateStatement ( node->thenPart ); … … 859 1191 visitExpression ( node->condition ); 860 1192 node->body = visitStatement( node->body ); 1193 } 1194 1195 VISIT_END( node ); 1196 } 1197 1198 template< typename pass_type > 1199 void PassVisitor< pass_type >::visit( const WhileStmt * node ) { 1200 VISIT_START( node ); 1201 1202 { 1203 // while statements introduce a level of scope (for the initialization) 1204 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1205 maybeAccept_impl( node->initialization, *this ); 1206 visitExpression ( node->condition ); 1207 visitStatement ( node->body ); 861 1208 } 862 1209 … … 897 1244 898 1245 template< typename pass_type > 1246 void PassVisitor< pass_type >::visit( const ForStmt * node ) { 1247 VISIT_START( node ); 1248 { 1249 // for statements introduce a level of scope (for the initialization) 1250 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1251 maybeAccept_impl( node->initialization, *this ); 1252 visitExpression( node->condition ); 1253 visitExpression( node->increment ); 1254 visitStatement ( node->body ); 1255 } 1256 VISIT_END( node ); 1257 } 1258 1259 template< typename pass_type > 899 1260 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { 900 1261 MUTATE_START( node ); … … 923 1284 924 1285 template< typename pass_type > 1286 void PassVisitor< pass_type >::visit( const SwitchStmt * node ) { 1287 VISIT_START( node ); 1288 1289 visitExpression ( node->condition ); 1290 visitStatementList( node->statements ); 1291 1292 VISIT_END( node ); 1293 } 1294 1295 template< typename pass_type > 925 1296 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { 926 1297 MUTATE_START( node ); … … 945 1316 946 1317 template< typename pass_type > 1318 void PassVisitor< pass_type >::visit( const CaseStmt * node ) { 1319 VISIT_START( node ); 1320 1321 visitExpression ( node->condition ); 1322 visitStatementList( node->stmts ); 1323 1324 VISIT_END( node ); 1325 } 1326 1327 template< typename pass_type > 947 1328 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { 948 1329 MUTATE_START( node ); … … 963 1344 964 1345 template< typename pass_type > 1346 void PassVisitor< pass_type >::visit( const BranchStmt * node ) { 1347 VISIT_START( node ); 1348 VISIT_END( node ); 1349 } 1350 1351 template< typename pass_type > 965 1352 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { 966 1353 MUTATE_START( node ); … … 980 1367 981 1368 template< typename pass_type > 1369 void PassVisitor< pass_type >::visit( const ReturnStmt * node ) { 1370 VISIT_START( node ); 1371 1372 visitExpression( node->expr ); 1373 1374 VISIT_END( node ); 1375 } 1376 1377 template< typename pass_type > 982 1378 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { 983 1379 MUTATE_START( node ); … … 990 1386 //-------------------------------------------------------------------------- 991 1387 // ThrowStmt 992 993 1388 template< typename pass_type > 994 1389 void PassVisitor< pass_type >::visit( ThrowStmt * node ) { … … 1002 1397 1003 1398 template< typename pass_type > 1399 void PassVisitor< pass_type >::visit( const ThrowStmt * node ) { 1400 VISIT_START( node ); 1401 1402 maybeAccept_impl( node->expr, *this ); 1403 maybeAccept_impl( node->target, *this ); 1404 1405 VISIT_END( node ); 1406 } 1407 1408 template< typename pass_type > 1004 1409 Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { 1005 1410 MUTATE_START( node ); … … 1015 1420 template< typename pass_type > 1016 1421 void PassVisitor< pass_type >::visit( TryStmt * node ) { 1422 VISIT_START( node ); 1423 1424 maybeAccept_impl( node->block , *this ); 1425 maybeAccept_impl( node->handlers , *this ); 1426 maybeAccept_impl( node->finallyBlock, *this ); 1427 1428 VISIT_END( node ); 1429 } 1430 1431 template< typename pass_type > 1432 void PassVisitor< pass_type >::visit( const TryStmt * node ) { 1017 1433 VISIT_START( node ); 1018 1434 … … 1051 1467 1052 1468 template< typename pass_type > 1469 void PassVisitor< pass_type >::visit( const CatchStmt * node ) { 1470 VISIT_START( node ); 1471 { 1472 // catch statements introduce a level of scope (for the caught exception) 1473 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1474 maybeAccept_impl( node->decl, *this ); 1475 visitExpression ( node->cond ); 1476 visitStatement ( node->body ); 1477 } 1478 VISIT_END( node ); 1479 } 1480 1481 template< typename pass_type > 1053 1482 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { 1054 1483 MUTATE_START( node ); … … 1075 1504 1076 1505 template< typename pass_type > 1506 void PassVisitor< pass_type >::visit( const FinallyStmt * node ) { 1507 VISIT_START( node ); 1508 1509 maybeAccept_impl( node->block, *this ); 1510 1511 VISIT_END( node ); 1512 } 1513 1514 template< typename pass_type > 1077 1515 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { 1078 1516 MUTATE_START( node ); … … 1107 1545 1108 1546 template< typename pass_type > 1547 void PassVisitor< pass_type >::visit( const WaitForStmt * node ) { 1548 VISIT_START( node ); 1549 1550 for( auto & clause : node->clauses ) { 1551 maybeAccept_impl( clause.target.function, *this ); 1552 maybeAccept_impl( clause.target.arguments, *this ); 1553 1554 maybeAccept_impl( clause.statement, *this ); 1555 maybeAccept_impl( clause.condition, *this ); 1556 } 1557 1558 maybeAccept_impl( node->timeout.time, *this ); 1559 maybeAccept_impl( node->timeout.statement, *this ); 1560 maybeAccept_impl( node->timeout.condition, *this ); 1561 maybeAccept_impl( node->orelse.statement, *this ); 1562 maybeAccept_impl( node->orelse.condition, *this ); 1563 1564 VISIT_END( node ); 1565 } 1566 1567 template< typename pass_type > 1109 1568 Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) { 1110 1569 MUTATE_START( node ); … … 1130 1589 1131 1590 //-------------------------------------------------------------------------- 1132 // NullStmt1591 // WithStmt 1133 1592 template< typename pass_type > 1134 1593 void PassVisitor< pass_type >::visit( WithStmt * node ) { … … 1145 1604 1146 1605 template< typename pass_type > 1147 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1606 void PassVisitor< pass_type >::visit( const WithStmt * node ) { 1607 VISIT_START( node ); 1608 maybeAccept_impl( node->exprs, *this ); 1609 { 1610 // catch statements introduce a level of scope (for the caught exception) 1611 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1612 indexerAddWith( node->exprs, node ); 1613 maybeAccept_impl( node->stmt, *this ); 1614 } 1615 VISIT_END( node ); 1616 } 1617 1618 template< typename pass_type > 1619 Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) { 1148 1620 MUTATE_START( node ); 1149 1621 maybeMutate_impl( node->exprs, *this ); … … 1154 1626 maybeMutate_impl( node->stmt, *this ); 1155 1627 } 1628 MUTATE_END( Declaration, node ); 1629 } 1630 1631 //-------------------------------------------------------------------------- 1632 // NullStmt 1633 template< typename pass_type > 1634 void PassVisitor< pass_type >::visit( NullStmt * node ) { 1635 VISIT_START( node ); 1636 VISIT_END( node ); 1637 } 1638 1639 template< typename pass_type > 1640 void PassVisitor< pass_type >::visit( const NullStmt * node ) { 1641 VISIT_START( node ); 1642 VISIT_END( node ); 1643 } 1644 1645 template< typename pass_type > 1646 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1647 MUTATE_START( node ); 1648 MUTATE_END( NullStmt, node ); 1649 } 1650 1651 //-------------------------------------------------------------------------- 1652 // DeclStmt 1653 template< typename pass_type > 1654 void PassVisitor< pass_type >::visit( DeclStmt * node ) { 1655 VISIT_START( node ); 1656 1657 maybeAccept_impl( node->decl, *this ); 1658 1659 VISIT_END( node ); 1660 } 1661 1662 template< typename pass_type > 1663 void PassVisitor< pass_type >::visit( const DeclStmt * node ) { 1664 VISIT_START( node ); 1665 1666 maybeAccept_impl( node->decl, *this ); 1667 1668 VISIT_END( node ); 1669 } 1670 1671 template< typename pass_type > 1672 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1673 MUTATE_START( node ); 1674 1675 maybeMutate_impl( node->decl, *this ); 1676 1156 1677 MUTATE_END( Statement, node ); 1157 1678 } 1158 1679 1159 1680 //-------------------------------------------------------------------------- 1160 // NullStmt 1161 template< typename pass_type > 1162 void PassVisitor< pass_type >::visit( NullStmt * node ) { 1163 VISIT_START( node ); 1164 VISIT_END( node ); 1165 } 1166 1167 template< typename pass_type > 1168 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { 1169 MUTATE_START( node ); 1170 MUTATE_END( NullStmt, node ); 1171 } 1172 1173 //-------------------------------------------------------------------------- 1174 // DeclStmt 1175 template< typename pass_type > 1176 void PassVisitor< pass_type >::visit( DeclStmt * node ) { 1177 VISIT_START( node ); 1178 1179 maybeAccept_impl( node->decl, *this ); 1180 1181 VISIT_END( node ); 1182 } 1183 1184 template< typename pass_type > 1185 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { 1186 MUTATE_START( node ); 1187 1188 maybeMutate_impl( node->decl, *this ); 1681 // ImplicitCtorDtorStmt 1682 template< typename pass_type > 1683 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) { 1684 VISIT_START( node ); 1685 1686 maybeAccept_impl( node->callStmt, *this ); 1687 1688 VISIT_END( node ); 1689 } 1690 1691 template< typename pass_type > 1692 void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) { 1693 VISIT_START( node ); 1694 1695 maybeAccept_impl( node->callStmt, *this ); 1696 1697 VISIT_END( node ); 1698 } 1699 1700 template< typename pass_type > 1701 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) { 1702 MUTATE_START( node ); 1703 1704 maybeMutate_impl( node->callStmt, *this ); 1189 1705 1190 1706 MUTATE_END( Statement, node ); … … 1192 1708 1193 1709 //-------------------------------------------------------------------------- 1194 // ImplicitCtorDtorStmt1195 template< typename pass_type >1196 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {1197 VISIT_START( node );1198 1199 maybeAccept_impl( node->callStmt, *this );1200 1201 VISIT_END( node );1202 }1203 1204 template< typename pass_type >1205 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {1206 MUTATE_START( node );1207 1208 maybeMutate_impl( node->callStmt, *this );1209 1210 MUTATE_END( Statement, node );1211 }1212 1213 //--------------------------------------------------------------------------1214 1710 // ApplicationExpr 1215 1711 template< typename pass_type > … … 1218 1714 1219 1715 indexerScopedAccept( node->result , *this ); 1220 maybeAccept_impl ( node->function, *this ); 1221 maybeAccept_impl ( node->args , *this ); 1716 maybeAccept_impl ( node->function, *this ); 1717 maybeAccept_impl ( node->args , *this ); 1718 1719 VISIT_END( node ); 1720 } 1721 1722 template< typename pass_type > 1723 void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) { 1724 VISIT_START( node ); 1725 1726 indexerScopedAccept( node->result , *this ); 1727 maybeAccept_impl ( node->function, *this ); 1728 maybeAccept_impl ( node->args , *this ); 1222 1729 1223 1730 VISIT_END( node ); … … 1253 1760 1254 1761 template< typename pass_type > 1762 void PassVisitor< pass_type >::visit( const UntypedExpr * node ) { 1763 VISIT_START( node ); 1764 1765 indexerScopedAccept( node->result, *this ); 1766 1767 for ( auto expr : node->args ) { 1768 visitExpression( expr ); 1769 } 1770 1771 VISIT_END( node ); 1772 } 1773 1774 template< typename pass_type > 1255 1775 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { 1256 1776 MUTATE_START( node ); … … 1278 1798 1279 1799 template< typename pass_type > 1800 void PassVisitor< pass_type >::visit( const NameExpr * node ) { 1801 VISIT_START( node ); 1802 1803 indexerScopedAccept( node->result, *this ); 1804 1805 VISIT_END( node ); 1806 } 1807 1808 template< typename pass_type > 1280 1809 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) { 1281 1810 MUTATE_START( node ); … … 1294 1823 1295 1824 indexerScopedAccept( node->result, *this ); 1296 maybeAccept_impl ( node->arg , *this ); 1825 maybeAccept_impl ( node->arg , *this ); 1826 1827 VISIT_END( node ); 1828 } 1829 1830 template< typename pass_type > 1831 void PassVisitor< pass_type >::visit( const CastExpr * node ) { 1832 VISIT_START( node ); 1833 1834 indexerScopedAccept( node->result, *this ); 1835 maybeAccept_impl ( node->arg , *this ); 1297 1836 1298 1837 VISIT_END( node ); … … 1323 1862 1324 1863 template< typename pass_type > 1864 void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) { 1865 VISIT_START( node ); 1866 1867 indexerScopedAccept( node->result, *this ); 1868 maybeAccept_impl ( node->arg , *this ); 1869 1870 VISIT_END( node ); 1871 } 1872 1873 template< typename pass_type > 1325 1874 Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) { 1326 1875 MUTATE_START( node ); … … 1340 1889 1341 1890 indexerScopedAccept( node->result, *this ); 1342 maybeAccept_impl( node->arg, *this ); 1891 maybeAccept_impl ( node->arg, *this ); 1892 1893 VISIT_END( node ); 1894 } 1895 1896 template< typename pass_type > 1897 void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) { 1898 VISIT_START( node ); 1899 1900 indexerScopedAccept( node->result, *this ); 1901 maybeAccept_impl ( node->arg, *this ); 1343 1902 1344 1903 VISIT_END( node ); … … 1369 1928 1370 1929 template< typename pass_type > 1930 void PassVisitor< pass_type >::visit( const AddressExpr * node ) { 1931 VISIT_START( node ); 1932 1933 indexerScopedAccept( node->result, *this ); 1934 maybeAccept_impl ( node->arg , *this ); 1935 1936 VISIT_END( node ); 1937 } 1938 1939 template< typename pass_type > 1371 1940 Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) { 1372 1941 MUTATE_START( node ); … … 1391 1960 1392 1961 template< typename pass_type > 1962 void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) { 1963 VISIT_START( node ); 1964 1965 indexerScopedAccept( node->result, *this ); 1966 1967 VISIT_END( node ); 1968 } 1969 1970 template< typename pass_type > 1393 1971 Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) { 1394 1972 MUTATE_START( node ); … … 1404 1982 template< typename pass_type > 1405 1983 void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) { 1984 VISIT_START( node ); 1985 1986 indexerScopedAccept( node->result , *this ); 1987 maybeAccept_impl ( node->aggregate, *this ); 1988 maybeAccept_impl ( node->member , *this ); 1989 1990 VISIT_END( node ); 1991 } 1992 1993 template< typename pass_type > 1994 void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) { 1406 1995 VISIT_START( node ); 1407 1996 … … 1438 2027 1439 2028 template< typename pass_type > 2029 void PassVisitor< pass_type >::visit( const MemberExpr * node ) { 2030 VISIT_START( node ); 2031 2032 indexerScopedAccept( node->result , *this ); 2033 maybeAccept_impl ( node->aggregate, *this ); 2034 2035 VISIT_END( node ); 2036 } 2037 2038 template< typename pass_type > 1440 2039 Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) { 1441 2040 MUTATE_START( node ); … … 1460 2059 1461 2060 template< typename pass_type > 2061 void PassVisitor< pass_type >::visit( const VariableExpr * node ) { 2062 VISIT_START( node ); 2063 2064 indexerScopedAccept( node->result, *this ); 2065 2066 VISIT_END( node ); 2067 } 2068 2069 template< typename pass_type > 1462 2070 Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) { 1463 2071 MUTATE_START( node ); … … 1473 2081 template< typename pass_type > 1474 2082 void PassVisitor< pass_type >::visit( ConstantExpr * node ) { 2083 VISIT_START( node ); 2084 2085 indexerScopedAccept( node->result , *this ); 2086 maybeAccept_impl ( &node->constant, *this ); 2087 2088 VISIT_END( node ); 2089 } 2090 2091 template< typename pass_type > 2092 void PassVisitor< pass_type >::visit( const ConstantExpr * node ) { 1475 2093 VISIT_START( node ); 1476 2094 … … 1498 2116 template< typename pass_type > 1499 2117 void PassVisitor< pass_type >::visit( SizeofExpr * node ) { 2118 VISIT_START( node ); 2119 2120 indexerScopedAccept( node->result, *this ); 2121 if ( node->get_isType() ) { 2122 maybeAccept_impl( node->type, *this ); 2123 } else { 2124 maybeAccept_impl( node->expr, *this ); 2125 } 2126 2127 VISIT_END( node ); 2128 } 2129 2130 template< typename pass_type > 2131 void PassVisitor< pass_type >::visit( const SizeofExpr * node ) { 1500 2132 VISIT_START( node ); 1501 2133 … … 1542 2174 1543 2175 template< typename pass_type > 2176 void PassVisitor< pass_type >::visit( const AlignofExpr * node ) { 2177 VISIT_START( node ); 2178 2179 indexerScopedAccept( node->result, *this ); 2180 if ( node->get_isType() ) { 2181 maybeAccept_impl( node->type, *this ); 2182 } else { 2183 maybeAccept_impl( node->expr, *this ); 2184 } 2185 2186 VISIT_END( node ); 2187 } 2188 2189 template< typename pass_type > 1544 2190 Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) { 1545 2191 MUTATE_START( node ); … … 1569 2215 1570 2216 template< typename pass_type > 2217 void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) { 2218 VISIT_START( node ); 2219 2220 indexerScopedAccept( node->result, *this ); 2221 maybeAccept_impl ( node->type , *this ); 2222 2223 VISIT_END( node ); 2224 } 2225 2226 template< typename pass_type > 1571 2227 Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) { 1572 2228 MUTATE_START( node ); … … 1592 2248 1593 2249 template< typename pass_type > 2250 void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) { 2251 VISIT_START( node ); 2252 2253 indexerScopedAccept( node->result, *this ); 2254 maybeAccept_impl ( node->type , *this ); 2255 2256 VISIT_END( node ); 2257 } 2258 2259 template< typename pass_type > 1594 2260 Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) { 1595 2261 MUTATE_START( node ); … … 1615 2281 1616 2282 template< typename pass_type > 2283 void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) { 2284 VISIT_START( node ); 2285 2286 indexerScopedAccept( node->result, *this ); 2287 maybeAccept_impl ( node->type , *this ); 2288 2289 VISIT_END( node ); 2290 } 2291 2292 template< typename pass_type > 1617 2293 Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) { 1618 2294 MUTATE_START( node ); … … 1629 2305 template< typename pass_type > 1630 2306 void PassVisitor< pass_type >::visit( AttrExpr * node ) { 2307 VISIT_START( node ); 2308 2309 indexerScopedAccept( node->result, *this ); 2310 if ( node->get_isType() ) { 2311 maybeAccept_impl( node->type, *this ); 2312 } else { 2313 maybeAccept_impl( node->expr, *this ); 2314 } 2315 2316 VISIT_END( node ); 2317 } 2318 2319 template< typename pass_type > 2320 void PassVisitor< pass_type >::visit( const AttrExpr * node ) { 1631 2321 VISIT_START( node ); 1632 2322 … … 1670 2360 1671 2361 template< typename pass_type > 2362 void PassVisitor< pass_type >::visit( const LogicalExpr * node ) { 2363 VISIT_START( node ); 2364 2365 indexerScopedAccept( node->result, *this ); 2366 maybeAccept_impl ( node->arg1 , *this ); 2367 maybeAccept_impl ( node->arg2 , *this ); 2368 2369 VISIT_END( node ); 2370 } 2371 2372 template< typename pass_type > 1672 2373 Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) { 1673 2374 MUTATE_START( node ); … … 1691 2392 maybeAccept_impl ( node->arg2 , *this ); 1692 2393 maybeAccept_impl ( node->arg3 , *this ); 2394 2395 VISIT_END( node ); 2396 } 2397 2398 template< typename pass_type > 2399 void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) { 2400 VISIT_START( node ); 2401 2402 indexerScopedAccept( node->result, *this ); 2403 maybeAccept_impl ( node->arg1 , *this ); 2404 maybeAccept_impl ( node->arg2 , *this ); 2405 maybeAccept_impl ( node->arg3 , *this ); 1693 2406 1694 2407 VISIT_END( node ); … … 1722 2435 1723 2436 template< typename pass_type > 2437 void PassVisitor< pass_type >::visit( const CommaExpr * node ) { 2438 VISIT_START( node ); 2439 2440 indexerScopedAccept( node->result, *this ); 2441 maybeAccept_impl ( node->arg1 , *this ); 2442 maybeAccept_impl ( node->arg2 , *this ); 2443 2444 VISIT_END( node ); 2445 } 2446 2447 template< typename pass_type > 1724 2448 Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) { 1725 2449 MUTATE_START( node ); … … 1746 2470 1747 2471 template< typename pass_type > 2472 void PassVisitor< pass_type >::visit( const TypeExpr * node ) { 2473 VISIT_START( node ); 2474 2475 indexerScopedAccept( node->result, *this ); 2476 maybeAccept_impl ( node->type, *this ); 2477 2478 VISIT_END( node ); 2479 } 2480 2481 template< typename pass_type > 1748 2482 Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) { 1749 2483 MUTATE_START( node ); … … 1760 2494 template< typename pass_type > 1761 2495 void PassVisitor< pass_type >::visit( AsmExpr * node ) { 2496 VISIT_START( node ); 2497 2498 indexerScopedAccept( node->result , *this ); 2499 maybeAccept_impl ( node->inout , *this ); 2500 maybeAccept_impl ( node->constraint, *this ); 2501 maybeAccept_impl ( node->operand , *this ); 2502 2503 VISIT_END( node ); 2504 } 2505 2506 template< typename pass_type > 2507 void PassVisitor< pass_type >::visit( const AsmExpr * node ) { 1762 2508 VISIT_START( node ); 1763 2509 … … 1796 2542 1797 2543 template< typename pass_type > 2544 void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) { 2545 VISIT_START( node ); 2546 2547 indexerScopedAccept( node->result , *this ); 2548 maybeAccept_impl ( node->callExpr , *this ); 2549 2550 VISIT_END( node ); 2551 } 2552 2553 template< typename pass_type > 1798 2554 Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) { 1799 2555 MUTATE_START( node ); … … 1819 2575 1820 2576 template< typename pass_type > 2577 void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) { 2578 VISIT_START( node ); 2579 2580 indexerScopedAccept( node->result , *this ); 2581 maybeAccept_impl ( node->callExpr, *this ); 2582 2583 VISIT_END( node ); 2584 } 2585 2586 template< typename pass_type > 1821 2587 Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) { 1822 2588 MUTATE_START( node ); … … 1842 2608 1843 2609 template< typename pass_type > 2610 void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) { 2611 VISIT_START( node ); 2612 2613 indexerScopedAccept( node->result , *this ); 2614 maybeAccept_impl ( node->initializer, *this ); 2615 2616 VISIT_END( node ); 2617 } 2618 2619 template< typename pass_type > 1844 2620 Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) { 1845 2621 MUTATE_START( node ); … … 1856 2632 template< typename pass_type > 1857 2633 void PassVisitor< pass_type >::visit( RangeExpr * node ) { 2634 VISIT_START( node ); 2635 2636 indexerScopedAccept( node->result, *this ); 2637 maybeAccept_impl ( node->low , *this ); 2638 maybeAccept_impl ( node->high , *this ); 2639 2640 VISIT_END( node ); 2641 } 2642 2643 template< typename pass_type > 2644 void PassVisitor< pass_type >::visit( const RangeExpr * node ) { 1858 2645 VISIT_START( node ); 1859 2646 … … 1890 2677 1891 2678 template< typename pass_type > 2679 void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) { 2680 VISIT_START( node ); 2681 2682 indexerScopedAccept( node->result, *this ); 2683 maybeAccept_impl ( node->exprs , *this ); 2684 2685 VISIT_END( node ); 2686 } 2687 2688 template< typename pass_type > 1892 2689 Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) { 1893 2690 MUTATE_START( node ); … … 1913 2710 1914 2711 template< typename pass_type > 2712 void PassVisitor< pass_type >::visit( const TupleExpr * node ) { 2713 VISIT_START( node ); 2714 2715 indexerScopedAccept( node->result, *this ); 2716 maybeAccept_impl ( node->exprs , *this ); 2717 2718 VISIT_END( node ); 2719 } 2720 2721 template< typename pass_type > 1915 2722 Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) { 1916 2723 MUTATE_START( node ); … … 1936 2743 1937 2744 template< typename pass_type > 2745 void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) { 2746 VISIT_START( node ); 2747 2748 indexerScopedAccept( node->result, *this ); 2749 maybeAccept_impl ( node->tuple , *this ); 2750 2751 VISIT_END( node ); 2752 } 2753 2754 template< typename pass_type > 1938 2755 Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) { 1939 2756 MUTATE_START( node ); … … 1954 2771 indexerScopedAccept( node->result , *this ); 1955 2772 maybeAccept_impl ( node->stmtExpr, *this ); 2773 2774 VISIT_END( node ); 2775 } 2776 2777 template< typename pass_type > 2778 void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) { 2779 VISIT_START( node ); 2780 2781 indexerScopedAccept( node->result , *this ); 2782 maybeAccept_impl( node->stmtExpr, *this ); 1956 2783 1957 2784 VISIT_END( node ); … … 1989 2816 1990 2817 template< typename pass_type > 1991 Expression * PassVisitor< pass_type >::mutate(StmtExpr * node ) {1992 MUTATE_START( node );2818 void PassVisitor< pass_type >::visit( const StmtExpr * node ) { 2819 VISIT_START( node ); 1993 2820 1994 2821 // don't want statements from outer CompoundStmts to be added to this StmtExpr … … 1997 2824 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 1998 2825 2826 indexerScopedAccept( node->result , *this ); 2827 maybeAccept_impl ( node->statements , *this ); 2828 maybeAccept_impl ( node->returnDecls, *this ); 2829 maybeAccept_impl ( node->dtors , *this ); 2830 2831 VISIT_END( node ); 2832 } 2833 2834 template< typename pass_type > 2835 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { 2836 MUTATE_START( node ); 2837 2838 // don't want statements from outer CompoundStmts to be added to this StmtExpr 2839 ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type > oldEnv( get_env_ptr() ); 2840 ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); 2841 ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); 2842 1999 2843 indexerScopedMutate( node->result , *this ); 2000 2844 maybeMutate_impl ( node->statements , *this ); … … 2018 2862 2019 2863 template< typename pass_type > 2864 void PassVisitor< pass_type >::visit( const UniqueExpr * node ) { 2865 VISIT_START( node ); 2866 2867 indexerScopedAccept( node->result, *this ); 2868 maybeAccept_impl ( node->expr , *this ); 2869 2870 VISIT_END( node ); 2871 } 2872 2873 template< typename pass_type > 2020 2874 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { 2021 2875 MUTATE_START( node ); … … 2032 2886 template< typename pass_type > 2033 2887 void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) { 2888 VISIT_START( node ); 2889 2890 indexerScopedAccept( node->result, *this ); 2891 maybeAccept_impl ( node->expr , *this ); 2892 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 2893 2894 VISIT_END( node ); 2895 } 2896 2897 template< typename pass_type > 2898 void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) { 2034 2899 VISIT_START( node ); 2035 2900 … … 2067 2932 2068 2933 template< typename pass_type > 2934 void PassVisitor< pass_type >::visit( const InitExpr * node ) { 2935 VISIT_START( node ); 2936 2937 indexerScopedAccept( node->result, *this ); 2938 maybeAccept_impl ( node->expr , *this ); 2939 maybeAccept_impl ( node->designation, *this ); 2940 2941 VISIT_END( node ); 2942 } 2943 2944 template< typename pass_type > 2069 2945 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) { 2070 2946 MUTATE_START( node ); … … 2085 2961 2086 2962 indexerScopedAccept( node->result, *this ); 2087 maybeAccept_impl( node->expr, *this ); 2963 maybeAccept_impl ( node->expr, *this ); 2964 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2965 2966 VISIT_END( node ); 2967 } 2968 2969 template< typename pass_type > 2970 void PassVisitor< pass_type >::visit( const DeletedExpr * node ) { 2971 VISIT_START( node ); 2972 2973 indexerScopedAccept( node->result, *this ); 2974 maybeAccept_impl ( node->expr, *this ); 2088 2975 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 2089 2976 … … 2109 2996 2110 2997 indexerScopedAccept( node->result, *this ); 2111 maybeAccept_impl( node->expr, *this ); 2998 maybeAccept_impl ( node->expr, *this ); 2999 3000 VISIT_END( node ); 3001 } 3002 3003 template< typename pass_type > 3004 void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) { 3005 VISIT_START( node ); 3006 3007 indexerScopedAccept( node->result, *this ); 3008 maybeAccept_impl ( node->expr, *this ); 2112 3009 2113 3010 VISIT_END( node ); … … 2134 3031 maybeAccept_impl( node->control, *this ); 2135 3032 for ( GenericExpr::Association & assoc : node->associations ) { 3033 indexerScopedAccept( assoc.type, *this ); 3034 maybeAccept_impl( assoc.expr, *this ); 3035 } 3036 3037 VISIT_END( node ); 3038 } 3039 3040 template< typename pass_type > 3041 void PassVisitor< pass_type >::visit( const GenericExpr * node ) { 3042 VISIT_START( node ); 3043 3044 indexerScopedAccept( node->result, *this ); 3045 maybeAccept_impl( node->control, *this ); 3046 for ( const GenericExpr::Association & assoc : node->associations ) { 2136 3047 indexerScopedAccept( assoc.type, *this ); 2137 3048 maybeAccept_impl( assoc.expr, *this ); … … 2168 3079 2169 3080 template< typename pass_type > 3081 void PassVisitor< pass_type >::visit( const VoidType * node ) { 3082 VISIT_START( node ); 3083 3084 maybeAccept_impl( node->forall, *this ); 3085 3086 VISIT_END( node ); 3087 } 3088 3089 template< typename pass_type > 2170 3090 Type * PassVisitor< pass_type >::mutate( VoidType * node ) { 2171 3091 MUTATE_START( node ); … … 2180 3100 template< typename pass_type > 2181 3101 void PassVisitor< pass_type >::visit( BasicType * node ) { 3102 VISIT_START( node ); 3103 3104 maybeAccept_impl( node->forall, *this ); 3105 3106 VISIT_END( node ); 3107 } 3108 3109 template< typename pass_type > 3110 void PassVisitor< pass_type >::visit( const BasicType * node ) { 2182 3111 VISIT_START( node ); 2183 3112 … … 2210 3139 2211 3140 template< typename pass_type > 3141 void PassVisitor< pass_type >::visit( const PointerType * node ) { 3142 VISIT_START( node ); 3143 3144 maybeAccept_impl( node->forall, *this ); 3145 // xxx - should PointerType visit/mutate dimension? 3146 maybeAccept_impl( node->base, *this ); 3147 3148 VISIT_END( node ); 3149 } 3150 3151 template< typename pass_type > 2212 3152 Type * PassVisitor< pass_type >::mutate( PointerType * node ) { 2213 3153 MUTATE_START( node ); … … 2234 3174 2235 3175 template< typename pass_type > 3176 void PassVisitor< pass_type >::visit( const ArrayType * node ) { 3177 VISIT_START( node ); 3178 3179 maybeAccept_impl( node->forall, *this ); 3180 maybeAccept_impl( node->dimension, *this ); 3181 maybeAccept_impl( node->base, *this ); 3182 3183 VISIT_END( node ); 3184 } 3185 3186 template< typename pass_type > 2236 3187 Type * PassVisitor< pass_type >::mutate( ArrayType * node ) { 2237 3188 MUTATE_START( node ); … … 2257 3208 2258 3209 template< typename pass_type > 3210 void PassVisitor< pass_type >::visit( const ReferenceType * node ) { 3211 VISIT_START( node ); 3212 3213 maybeAccept_impl( node->forall, *this ); 3214 maybeAccept_impl( node->base, *this ); 3215 3216 VISIT_END( node ); 3217 } 3218 3219 template< typename pass_type > 2259 3220 Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) { 2260 3221 MUTATE_START( node ); … … 2280 3241 2281 3242 template< typename pass_type > 3243 void PassVisitor< pass_type >::visit( const QualifiedType * node ) { 3244 VISIT_START( node ); 3245 3246 maybeAccept_impl( node->forall, *this ); 3247 maybeAccept_impl( node->parent, *this ); 3248 maybeAccept_impl( node->child, *this ); 3249 3250 VISIT_END( node ); 3251 } 3252 3253 template< typename pass_type > 2282 3254 Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) { 2283 3255 MUTATE_START( node ); … … 2304 3276 2305 3277 template< typename pass_type > 3278 void PassVisitor< pass_type >::visit( const FunctionType * node ) { 3279 VISIT_START( node ); 3280 3281 maybeAccept_impl( node->forall, *this ); 3282 maybeAccept_impl( node->returnVals, *this ); 3283 maybeAccept_impl( node->parameters, *this ); 3284 3285 VISIT_END( node ); 3286 } 3287 3288 template< typename pass_type > 2306 3289 Type * PassVisitor< pass_type >::mutate( FunctionType * node ) { 2307 3290 MUTATE_START( node ); … … 2332 3315 2333 3316 template< typename pass_type > 3317 void PassVisitor< pass_type >::visit( const StructInstType * node ) { 3318 VISIT_START( node ); 3319 3320 indexerAddStruct( node->name ); 3321 3322 { 3323 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3324 maybeAccept_impl( node->forall , *this ); 3325 maybeAccept_impl( node->parameters, *this ); 3326 } 3327 3328 VISIT_END( node ); 3329 } 3330 3331 template< typename pass_type > 2334 3332 Type * PassVisitor< pass_type >::mutate( StructInstType * node ) { 2335 3333 MUTATE_START( node ); … … 2364 3362 2365 3363 template< typename pass_type > 3364 void PassVisitor< pass_type >::visit( const UnionInstType * node ) { 3365 VISIT_START( node ); 3366 3367 indexerAddStruct( node->name ); 3368 3369 { 3370 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 3371 maybeAccept_impl( node->forall , *this ); 3372 maybeAccept_impl( node->parameters, *this ); 3373 } 3374 3375 VISIT_END( node ); 3376 } 3377 3378 template< typename pass_type > 2366 3379 Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) { 2367 3380 MUTATE_START( node ); … … 2391 3404 2392 3405 template< typename pass_type > 3406 void PassVisitor< pass_type >::visit( const EnumInstType * node ) { 3407 VISIT_START( node ); 3408 3409 maybeAccept_impl( node->forall, *this ); 3410 maybeAccept_impl( node->parameters, *this ); 3411 3412 VISIT_END( node ); 3413 } 3414 3415 template< typename pass_type > 2393 3416 Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) { 2394 3417 MUTATE_START( node ); … … 2413 3436 2414 3437 template< typename pass_type > 3438 void PassVisitor< pass_type >::visit( const TraitInstType * node ) { 3439 VISIT_START( node ); 3440 3441 maybeAccept_impl( node->forall , *this ); 3442 maybeAccept_impl( node->parameters, *this ); 3443 3444 VISIT_END( node ); 3445 } 3446 3447 template< typename pass_type > 2415 3448 Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) { 2416 3449 MUTATE_START( node ); … … 2426 3459 template< typename pass_type > 2427 3460 void PassVisitor< pass_type >::visit( TypeInstType * node ) { 3461 VISIT_START( node ); 3462 3463 maybeAccept_impl( node->forall , *this ); 3464 maybeAccept_impl( node->parameters, *this ); 3465 3466 VISIT_END( node ); 3467 } 3468 3469 template< typename pass_type > 3470 void PassVisitor< pass_type >::visit( const TypeInstType * node ) { 2428 3471 VISIT_START( node ); 2429 3472 … … 2458 3501 2459 3502 template< typename pass_type > 3503 void PassVisitor< pass_type >::visit( const TupleType * node ) { 3504 VISIT_START( node ); 3505 3506 maybeAccept_impl( node->forall, *this ); 3507 maybeAccept_impl( node->types, *this ); 3508 maybeAccept_impl( node->members, *this ); 3509 3510 VISIT_END( node ); 3511 } 3512 3513 template< typename pass_type > 2460 3514 Type * PassVisitor< pass_type >::mutate( TupleType * node ) { 2461 3515 MUTATE_START( node ); … … 2472 3526 template< typename pass_type > 2473 3527 void PassVisitor< pass_type >::visit( TypeofType * node ) { 3528 VISIT_START( node ); 3529 3530 assert( node->expr ); 3531 maybeAccept_impl( node->expr, *this ); 3532 3533 VISIT_END( node ); 3534 } 3535 3536 template< typename pass_type > 3537 void PassVisitor< pass_type >::visit( const TypeofType * node ) { 2474 3538 VISIT_START( node ); 2475 3539 … … 2508 3572 2509 3573 template< typename pass_type > 3574 void PassVisitor< pass_type >::visit( const AttrType * node ) { 3575 VISIT_START( node ); 3576 3577 if ( node->isType ) { 3578 assert( node->type ); 3579 maybeAccept_impl( node->type, *this ); 3580 } else { 3581 assert( node->expr ); 3582 maybeAccept_impl( node->expr, *this ); 3583 } // if 3584 3585 VISIT_END( node ); 3586 } 3587 3588 template< typename pass_type > 2510 3589 Type * PassVisitor< pass_type >::mutate( AttrType * node ) { 2511 3590 MUTATE_START( node ); … … 2534 3613 2535 3614 template< typename pass_type > 3615 void PassVisitor< pass_type >::visit( const VarArgsType * node ) { 3616 VISIT_START( node ); 3617 3618 maybeAccept_impl( node->forall, *this ); 3619 3620 VISIT_END( node ); 3621 } 3622 3623 template< typename pass_type > 2536 3624 Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) { 2537 3625 MUTATE_START( node ); … … 2554 3642 2555 3643 template< typename pass_type > 3644 void PassVisitor< pass_type >::visit( const ZeroType * node ) { 3645 VISIT_START( node ); 3646 3647 maybeAccept_impl( node->forall, *this ); 3648 3649 VISIT_END( node ); 3650 } 3651 3652 template< typename pass_type > 2556 3653 Type * PassVisitor< pass_type >::mutate( ZeroType * node ) { 2557 3654 MUTATE_START( node ); … … 2574 3671 2575 3672 template< typename pass_type > 3673 void PassVisitor< pass_type >::visit( const OneType * node ) { 3674 VISIT_START( node ); 3675 3676 maybeAccept_impl( node->forall, *this ); 3677 3678 VISIT_END( node ); 3679 } 3680 3681 template< typename pass_type > 2576 3682 Type * PassVisitor< pass_type >::mutate( OneType * node ) { 2577 3683 MUTATE_START( node ); … … 2594 3700 2595 3701 template< typename pass_type > 3702 void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) { 3703 VISIT_START( node ); 3704 3705 maybeAccept_impl( node->forall, *this ); 3706 3707 VISIT_END( node ); 3708 } 3709 3710 template< typename pass_type > 2596 3711 Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) { 2597 3712 MUTATE_START( node ); … … 2614 3729 2615 3730 template< typename pass_type > 3731 void PassVisitor< pass_type >::visit( const Designation * node ) { 3732 VISIT_START( node ); 3733 3734 maybeAccept_impl( node->designators, *this ); 3735 3736 VISIT_END( node ); 3737 } 3738 3739 template< typename pass_type > 2616 3740 Designation * PassVisitor< pass_type >::mutate( Designation * node ) { 2617 3741 MUTATE_START( node ); … … 2634 3758 2635 3759 template< typename pass_type > 3760 void PassVisitor< pass_type >::visit( const SingleInit * node ) { 3761 VISIT_START( node ); 3762 3763 visitExpression( node->value ); 3764 3765 VISIT_END( node ); 3766 } 3767 3768 template< typename pass_type > 2636 3769 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { 2637 3770 MUTATE_START( node ); … … 2646 3779 template< typename pass_type > 2647 3780 void PassVisitor< pass_type >::visit( ListInit * node ) { 3781 VISIT_START( node ); 3782 3783 maybeAccept_impl( node->designations, *this ); 3784 maybeAccept_impl( node->initializers, *this ); 3785 3786 VISIT_END( node ); 3787 } 3788 3789 template< typename pass_type > 3790 void PassVisitor< pass_type >::visit( const ListInit * node ) { 2648 3791 VISIT_START( node ); 2649 3792 … … 2678 3821 2679 3822 template< typename pass_type > 3823 void PassVisitor< pass_type >::visit( const ConstructorInit * node ) { 3824 VISIT_START( node ); 3825 3826 maybeAccept_impl( node->ctor, *this ); 3827 maybeAccept_impl( node->dtor, *this ); 3828 maybeAccept_impl( node->init, *this ); 3829 3830 VISIT_END( node ); 3831 } 3832 3833 template< typename pass_type > 2680 3834 Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) { 2681 3835 MUTATE_START( node ); … … 2698 3852 2699 3853 template< typename pass_type > 3854 void PassVisitor< pass_type >::visit( const Constant * node ) { 3855 VISIT_START( node ); 3856 3857 VISIT_END( node ); 3858 } 3859 3860 template< typename pass_type > 2700 3861 Constant * PassVisitor< pass_type >::mutate( Constant * node ) { 2701 3862 MUTATE_START( node ); … … 2708 3869 template< typename pass_type > 2709 3870 void PassVisitor< pass_type >::visit( Attribute * node ) { 3871 VISIT_START( node ); 3872 3873 maybeAccept_impl( node->parameters, *this ); 3874 3875 VISIT_END( node ); 3876 } 3877 3878 template< typename pass_type > 3879 void PassVisitor< pass_type >::visit( const Attribute * node ) { 2710 3880 VISIT_START( node ); 2711 3881 -
src/Common/PassVisitor.proto.h
r1f1c102 rf53acdf8 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 ) { } 214 229 215 230 216 INDEXER_FUNC1( addId , DeclarationWithType * );217 INDEXER_FUNC1( addType , NamedTypeDecl * );218 INDEXER_FUNC1( addStruct , StructDecl * );219 INDEXER_FUNC1( addEnum , EnumDecl * );220 INDEXER_FUNC1( addUnion , UnionDecl * );221 INDEXER_FUNC1( addTrait , TraitDecl * );222 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode* );231 INDEXER_FUNC1( addId , const DeclarationWithType * ); 232 INDEXER_FUNC1( addType , const NamedTypeDecl * ); 233 INDEXER_FUNC1( addStruct , const StructDecl * ); 234 INDEXER_FUNC1( addEnum , const EnumDecl * ); 235 INDEXER_FUNC1( addUnion , const UnionDecl * ); 236 INDEXER_FUNC1( addTrait , const TraitDecl * ); 237 INDEXER_FUNC2( addWith , const std::list< Expression * > &, const Declaration * ); 223 238 224 239 #undef INDEXER_FUNC1 … … 226 241 227 242 template<typename pass_type> 228 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {243 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 229 244 StructDecl * fwd = new StructDecl( decl->name ); 230 245 cloneAll( decl->parameters, fwd->parameters ); … … 233 248 234 249 template<typename pass_type> 235 static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}236 237 template<typename pass_type> 238 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {250 static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {} 251 252 template<typename pass_type> 253 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 239 254 UnionDecl * fwd = new UnionDecl( decl->name ); 240 255 cloneAll( decl->parameters, fwd->parameters ); … … 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/InitTweak/InitTweak.cc
r1f1c102 rf53acdf8 318 318 virtual ~ExpanderImpl() = default; 319 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 320 virtual ast::ptr< ast::Stmt > buildListInit( 320 virtual ast::ptr< ast::Stmt > buildListInit( 321 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 322 }; … … 324 324 namespace { 325 325 template< typename Out > 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 328 328 const ast::Init * init, Out & out 329 329 ) { 330 330 const CodeLocation & loc = init->location; 331 331 332 auto cond = new ast::UntypedExpr{ 332 auto cond = new ast::UntypedExpr{ 333 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 334 335 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 336 splice( callExpr->args, args ); … … 338 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 339 340 out.emplace_back( new ast::ExprStmt{ 340 out.emplace_back( new ast::ExprStmt{ 341 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 342 } … … 344 344 template< typename Out > 345 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 347 const ast::Init * init, Out & out 348 348 ) { … … 371 371 372 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 373 ast::Label switchLabel{ 374 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 375 376 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 377 for ( const ast::Init * init : *listInit ) { … … 381 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 383 stmts.emplace_back( 384 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); … … 398 398 return makeInitList( init ); 399 399 } 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 403 403 ) override { 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 408 // statement consuming all of expander's elements 409 409 … … 427 427 ExprImpl_new( const ast::Expr * a ) : arg( a ) {} 428 428 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 431 431 ) override { 432 432 if ( ! arg ) return {}; … … 437 437 // go through indices and layer on subscript exprs ?[?] 438 438 ++it; 439 expr = new ast::UntypedExpr{ 439 expr = new ast::UntypedExpr{ 440 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 441 } 442 442 return { expr }; 443 443 } 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 448 448 return {}; 449 449 } … … 464 464 } 465 465 466 /// builds statement which has the same semantics as a C-style list initializer (for array 466 /// builds statement which has the same semantics as a C-style list initializer (for array 467 467 /// initializers) using callExpr as the base expression to perform initialization 468 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { … … 668 668 669 669 const ast::DeclWithType * func = getCalledFunction( appExpr->func ); 670 assertf( func, 670 assertf( func, 671 671 "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() ); 672 673 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 674 // autogenerated ctor/dtor will call all member dtors, and some members may have a 672 673 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because 674 // autogenerated ctor/dtor will call all member dtors, and some members may have a 675 675 // user-defined dtor 676 676 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr; … … 707 707 return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){ 708 708 if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 709 const ast::FunctionType * funcType = 709 const ast::FunctionType * funcType = 710 710 GenPoly::getFunctionType( appExpr->func->result ); 711 711 assert( funcType ); … … 997 997 bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); } 998 998 999 FunctionDecl * isCopyFunction(Declaration * decl, const std::string & fname ) {1000 FunctionDecl * function = dynamic_cast<FunctionDecl * >( decl );999 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) { 1000 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl ); 1001 1001 if ( ! function ) return nullptr; 1002 1002 if ( function->name != fname ) return nullptr; … … 1022 1022 if ( ! t1 ) return false; 1023 1023 const ast::Type * t2 = ftype->params.back()->get_type(); 1024 1024 1025 1025 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); 1026 1026 } 1027 1027 1028 FunctionDecl * isAssignment(Declaration * decl ) {1028 const FunctionDecl * isAssignment( const Declaration * decl ) { 1029 1029 return isCopyFunction( decl, "?=?" ); 1030 1030 } 1031 FunctionDecl * isDestructor(Declaration * decl ) {1032 if ( isDestructor( decl-> get_name()) ) {1033 return dynamic_cast< FunctionDecl * >( decl );1031 const FunctionDecl * isDestructor( const Declaration * decl ) { 1032 if ( isDestructor( decl->name ) ) { 1033 return dynamic_cast< const FunctionDecl * >( decl ); 1034 1034 } 1035 1035 return nullptr; 1036 1036 } 1037 FunctionDecl * isDefaultConstructor(Declaration * decl ) {1037 const FunctionDecl * isDefaultConstructor( const Declaration * decl ) { 1038 1038 if ( isConstructor( decl->name ) ) { 1039 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {1039 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 1040 1040 if ( func->type->parameters.size() == 1 ) { 1041 1041 return func; … … 1045 1045 return nullptr; 1046 1046 } 1047 FunctionDecl * isCopyConstructor(Declaration * decl ) {1047 const FunctionDecl * isCopyConstructor( const Declaration * decl ) { 1048 1048 return isCopyFunction( decl, "?{}" ); 1049 1049 } -
src/InitTweak/InitTweak.h
r1f1c102 rf53acdf8 26 26 // helper functions for initialization 27 27 namespace InitTweak { 28 FunctionDecl * isAssignment(Declaration * decl );29 FunctionDecl * isDestructor(Declaration * decl );30 FunctionDecl * isDefaultConstructor(Declaration * decl );31 FunctionDecl * isCopyConstructor(Declaration * decl );32 FunctionDecl * isCopyFunction(Declaration * decl, const std::string & fname );28 const FunctionDecl * isAssignment( const Declaration * decl ); 29 const FunctionDecl * isDestructor( const Declaration * decl ); 30 const FunctionDecl * isDefaultConstructor( const Declaration * decl ); 31 const FunctionDecl * isCopyConstructor( const Declaration * decl ); 32 const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ); 33 33 bool isCopyFunction( const ast::FunctionDecl * decl ); 34 34 … … 153 153 InitExpander_new & operator++ (); 154 154 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 157 157 /// Mutates callExpr 158 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); -
src/Parser/LinkageSpec.h
r1f1c102 rf53acdf8 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:24:28 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Spt 13 15:59:00 201813 // Update Count : 1 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 16:02:34 2019 13 // Update Count : 18 14 14 // 15 15 … … 35 35 constexpr Spec( unsigned int val ) : val( val ) {} 36 36 constexpr Spec( Spec const & other ) : val( other.val ) {} 37 constexpr Spec & operator=( const Spec & ) = default; 37 38 // Operators may go here. 38 39 // Supports == and != -
src/Parser/ParseNode.h
r1f1c102 rf53acdf8 437 437 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ); 438 438 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when ); 439 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );439 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ); 440 440 441 441 //############################################################################## -
src/Parser/StatementNode.cc
r1f1c102 rf53acdf8 317 317 } // build_waitfor_timeout 318 318 319 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {319 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) { 320 320 std::list< Expression * > e; 321 321 buildMoveList( exprs, e ); 322 322 Statement * s = maybeMoveBuild<Statement>( stmt ); 323 return new WithStmt( e, s);323 return new DeclStmt( new WithStmt( e, s ) ); 324 324 } // build_with 325 325 -
src/Parser/parser.yy
r1f1c102 rf53acdf8 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 28 17:06:37201913 // Update Count : 435 412 // Last Modified On : Sun Jul 14 07:54:30 2019 13 // Update Count : 4355 14 14 // 15 15 … … 678 678 679 679 argument_expression_list: 680 argument_expression 680 // empty 681 { $$ = nullptr; } 682 | argument_expression 681 683 | argument_expression_list ',' argument_expression 682 684 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 684 686 685 687 argument_expression: 686 // empty 687 { $$ = nullptr; } 688 | '@' // CFA, default parameter 688 '@' // CFA, default parameter 689 689 { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; } 690 690 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); } -
src/ResolvExpr/AdjustExprType.cc
r1f1c102 rf53acdf8 47 47 void premutate( OneType * ) { visit_children = false; } 48 48 49 Type * postmutate( ArrayType * arrayType );50 Type * postmutate( FunctionType * functionType );51 Type * postmutate( TypeInstType * aggregateUseType );49 Type * postmutate( ArrayType * arrayType ); 50 Type * postmutate( FunctionType * functionType ); 51 Type * postmutate( TypeInstType * aggregateUseType ); 52 52 53 53 private: … … 61 61 62 62 Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) { 63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 64 64 arrayType->base = nullptr; 65 65 delete arrayType; … … 72 72 73 73 Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) { 74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 75 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 76 76 return new PointerType{ Type::Qualifiers(), typeInst }; 77 77 } 78 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {79 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {78 } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) { 79 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) { 80 80 if ( tyDecl->get_kind() == TypeDecl::Ftype ) { 81 81 return new PointerType{ Type::Qualifiers(), typeInst }; … … 89 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type * newType = type->acceptMutator( adjuster );91 Type * newType = type->acceptMutator( adjuster ); 92 92 type = newType; 93 93 } … … 149 149 } // anonymous namespace 150 150 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 151 const ast::Type * adjustExprType( 152 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 153 153 ) { 154 154 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; -
src/ResolvExpr/AlternativeFinder.cc
r1f1c102 rf53acdf8 336 336 } 337 337 338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {338 if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 339 339 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {340 } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 341 341 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 342 342 } // if … … 344 344 345 345 template< typename StructOrUnionType > 346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {346 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 347 347 std::list< Declaration* > members; 348 348 aggInst->lookup( name, members ); 349 349 350 350 for ( Declaration * decl : members ) { 351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {351 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) { 352 352 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 353 353 // can't construct in place and use vector::back … … 362 362 } 363 363 364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ) {364 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) { 365 365 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 366 366 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 368 368 std::string tmp; 369 369 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 370 alternatives.push_back( Alternative{ 370 alternatives.push_back( Alternative{ 371 371 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 372 372 } // if … … 374 374 } 375 375 376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {376 void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) { 377 377 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 378 378 } … … 475 475 } 476 476 477 // specialization cost of return types can't be accounted for directly, it disables 477 // specialization cost of return types can't be accounted for directly, it disables 478 478 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 479 479 // … … 1226 1226 // count one safe conversion for each value that is thrown away 1227 1227 thisCost.incSafe( discardedValues ); 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1228 Alternative newAlt{ 1229 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1230 1230 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1231 1231 inferParameters( newAlt, back_inserter( candidates ) ); … … 1328 1328 if ( sizeofExpr->get_isType() ) { 1329 1329 Type * newType = sizeofExpr->get_type()->clone(); 1330 alternatives.push_back( Alternative{ 1330 alternatives.push_back( Alternative{ 1331 1331 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1332 1332 } else { … … 1343 1343 Alternative &choice = winners.front(); 1344 1344 referenceToRvalueConversion( choice.expr, choice.cost ); 1345 alternatives.push_back( Alternative{ 1345 alternatives.push_back( Alternative{ 1346 1346 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1347 1347 } // if … … 1351 1351 if ( alignofExpr->get_isType() ) { 1352 1352 Type * newType = alignofExpr->get_type()->clone(); 1353 alternatives.push_back( Alternative{ 1353 alternatives.push_back( Alternative{ 1354 1354 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1355 1355 } else { … … 1366 1366 Alternative &choice = winners.front(); 1367 1367 referenceToRvalueConversion( choice.expr, choice.cost ); 1368 alternatives.push_back( Alternative{ 1368 alternatives.push_back( Alternative{ 1369 1369 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1370 1370 } // if … … 1377 1377 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1378 1378 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1379 alternatives.push_back( Alternative{ 1379 alternatives.push_back( Alternative{ 1380 1380 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1381 1381 renameTypes( alternatives.back().expr ); … … 1405 1405 1406 1406 namespace { 1407 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {1407 void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) { 1408 1408 // assume no polymorphism 1409 1409 // assume no implicit conversions 1410 assert( function-> get_parameters().size() == 1 );1410 assert( function->parameters.size() == 1 ); 1411 1411 PRINT( 1412 1412 std::cerr << "resolvAttr: funcDecl is "; … … 1418 1418 const SymTab::Indexer & indexer = finder.get_indexer(); 1419 1419 AltList & alternatives = finder.get_alternatives(); 1420 if ( typesCompatibleIgnoreQualifiers( argType, function-> get_parameters().front()->get_type(), indexer, env ) ) {1420 if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) { 1421 1421 Cost cost = Cost::zero; 1422 1422 Expression * newExpr = data.combine( cost ); 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1423 alternatives.push_back( Alternative{ 1424 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1425 1425 AssertionList{}, Cost::zero, cost } ); 1426 1426 for ( DeclarationWithType * retVal : function->returnVals ) { … … 1431 1431 } 1432 1432 1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {1433 void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) { 1434 1434 // assume no 'pointer-to-attribute' 1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );1435 NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); 1436 1436 assert( nameExpr ); 1437 1437 std::list< SymTab::Indexer::IdData > attrList; … … 1439 1439 if ( attrExpr->get_isType() || attrExpr->get_expr() ) { 1440 1440 for ( auto & data : attrList ) { 1441 DeclarationWithType * id = data.id;1441 const DeclarationWithType * id = data.id; 1442 1442 // check if the type is function 1443 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {1443 if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) { 1444 1444 // assume exactly one parameter 1445 if ( function-> get_parameters().size() == 1 ) {1445 if ( function->parameters.size() == 1 ) { 1446 1446 if ( attrExpr->get_isType() ) { 1447 1447 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); … … 1462 1462 Cost cost = Cost::zero; 1463 1463 Expression * newExpr = data.combine( cost ); 1464 alternatives.push_back( Alternative{ 1464 alternatives.push_back( Alternative{ 1465 1465 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1466 1466 renameTypes( alternatives.back().expr ); … … 1469 1469 } 1470 1470 1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {1471 void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) { 1472 1472 AlternativeFinder firstFinder( indexer, env ); 1473 1473 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1486 1486 cloneAll( second.need, need ); 1487 1487 1488 LogicalExpr *newExpr = new LogicalExpr{ 1488 LogicalExpr *newExpr = new LogicalExpr{ 1489 1489 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1490 alternatives.push_back( Alternative{ 1491 newExpr, std::move(compositeEnv), std::move(openVars), 1492 1492 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1493 1493 } … … 1522 1522 cloneAll( third.need, need ); 1523 1523 AssertionSet have; 1524 1524 1525 1525 // unify true and false types, then infer parameters to produce new alternatives 1526 1526 Type* commonType = nullptr; 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1528 1528 need, have, openVars, indexer, commonType ) ) { 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 ConditionalExpr *newExpr = new ConditionalExpr{ 1530 1530 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1531 1531 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1532 1532 // convert both options to the conditional result type 1533 1533 Cost cost = first.cost + second.cost + third.cost; 1534 cost += computeExpressionConversionCost( 1534 cost += computeExpressionConversionCost( 1535 1535 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1536 cost += computeExpressionConversionCost( 1536 cost += computeExpressionConversionCost( 1537 1537 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1538 1538 // output alternative 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1539 Alternative newAlt{ 1540 newExpr, std::move(compositeEnv), std::move(openVars), 1541 1541 AssertionList( need.begin(), need.end() ), cost }; 1542 1542 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1553 1553 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1554 1554 for ( const Alternative & alt : secondFinder.alternatives ) { 1555 alternatives.push_back( Alternative{ 1555 alternatives.push_back( Alternative{ 1556 1556 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1557 1557 } // for … … 1579 1579 1580 1580 Type* commonType = nullptr; 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1581 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1582 1582 openVars, indexer, commonType ) ) { 1583 RangeExpr * newExpr = 1583 RangeExpr * newExpr = 1584 1584 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1585 1585 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1586 Alternative newAlt{ 1587 newExpr, std::move(compositeEnv), std::move(openVars), 1588 1588 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1589 1589 inferParameters( newAlt, back_inserter( alternatives ) ); … … 1612 1612 cloneAll( alt.need, need ); 1613 1613 } 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1614 1615 alternatives.push_back( Alternative{ 1616 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1617 1617 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1618 1618 } // for … … 1633 1633 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1634 1634 for ( Alternative & alt : finder.alternatives ) { 1635 alternatives.push_back( Alternative{ 1635 alternatives.push_back( Alternative{ 1636 1636 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1637 1637 } … … 1685 1685 cloneAll( alt.need, need ); 1686 1686 AssertionSet have; 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1687 OpenVarSet openVars( alt.openVars ); 1688 // xxx - find things in env that don't have a "representative type" and claim 1689 1689 // those are open vars? 1690 1690 PRINT( 1691 1691 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1692 1692 ) 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1693 // It's possible that a cast can throw away some values in a multiply-valued 1694 // expression. (An example is a cast-to-void, which casts from one value to 1695 // zero.) Figure out the prefix of the subexpression results that are cast 1696 // directly. The candidate is invalid if it has fewer results than there are 1697 1697 // types to cast to. 1698 1698 int discardedValues = alt.expr->result->size() - toType->size(); 1699 1699 if ( discardedValues < 0 ) continue; 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1700 // xxx - may need to go into tuple types and extract relevant types and use 1701 // unifyList. Note that currently, this does not allow casting a tuple to an 1702 1702 // atomic type (e.g. (int)([1, 2, 3])) 1703 1703 1704 1704 // unification run for side-effects 1705 1705 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); … … 1710 1710 // count one safe conversion for each value that is thrown away 1711 1711 thisCost.incSafe( discardedValues ); 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1712 Alternative newAlt{ 1713 new InitExpr{ 1714 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1715 std::move(newEnv), std::move(openVars), 1716 1716 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1717 1717 inferParameters( newAlt, back_inserter( candidates ) ); -
src/ResolvExpr/CastCost.cc
r1f1c102 rf53acdf8 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 ( const 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 // necessary for, e.g. unsigned long => void *105 // necessary for, e.g. unsigned long => void * 106 106 cost = Cost::unsafe; 107 107 } else { … … 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 // necessary for, e.g. void * => unsigned long129 // necessary for, e.g. void * => unsigned long 130 130 cost = Cost::unsafe; 131 131 } // if … … 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/CommonType.cc
r1f1c102 rf53acdf8 38 38 namespace ResolvExpr { 39 39 struct CommonType_old : public WithShortCircuiting { 40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );41 Type * get_result() const { return result; }40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 41 Type * get_result() const { return result; } 42 42 43 43 void previsit( BaseSyntaxNode * ) { visit_children = false; } … … 60 60 61 61 private: 62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer );63 template< typename RefType > void handleRefType( RefType * inst, Type *other );64 65 Type * result;66 Type * type2; // inherited62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ); 63 template< typename RefType > void handleRefType( RefType * inst, Type * other ); 64 65 Type * result; 66 Type * type2; // inherited 67 67 bool widenFirst, widenSecond; 68 68 const SymTab::Indexer &indexer; … … 80 80 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 81 81 ) 82 if ( (widenFirst || t2-> get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {82 if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) { 83 83 PRINT( 84 84 std::cerr << "widen okay" << std::endl; 85 85 ) 86 common-> get_qualifiers() |= t1->get_qualifiers();87 common-> get_qualifiers() |= t2->get_qualifiers();86 common->tq |= t1->tq; 87 common->tq |= t2->tq; 88 88 return common; 89 89 } … … 95 95 } 96 96 97 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {97 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 98 98 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 99 99 … … 127 127 std::cerr << "formal is reference; result should be reference" << std::endl; 128 128 ) 129 result = new ReferenceType( ref1-> get_qualifiers(), result );129 result = new ReferenceType( ref1->tq, result ); 130 130 } 131 131 PRINT( … … 138 138 139 139 type1->accept( visitor ); 140 Type * result = visitor.pass.get_result();140 Type * result = visitor.pass.get_result(); 141 141 if ( ! result ) { 142 142 // this appears to be handling for opaque type declarations 143 143 if ( widenSecond ) { 144 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {145 if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {146 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );144 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) { 145 if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) { 146 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 147 147 if ( type->get_base() ) { 148 Type::Qualifiers tq1 = type1-> get_qualifiers(), tq2 = type2->get_qualifiers();148 Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq; 149 149 AssertionSet have, need; 150 150 OpenVarSet newOpen( openVars ); 151 type1-> get_qualifiers()= Type::Qualifiers();152 type->get_base()-> get_qualifiers()= tq1;151 type1->tq = Type::Qualifiers(); 152 type->get_base()->tq = tq1; 153 153 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) { 154 154 result = type1->clone(); 155 result-> get_qualifiers()= tq1 | tq2;155 result->tq = tq1 | tq2; 156 156 } // if 157 type1-> get_qualifiers()= tq1;158 type->get_base()-> get_qualifiers()= Type::Qualifiers();157 type1->tq = tq1; 158 type->get_base()->tq = Type::Qualifiers(); 159 159 } // if 160 160 } // if … … 190 190 */ 191 191 { 192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 193 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 198 198 }, 199 199 { 200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 201 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 206 206 }, 207 207 { 208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 209 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 214 214 }, 215 215 { 216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 217 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 222 222 }, 223 223 { 224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt,224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt, 225 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 230 230 }, 231 231 { 232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt,232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, 233 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 238 238 }, 239 239 { 240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt,240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, 241 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 246 246 }, 247 247 { 248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt,248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, 249 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 254 254 }, 255 255 { 256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt,256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, 257 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 262 262 }, 263 263 { 264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt,264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, 265 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 270 270 }, 271 271 { 272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt,272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, 273 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 278 278 }, 279 279 { 280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 281 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 286 286 }, 287 287 { 288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128,288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 289 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 294 294 }, 295 295 { 296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128,296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 297 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 302 302 }, 303 303 { 304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16,304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 305 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 310 310 }, 311 311 { 312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex,312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 313 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, … … 318 318 }, 319 319 { 320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32,320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 321 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, … … 326 326 }, 327 327 { 328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 329 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, … … 334 334 }, 335 335 { 336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float,336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 337 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, … … 342 342 }, 343 343 { 344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 345 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, … … 350 350 }, 351 351 { 352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x,352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 353 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, … … 358 358 }, 359 359 { 360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 361 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, … … 366 366 }, 367 367 { 368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64,368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 369 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, … … 374 374 }, 375 375 { 376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 377 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, … … 382 382 }, 383 383 { 384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double,384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 385 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, … … 390 390 }, 391 391 { 392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 393 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, … … 398 398 }, 399 399 { 400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x,400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 401 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, … … 406 406 }, 407 407 { 408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 409 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, … … 422 422 }, 423 423 { 424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128,424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 425 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, … … 430 430 }, 431 431 { 432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 433 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, … … 438 438 }, 439 439 { 440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128,440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 441 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, … … 446 446 }, 447 447 { 448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble,448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 449 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, … … 454 454 }, 455 455 { 456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 457 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, … … 462 462 }, 463 463 { 464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x,464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 465 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, … … 470 470 }, 471 471 { 472 /* _FLDXC*/ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,472 /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 473 473 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 474 474 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, … … 481 481 // GENERATED END 482 482 static_assert( 483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 484 484 "Each basic type kind should have a corresponding row in the combined type matrix" 485 485 ); 486 486 487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) 488 488 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) { 489 489 } … … 491 491 void CommonType_old::postvisit( VoidType * ) {} 492 492 493 void CommonType_old::postvisit( BasicType * basicType ) {494 if ( BasicType * otherBasic = dynamic_cast< BasicType* >( type2 ) ) {493 void CommonType_old::postvisit( BasicType * basicType ) { 494 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) { 495 495 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ]; 496 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers()) || widenSecond ) ) {497 result = new BasicType( basicType-> get_qualifiers() | otherBasic->get_qualifiers(), newType );496 if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) { 497 result = new BasicType( basicType->tq | otherBasic->tq, newType ); 498 498 } // if 499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 500 500 // use signed int in lieu of the enum/zero/one type 501 501 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; 502 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers()) || widenSecond ) ) {503 result = new BasicType( basicType-> get_qualifiers() | type2->get_qualifiers(), newType );502 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) { 503 result = new BasicType( basicType->tq | type2->tq, newType ); 504 504 } // if 505 505 } // if … … 507 507 508 508 template< typename Pointer > 509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer ) {510 if ( TypeInstType * var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) { 510 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) { 511 511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); 512 512 if ( entry != openVars.end() ) { … … 517 517 } 518 518 result = voidPointer->clone(); 519 result-> get_qualifiers() |= otherPointer->get_qualifiers();520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) {523 if ( PointerType * otherPointer = dynamic_cast< PointerType* >( type2 ) ) {519 result->tq |= otherPointer->tq; 520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) { 523 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) { 524 524 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; 525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) { 526 526 getCommonWithVoidPointer( otherPointer, pointerType ); 527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) { 528 528 getCommonWithVoidPointer( pointerType, otherPointer ); 529 } else if ( ( pointerType->get_base()-> get_qualifiers() >= otherPointer->get_base()->get_qualifiers()|| widenFirst )530 && ( pointerType->get_base()-> get_qualifiers() <= otherPointer->get_base()->get_qualifiers()|| widenSecond ) ) {529 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst ) 530 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) { 531 531 // std::cerr << "middle case" << std::endl; 532 Type::Qualifiers tq1 = pointerType->get_base()-> get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();533 pointerType->get_base()-> get_qualifiers()= Type::Qualifiers();534 otherPointer->get_base()-> get_qualifiers()= Type::Qualifiers();532 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq; 533 pointerType->get_base()->tq = Type::Qualifiers(); 534 otherPointer->get_base()->tq = Type::Qualifiers(); 535 535 AssertionSet have, need; 536 536 OpenVarSet newOpen( openVars ); … … 542 542 result = otherPointer->clone(); 543 543 } // if 544 strict_dynamic_cast<PointerType *>(result)->base->get_qualifiers()= tq1 | tq2;544 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2; 545 545 } else { 546 546 /// std::cerr << "place for ptr-to-type" << std::endl; 547 547 } // if 548 pointerType->get_base()-> get_qualifiers()= tq1;549 otherPointer->get_base()-> get_qualifiers()= tq2;548 pointerType->get_base()->tq = tq1; 549 otherPointer->get_base()->tq = tq2; 550 550 } // if 551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 552 552 result = pointerType->clone(); 553 result-> get_qualifiers() |= type2->get_qualifiers();553 result->tq |= type2->tq; 554 554 } // if 555 555 } … … 557 557 void CommonType_old::postvisit( ArrayType * ) {} 558 558 559 void CommonType_old::postvisit( ReferenceType * refType ) {560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {559 void CommonType_old::postvisit( ReferenceType * refType ) { 560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) { 561 561 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; 562 // std::cerr << ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond) << std::endl;563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {562 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl; 563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) { 564 564 getCommonWithVoidPointer( otherRef, refType ); 565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) { 566 566 getCommonWithVoidPointer( refType, otherRef ); 567 } else if ( ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers()|| widenFirst )568 && ( refType->get_base()-> get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond ) ) {567 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) 568 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) { 569 569 // std::cerr << "middle case" << std::endl; 570 Type::Qualifiers tq1 = refType->get_base()-> get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();571 refType->get_base()-> get_qualifiers()= Type::Qualifiers();572 otherRef->get_base()-> get_qualifiers()= Type::Qualifiers();570 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq; 571 refType->get_base()->tq = Type::Qualifiers(); 572 otherRef->get_base()->tq = Type::Qualifiers(); 573 573 AssertionSet have, need; 574 574 OpenVarSet newOpen( openVars ); … … 579 579 result = otherRef->clone(); 580 580 } // if 581 strict_dynamic_cast<ReferenceType *>(result)->base->get_qualifiers()= tq1 | tq2;581 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2; 582 582 } else { 583 583 /// std::cerr << "place for ptr-to-type" << std::endl; 584 584 } // if 585 refType->get_base()-> get_qualifiers()= tq1;586 otherRef->get_base()-> get_qualifiers()= tq2;585 refType->get_base()->tq = tq1; 586 otherRef->get_base()->tq = tq2; 587 587 } // if 588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 589 589 result = refType->clone(); 590 result-> get_qualifiers() |= type2->get_qualifiers();590 result->tq |= type2->tq; 591 591 } // if 592 592 } … … 596 596 void CommonType_old::postvisit( UnionInstType * ) {} 597 597 598 void CommonType_old::postvisit( EnumInstType * enumInstType ) {599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {598 void CommonType_old::postvisit( EnumInstType * enumInstType ) { 599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 600 600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 601 601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); … … 606 606 } 607 607 608 void CommonType_old::postvisit( TypeInstType * inst ) {608 void CommonType_old::postvisit( TypeInstType * inst ) { 609 609 if ( widenFirst ) { 610 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );610 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ); 611 611 if ( nt ) { 612 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 613 613 if ( type->get_base() ) { 614 Type::Qualifiers tq1 = inst-> get_qualifiers(), tq2 = type2->get_qualifiers();614 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq; 615 615 AssertionSet have, need; 616 616 OpenVarSet newOpen( openVars ); 617 type2-> get_qualifiers()= Type::Qualifiers();618 type->get_base()-> get_qualifiers()= tq1;617 type2->tq = Type::Qualifiers(); 618 type->get_base()->tq = tq1; 619 619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) { 620 620 result = type2->clone(); 621 result-> get_qualifiers()= tq1 | tq2;621 result->tq = tq1 | tq2; 622 622 } // if 623 type2-> get_qualifiers()= tq2;624 type->get_base()-> get_qualifiers()= Type::Qualifiers();623 type2->tq = tq2; 624 type->get_base()->tq = Type::Qualifiers(); 625 625 } // if 626 626 } // if … … 631 631 void CommonType_old::postvisit( VarArgsType * ) {} 632 632 633 void CommonType_old::postvisit( ZeroType * zeroType ) {633 void CommonType_old::postvisit( ZeroType * zeroType ) { 634 634 if ( widenFirst ) { 635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {636 if ( widenSecond || zeroType-> get_qualifiers() <= type2->get_qualifiers()) {635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 636 if ( widenSecond || zeroType->tq <= type2->tq ) { 637 637 result = type2->clone(); 638 result-> get_qualifiers() |= zeroType->get_qualifiers();639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {641 result = new BasicType( zeroType-> get_qualifiers(), BasicType::SignedInt );642 result-> get_qualifiers() |= type2->get_qualifiers();643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) {638 result->tq |= zeroType->tq; 639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) { 641 result = new BasicType( zeroType->tq, BasicType::SignedInt ); 642 result->tq |= type2->tq; 643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) { 648 648 if ( widenFirst ) { 649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {650 if ( widenSecond || oneType-> get_qualifiers() <= type2->get_qualifiers()) {649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 650 if ( widenSecond || oneType->tq <= type2->tq ) { 651 651 result = type2->clone(); 652 result-> get_qualifiers() |= oneType->get_qualifiers();653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {655 result = new BasicType( oneType-> get_qualifiers(), BasicType::SignedInt );656 result-> get_qualifiers() |= type2->get_qualifiers();652 result->tq |= oneType->tq; 653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 655 result = new BasicType( oneType->tq, BasicType::SignedInt ); 656 result->tq |= type2->tq; 657 657 } 658 658 } … … 668 668 ast::ptr< ast::Type > result; 669 669 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 672 672 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 673 673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} … … 681 681 #warning remove casts when `commonTypes` moved to new AST 682 682 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ]; 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 688 688 ) { 689 689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 690 690 } 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 693 693 || dynamic_cast< const ast::ZeroType * >( type2 ) 694 694 || dynamic_cast< const ast::OneType * >( type2 ) … … 696 696 #warning remove casts when `commonTypes` moved to new AST 697 697 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 703 703 ) { 704 704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; … … 715 715 if ( entry != open.end() ) { 716 716 ast::AssertionSet need, have; 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 719 719 ) return; 720 720 } … … 727 727 void postvisit( const ast::PointerType * pointer ) { 728 728 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 733 733 ) { 734 734 getCommonWithVoidPointer( pointer2, pointer ); 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 739 739 ) { 740 740 getCommonWithVoidPointer( pointer, pointer2 ); … … 746 746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers; 747 747 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 749 749 // pointer{,2}->base are unchanged 750 750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; 751 751 reset_qualifiers( t1 ); 752 752 reset_qualifiers( t2 ); 753 753 754 754 ast::AssertionSet have, need; 755 755 ast::OpenVarSet newOpen{ open }; … … 758 758 if ( q1.val != q2.val ) { 759 759 // reset result->base->qualifiers to be union of two base qualifiers 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 762 762 )->base.get_and_mutate()->qualifiers = q1 | q2; 763 763 } … … 775 775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 776 776 if ( 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 778 778 ) { 779 779 getCommonWithVoidPointer( ref2, ref ); 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 782 782 ) { 783 783 getCommonWithVoidPointer( ref, ref2 ); … … 788 788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; 789 789 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 791 791 // ref{,2}->base are unchanged 792 792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; … … 800 800 if ( q1.val != q2.val ) { 801 801 // reset result->base->qualifiers to be union of two base qualifiers 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 804 804 )->base.get_and_mutate()->qualifiers = q1 | q2; 805 805 } … … 819 819 820 820 void postvisit( const ast::EnumInstType * enumInst ) { 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 823 823 || dynamic_cast< const ast::ZeroType * >( type2 ) 824 824 || dynamic_cast< const ast::OneType * >( type2 ) … … 834 834 if ( ! widen.first ) return; 835 835 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 838 838 ) { 839 839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; … … 860 860 void postvisit( const ast::ZeroType * zero ) { 861 861 if ( ! widen.first ) return; 862 if ( 862 if ( 863 863 dynamic_cast< const ast::BasicType * >( type2 ) 864 864 || dynamic_cast< const ast::PointerType * >( type2 ) … … 870 870 } 871 871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 872 result = new ast::BasicType{ 872 result = new ast::BasicType{ 873 873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 874 874 } … … 877 877 void postvisit( const ast::OneType * one ) { 878 878 if ( ! widen.first ) return; 879 if ( 879 if ( 880 880 dynamic_cast< const ast::BasicType * >( type2 ) 881 881 || dynamic_cast< const ast::EnumInstType * >( type2 ) … … 886 886 } 887 887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 888 result = new ast::BasicType{ 888 result = new ast::BasicType{ 889 889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 890 890 } … … 894 894 895 895 namespace { 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 900 900 ) { 901 901 ast::ptr<ast::Type> common; … … 926 926 927 927 ast::ptr< ast::Type > commonType( 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 931 931 ) { 932 932 unsigned depth1 = type1->referenceDepth(); … … 940 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 941 const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >(); 942 942 943 943 if ( depth1 > depth2 ) { 944 944 assert( ref1 ); … … 978 978 ast::OpenVarSet newOpen{ open }; 979 979 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 982 982 // {type1,type->base}->strong_ref >= 1 983 983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 984 984 reset_qualifiers( t1 ); 985 985 reset_qualifiers( t2, q1 ); 986 986 987 987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 988 988 result = t1; -
src/ResolvExpr/ConversionCost.cc
r1f1c102 rf53acdf8 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 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 52 52 if ( eqvClass->type ) { 53 53 return conversionCost( src, eqvClass->type, indexer, env ); … … 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 … … 218 218 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 219 219 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, },221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, },235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, },236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, },237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, },238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, },239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, },240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, },241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, },242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, },243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, },244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, },245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, },246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, },247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, },220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, 221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, }, 235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, }, 236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, }, 237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, }, 238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, }, 239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, }, 240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, }, 241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, }, 242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, }, 243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, }, 244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, }, 245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, }, 246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, }, 247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, }, 248 248 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, 3, 4, 4, }, 249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, },250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, },251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, },252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, },253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, },254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, },255 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, }, 250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, }, 251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, }, 252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, }, 253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, }, 254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, }, 255 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 256 256 }; // costMatrix 257 257 static const int maxIntCost = 15; 258 258 // GENERATED END 259 259 static_assert( 260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 261 261 "Missing row in the cost matrix" 262 262 ); … … 266 266 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 267 267 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 296 296 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, },298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, },299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, },300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, },301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, },302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, },303 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, }, 298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, }, 299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, }, 300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, }, 301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, }, 302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, }, 303 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 304 304 }; // signMatrix 305 305 // GENERATED END 306 306 static_assert( 307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 308 308 "Missing row in the sign matrix" 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 ) {414 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {411 void ConversionCost::postvisit( const TraitInstType * ) {} 412 413 void ConversionCost::postvisit( const TypeInstType * inst ) { 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 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {421 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );420 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) { 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(); 435 435 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 436 Cost newCost = costFunc( * srcIt++, *destIt++, indexer, env );436 Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env ); 437 437 if ( newCost == Cost::infinity ) { 438 438 return; … … 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 ) ) {460 // copied from visit(BasicType *) for signed int, but +1 for safe conversions461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];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 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 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 ) ) {479 // copied from visit(BasicType *) for signed int, but +1 for safe conversions480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic-> get_kind()];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 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 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 … … 729 729 auto dstEnd = dstAsTuple->types.end(); 730 730 while ( srcIt != srcEnd && dstIt != dstEnd ) { 731 Cost newCost = costCalc( * srcIt++, *dstIt++, symtab, env );731 Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env ); 732 732 if ( newCost == Cost::infinity ) { 733 733 return; -
src/ResolvExpr/ConversionCost.h
r1f1c102 rf53acdf8 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
r1f1c102 rf53acdf8 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
r1f1c102 rf53acdf8 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/ResolveAssertions.cc
r1f1c102 rf53acdf8 9 9 // Author : Aaron B. Moss 10 10 // Created On : Fri Oct 05 13:46:00 2018 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Fri Oct 05 13:46:00 201813 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 16:10:37 2019 13 // Update Count : 2 14 14 // 15 15 … … 197 197 } 198 198 if ( i == b.size() /* && i < a.size() */ ) return 1; 199 199 200 200 int c = a[i].compare( b[i] ); 201 201 if ( c != 0 ) return c; … … 220 220 221 221 /// Initial resolution state for an alternative 222 ResnState( Alternative & a, SymTab::Indexer& indexer )222 ResnState( Alternative & a, SymTab::Indexer & indexer ) 223 223 : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) { 224 224 need.swap( a.need ); … … 226 226 227 227 /// Updated resolution state with new need-list 228 ResnState( ResnState && o, IterateFlag )228 ResnState( ResnState && o, IterateFlag ) 229 229 : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(), 230 230 inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) { … … 234 234 235 235 /// Binds a single assertion, updating resolution state 236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative& alt,237 AssnCandidate & match, InferCache& inferred ) {238 239 DeclarationWithType* candidate = match.cdata.id;240 assertf( candidate-> get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost );236 void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt, 237 AssnCandidate & match, InferCache & inferred ) { 238 239 const DeclarationWithType * candidate = match.cdata.id; 240 assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 241 242 Expression * varExpr = match.cdata.combine( alt.cvtCost ); 243 243 delete varExpr->result; 244 244 varExpr->result = match.adjType->clone(); … … 247 247 // place newly-inferred assertion in proper place in cache 248 248 inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{ 249 candidate-> get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),249 candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(), 250 250 varExpr }; 251 251 } 252 252 253 253 /// Adds a captured assertion to the symbol table 254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer &indexer ) {254 void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) { 255 255 for ( auto& i : assertSet ) { 256 256 if ( i.second.isUsed ) { … … 264 264 265 265 /// Resolve a single assertion, in context 266 bool resolveAssertion( AssertionItem & assn, ResnState& resn ) {266 bool resolveAssertion( AssertionItem & assn, ResnState & resn ) { 267 267 // skip unused assertions 268 268 if ( ! assn.info.isUsed ) return true; … … 274 274 // find the candidates that unify with the desired type 275 275 CandidateList matches; 276 for ( const auto & cdata : candidates ) {277 DeclarationWithType* candidate = cdata.id;276 for ( const auto & cdata : candidates ) { 277 const DeclarationWithType * candidate = cdata.id; 278 278 279 279 // build independent unification context for candidate … … 281 281 TypeEnvironment newEnv{ resn.alt.env }; 282 282 OpenVarSet newOpenVars{ resn.alt.openVars }; 283 Type * adjType = candidate->get_type()->clone();283 Type * adjType = candidate->get_type()->clone(); 284 284 adjustExprType( adjType, newEnv, resn.indexer ); 285 285 renameTyVars( adjType ); … … 368 368 std::string resKey = SymTab::Mangler::mangleType( resType ); 369 369 delete resType; 370 return std::move( resKey );371 } 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 370 return resKey; 371 } 372 373 /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 374 374 /// threshold. 375 375 void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) { … … 406 406 ResnList resns{ ResnState{ alt, root_indexer } }; 407 407 ResnList new_resns{}; 408 408 409 409 // Pruning thresholds by result type of the output alternatives. 410 410 // Alternatives *should* be generated in sorted order, so no need to retroactively prune -
src/ResolvExpr/Resolver.cc
r1f1c102 rf53acdf8 562 562 // TODO: Replace *exception type with &exception type. 563 563 if ( throwStmt->get_expr() ) { 564 StructDecl * exception_decl = 565 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 564 const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 566 565 assert( exception_decl ); 567 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl) );566 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) ); 568 567 findSingleExpression( throwStmt->expr, exceptType, indexer ); 569 568 } … … 972 971 /// Calls the CandidateFinder and finds the single best candidate 973 972 CandidateRef findUnfinishedKindExpression( 974 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 973 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 975 974 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 976 975 ) { … … 994 993 // produce invalid error if no candidates 995 994 if ( candidates.empty() ) { 996 SemanticError( untyped, 997 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 995 SemanticError( untyped, 996 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 998 997 "expression: ") ); 999 998 } … … 1031 1030 if ( winners.size() != 1 ) { 1032 1031 std::ostringstream stream; 1033 stream << "Cannot choose between " << winners.size() << " alternatives for " 1032 stream << "Cannot choose between " << winners.size() << " alternatives for " 1034 1033 << kind << (kind != "" ? " " : "") << "expression\n"; 1035 1034 ast::print( stream, untyped ); … … 1054 1053 struct StripCasts_new final { 1055 1054 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1056 if ( 1057 castExpr->isGenerated 1058 && typesCompatible( castExpr->arg->result, castExpr->result ) 1055 if ( 1056 castExpr->isGenerated 1057 && typesCompatible( castExpr->arg->result, castExpr->result ) 1059 1058 ) { 1060 1059 // generated cast is the same type as its argument, remove it after keeping env 1061 return ast::mutate_field( 1060 return ast::mutate_field( 1062 1061 castExpr->arg.get(), &ast::Expr::env, castExpr->env ); 1063 1062 } … … 1088 1087 1089 1088 /// Establish post-resolver invariants for expressions 1090 void finishExpr( 1091 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1089 void finishExpr( 1090 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1092 1091 const ast::TypeSubstitution * oldenv = nullptr 1093 1092 ) { 1094 1093 // set up new type substitution for expression 1095 ast::ptr< ast::TypeSubstitution > newenv = 1094 ast::ptr< ast::TypeSubstitution > newenv = 1096 1095 oldenv ? oldenv : new ast::TypeSubstitution{}; 1097 1096 env.writeToSubstitution( *newenv.get_and_mutate() ); … … 1102 1101 } // anonymous namespace 1103 1102 1104 1103 1105 1104 ast::ptr< ast::Expr > resolveInVoidContext( 1106 1105 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1107 1106 ) { 1108 1107 assertf( expr, "expected a non-null expression" ); 1109 1108 1110 1109 // set up and resolve expression cast to void 1111 1110 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1112 CandidateRef choice = findUnfinishedKindExpression( 1111 CandidateRef choice = findUnfinishedKindExpression( 1113 1112 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1114 1113 1115 1114 // a cast expression has either 0 or 1 interpretations (by language rules); 1116 1115 // if 0, an exception has already been thrown, and this code will not run … … 1122 1121 1123 1122 namespace { 1124 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1123 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1125 1124 /// context. 1126 ast::ptr< ast::Expr > findVoidExpression( 1125 ast::ptr< ast::Expr > findVoidExpression( 1127 1126 const ast::Expr * untyped, const ast::SymbolTable & symtab 1128 1127 ) { … … 1134 1133 } 1135 1134 1136 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1135 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1137 1136 /// lowest cost, returning the resolved version 1138 1137 ast::ptr< ast::Expr > findKindExpression( 1139 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1140 std::function<bool(const Candidate &)> pred = anyCandidate, 1138 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1139 std::function<bool(const Candidate &)> pred = anyCandidate, 1141 1140 const std::string & kind = "", ResolvMode mode = {} 1142 1141 ) { 1143 1142 if ( ! untyped ) return {}; 1144 CandidateRef choice = 1143 CandidateRef choice = 1145 1144 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1146 1145 finishExpr( choice->expr, choice->env, untyped->env ); … … 1149 1148 1150 1149 /// Resolve `untyped` to the single expression whose candidate is the best match 1151 ast::ptr< ast::Expr > findSingleExpression( 1152 const ast::Expr * untyped, const ast::SymbolTable & symtab 1150 ast::ptr< ast::Expr > findSingleExpression( 1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1153 1152 ) { 1154 1153 return findKindExpression( untyped, symtab ); … … 1170 1169 bool hasIntegralType( const Candidate & i ) { 1171 1170 const ast::Type * type = i.expr->result; 1172 1171 1173 1172 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1174 1173 return bt->isInteger(); 1175 } else if ( 1176 dynamic_cast< const ast::EnumInstType * >( type ) 1174 } else if ( 1175 dynamic_cast< const ast::EnumInstType * >( type ) 1177 1176 || dynamic_cast< const ast::ZeroType * >( type ) 1178 1177 || dynamic_cast< const ast::OneType * >( type ) … … 1183 1182 1184 1183 /// Resolve `untyped` as an integral expression, returning the resolved version 1185 ast::ptr< ast::Expr > findIntegralExpression( 1186 const ast::Expr * untyped, const ast::SymbolTable & symtab 1184 ast::ptr< ast::Expr > findIntegralExpression( 1185 const ast::Expr * untyped, const ast::SymbolTable & symtab 1187 1186 ) { 1188 1187 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); … … 1192 1191 bool isCharType( const ast::Type * t ) { 1193 1192 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1194 return bt->kind == ast::BasicType::Char 1195 || bt->kind == ast::BasicType::SignedChar 1193 return bt->kind == ast::BasicType::Char 1194 || bt->kind == ast::BasicType::SignedChar 1196 1195 || bt->kind == ast::BasicType::UnsignedChar; 1197 1196 } … … 1253 1252 } 1254 1253 1255 ast::ptr< ast::Init > resolveCtorInit( 1256 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1254 ast::ptr< ast::Init > resolveCtorInit( 1255 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1257 1256 ) { 1258 1257 assert( ctorInit ); … … 1261 1260 } 1262 1261 1263 ast::ptr< ast::Expr > resolveStmtExpr( 1264 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1262 ast::ptr< ast::Expr > resolveStmtExpr( 1263 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1265 1264 ) { 1266 1265 assert( stmtExpr ); … … 1303 1302 1304 1303 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1305 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1306 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1307 // twice. The second analysis changes `initContext` because a function type can contain 1308 // object declarations in the return and parameter types. Therefore each value of 1309 // `initContext` is retained so the type on the first analysis is preserved and used for 1304 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1305 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1306 // twice. The second analysis changes `initContext` because a function type can contain 1307 // object declarations in the return and parameter types. Therefore each value of 1308 // `initContext` is retained so the type on the first analysis is preserved and used for 1310 1309 // selecting the RHS. 1311 1310 GuardValue( currentObject ); 1312 1311 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1313 1312 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1314 // enumerator initializers should not use the enum type to initialize, since the 1313 // enumerator initializers should not use the enum type to initialize, since the 1315 1314 // enum type is still incomplete at this point. Use `int` instead. 1316 currentObject = ast::CurrentObject{ 1315 currentObject = ast::CurrentObject{ 1317 1316 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1318 1317 } … … 1325 1324 } 1326 1325 1327 const ast::StaticAssertDecl * Resolver_new::previsit( 1328 const ast::StaticAssertDecl * assertDecl 1326 const ast::StaticAssertDecl * Resolver_new::previsit( 1327 const ast::StaticAssertDecl * assertDecl 1329 1328 ) { 1330 return ast::mutate_field( 1331 assertDecl, &ast::StaticAssertDecl::cond, 1329 return ast::mutate_field( 1330 assertDecl, &ast::StaticAssertDecl::cond, 1332 1331 findIntegralExpression( assertDecl->cond, symtab ) ); 1333 1332 } … … 1338 1337 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1339 1338 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1340 ast::mutate_field( 1341 type, &PtrType::dimension, 1339 ast::mutate_field( 1340 type, &PtrType::dimension, 1342 1341 findSingleExpression( type->dimension, sizeType, symtab ) ); 1343 1342 } … … 1356 1355 visit_children = false; 1357 1356 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" ); 1358 1359 return ast::mutate_field( 1357 1358 return ast::mutate_field( 1360 1359 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1361 1360 } … … 1364 1363 visit_children = false; 1365 1364 1366 asmExpr = ast::mutate_field( 1365 asmExpr = ast::mutate_field( 1367 1366 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1368 1367 1369 1368 if ( asmExpr->inout ) { 1370 1369 asmExpr = ast::mutate_field( 1371 1370 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) ); 1372 1371 } 1373 1372 1374 1373 return asmExpr; 1375 1374 } … … 1388 1387 1389 1388 const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1390 return ast::mutate_field( 1389 return ast::mutate_field( 1391 1390 whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) ); 1392 1391 } … … 1409 1408 GuardValue( currentObject ); 1410 1409 switchStmt = ast::mutate_field( 1411 switchStmt, &ast::SwitchStmt::cond, 1410 switchStmt, &ast::SwitchStmt::cond, 1412 1411 findIntegralExpression( switchStmt->cond, symtab ) ); 1413 1412 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; … … 1420 1419 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1421 1420 "expression." ); 1422 1423 ast::ptr< ast::Expr > untyped = 1421 1422 ast::ptr< ast::Expr > untyped = 1424 1423 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1425 1424 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab ); 1426 1427 // case condition cannot have a cast in C, so it must be removed here, regardless of 1425 1426 // case condition cannot have a cast in C, so it must be removed here, regardless of 1428 1427 // whether it would perform a conversion. 1429 1428 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1430 1429 swap_and_save_env( newExpr, castExpr->arg ); 1431 1430 } 1432 1431 1433 1432 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1434 1433 } … … 1443 1442 ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} }; 1444 1443 branchStmt = ast::mutate_field( 1445 branchStmt, &ast::BranchStmt::computedTarget, 1444 branchStmt, &ast::BranchStmt::computedTarget, 1446 1445 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1447 1446 } … … 1453 1452 if ( returnStmt->expr ) { 1454 1453 returnStmt = ast::mutate_field( 1455 returnStmt, &ast::ReturnStmt::expr, 1454 returnStmt, &ast::ReturnStmt::expr, 1456 1455 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1457 1456 } … … 1462 1461 visit_children = false; 1463 1462 if ( throwStmt->expr ) { 1464 const ast::StructDecl * exceptionDecl = 1463 const ast::StructDecl * exceptionDecl = 1465 1464 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1466 1465 assert( exceptionDecl ); 1467 ast::ptr< ast::Type > exceptType = 1466 ast::ptr< ast::Type > exceptType = 1468 1467 new ast::PointerType{ new ast::StructInstType{ exceptionDecl } }; 1469 1468 throwStmt = ast::mutate_field( 1470 throwStmt, &ast::ThrowStmt::expr, 1469 throwStmt, &ast::ThrowStmt::expr, 1471 1470 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1472 1471 } … … 1477 1476 if ( catchStmt->cond ) { 1478 1477 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1479 catchStmt = ast::mutate_field( 1480 catchStmt, &ast::CatchStmt::cond, 1478 catchStmt = ast::mutate_field( 1479 catchStmt, &ast::CatchStmt::cond, 1481 1480 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1482 1481 } … … 1506 1505 1507 1506 if ( clause.target.args.empty() ) { 1508 SemanticError( stmt->location, 1507 SemanticError( stmt->location, 1509 1508 "Waitfor clause must have at least one mutex parameter"); 1510 1509 } 1511 1510 1512 1511 // Find all alternatives for all arguments in canonical form 1513 std::vector< CandidateFinder > argFinders = 1512 std::vector< CandidateFinder > argFinders = 1514 1513 funcFinder.findSubExprs( clause.target.args ); 1515 1514 1516 1515 // List all combinations of arguments 1517 1516 std::vector< CandidateList > possibilities; … … 1519 1518 1520 1519 // For every possible function: 1521 // * try matching the arguments to the parameters, not the other way around because 1520 // * try matching the arguments to the parameters, not the other way around because 1522 1521 // more arguments than parameters 1523 1522 CandidateList funcCandidates; … … 1526 1525 for ( CandidateRef & func : funcFinder.candidates ) { 1527 1526 try { 1528 auto pointerType = dynamic_cast< const ast::PointerType * >( 1527 auto pointerType = dynamic_cast< const ast::PointerType * >( 1529 1528 func->expr->result->stripReferences() ); 1530 1529 if ( ! pointerType ) { 1531 SemanticError( stmt->location, func->expr->result.get(), 1530 SemanticError( stmt->location, func->expr->result.get(), 1532 1531 "candidate not viable: not a pointer type\n" ); 1533 1532 } … … 1535 1534 auto funcType = pointerType->base.as< ast::FunctionType >(); 1536 1535 if ( ! funcType ) { 1537 SemanticError( stmt->location, func->expr->result.get(), 1536 SemanticError( stmt->location, func->expr->result.get(), 1538 1537 "candidate not viable: not a function type\n" ); 1539 1538 } … … 1544 1543 1545 1544 if( ! nextMutex( param, paramEnd ) ) { 1546 SemanticError( stmt->location, funcType, 1545 SemanticError( stmt->location, funcType, 1547 1546 "candidate function not viable: no mutex parameters\n"); 1548 1547 } … … 1560 1559 ast::AssertionSet need, have; 1561 1560 ast::TypeEnvironment resultEnv{ func->env }; 1562 // Add all type variables as open so that those not used in the 1561 // Add all type variables as open so that those not used in the 1563 1562 // parameter list are still considered open 1564 1563 resultEnv.add( funcType->forall ); … … 1580 1579 unsigned n_mutex_param = 0; 1581 1580 1582 // For every argument of its set, check if it matches one of the 1581 // For every argument of its set, check if it matches one of the 1583 1582 // parameters. The order is important 1584 1583 for ( auto & arg : argsList ) { … … 1587 1586 // We ran out of parameters but still have arguments. 1588 1587 // This function doesn't match 1589 SemanticError( stmt->location, funcType, 1588 SemanticError( stmt->location, funcType, 1590 1589 toString("candidate function not viable: too many mutex " 1591 1590 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1594 1593 ++n_mutex_param; 1595 1594 1596 // Check if the argument matches the parameter type in the current 1595 // Check if the argument matches the parameter type in the current 1597 1596 // scope 1598 1597 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1599 if ( 1600 ! unify( 1601 arg->expr->result, paramType, resultEnv, need, have, open, 1602 symtab ) 1598 if ( 1599 ! unify( 1600 arg->expr->result, paramType, resultEnv, need, have, open, 1601 symtab ) 1603 1602 ) { 1604 1603 // Type doesn't match … … 1627 1626 } while ( nextMutex( param, paramEnd ) ); 1628 1627 1629 // We ran out of arguments but still have parameters left; this 1628 // We ran out of arguments but still have parameters left; this 1630 1629 // function doesn't match 1631 SemanticError( stmt->location, funcType, 1630 SemanticError( stmt->location, funcType, 1632 1631 toString( "candidate function not viable: too few mutex " 1633 1632 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1657 1656 // Make sure correct number of arguments 1658 1657 if( funcCandidates.empty() ) { 1659 SemanticErrorException top( stmt->location, 1658 SemanticErrorException top( stmt->location, 1660 1659 "No alternatives for function in call to waitfor" ); 1661 1660 top.append( errors ); … … 1664 1663 1665 1664 if( argsCandidates.empty() ) { 1666 SemanticErrorException top( stmt->location, 1667 "No alternatives for arguments in call to waitfor" ); 1665 SemanticErrorException top( stmt->location, 1666 "No alternatives for arguments in call to waitfor" ); 1668 1667 top.append( errors ); 1669 1668 throw top; … … 1671 1670 1672 1671 if( funcCandidates.size() > 1 ) { 1673 SemanticErrorException top( stmt->location, 1672 SemanticErrorException top( stmt->location, 1674 1673 "Ambiguous function in call to waitfor" ); 1675 1674 top.append( errors ); … … 1686 1685 // build new clause 1687 1686 ast::WaitForStmt::Clause clause2; 1688 1687 1689 1688 clause2.target.func = funcCandidates.front()->expr; 1690 1689 1691 1690 clause2.target.args.reserve( clause.target.args.size() ); 1692 1691 for ( auto arg : argsCandidates.front() ) { … … 1708 1707 ast::WaitForStmt::Timeout timeout2; 1709 1708 1710 ast::ptr< ast::Type > target = 1709 ast::ptr< ast::Type > target = 1711 1710 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1712 1711 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); … … 1740 1739 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1741 1740 visit_children = false; 1742 // resolve initialization using the possibilities as determined by the `currentObject` 1741 // resolve initialization using the possibilities as determined by the `currentObject` 1743 1742 // cursor. 1744 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1743 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1745 1744 singleInit->location, singleInit->value, currentObject.getOptions() }; 1746 1745 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); … … 1751 1750 1752 1751 // discard InitExpr wrapper and retain relevant pieces. 1753 // `initExpr` may have inferred params in the case where the expression specialized a 1754 // function pointer, and newExpr may already have inferParams of its own, so a simple 1752 // `initExpr` may have inferred params in the case where the expression specialized a 1753 // function pointer, and newExpr may already have inferParams of its own, so a simple 1755 1754 // swap is not sufficient 1756 1755 ast::Expr::InferUnion inferred = initExpr->inferred; … … 1758 1757 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1759 1758 1760 // get the actual object's type (may not exactly match what comes back from the resolver 1759 // get the actual object's type (may not exactly match what comes back from the resolver 1761 1760 // due to conversions) 1762 1761 const ast::Type * initContext = currentObject.getCurrentType(); … … 1770 1769 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1771 1770 if ( isCharType( pt->base ) ) { 1772 // strip cast if we're initializing a char[] with a char* 1771 // strip cast if we're initializing a char[] with a char* 1773 1772 // e.g. char x[] = "hello" 1774 1773 if ( auto ce = newExpr.as< ast::CastExpr >() ) { … … 1793 1792 assert( listInit->designations.size() == listInit->initializers.size() ); 1794 1793 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1795 // iterate designations and initializers in pairs, moving the cursor to the current 1794 // iterate designations and initializers in pairs, moving the cursor to the current 1796 1795 // designated object and resolving the initializer against that object 1797 1796 listInit = ast::mutate_field_index( 1798 listInit, &ast::ListInit::designations, i, 1797 listInit, &ast::ListInit::designations, i, 1799 1798 currentObject.findNext( listInit->designations[i] ) ); 1800 1799 listInit = ast::mutate_field_index( … … 1818 1817 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr ); 1819 1818 1820 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1821 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1819 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1820 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1822 1821 // clean up generated code 1823 1822 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) { -
src/ResolvExpr/Unify.cc
r1f1c102 rf53acdf8 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 104 bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {104 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { 105 105 TypeEnvironment newEnv; 106 106 OpenVarSet openVars, closedVars; // added closedVars 107 107 AssertionSet needAssertions, haveAssertions; 108 Type * newFirst = first->clone(), *newSecond = second->clone();108 Type * newFirst = first->clone(), * newSecond = second->clone(); 109 109 env.apply( newFirst ); 110 110 env.apply( newSecond ); … … 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
r1f1c102 rf53acdf8 28 28 #include "SynTree/SynTree.h" 29 29 #include "SynTree/Type.h" 30 #include "SymTab/Indexer.h" 30 31 namespace SymTab { 32 class Indexer; 33 } 31 34 32 35 namespace ResolvExpr { … … 60 63 // in AdjustExprType.cc 61 64 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function 62 void adjustExprType( Type *& type, const TypeEnvironment &env, const SymTab::Indexer &indexer );65 void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 63 66 64 67 /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer … … 66 69 67 70 template< typename ForwardIterator > 68 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {71 void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) { 69 72 while ( begin != end ) { 70 73 adjustExprType( *begin++, env, indexer ); … … 73 76 74 77 /// Replaces array types with equivalent pointer, and function types with a pointer-to-function 75 const ast::Type * adjustExprType( 78 const ast::Type * adjustExprType( 76 79 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab ); 77 80 78 81 // 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, 82 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 83 Cost castCost( 84 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 82 85 const ast::TypeEnvironment & env ); 83 86 84 87 // 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, 88 Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 89 Cost conversionCost( 90 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 88 91 const ast::TypeEnvironment & env ); 89 92 90 93 // in AlternativeFinder.cc 91 Cost computeConversionCost( Type * actualType, Type *formalType,92 const SymTab::Indexer & indexer, const TypeEnvironment &env );94 Cost computeConversionCost( Type * actualType, Type * formalType, 95 const SymTab::Indexer & indexer, const TypeEnvironment & env ); 93 96 94 97 // in PtrsAssignable.cc 95 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );98 int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env ); 96 99 int ptrsAssignable( const ast::Type * src, const ast::Type * dst, 97 100 const ast::TypeEnvironment & env ); 98 101 99 102 // in PtrsCastable.cc 100 int ptrsCastable( 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, 103 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 104 int ptrsCastable( 105 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 103 106 const ast::TypeEnvironment & env ); 104 107 105 108 // in Unify.cc 106 bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );107 bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );108 109 inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {109 bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 110 bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env ); 111 112 inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 110 113 TypeEnvironment env; 111 114 return typesCompatible( t1, t2, indexer, env ); 112 115 } 113 116 114 inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {117 inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) { 115 118 TypeEnvironment env; 116 119 return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env ); 117 120 } 118 121 119 bool typesCompatible( 120 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 122 bool typesCompatible( 123 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 121 124 const ast::TypeEnvironment & env = {} ); 122 125 123 126 bool typesCompatibleIgnoreQualifiers( 124 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 127 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 125 128 const ast::TypeEnvironment & env = {} ); 126 129 … … 131 134 132 135 // in CommonType.cc 133 Type * commonType( Type * type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );136 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars ); 134 137 ast::ptr< ast::Type > commonType( 135 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 138 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 136 139 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open ); 137 140 138 141 // in PolyCost.cc 139 int polyCost( Type * type, const TypeEnvironment &env, const SymTab::Indexer &indexer );140 int polyCost( 142 int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer ); 143 int polyCost( 141 144 const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ); 142 145 143 146 // in SpecCost.cc 144 int specCost( Type * type );147 int specCost( Type * type ); 145 148 int specCost( const ast::Type * type ); 146 149 147 150 // in Occurs.cc 148 bool occurs( Type * type, std::string varName, const TypeEnvironment &env );151 bool occurs( Type * type, std::string varName, const TypeEnvironment & env ); 149 152 // new AST version in TypeEnvironment.cpp (only place it was used in old AST) 150 153 151 template<typename Iter> 152 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {154 template<typename Iter> 155 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) { 153 156 while ( begin != end ) { 154 157 if ( occurs( ty, *begin, env ) ) return true; … … 176 179 177 180 /// 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 181 static inline void flatten( 182 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 180 183 ) { 181 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 184 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) { 182 185 for ( const ast::Type * t : tupleType->types ) { 183 186 flatten( t, out ); … … 197 200 198 201 // in TypeEnvironment.cc 199 bool isFtype( Type * type );202 bool isFtype( Type * type ); 200 203 } // namespace ResolvExpr 201 204 -
src/SymTab/Indexer.cc
r1f1c102 rf53acdf8 74 74 } 75 75 76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; } 79 79 80 80 Indexer::~Indexer() { … … 84 84 void Indexer::lazyInitScope() { 85 85 if ( repScope < scope ) { 86 ++* stats().lazy_scopes;86 ++* stats().lazy_scopes; 87 87 // create rollback 88 prevScope = std::make_shared<Indexer>( * this );88 prevScope = std::make_shared<Indexer>( * this ); 89 89 // update repScope 90 90 repScope = scope; … … 95 95 ++scope; 96 96 97 ++* stats().new_scopes;97 ++* stats().new_scopes; 98 98 stats().avg_scope_depth->push( scope ); 99 99 stats().max_scope_depth->push( scope ); … … 103 103 if ( repScope == scope ) { 104 104 Ptr prev = prevScope; // make sure prevScope stays live 105 * this = std::move(*prevScope); // replace with previous scope105 * this = std::move(* prevScope); // replace with previous scope 106 106 } 107 107 … … 109 109 } 110 110 111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {112 ++* stats().lookup_calls;111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const { 112 ++* stats().lookup_calls; 113 113 if ( ! idTable ) return; 114 114 115 ++* stats().map_lookups;115 ++* stats().map_lookups; 116 116 auto decls = idTable->find( id ); 117 117 if ( decls == idTable->end() ) return; … … 122 122 } 123 123 124 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {125 ++* stats().lookup_calls;124 const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { 125 ++* stats().lookup_calls; 126 126 if ( ! typeTable ) return nullptr; 127 ++* stats().map_lookups;127 ++* stats().map_lookups; 128 128 auto it = typeTable->find( id ); 129 129 return it == typeTable->end() ? nullptr : it->second.decl; 130 130 } 131 131 132 StructDecl *Indexer::lookupStruct( const std::string &id ) const {133 ++* stats().lookup_calls;132 const StructDecl * Indexer::lookupStruct( const std::string & id ) const { 133 ++* stats().lookup_calls; 134 134 if ( ! structTable ) return nullptr; 135 ++* stats().map_lookups;135 ++* stats().map_lookups; 136 136 auto it = structTable->find( id ); 137 137 return it == structTable->end() ? nullptr : it->second.decl; 138 138 } 139 139 140 EnumDecl *Indexer::lookupEnum( const std::string &id ) const {141 ++* stats().lookup_calls;140 const EnumDecl * Indexer::lookupEnum( const std::string & id ) const { 141 ++* stats().lookup_calls; 142 142 if ( ! enumTable ) return nullptr; 143 ++* stats().map_lookups;143 ++* stats().map_lookups; 144 144 auto it = enumTable->find( id ); 145 145 return it == enumTable->end() ? nullptr : it->second.decl; 146 146 } 147 147 148 UnionDecl *Indexer::lookupUnion( const std::string &id ) const {149 ++* stats().lookup_calls;148 const UnionDecl * Indexer::lookupUnion( const std::string & id ) const { 149 ++* stats().lookup_calls; 150 150 if ( ! unionTable ) return nullptr; 151 ++* stats().map_lookups;151 ++* stats().map_lookups; 152 152 auto it = unionTable->find( id ); 153 153 return it == unionTable->end() ? nullptr : it->second.decl; 154 154 } 155 155 156 TraitDecl *Indexer::lookupTrait( const std::string &id ) const {157 ++* stats().lookup_calls;156 const TraitDecl * Indexer::lookupTrait( const std::string & id ) const { 157 ++* stats().lookup_calls; 158 158 if ( ! traitTable ) return nullptr; 159 ++* stats().map_lookups;159 ++* stats().map_lookups; 160 160 auto it = traitTable->find( id ); 161 161 return it == traitTable->end() ? nullptr : it->second.decl; 162 162 } 163 163 164 const Indexer * Indexer::atScope( unsigned long target ) const {164 const Indexer * Indexer::atScope( unsigned long target ) const { 165 165 // by lazy construction, final indexer in list has repScope 0, cannot be > target 166 166 // otherwise, will find first scope representing the target 167 const Indexer * indexer = this;167 const Indexer * indexer = this; 168 168 while ( indexer->repScope > target ) { 169 169 indexer = indexer->prevScope.get(); … … 172 172 } 173 173 174 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {174 const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const { 175 175 return atScope( 0 )->lookupType( id ); 176 176 } 177 177 178 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {178 const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const { 179 179 return atScope( 0 )->lookupStruct( id ); 180 180 } 181 181 182 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {182 const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const { 183 183 return atScope( 0 )->lookupUnion( id ); 184 184 } 185 185 186 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {186 const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const { 187 187 return atScope( 0 )->lookupEnum( id ); 188 188 } 189 189 190 bool isFunction( DeclarationWithType * decl ) {190 bool isFunction( const DeclarationWithType * decl ) { 191 191 return GenPoly::getFunctionType( decl->get_type() ); 192 192 } 193 193 194 bool isObject( DeclarationWithType * decl ) {194 bool isObject( const DeclarationWithType * decl ) { 195 195 return ! isFunction( decl ); 196 196 } 197 197 198 bool isDefinition( DeclarationWithType * decl ) {199 if ( FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl ) ) {198 bool isDefinition( const DeclarationWithType * decl ) { 199 if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) { 200 200 // a function is a definition if it has a body 201 201 return func->statements; … … 207 207 } 208 208 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, DeclarationWithType *added,212 Indexer::OnConflict handleConflicts, BaseSyntaxNode* deleteStmt ) {213 // if we're giving the same name mangling to things of different types then there is 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, const DeclarationWithType * added, 212 Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) { 213 // if we're giving the same name mangling to things of different types then there is 214 214 // something wrong 215 215 assert( (isObject( added ) && isObject( existing.id ) ) … … 219 219 // new definition shadows the autogenerated one, even at the same scope 220 220 return false; 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 223 223 added->get_type(), existing.id->get_type(), Indexer() ) ) { 224 224 … … 238 238 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 239 239 if ( handleConflicts.mode == OnConflict::Error ) { 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 243 243 "duplicate object definition for " ); 244 244 } … … 255 255 } 256 256 257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const {257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const { 258 258 if ( ! idTable ) return false; 259 259 260 ++* stats().map_lookups;260 ++* stats().map_lookups; 261 261 auto decls = idTable->find( id ); 262 262 if ( decls == idTable->end() ) return false; … … 270 270 } 271 271 } 272 272 273 273 return false; 274 274 } 275 275 276 bool Indexer::hasIncompatibleCDecl( 277 const std::string &id, const std::string &mangleName ) const { 276 bool Indexer::hasIncompatibleCDecl(const std::string & id, const std::string &mangleName ) const { 278 277 if ( ! idTable ) return false; 279 278 280 ++* stats().map_lookups;279 ++* stats().map_lookups; 281 280 auto decls = idTable->find( id ); 282 281 if ( decls == idTable->end() ) return false; … … 295 294 296 295 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 297 std::string getOtypeKey( FunctionDecl* function ) {296 std::string getOtypeKey( const FunctionDecl * function ) { 298 297 auto& params = function->type->parameters; 299 298 assert( ! params.empty() ); 300 299 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 301 Type * base = InitTweak::getPointerBase( params.front()->get_type() );300 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 302 301 assert( base ); 303 302 return Mangler::mangle( base ); 304 303 } 305 304 306 /// gets the declaration for the function acting on a type specified by otype key, 305 /// gets the declaration for the function acting on a type specified by otype key, 307 306 /// nullptr if none such 308 FunctionDecl * getFunctionForOtype(DeclarationWithType * decl, const std::string& otypeKey ) {309 FunctionDecl * func = dynamic_cast<FunctionDecl * >( decl );307 const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) { 308 const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ); 310 309 if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr; 311 310 return func; 312 311 } 313 312 314 bool Indexer::removeSpecialOverrides( 315 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 316 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 317 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 318 // if the user defines a default ctor, then the generated default ctor is unavailable, 319 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 320 // field ctors are available. If the user defines any ctor then the generated default ctor 321 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 322 // anything that looks like a copy constructor, then the generated copy constructor is 313 bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 314 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 315 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 316 // if the user defines a default ctor, then the generated default ctor is unavailable, 317 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 318 // field ctors are available. If the user defines any ctor then the generated default ctor 319 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 320 // anything that looks like a copy constructor, then the generated copy constructor is 323 321 // unavailable, and likewise for the assignment operator. 324 322 325 323 // only relevant on function declarations 326 FunctionDecl * function = dynamic_cast<FunctionDecl * >( data.id );324 const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id ); 327 325 if ( ! function ) return true; 328 326 // only need to perform this check for constructors, destructors, and assignment functions … … 340 338 std::vector< MangleTable::value_type > deleted; 341 339 bool alreadyUserDefinedFunc = false; 342 343 for ( const auto& entry : * mangleTable ) {340 341 for ( const auto& entry : * mangleTable ) { 344 342 // skip decls that aren't functions or are for the wrong type 345 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );343 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 346 344 if ( ! decl ) continue; 347 345 … … 368 366 // perform removals from mangle table, and deletions if necessary 369 367 for ( const auto& key : removed ) { 370 ++* stats().map_mutations;368 ++* stats().map_mutations; 371 369 mangleTable = mangleTable->erase( key ); 372 370 } 373 371 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 374 ++* stats().map_mutations;372 ++* stats().map_mutations; 375 373 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 376 374 } … … 379 377 // if this is the first user-defined function, delete non-user-defined overloads 380 378 std::vector< MangleTable::value_type > deleted; 381 382 for ( const auto& entry : * mangleTable ) {379 380 for ( const auto& entry : * mangleTable ) { 383 381 // skip decls that aren't functions or are for the wrong type 384 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );382 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 385 383 if ( ! decl ) continue; 386 384 … … 402 400 // this needs to be a separate loop because of iterator invalidation 403 401 for ( const auto& entry : deleted ) { 404 ++* stats().map_mutations;402 ++* stats().map_mutations; 405 403 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 406 404 } … … 408 406 // this is an overridable generated function 409 407 // if there already exists a matching user-defined function, delete this appropriately 410 for ( const auto& entry : * mangleTable ) {408 for ( const auto& entry : * mangleTable ) { 411 409 // skip decls that aren't functions or are for the wrong type 412 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );410 const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); 413 411 if ( ! decl ) continue; 414 412 … … 418 416 if ( dataIsCopyFunc ) { 419 417 // remove current function if exists a user-defined copy function 420 // since the signatures for copy functions don't need to match exactly, using 418 // since the signatures for copy functions don't need to match exactly, using 421 419 // a delete statement is the wrong approach 422 420 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; … … 428 426 } 429 427 } 430 428 431 429 // nothing (more) to fix, return true 432 430 return true; 433 431 } 434 432 435 void Indexer::addId( 436 DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 437 BaseSyntaxNode * deleteStmt ) { 438 ++*stats().add_calls; 433 void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr, 434 const Declaration * deleteStmt ) { 435 ++* stats().add_calls; 439 436 const std::string &name = decl->name; 440 437 if ( name == "" ) return; 441 438 442 439 std::string mangleName; 443 440 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 444 // mangle the name without including the appropriate suffix, so overridable routines 441 // mangle the name without including the appropriate suffix, so overridable routines 445 442 // are placed into the same "bucket" as their user defined versions. 446 443 mangleName = Mangler::mangle( decl, false ); … … 449 446 } // if 450 447 451 // this ensures that no two declarations with the same unmangled name at the same scope 448 // this ensures that no two declarations with the same unmangled name at the same scope 452 449 // both have C linkage 453 450 if ( LinkageSpec::isMangled( decl->linkage ) ) { … … 457 454 } 458 455 } else { 459 // NOTE: only correct if name mangling is completely isomorphic to C 456 // NOTE: only correct if name mangling is completely isomorphic to C 460 457 // type-compatibility, which it may not be. 461 458 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 470 467 mangleTable = MangleTable::new_ptr(); 471 468 } else { 472 ++* stats().map_lookups;469 ++* stats().map_lookups; 473 470 auto decls = idTable->find( name ); 474 471 if ( decls == idTable->end() ) { … … 477 474 mangleTable = decls->second; 478 475 // skip in-scope repeat declarations of same identifier 479 ++* stats().map_lookups;476 ++* stats().map_lookups; 480 477 auto existing = mangleTable->find( mangleName ); 481 478 if ( existing != mangleTable->end() … … 486 483 // set delete expression for conflicting identifier 487 484 lazyInitScope(); 488 * stats().map_mutations += 2;485 * stats().map_mutations += 2; 489 486 idTable = idTable->set( 490 487 name, 491 mangleTable->set( 492 mangleName, 488 mangleTable->set( 489 mangleName, 493 490 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 494 491 } … … 504 501 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 505 502 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 506 * stats().map_mutations += 2;503 * stats().map_mutations += 2; 507 504 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 508 505 } 509 506 510 void Indexer::addId( DeclarationWithType * decl,Expression * baseExpr ) {507 void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) { 511 508 // default handling of conflicts is to raise an error 512 509 addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr ); 513 510 } 514 511 515 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode* deleteStmt ) {512 void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) { 516 513 // default handling of conflicts is to raise an error 517 514 addId( decl, OnConflict::error(), nullptr, deleteStmt ); 518 515 } 519 516 520 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {517 bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) { 521 518 if ( existing->base == nullptr ) { 522 519 return false; … … 530 527 } 531 528 } 532 // does not need to be added to the table if both existing and added have a base that are 529 // does not need to be added to the table if both existing and added have a base that are 533 530 // the same 534 531 return true; 535 532 } 536 533 537 void Indexer::addType( NamedTypeDecl *decl ) {538 ++* stats().add_calls;539 const std::string & id = decl->name;540 541 if ( ! typeTable ) { 534 void Indexer::addType( const NamedTypeDecl * decl ) { 535 ++* stats().add_calls; 536 const std::string & id = decl->name; 537 538 if ( ! typeTable ) { 542 539 typeTable = TypeTable::new_ptr(); 543 540 } else { 544 ++* stats().map_lookups;541 ++* stats().map_lookups; 545 542 auto existing = typeTable->find( id ); 546 if ( existing != typeTable->end() 547 && existing->second.scope == scope 543 if ( existing != typeTable->end() 544 && existing->second.scope == scope 548 545 && addedTypeConflicts( existing->second.decl, decl ) ) return; 549 546 } 550 547 551 548 lazyInitScope(); 552 ++* stats().map_mutations;549 ++* stats().map_mutations; 553 550 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 554 551 } 555 552 556 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {553 bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) { 557 554 if ( ! existing->body ) { 558 555 return false; … … 563 560 } 564 561 565 void Indexer::addStruct( const std::string & id ) {562 void Indexer::addStruct( const std::string & id ) { 566 563 addStruct( new StructDecl( id ) ); 567 564 } 568 565 569 void Indexer::addStruct( StructDecl *decl ) {570 ++* stats().add_calls;571 const std::string & id = decl->name;566 void Indexer::addStruct( const StructDecl * decl ) { 567 ++* stats().add_calls; 568 const std::string & id = decl->name; 572 569 573 570 if ( ! structTable ) { 574 571 structTable = StructTable::new_ptr(); 575 572 } else { 576 ++* stats().map_lookups;573 ++* stats().map_lookups; 577 574 auto existing = structTable->find( id ); 578 if ( existing != structTable->end() 579 && existing->second.scope == scope 575 if ( existing != structTable->end() 576 && existing->second.scope == scope 580 577 && addedDeclConflicts( existing->second.decl, decl ) ) return; 581 578 } 582 579 583 580 lazyInitScope(); 584 ++* stats().map_mutations;581 ++* stats().map_mutations; 585 582 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 586 583 } 587 584 588 void Indexer::addEnum( EnumDecl *decl ) {589 ++* stats().add_calls;590 const std::string & id = decl->name;585 void Indexer::addEnum( const EnumDecl * decl ) { 586 ++* stats().add_calls; 587 const std::string & id = decl->name; 591 588 592 589 if ( ! enumTable ) { 593 590 enumTable = EnumTable::new_ptr(); 594 591 } else { 595 ++* stats().map_lookups;592 ++* stats().map_lookups; 596 593 auto existing = enumTable->find( id ); 597 if ( existing != enumTable->end() 598 && existing->second.scope == scope 594 if ( existing != enumTable->end() 595 && existing->second.scope == scope 599 596 && addedDeclConflicts( existing->second.decl, decl ) ) return; 600 597 } 601 598 602 599 lazyInitScope(); 603 ++* stats().map_mutations;600 ++* stats().map_mutations; 604 601 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 605 602 } 606 603 607 void Indexer::addUnion( const std::string & id ) {604 void Indexer::addUnion( const std::string & id ) { 608 605 addUnion( new UnionDecl( id ) ); 609 606 } 610 607 611 void Indexer::addUnion( UnionDecl *decl ) {612 ++* stats().add_calls;613 const std::string & id = decl->name;608 void Indexer::addUnion( const UnionDecl * decl ) { 609 ++* stats().add_calls; 610 const std::string & id = decl->name; 614 611 615 612 if ( ! unionTable ) { 616 613 unionTable = UnionTable::new_ptr(); 617 614 } else { 618 ++* stats().map_lookups;615 ++* stats().map_lookups; 619 616 auto existing = unionTable->find( id ); 620 if ( existing != unionTable->end() 621 && existing->second.scope == scope 617 if ( existing != unionTable->end() 618 && existing->second.scope == scope 622 619 && addedDeclConflicts( existing->second.decl, decl ) ) return; 623 620 } 624 621 625 622 lazyInitScope(); 626 ++* stats().map_mutations;623 ++* stats().map_mutations; 627 624 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 628 625 } 629 626 630 void Indexer::addTrait( TraitDecl *decl ) {631 ++* stats().add_calls;632 const std::string & id = decl->name;627 void Indexer::addTrait( const TraitDecl * decl ) { 628 ++* stats().add_calls; 629 const std::string & id = decl->name; 633 630 634 631 if ( ! traitTable ) { 635 632 traitTable = TraitTable::new_ptr(); 636 633 } else { 637 ++* stats().map_lookups;634 ++* stats().map_lookups; 638 635 auto existing = traitTable->find( id ); 639 if ( existing != traitTable->end() 640 && existing->second.scope == scope 636 if ( existing != traitTable->end() 637 && existing->second.scope == scope 641 638 && addedDeclConflicts( existing->second.decl, decl ) ) return; 642 639 } 643 640 644 641 lazyInitScope(); 645 ++* stats().map_mutations;642 ++* stats().map_mutations; 646 643 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 647 644 } 648 645 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 650 OnConflict handleConflicts ) { 646 void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) { 651 647 for ( Declaration * decl : aggr->members ) { 652 648 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 653 649 addId( dwt, handleConflicts, expr ); 654 650 if ( dwt->name == "" ) { 655 Type * t = dwt->get_type()->stripReferences();656 if ( dynamic_cast< StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {651 const Type * t = dwt->get_type()->stripReferences(); 652 if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) { 657 653 Expression * base = expr->clone(); 658 654 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? … … 665 661 } 666 662 667 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode* withStmt ) {668 for ( Expression * expr : withExprs ) {663 void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) { 664 for ( const Expression * expr : withExprs ) { 669 665 if ( expr->result ) { 670 666 AggregateDecl * aggr = expr->result->stripReferences()->getAggr(); … … 689 685 } 690 686 691 void Indexer::addFunctionType( FunctionType * ftype ) {687 void Indexer::addFunctionType( const FunctionType * ftype ) { 692 688 addTypes( ftype->forall ); 693 689 addIds( ftype->returnVals ); … … 700 696 Expression * base = baseExpr->clone(); 701 697 ResolvExpr::referenceToRvalueConversion( base, cost ); 702 ret = new MemberExpr( id, base );698 ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base ); 703 699 // xxx - this introduces hidden environments, for now remove them. 704 700 // std::swap( base->env, ret->env ); … … 706 702 base->env = nullptr; 707 703 } else { 708 ret = new VariableExpr( id);709 } 710 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt);704 ret = new VariableExpr( const_cast<DeclarationWithType *>(id) ); 705 } 706 if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) ); 711 707 return ret; 712 708 } -
src/SymTab/Indexer.h
r1f1c102 rf53acdf8 34 34 virtual ~Indexer(); 35 35 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 37 37 // tell the indexer explicitly when scopes begin and end 38 38 void enterScope(); … … 40 40 41 41 struct IdData { 42 DeclarationWithType * id = nullptr;43 Expression * baseExpr = nullptr; // WithExpr42 const DeclarationWithType * id = nullptr; 43 const Expression * baseExpr = nullptr; // WithExpr 44 44 45 45 /// non-null if this declaration is deleted 46 BaseSyntaxNode* deleteStmt = nullptr;46 const Declaration * deleteStmt = nullptr; 47 47 /// scope of identifier 48 48 unsigned long scope = 0; … … 50 50 // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members. 51 51 IdData() = default; 52 IdData( 53 DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode* deleteStmt,54 unsigned long scope ) 52 IdData( 53 const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt, 54 unsigned long scope ) 55 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 IdData( const IdData& o, BaseSyntaxNode* deleteStmt )56 IdData( const IdData& o, const Declaration * deleteStmt ) 57 57 : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {} 58 58 … … 61 61 62 62 /// Gets all declarations with the given ID 63 void lookupId( const std::string & id, std::list< IdData > &out ) const;63 void lookupId( const std::string & id, std::list< IdData > &out ) const; 64 64 /// Gets the top-most type declaration with the given ID 65 NamedTypeDecl *lookupType( const std::string &id ) const;65 const NamedTypeDecl * lookupType( const std::string & id ) const; 66 66 /// Gets the top-most struct declaration with the given ID 67 StructDecl *lookupStruct( const std::string &id ) const;67 const StructDecl * lookupStruct( const std::string & id ) const; 68 68 /// Gets the top-most enum declaration with the given ID 69 EnumDecl *lookupEnum( const std::string &id ) const;69 const EnumDecl * lookupEnum( const std::string & id ) const; 70 70 /// Gets the top-most union declaration with the given ID 71 UnionDecl *lookupUnion( const std::string &id ) const;71 const UnionDecl * lookupUnion( const std::string & id ) const; 72 72 /// Gets the top-most trait declaration with the given ID 73 TraitDecl *lookupTrait( const std::string &id ) const;73 const TraitDecl * lookupTrait( const std::string & id ) const; 74 74 75 75 /// Gets the type declaration with the given ID at global scope 76 NamedTypeDecl *globalLookupType( const std::string &id ) const;76 const NamedTypeDecl * globalLookupType( const std::string & id ) const; 77 77 /// Gets the struct declaration with the given ID at global scope 78 StructDecl *globalLookupStruct( const std::string &id ) const;78 const StructDecl * globalLookupStruct( const std::string & id ) const; 79 79 /// Gets the union declaration with the given ID at global scope 80 UnionDecl *globalLookupUnion( const std::string &id ) const;80 const UnionDecl * globalLookupUnion( const std::string & id ) const; 81 81 /// Gets the enum declaration with the given ID at global scope 82 EnumDecl *globalLookupEnum( const std::string &id ) const;82 const EnumDecl * globalLookupEnum( const std::string & id ) const; 83 83 84 void addId( DeclarationWithType * decl,Expression * baseExpr = nullptr );85 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode* deleteStmt );84 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr ); 85 void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ); 86 86 87 void addType( NamedTypeDecl *decl );88 void addStruct( const std::string & id );89 void addStruct( StructDecl *decl );90 void addEnum( EnumDecl *decl );91 void addUnion( const std::string & id );92 void addUnion( UnionDecl *decl );93 void addTrait( TraitDecl *decl );87 void addType( const NamedTypeDecl * decl ); 88 void addStruct( const std::string & id ); 89 void addStruct( const StructDecl * decl ); 90 void addEnum( const EnumDecl * decl ); 91 void addUnion( const std::string & id ); 92 void addUnion( const UnionDecl * decl ); 93 void addTrait( const TraitDecl * decl ); 94 94 95 95 /// adds all of the IDs from WithStmt exprs 96 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode* withStmt );96 void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ); 97 97 98 98 /// convenience function for adding a list of Ids to the indexer … … 103 103 104 104 /// convenience function for adding all of the declarations in a function type to the indexer 105 void addFunctionType( FunctionType * ftype );105 void addFunctionType( const FunctionType * ftype ); 106 106 107 107 private: 108 /// Wraps a Decl * with a scope108 /// Wraps a Decl * with a scope 109 109 template<typename Decl> 110 110 struct Scoped { 111 Decl* decl; ///< declaration111 const Decl * decl; ///< declaration 112 112 unsigned long scope; ///< scope of this declaration 113 113 114 Scoped( Decl* d, unsigned long s) : decl(d), scope(s) {}114 Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {} 115 115 }; 116 116 … … 140 140 141 141 /// Gets the indexer at the given scope 142 const Indexer * atScope( unsigned long scope ) const;142 const Indexer * atScope( unsigned long scope ) const; 143 143 144 /// Removes matching autogenerated constructors and destructors so that they will not be 144 /// Removes matching autogenerated constructors and destructors so that they will not be 145 145 /// selected. If returns false, passed decl should not be added. 146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr& mangleTable );146 bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable ); 147 147 148 148 /// Options for handling identifier conflicts … … 152 152 Delete ///< Delete the earlier version with the delete statement 153 153 } mode; 154 BaseSyntaxNode* deleteStmt; ///< Statement that deletes this expression154 const Declaration * deleteStmt; ///< Statement that deletes this expression 155 155 156 156 private: 157 157 OnConflict() : mode(Error), deleteStmt(nullptr) {} 158 OnConflict( BaseSyntaxNode* d ) : mode(Delete), deleteStmt(d) {}158 OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {} 159 159 public: 160 160 OnConflict( const OnConflict& ) = default; 161 161 162 162 static OnConflict error() { return {}; } 163 static OnConflict deleteWith( BaseSyntaxNode* d ) { return { d }; }163 static OnConflict deleteWith( const Declaration * d ) { return { d }; } 164 164 }; 165 165 166 166 /// true if the existing identifier conflicts with the added identifier 167 167 bool addedIdConflicts( 168 const IdData & existing, DeclarationWithType * added, OnConflict handleConflicts,169 BaseSyntaxNode* deleteStmt );168 const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts, 169 const Declaration * deleteStmt ); 170 170 171 171 /// common code for addId, addDeletedId, etc. 172 void addId( 173 DeclarationWithType * decl, OnConflict handleConflicts, 174 Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 172 void addId(const DeclarationWithType * decl, OnConflict handleConflicts, 173 const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr ); 175 174 176 175 /// adds all of the members of the Aggregate (addWith helper) 177 void addMembers( AggregateDecl * aggr,Expression * expr, OnConflict handleConflicts );176 void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ); 178 177 179 178 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 180 bool hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const;179 bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 181 180 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 182 bool hasIncompatibleCDecl( const std::string & id, const std::string &mangleName ) const;181 bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const; 183 182 }; 184 183 } // namespace SymTab -
src/SymTab/Mangler.cc
r1f1c102 rf53acdf8 42 42 Mangler_old( const Mangler_old & ) = delete; 43 43 44 void previsit( BaseSyntaxNode * ) { visit_children = false; }45 46 void postvisit( ObjectDecl * declaration );47 void postvisit( FunctionDecl * declaration );48 void postvisit( TypeDecl * declaration );49 50 void postvisit( VoidType * voidType );51 void postvisit( BasicType * basicType );52 void postvisit( PointerType * pointerType );53 void postvisit( ArrayType * arrayType );54 void postvisit( ReferenceType * refType );55 void postvisit( FunctionType * functionType );56 void postvisit( StructInstType * aggregateUseType );57 void postvisit( UnionInstType * aggregateUseType );58 void postvisit( EnumInstType * aggregateUseType );59 void postvisit( TypeInstType * aggregateUseType );60 void postvisit( TraitInstType * inst );61 void postvisit( TupleType * tupleType );62 void postvisit( VarArgsType * varArgsType );63 void postvisit( ZeroType * zeroType );64 void postvisit( OneType * oneType );65 void postvisit( QualifiedType * qualType );44 void previsit( const BaseSyntaxNode * ) { visit_children = false; } 45 46 void postvisit( const ObjectDecl * declaration ); 47 void postvisit( const FunctionDecl * declaration ); 48 void postvisit( const TypeDecl * declaration ); 49 50 void postvisit( const VoidType * voidType ); 51 void postvisit( const BasicType * basicType ); 52 void postvisit( const PointerType * pointerType ); 53 void postvisit( const ArrayType * arrayType ); 54 void postvisit( const ReferenceType * refType ); 55 void postvisit( const FunctionType * functionType ); 56 void postvisit( const StructInstType * aggregateUseType ); 57 void postvisit( const UnionInstType * aggregateUseType ); 58 void postvisit( const EnumInstType * aggregateUseType ); 59 void postvisit( const TypeInstType * aggregateUseType ); 60 void postvisit( const TraitInstType * inst ); 61 void postvisit( const TupleType * tupleType ); 62 void postvisit( const VarArgsType * varArgsType ); 63 void postvisit( const ZeroType * zeroType ); 64 void postvisit( const OneType * oneType ); 65 void postvisit( const QualifiedType * qualType ); 66 66 67 67 std::string get_mangleName() { return mangleName.str(); } … … 79 79 80 80 public: 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 82 int nextVarNum, const VarMapType& varNums ); 83 83 84 84 private: 85 void mangleDecl( DeclarationWithType *declaration );86 void mangleRef( ReferenceToType *refType, std::string prefix );87 88 void printQualifiers( Type *type );85 void mangleDecl( const DeclarationWithType * declaration ); 86 void mangleRef( const ReferenceToType * refType, std::string prefix ); 87 88 void printQualifiers( const Type *type ); 89 89 }; // Mangler_old 90 90 } // namespace 91 91 92 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 93 93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams ); 94 94 maybeAccept( decl, mangler ); … … 96 96 } 97 97 98 std::string mangleType( Type * ty ) {98 std::string mangleType( const Type * ty ) { 99 99 PassVisitor<Mangler_old> mangler( false, true, true ); 100 100 maybeAccept( ty, mangler ); … … 102 102 } 103 103 104 std::string mangleConcrete( Type * ty ) {104 std::string mangleConcrete( const Type * ty ) { 105 105 PassVisitor<Mangler_old> mangler( false, false, false ); 106 106 maybeAccept( ty, mangler ); … … 110 110 namespace { 111 111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 112 : nextVarNum( 0 ), isTopLevel( true ), 113 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 114 114 mangleGenericParams( mangleGenericParams ) {} 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 117 117 int nextVarNum, const VarMapType& varNums ) 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 119 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 120 120 mangleGenericParams( mangleGenericParams ) {} 121 121 122 void Mangler_old::mangleDecl( DeclarationWithType * declaration ) {122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) { 123 123 bool wasTopLevel = isTopLevel; 124 124 if ( isTopLevel ) { … … 150 150 } 151 151 152 void Mangler_old::postvisit( ObjectDecl * declaration ) {152 void Mangler_old::postvisit( const ObjectDecl * declaration ) { 153 153 mangleDecl( declaration ); 154 154 } 155 155 156 void Mangler_old::postvisit( FunctionDecl * declaration ) {156 void Mangler_old::postvisit( const FunctionDecl * declaration ) { 157 157 mangleDecl( declaration ); 158 158 } 159 159 160 void Mangler_old::postvisit( VoidType * voidType ) {160 void Mangler_old::postvisit( const VoidType * voidType ) { 161 161 printQualifiers( voidType ); 162 162 mangleName << Encoding::void_t; 163 163 } 164 164 165 void Mangler_old::postvisit( BasicType * basicType ) {165 void Mangler_old::postvisit( const BasicType * basicType ) { 166 166 printQualifiers( basicType ); 167 assertf( basicType-> get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind());168 mangleName << Encoding::basicTypes[ basicType-> get_kind()];169 } 170 171 void Mangler_old::postvisit( PointerType * pointerType ) {167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); 168 mangleName << Encoding::basicTypes[ basicType->kind ]; 169 } 170 171 void Mangler_old::postvisit( const PointerType * pointerType ) { 172 172 printQualifiers( pointerType ); 173 173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers … … 176 176 } 177 177 178 void Mangler_old::postvisit( ArrayType * arrayType ) {178 void Mangler_old::postvisit( const ArrayType * arrayType ) { 179 179 // TODO: encode dimension 180 180 printQualifiers( arrayType ); … … 183 183 } 184 184 185 void Mangler_old::postvisit( ReferenceType * refType ) {185 void Mangler_old::postvisit( const ReferenceType * refType ) { 186 186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 187 187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 202 202 } 203 203 204 void Mangler_old::postvisit( FunctionType * functionType ) {204 void Mangler_old::postvisit( const FunctionType * functionType ) { 205 205 printQualifiers( functionType ); 206 206 mangleName << Encoding::function; … … 219 219 } 220 220 221 void Mangler_old::mangleRef( ReferenceToType * refType, std::string prefix ) {221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) { 222 222 printQualifiers( refType ); 223 223 … … 225 225 226 226 if ( mangleGenericParams ) { 227 std::list< Expression* >& params = refType->parameters;227 const std::list< Expression* > & params = refType->parameters; 228 228 if ( ! params.empty() ) { 229 229 mangleName << "_"; 230 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param) {231 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString( *param));230 for ( const Expression * param : params ) { 231 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param ); 232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 233 233 maybeAccept( paramType->type, *visitor ); 234 234 } … … 238 238 } 239 239 240 void Mangler_old::postvisit( StructInstType * aggregateUseType ) {240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) { 241 241 mangleRef( aggregateUseType, Encoding::struct_t ); 242 242 } 243 243 244 void Mangler_old::postvisit( UnionInstType * aggregateUseType ) {244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) { 245 245 mangleRef( aggregateUseType, Encoding::union_t ); 246 246 } 247 247 248 void Mangler_old::postvisit( EnumInstType * aggregateUseType ) {248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) { 249 249 mangleRef( aggregateUseType, Encoding::enum_t ); 250 250 } 251 251 252 void Mangler_old::postvisit( TypeInstType * typeInst ) {252 void Mangler_old::postvisit( const TypeInstType * typeInst ) { 253 253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 254 254 if ( varNum == varNums.end() ) { … … 266 266 } 267 267 268 void Mangler_old::postvisit( TraitInstType * inst ) {268 void Mangler_old::postvisit( const TraitInstType * inst ) { 269 269 printQualifiers( inst ); 270 270 mangleName << inst->name.size() << inst->name; 271 271 } 272 272 273 void Mangler_old::postvisit( TupleType * tupleType ) {273 void Mangler_old::postvisit( const TupleType * tupleType ) { 274 274 printQualifiers( tupleType ); 275 275 mangleName << Encoding::tuple << tupleType->types.size(); … … 277 277 } 278 278 279 void Mangler_old::postvisit( VarArgsType * varArgsType ) {279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) { 280 280 printQualifiers( varArgsType ); 281 281 static const std::string vargs = "__builtin_va_list"; … … 283 283 } 284 284 285 void Mangler_old::postvisit( ZeroType * ) {285 void Mangler_old::postvisit( const ZeroType * ) { 286 286 mangleName << Encoding::zero; 287 287 } 288 288 289 void Mangler_old::postvisit( OneType * ) {289 void Mangler_old::postvisit( const OneType * ) { 290 290 mangleName << Encoding::one; 291 291 } 292 292 293 void Mangler_old::postvisit( QualifiedType * qualType ) {293 void Mangler_old::postvisit( const QualifiedType * qualType ) { 294 294 bool inqual = inQualifiedType; 295 295 if (! inqual ) { … … 307 307 } 308 308 309 void Mangler_old::postvisit( TypeDecl * decl ) {309 void Mangler_old::postvisit( const TypeDecl * decl ) { 310 310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 311 311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. … … 314 314 // aside from the assert false. 315 315 assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl)); 316 assertf( decl-> get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind());317 mangleName << Encoding::typeVariables[ decl-> get_kind()] << ( decl->name.length() ) << decl->name;316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 317 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name; 318 318 } 319 319 … … 324 324 } 325 325 326 void Mangler_old::printQualifiers( Type * type ) {326 void Mangler_old::printQualifiers( const Type * type ) { 327 327 // skip if not including qualifiers 328 328 if ( typeMode ) return; 329 if ( ! type-> get_forall().empty() ) {329 if ( ! type->forall.empty() ) { 330 330 std::list< std::string > assertionNames; 331 331 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 332 332 mangleName << Encoding::forall; 333 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i) {334 switch ( (*i)->get_kind()) {333 for ( const TypeDecl * i : type->forall ) { 334 switch ( i->kind ) { 335 335 case TypeDecl::Dtype: 336 336 dcount++; … … 345 345 assert( false ); 346 346 } // switch 347 varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind());348 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert) {349 PassVisitor<Mangler_old> sub_mangler( 347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind ); 348 for ( const DeclarationWithType * assert : i->assertions ) { 349 PassVisitor<Mangler_old> sub_mangler( 350 350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 351 (*assert)->accept( sub_mangler );351 assert->accept( sub_mangler ); 352 352 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 353 353 acount++; … … 436 436 437 437 private: 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 438 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 439 439 int nextVarNum, const VarMapType& varNums ); 440 440 friend class ast::Pass<Mangler_new>; … … 457 457 namespace { 458 458 Mangler_new::Mangler_new( Mangle::Mode mode ) 459 : nextVarNum( 0 ), isTopLevel( true ), 459 : nextVarNum( 0 ), isTopLevel( true ), 460 460 mangleOverridable ( ! mode.no_overrideable ), 461 typeMode ( mode.type ), 461 typeMode ( mode.type ), 462 462 mangleGenericParams( ! mode.no_generic_params ) {} 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 463 464 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 465 465 int nextVarNum, const VarMapType& varNums ) 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 466 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), 467 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 468 468 mangleGenericParams( mangleGenericParams ) {} 469 469 … … 693 693 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind ); 694 694 for ( const ast::DeclWithType * assert : decl->assertions ) { 695 ast::Pass<Mangler_new> sub_mangler( 695 ast::Pass<Mangler_new> sub_mangler( 696 696 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ); 697 697 assert->accept( sub_mangler ); -
src/SymTab/Mangler.h
r1f1c102 rf53acdf8 40 40 namespace Mangler { 41 41 /// Mangle syntax tree object; primary interface to clients 42 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );42 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 43 43 44 44 /// Mangle a type name; secondary interface 45 std::string mangleType( Type* ty );45 std::string mangleType( const Type * ty ); 46 46 /// Mangle ignoring generic type parameters 47 std::string mangleConcrete( Type* ty );47 std::string mangleConcrete( const Type * ty ); 48 48 49 49 namespace Encoding { -
src/SymTab/Validate.cc
r1f1c102 rf53acdf8 119 119 120 120 private: 121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl ); 122 122 123 123 AggregateDecl * parentAggr = nullptr; … … 134 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 135 135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl );137 void previsit( FunctionType * func );136 void previsit( EnumDecl * aggregateDecl ); 137 void previsit( FunctionType * func ); 138 138 }; 139 139 140 140 /// Associates forward declarations of aggregates with their definitions 141 141 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 142 LinkReferenceToTypes_old( const Indexer * indexer );143 void postvisit( TypeInstType * typeInst );144 145 void postvisit( EnumInstType * enumInst );146 void postvisit( StructInstType * structInst );147 void postvisit( UnionInstType * unionInst );148 void postvisit( TraitInstType * traitInst );142 LinkReferenceToTypes_old( const Indexer * indexer ); 143 void postvisit( TypeInstType * typeInst ); 144 145 void postvisit( EnumInstType * enumInst ); 146 void postvisit( StructInstType * structInst ); 147 void postvisit( UnionInstType * unionInst ); 148 void postvisit( TraitInstType * traitInst ); 149 149 void previsit( QualifiedType * qualType ); 150 150 void postvisit( QualifiedType * qualType ); 151 151 152 void postvisit( EnumDecl * enumDecl );153 void postvisit( StructDecl * structDecl );154 void postvisit( UnionDecl * unionDecl );152 void postvisit( EnumDecl * enumDecl ); 153 void postvisit( StructDecl * structDecl ); 154 void postvisit( UnionDecl * unionDecl ); 155 155 void postvisit( TraitDecl * traitDecl ); 156 156 157 void previsit( StructDecl * structDecl );158 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl * structDecl ); 158 void previsit( UnionDecl * unionDecl ); 159 159 160 160 void renameGenericParams( std::list< TypeDecl * > & params ); 161 161 162 162 private: 163 const Indexer * local_indexer;163 const Indexer * local_indexer; 164 164 165 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 239 239 240 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl );241 void handleAggregate( AggDecl * aggregateDecl ); 242 242 243 243 void previsit( StructDecl * aggregateDecl ); … … 252 252 static void verify( std::list< Declaration * > &translationUnit ); 253 253 254 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl * funcDecl ); 255 255 }; 256 256 … … 287 287 Type::StorageClasses storageClasses; 288 288 289 void premutate( ObjectDecl * objectDecl );290 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl * objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr * compLitExpr ); 291 291 }; 292 292 … … 393 393 } 394 394 395 void validateType( Type * type, const Indexer *indexer ) {395 void validateType( Type * type, const Indexer * indexer ) { 396 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); … … 496 496 } 497 497 498 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration * decl ) { 499 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 500 500 } … … 515 515 516 516 template< typename AggDecl > 517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) { 518 518 if ( parentAggr ) { 519 519 aggregateDecl->parent = parentAggr; … … 560 560 561 561 562 bool isTypedef( Declaration * decl ) {562 bool isTypedef( Declaration * decl ) { 563 563 return dynamic_cast< TypedefDecl * >( decl ); 564 564 } … … 571 571 572 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) { 574 574 filter( aggregateDecl->members, isTypedef, true ); 575 575 } … … 586 586 // remove and delete decl stmts 587 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 590 return true; … … 595 595 } 596 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) { 598 598 // Set the type of each member of the enumeration to be EnumConstant 599 599 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i ); 601 601 assert( obj ); 602 602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); … … 627 627 } 628 628 629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) { 630 630 // Fix up parameters and return types 631 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 633 633 } 634 634 635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) { 636 636 if ( other_indexer ) { 637 637 local_indexer = other_indexer; … … 641 641 } 642 642 643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {644 EnumDecl *st = local_indexer->lookupEnum( enumInst->name );643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) { 644 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name ); 645 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 646 646 if ( st ) { 647 enumInst->baseEnum = st;647 enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node 648 648 } // if 649 649 if ( ! st || ! st->body ) { … … 661 661 } 662 662 663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {664 StructDecl *st = local_indexer->lookupStruct( structInst->name );663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 664 const StructDecl * st = local_indexer->lookupStruct( structInst->name ); 665 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 666 666 if ( st ) { 667 structInst->baseStruct = st;667 structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node 668 668 } // if 669 669 if ( ! st || ! st->body ) { … … 674 674 } 675 675 676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {677 UnionDecl *un = local_indexer->lookupUnion( unionInst->name );676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 677 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name ); 678 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 679 679 if ( un ) { 680 unionInst->baseUnion = un;680 unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node 681 681 } // if 682 682 if ( ! un || ! un->body ) { … … 693 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor );695 qualType->parent->accept( * visitor ); 696 696 } 697 697 … … 762 762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 763 763 // handle other traits 764 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );764 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name ); 765 765 if ( ! traitDecl ) { 766 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); … … 769 769 SemanticError( traitInst, "incorrect number of trait parameters: " ); 770 770 } // if 771 traitInst->baseTrait = traitDecl;771 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node 772 772 773 773 // need to carry over the 'sized' status of each decl in the instance … … 786 786 } 787 787 788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 789 789 // visit enum members first so that the types of self-referencing members are updated properly 790 790 if ( enumDecl->body ) { … … 792 792 if ( fwds != forwardEnums.end() ) { 793 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 794 (* inst)->baseEnum = enumDecl;794 (* inst)->baseEnum = enumDecl; 795 795 } // for 796 796 forwardEnums.erase( fwds ); … … 834 834 } 835 835 836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 837 837 // visit struct members first so that the types of self-referencing members are updated properly 838 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 841 841 if ( fwds != forwardStructs.end() ) { 842 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 843 (* inst)->baseStruct = structDecl;843 (* inst)->baseStruct = structDecl; 844 844 } // for 845 845 forwardStructs.erase( fwds ); … … 848 848 } 849 849 850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 851 851 if ( unionDecl->body ) { 852 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 853 853 if ( fwds != forwardUnions.end() ) { 854 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 855 (* inst)->baseUnion = unionDecl;855 (* inst)->baseUnion = unionDecl; 856 856 } // for 857 857 forwardUnions.erase( fwds ); … … 860 860 } 861 861 862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 863 863 // ensure generic parameter instances are renamed like the base type 864 864 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 865 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {866 if ( TypeDecl *typeDecl = dynamic_cast<TypeDecl * >( namedTypeDecl ) ) {867 typeInst->set_isFtype( typeDecl-> get_kind()== TypeDecl::Ftype );865 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 866 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 867 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 868 868 } // if 869 869 } // if … … 877 877 // expand trait instances into their members 878 878 for ( DeclarationWithType * assertion : asserts ) { 879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 880 880 // expand trait instance into all of its members 881 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 897 897 } 898 898 899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) { 900 900 // ensure that operator names only apply to functions or function pointers 901 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 905 905 } 906 906 907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) { 908 908 func->fixUniqueId(); 909 909 } … … 961 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 962 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 963 qualType->parent = qualType->parent->acceptMutator( * visitor );963 qualType->parent = qualType->parent->acceptMutator( * visitor ); 964 964 return qualType; 965 965 } … … 970 970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 971 971 if ( def != typedefNames.end() ) { 972 Type * ret = def->second.first->base->clone();972 Type * ret = def->second.first->base->clone(); 973 973 ret->location = typeInst->location; 974 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); … … 982 982 // place instance parameters on the typedef'd type 983 983 if ( ! typeInst->parameters.empty() ) { 984 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret); 985 985 if ( ! rtt ) { 986 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); … … 988 988 rtt->parameters.clear(); 989 989 cloneAll( typeInst->parameters, rtt->parameters ); 990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters 991 991 } // if 992 992 delete typeInst; … … 1043 1043 // struct screen; 1044 1044 // because the expansion of the typedef is: 1045 // void rtn( SCREEN * p ) => void rtn( struct screen *p )1045 // void rtn( SCREEN * p ) => void rtn( struct screen * p ) 1046 1046 // hence the type-name "screen" must be defined. 1047 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 1048 1048 1049 Type * designatorType = tyDecl->base->stripDeclarator();1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {1049 Type * designatorType = tyDecl->base->stripDeclarator(); 1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 1051 1051 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) ); 1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 1053 1053 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 1055 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 1056 } // if … … 1078 1078 1079 1079 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 1081 1081 // replace the current object declaration with a function declaration 1082 1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); … … 1104 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1105 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1106 Type * type = nullptr;1106 Type * type = nullptr; 1107 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 1108 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 1130 1130 GuardScope( typedefNames ); 1131 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor );1132 mutateAll( aggr->parameters, * visitor ); 1133 1133 1134 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1137 1137 1138 1138 try { 1139 * i = maybeMutate( *i, *visitor );1139 * i = maybeMutate( * i, * visitor ); 1140 1140 } catch ( SemanticErrorException &e ) { 1141 1141 errors.append( e ); … … 1217 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1218 1218 if ( i < args.size() ) { 1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) ); 1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 1221 1221 } else if ( i == args.size() ) { 1222 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (* paramIter)->get_init(); 1223 1223 if ( defaultType ) { 1224 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 1225 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (* paramIter)->get_name(), defaultType->clone() ); 1226 1226 } 1227 1227 } … … 1242 1242 } 1243 1243 1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) { 1245 1245 storageClasses = objectDecl->get_storageClasses(); 1246 1246 } 1247 1247 1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) { 1249 1249 // transform [storage_class] ... (struct S){ 3, ... }; 1250 1250 // into [storage_class] struct S temp = { 3, ... }; 1251 1251 static UniqueName indexName( "_compLit" ); 1252 1252 1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 1254 1254 compLitExpr->set_result( nullptr ); 1255 1255 compLitExpr->set_initializer( nullptr ); … … 1289 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1290 1290 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) ); 1292 1292 deleteAll( retVals ); 1293 1293 retVals.clear(); … … 1302 1302 1303 1303 void FixObjectType::previsit( ObjectDecl * objDecl ) { 1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer ); 1305 1305 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1306 1306 objDecl->set_type( new_type ); … … 1308 1308 1309 1309 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1311 1311 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1312 1312 funcDecl->set_type( new_type ); 1313 1313 } 1314 1314 1315 void FixObjectType::previsit( TypeDecl * typeDecl ) {1315 void FixObjectType::previsit( TypeDecl * typeDecl ) { 1316 1316 if ( typeDecl->get_base() ) { 1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1318 1318 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1319 1319 typeDecl->set_base( new_type ); … … 1378 1378 1379 1379 namespace { 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1381 1381 /// lists by appropriate pointers 1382 1382 struct EnumAndPointerDecay_new { … … 1385 1385 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1386 1386 // build new version of object with EnumConstant 1387 ast::ptr< ast::ObjectDecl > obj = 1387 ast::ptr< ast::ObjectDecl > obj = 1388 1388 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1389 obj.get_and_mutate()->type = 1389 obj.get_and_mutate()->type = 1390 1390 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1391 1391 1392 1392 // set into decl 1393 1393 ast::EnumDecl * mut = mutate( enumDecl ); … … 1399 1399 1400 1400 static const ast::FunctionType * fixFunctionList( 1401 const ast::FunctionType * func, 1401 const ast::FunctionType * func, 1402 1402 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1403 1403 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1404 1404 ) { 1405 const auto & dwts = func->* field;1405 const auto & dwts = func->* field; 1406 1406 unsigned nvals = dwts.size(); 1407 1407 bool hasVoid = false; … … 1409 1409 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1410 1410 } 1411 1411 1412 1412 // the only case in which "void" is valid is where it is the only one in the list 1413 1413 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1414 SemanticError( 1414 SemanticError( 1415 1415 dwts.front()->location, func, "invalid type void in function type" ); 1416 1416 } … … 1418 1418 // one void is the only thing in the list, remove it 1419 1419 if ( hasVoid ) { 1420 func = ast::mutate_field( 1420 func = ast::mutate_field( 1421 1421 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1422 1422 } … … 1432 1432 1433 1433 /// expand assertions from a trait instance, performing appropriate type variable substitutions 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1436 1436 ) { 1437 1437 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1438 1438 1439 1439 // build list of trait members, substituting trait decl parameters for instance parameters 1440 ast::TypeSubstitution sub{ 1440 ast::TypeSubstitution sub{ 1441 1441 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1442 1442 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base … … 1449 1449 1450 1450 /// Associates forward declarations of aggregates with their definitions 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1453 1453 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after* they have been traversed. To enable this in the1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after * they have been traversed. To enable this in the 1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1459 1459 // then can have the actual mutation applied later 1460 1460 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1461 1461 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1462 1462 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1463 1463 1464 1464 const CodeLocation & location; 1465 1465 const ast::SymbolTable * localSymtab; 1466 1466 1467 1467 ForwardEnumsType forwardEnums; 1468 1468 ForwardStructsType forwardStructs; 1469 1469 ForwardUnionsType forwardUnions; 1470 1470 1471 /// true if currently in a generic type body, so that type parameter instances can be 1471 /// true if currently in a generic type body, so that type parameter instances can be 1472 1472 /// renamed appropriately 1473 1473 bool inGeneric = false; … … 1475 1475 public: 1476 1476 /// contstruct using running symbol table 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1478 1478 : location( loc ), localSymtab( &symtab ) {} 1479 1479 1480 1480 /// construct using provided symbol table 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1482 1482 : location( loc ), localSymtab( &syms ) {} 1483 1483 … … 1485 1485 // ensure generic parameter instances are renamed like the base type 1486 1486 if ( inGeneric && typeInst->base ) { 1487 typeInst = ast::mutate_field( 1487 typeInst = ast::mutate_field( 1488 1488 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1489 1489 } 1490 1490 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1494 1494 ) { 1495 1495 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); … … 1517 1517 for ( const ast::Expr * param : inst->params ) { 1518 1518 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1519 SemanticError( 1519 SemanticError( 1520 1520 location, inst, "Expression parameters for generic types are currently " 1521 1521 "unsupported: " ); … … 1571 1571 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1572 1572 if ( ! expr ) { 1573 SemanticError( 1573 SemanticError( 1574 1574 traitInst->params[i].get(), "Expression parameters for trait instances " 1575 1575 "are currently unsupported: " ); … … 1593 1593 return traitInst; 1594 1594 } 1595 1595 1596 1596 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1597 1597 1598 1598 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1599 1599 // linking only makes sense for the "oldest ancestor" of the qualified type 1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) ); 1602 1602 } 1603 1603 1604 1604 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1605 // visit enum members first so that the types of self-referencing members are updated 1605 // visit enum members first so that the types of self-referencing members are updated 1606 1606 // properly 1607 1607 if ( ! enumDecl->body ) return enumDecl; … … 1612 1612 auto inst = fwds.first; 1613 1613 do { 1614 // forward decl is stored * mutably* in map, can thus be updated1614 // forward decl is stored * mutably * in map, can thus be updated 1615 1615 inst->second->base = enumDecl; 1616 1616 } while ( ++inst != fwds.second ); 1617 1617 forwardEnums.erase( fwds.first, fwds.second ); 1618 1618 } 1619 1619 1620 1620 // ensure that enumerator initializers are properly set 1621 1621 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1622 1622 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1623 1623 if ( field->init ) { 1624 // need to resolve enumerator initializers early so that other passes that 1624 // need to resolve enumerator initializers early so that other passes that 1625 1625 // determine if an expression is constexpr have appropriate information 1626 1626 auto init = field->init.strict_as< ast::SingleInit >(); 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1631 1631 ast::mutate_field( init, &ast::SingleInit::value, 1632 ResolvExpr::findSingleExpression( 1632 ResolvExpr::findSingleExpression( 1633 1633 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1634 1634 symtab ) ) ) ); … … 1639 1639 } 1640 1640 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1642 1642 /// function forall parameters, e.g. the T in Box and the T in f, below 1643 1643 /// forall(otype T) … … 1657 1657 const ast::TypeDecl * td = aggr->params[i]; 1658 1658 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1661 1661 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1662 1662 } … … 1669 1669 1670 1670 void postvisit( const ast::StructDecl * structDecl ) { 1671 // visit struct members first so that the types of self-referencing members are 1671 // visit struct members first so that the types of self-referencing members are 1672 1672 // updated properly 1673 1673 if ( ! structDecl->body ) return; … … 1678 1678 auto inst = fwds.first; 1679 1679 do { 1680 // forward decl is stored * mutably* in map, can thus be updated1680 // forward decl is stored * mutably * in map, can thus be updated 1681 1681 inst->second->base = structDecl; 1682 1682 } while ( ++inst != fwds.second ); … … 1690 1690 1691 1691 void postvisit( const ast::UnionDecl * unionDecl ) { 1692 // visit union members first so that the types of self-referencing members are updated 1692 // visit union members first so that the types of self-referencing members are updated 1693 1693 // properly 1694 1694 if ( ! unionDecl->body ) return; … … 1699 1699 auto inst = fwds.first; 1700 1700 do { 1701 // forward decl is stored * mutably* in map, can thus be updated1701 // forward decl is stored * mutably * in map, can thus be updated 1702 1702 inst->second->base = unionDecl; 1703 1703 } while ( ++inst != fwds.second ); … … 1712 1712 "number of parameters: %zd", traitDecl->params.size() ); 1713 1713 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1717 1717 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1718 1718 } … … 1737 1737 traitDecl = mut; 1738 1738 } 1739 1739 1740 1740 return traitDecl; 1741 1741 } 1742 1742 }; 1743 1743 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1745 1745 /// each object and function declaration a unique ID 1746 1746 class ForallPointerDecay_new { … … 1751 1751 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1752 1752 // ensure that operator names only apply to functions or function pointers 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1755 1755 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1756 1756 ) { … … 1776 1776 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1777 1777 template< typename node_t, typename parent_t > 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1780 1780 ast::ParameterizedType::ForallList parent_t::* forallField 1781 1781 ) { 1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {1783 const ast::TypeDecl * type = (node->* forallField)[i];1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) { 1783 const ast::TypeDecl * type = (node->* forallField)[i]; 1784 1784 if ( type->assertions.empty() ) continue; 1785 1785 … … 1789 1789 // expand trait instances into their members 1790 1790 for ( const ast::DeclWithType * assn : type->assertions ) { 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1793 1793 if ( traitInst ) { 1794 1794 // expand trait instance to all its members … … 1831 1831 } // anonymous namespace 1832 1832 1833 const ast::Type * validateType( 1833 const ast::Type * validateType( 1834 1834 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1835 1835 ast::Pass< EnumAndPointerDecay_new > epc; -
src/SymTab/Validate.h
r1f1c102 rf53acdf8 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
r1f1c102 rf53acdf8 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
r1f1c102 rf53acdf8 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Feb 14 07:44:20 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Aug 17 13:44:0013 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 16:13:49 2019 13 // Update Count : 4 14 14 // 15 15 … … 25 25 class BaseSyntaxNode { 26 26 public: 27 27 static Stats::Counters::SimpleCounter* new_nodes; 28 28 29 29 CodeLocation location; 30 30 31 BaseSyntaxNode() { ++*new_nodes; } 32 BaseSyntaxNode( const BaseSyntaxNode& o ) : location(o.location) { ++*new_nodes; } 31 BaseSyntaxNode() { ++*new_nodes; } 32 BaseSyntaxNode( const BaseSyntaxNode & o ) : location(o.location) { ++*new_nodes; } 33 BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default; 33 34 34 35 virtual ~BaseSyntaxNode() {} … … 36 37 virtual BaseSyntaxNode * clone() const = 0; 37 38 virtual void accept( Visitor & v ) = 0; 39 virtual void accept( Visitor & v ) const = 0; 38 40 virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0; 39 40 41 41 /// Notes: 42 /// * each node is responsible for indenting its children. 43 /// * Expressions should not finish with a newline, since the expression's parent has better information. 42 44 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 43 45 }; -
src/SynTree/Constant.h
r1f1c102 rf53acdf8 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Spt 28 14:48:00 201813 // Update Count : 1 811 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 10 15:57:38 2019 13 // Update Count : 19 14 14 // 15 15 … … 30 30 Constant( Type * type, std::string rep, std::optional<unsigned long long> i ); 31 31 Constant( const Constant & other ); 32 Constant & operator=( const Constant & ) = default; 32 33 virtual ~Constant(); 33 34 34 virtual Constant * clone() const { return new Constant( *this ); }35 virtual Constant * clone() const override { return new Constant( *this ); } 35 36 36 37 Type * get_type() { return type; } … … 50 51 static Constant null( Type * ptrtype = nullptr ); 51 52 52 virtual void accept( Visitor & v ) { v.visit( this ); } 53 virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); } 54 virtual void print( std::ostream & os, Indenter indent = 0 ) const; 55 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 56 58 Type * type; 57 59 std::string rep; 58 60 std::optional<unsigned long long> ival; 59 60 friend class ConverterOldToNew;61 61 }; 62 62 -
src/SynTree/Declaration.h
r1f1c102 rf53acdf8 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 ); } 348 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 349 private: 350 virtual std::string typeString() const override; 355 virtual void accept( Visitor & v ) override { v.visit( this ); } 356 virtual void accept( Visitor & v ) const override { v.visit( this ); } 357 virtual Declaration *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 358 private: 359 virtual std::string typeString() const override; 360 }; 361 362 class WithStmt : public Declaration { 363 public: 364 std::list< Expression * > exprs; 365 Statement * stmt; 366 367 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 368 WithStmt( const WithStmt & other ); 369 virtual ~WithStmt(); 370 371 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 372 virtual void accept( Visitor & v ) override { v.visit( this ); } 373 virtual void accept( Visitor & v ) const override { v.visit( this ); } 374 virtual Declaration * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 375 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 376 virtual void printShort( std::ostream & os, Indenter indent = {} ) const override { print(os, indent); } 351 377 }; 352 378 … … 363 389 364 390 virtual AsmDecl *clone() const override { return new AsmDecl( *this ); } 365 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 ); } 366 393 virtual AsmDecl *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 367 394 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 379 406 380 407 virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 381 virtual void accept( Visitor &v ) override { v.visit( this ); } 408 virtual void accept( Visitor & v ) override { v.visit( this ); } 409 virtual void accept( Visitor & v ) const override { v.visit( this ); } 382 410 virtual StaticAssertDecl * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 383 411 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Expression.cc
r1f1c102 rf53acdf8 724 724 } 725 725 726 DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode* deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {726 DeletedExpr::DeletedExpr( Expression * expr, Declaration * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) { 727 727 assert( expr->result ); 728 728 result = expr->result->clone(); -
src/SynTree/Expression.h
r1f1c102 rf53acdf8 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 ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); } 324 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 325 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 314 326 }; 315 327 … … 329 341 long long int intValue() const; 330 342 331 virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); } 332 virtual void accept( Visitor & v ) { v.visit( this ); } 333 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 334 virtual void print( std::ostream & os, Indenter indent = {} ) const; 343 virtual ConstantExpr * clone() const override { return new ConstantExpr( * this ); } 344 virtual void accept( Visitor & v ) override { v.visit( this ); } 345 virtual void accept( Visitor & v ) const override { v.visit( this ); } 346 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 347 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 335 348 }; 336 349 … … 354 367 void set_isType( bool newValue ) { isType = newValue; } 355 368 356 virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); } 357 virtual void accept( Visitor & v ) { v.visit( this ); } 358 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 359 virtual void print( std::ostream & os, Indenter indent = {} ) const; 369 virtual SizeofExpr * clone() const override { return new SizeofExpr( * this ); } 370 virtual void accept( Visitor & v ) override { v.visit( this ); } 371 virtual void accept( Visitor & v ) const override { v.visit( this ); } 372 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 373 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 360 374 }; 361 375 … … 379 393 void set_isType( bool newValue ) { isType = newValue; } 380 394 381 virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); } 382 virtual void accept( Visitor & v ) { v.visit( this ); } 383 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 384 virtual void print( std::ostream & os, Indenter indent = {} ) const; 395 virtual AlignofExpr * clone() const override { return new AlignofExpr( * this ); } 396 virtual void accept( Visitor & v ) override { v.visit( this ); } 397 virtual void accept( Visitor & v ) const override { v.visit( this ); } 398 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 399 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 385 400 }; 386 401 … … 400 415 void set_type( Type * newValue ) { type = newValue; } 401 416 402 virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); } 403 virtual void accept( Visitor & v ) { v.visit( this ); } 404 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 405 virtual void print( std::ostream & os, Indenter indent = {} ) const; 417 virtual UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr( * this ); } 418 virtual void accept( Visitor & v ) override { v.visit( this ); } 419 virtual void accept( Visitor & v ) const override { v.visit( this ); } 420 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 421 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 406 422 }; 407 423 … … 421 437 void set_member( DeclarationWithType * newValue ) { member = newValue; } 422 438 423 virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); } 424 virtual void accept( Visitor & v ) { v.visit( this ); } 425 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 426 virtual void print( std::ostream & os, Indenter indent = {} ) const; 439 virtual OffsetofExpr * clone() const override { return new OffsetofExpr( * this ); } 440 virtual void accept( Visitor & v ) override { v.visit( this ); } 441 virtual void accept( Visitor & v ) const override { v.visit( this ); } 442 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 443 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 427 444 }; 428 445 … … 439 456 void set_type( StructInstType * newValue ) { type = newValue; } 440 457 441 virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); } 442 virtual void accept( Visitor & v ) { v.visit( this ); } 443 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 444 virtual void print( std::ostream & os, Indenter indent = {} ) const; 458 virtual OffsetPackExpr * clone() const override { return new OffsetPackExpr( * this ); } 459 virtual void accept( Visitor & v ) override { v.visit( this ); } 460 virtual void accept( Visitor & v ) const override { v.visit( this ); } 461 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 462 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 445 463 }; 446 464 … … 467 485 void set_isType( bool newValue ) { isType = newValue; } 468 486 469 virtual AttrExpr * clone() const { return new AttrExpr( * this ); } 470 virtual void accept( Visitor & v ) { v.visit( this ); } 471 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 472 virtual void print( std::ostream & os, Indenter indent = {} ) const; 487 virtual AttrExpr * clone() const override { return new AttrExpr( * this ); } 488 virtual void accept( Visitor & v ) override { v.visit( this ); } 489 virtual void accept( Visitor & v ) const override { v.visit( this ); } 490 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 491 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 473 492 }; 474 493 … … 489 508 void set_arg2( Expression * newValue ) { arg2 = newValue; } 490 509 491 virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); } 492 virtual void accept( Visitor & v ) { v.visit( this ); } 493 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 494 virtual void print( std::ostream & os, Indenter indent = {} ) const; 510 virtual LogicalExpr * clone() const override { return new LogicalExpr( * this ); } 511 virtual void accept( Visitor & v ) override { v.visit( this ); } 512 virtual void accept( Visitor & v ) const override { v.visit( this ); } 513 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 514 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 495 515 496 516 private: … … 516 536 void set_arg3( Expression * newValue ) { arg3 = newValue; } 517 537 518 virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); } 519 virtual void accept( Visitor & v ) { v.visit( this ); } 520 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 521 virtual void print( std::ostream & os, Indenter indent = {} ) const; 538 virtual ConditionalExpr * clone() const override { return new ConditionalExpr( * this ); } 539 virtual void accept( Visitor & v ) override { v.visit( this ); } 540 virtual void accept( Visitor & v ) const override { v.visit( this ); } 541 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 542 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 522 543 }; 523 544 … … 537 558 void set_arg2( Expression * newValue ) { arg2 = newValue; } 538 559 539 virtual CommaExpr * clone() const { return new CommaExpr( * this ); } 540 virtual void accept( Visitor & v ) { v.visit( this ); } 541 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 542 virtual void print( std::ostream & os, Indenter indent = {} ) const; 560 virtual CommaExpr * clone() const override { return new CommaExpr( * this ); } 561 virtual void accept( Visitor & v ) override { v.visit( this ); } 562 virtual void accept( Visitor & v ) const override { v.visit( this ); } 563 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 564 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 543 565 }; 544 566 … … 555 577 void set_type( Type * newValue ) { type = newValue; } 556 578 557 virtual TypeExpr * clone() const { return new TypeExpr( * this ); } 558 virtual void accept( Visitor & v ) { v.visit( this ); } 559 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 560 virtual void print( std::ostream & os, Indenter indent = {} ) const; 579 virtual TypeExpr * clone() const override { return new TypeExpr( * this ); } 580 virtual void accept( Visitor & v ) override { v.visit( this ); } 581 virtual void accept( Visitor & v ) const override { v.visit( this ); } 582 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 583 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 561 584 }; 562 585 … … 581 604 void set_operand( Expression * newValue ) { operand = newValue; } 582 605 583 virtual AsmExpr * clone() const { return new AsmExpr( * this ); } 584 virtual void accept( Visitor & v ) { v.visit( this ); } 585 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 586 virtual void print( std::ostream & os, Indenter indent = {} ) const; 606 virtual AsmExpr * clone() const override { return new AsmExpr( * this ); } 607 virtual void accept( Visitor & v ) override { v.visit( this ); } 608 virtual void accept( Visitor & v ) const override { v.visit( this ); } 609 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 610 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 587 611 588 612 // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints … … 599 623 virtual ~ImplicitCopyCtorExpr(); 600 624 601 virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); } 602 virtual void accept( Visitor & v ) { v.visit( this ); } 603 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 604 virtual void print( std::ostream & os, Indenter indent = {} ) const; 625 virtual ImplicitCopyCtorExpr * clone() const override { return new ImplicitCopyCtorExpr( * this ); } 626 virtual void accept( Visitor & v ) override { v.visit( this ); } 627 virtual void accept( Visitor & v ) const override { v.visit( this ); } 628 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 629 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 605 630 }; 606 631 … … 617 642 void set_callExpr( Expression * newValue ) { callExpr = newValue; } 618 643 619 virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); } 620 virtual void accept( Visitor & v ) { v.visit( this ); } 621 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 622 virtual void print( std::ostream & os, Indenter indent = {} ) const; 644 virtual ConstructorExpr * clone() const override { return new ConstructorExpr( * this ); } 645 virtual void accept( Visitor & v ) override { v.visit( this ); } 646 virtual void accept( Visitor & v ) const override { v.visit( this ); } 647 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 648 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 623 649 }; 624 650 … … 635 661 void set_initializer( Initializer * i ) { initializer = i; } 636 662 637 virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); } 638 virtual void accept( Visitor & v ) { v.visit( this ); } 639 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 640 virtual void print( std::ostream & os, Indenter indent = {} ) const; 663 virtual CompoundLiteralExpr * clone() const override { return new CompoundLiteralExpr( * this ); } 664 virtual void accept( Visitor & v ) override { v.visit( this ); } 665 virtual void accept( Visitor & v ) const override { v.visit( this ); } 666 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 667 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 641 668 }; 642 669 … … 654 681 RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; } 655 682 656 virtual RangeExpr * clone() const { return new RangeExpr( * this ); } 657 virtual void accept( Visitor & v ) { v.visit( this ); } 658 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 659 virtual void print( std::ostream & os, Indenter indent = {} ) const; 683 virtual RangeExpr * clone() const override { return new RangeExpr( * this ); } 684 virtual void accept( Visitor & v ) override { v.visit( this ); } 685 virtual void accept( Visitor & v ) const override { v.visit( this ); } 686 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 687 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 660 688 }; 661 689 … … 671 699 std::list<Expression*>& get_exprs() { return exprs; } 672 700 673 virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); } 674 virtual void accept( Visitor & v ) { v.visit( this ); } 675 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 676 virtual void print( std::ostream & os, Indenter indent = {} ) const; 701 virtual UntypedTupleExpr * clone() const override { return new UntypedTupleExpr( * this ); } 702 virtual void accept( Visitor & v ) override { v.visit( this ); } 703 virtual void accept( Visitor & v ) const override { v.visit( this ); } 704 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 705 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 677 706 }; 678 707 … … 688 717 std::list<Expression*>& get_exprs() { return exprs; } 689 718 690 virtual TupleExpr * clone() const { return new TupleExpr( * this ); } 691 virtual void accept( Visitor & v ) { v.visit( this ); } 692 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 693 virtual void print( std::ostream & os, Indenter indent = {} ) const; 719 virtual TupleExpr * clone() const override { return new TupleExpr( * this ); } 720 virtual void accept( Visitor & v ) override { v.visit( this ); } 721 virtual void accept( Visitor & v ) const override { v.visit( this ); } 722 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 723 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 694 724 }; 695 725 … … 709 739 TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; } 710 740 711 virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * this ); } 712 virtual void accept( Visitor & v ) { v.visit( this ); } 713 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 714 virtual void print( std::ostream & os, Indenter indent = {} ) const; 741 virtual TupleIndexExpr * clone() const override { return new TupleIndexExpr( * this ); } 742 virtual void accept( Visitor & v ) override { v.visit( this ); } 743 virtual void accept( Visitor & v ) const override { v.visit( this ); } 744 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 745 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 715 746 }; 716 747 … … 727 758 StmtExpr * get_stmtExpr() const { return stmtExpr; } 728 759 729 virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); } 730 virtual void accept( Visitor & v ) { v.visit( this ); } 731 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 732 virtual void print( std::ostream & os, Indenter indent = {} ) const; 760 virtual TupleAssignExpr * clone() const override { return new TupleAssignExpr( * this ); } 761 virtual void accept( Visitor & v ) override { v.visit( this ); } 762 virtual void accept( Visitor & v ) const override { v.visit( this ); } 763 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 764 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 733 765 734 766 friend class ConverterNewToOld; … … 760 792 std::list< Expression * > & get_dtors() { return dtors; } 761 793 762 virtual StmtExpr * clone() const { return new StmtExpr( * this ); } 763 virtual void accept( Visitor & v ) { v.visit( this ); } 764 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 765 virtual void print( std::ostream & os, Indenter indent = {} ) const; 794 virtual StmtExpr * clone() const override { return new StmtExpr( * this ); } 795 virtual void accept( Visitor & v ) override { v.visit( this ); } 796 virtual void accept( Visitor & v ) const override { v.visit( this ); } 797 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 798 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 766 799 }; 767 800 … … 787 820 int get_id() const { return id; } 788 821 789 virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); } 790 virtual void accept( Visitor & v ) { v.visit( this ); } 791 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 792 virtual void print( std::ostream & os, Indenter indent = {} ) const; 822 virtual UniqueExpr * clone() const override { return new UniqueExpr( * this ); } 823 virtual void accept( Visitor & v ) override { v.visit( this ); } 824 virtual void accept( Visitor & v ) const override { v.visit( this ); } 825 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 826 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 793 827 794 828 private: … … 821 855 std::list<InitAlternative> & get_initAlts() { return initAlts; } 822 856 823 virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); } 824 virtual void accept( Visitor & v ) { v.visit( this ); } 825 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 826 virtual void print( std::ostream & os, Indenter indent = {} ) const; 857 virtual UntypedInitExpr * clone() const override { return new UntypedInitExpr( * this ); } 858 virtual void accept( Visitor & v ) override { v.visit( this ); } 859 virtual void accept( Visitor & v ) const override { v.visit( this ); } 860 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 861 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 827 862 }; 828 863 … … 842 877 InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; } 843 878 844 virtual InitExpr * clone() const { return new InitExpr( * this ); } 845 virtual void accept( Visitor & v ) { v.visit( this ); } 846 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 847 virtual void print( std::ostream & os, Indenter indent = {} ) const; 879 virtual InitExpr * clone() const override { return new InitExpr( * this ); } 880 virtual void accept( Visitor & v ) override { v.visit( this ); } 881 virtual void accept( Visitor & v ) const override { v.visit( this ); } 882 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 883 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 848 884 }; 849 885 … … 852 888 public: 853 889 Expression * expr; 854 BaseSyntaxNode* deleteStmt;855 856 DeletedExpr( Expression * expr, BaseSyntaxNode* deleteStmt );890 Declaration * deleteStmt; 891 892 DeletedExpr( Expression * expr, Declaration * deleteStmt ); 857 893 DeletedExpr( const DeletedExpr & other ); 858 894 ~DeletedExpr(); 859 895 860 virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); } 861 virtual void accept( Visitor & v ) { v.visit( this ); } 862 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 863 virtual void print( std::ostream & os, Indenter indent = {} ) const; 896 virtual DeletedExpr * clone() const override { return new DeletedExpr( * this ); } 897 virtual void accept( Visitor & v ) override { v.visit( this ); } 898 virtual void accept( Visitor & v ) const override { v.visit( this ); } 899 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 900 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 864 901 }; 865 902 … … 873 910 ~DefaultArgExpr(); 874 911 875 virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); } 876 virtual void accept( Visitor & v ) { v.visit( this ); } 877 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 878 virtual void print( std::ostream & os, Indenter indent = {} ) const; 912 virtual DefaultArgExpr * clone() const override { return new DefaultArgExpr( * this ); } 913 virtual void accept( Visitor & v ) override { v.visit( this ); } 914 virtual void accept( Visitor & v ) const override { v.visit( this ); } 915 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 916 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 879 917 }; 880 918 … … 901 939 virtual ~GenericExpr(); 902 940 903 virtual GenericExpr * clone() const { return new GenericExpr( * this ); } 904 virtual void accept( Visitor & v ) { v.visit( this ); } 905 virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } 906 virtual void print( std::ostream & os, Indenter indent = {} ) const; 941 virtual GenericExpr * clone() const override { return new GenericExpr( * this ); } 942 virtual void accept( Visitor & v ) override { v.visit( this ); } 943 virtual void accept( Visitor & v ) const override { v.visit( this ); } 944 virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 945 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 907 946 }; 908 947 -
src/SynTree/Initializer.h
r1f1c102 rf53acdf8 38 38 39 39 virtual Designation * clone() const override { return new Designation( *this ); }; 40 virtual void accept( Visitor &v ) override { v.visit( this ); } 40 virtual void accept( Visitor & v ) override { v.visit( this ); } 41 virtual void accept( Visitor & v ) const override { v.visit( this ); } 41 42 virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 42 43 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 52 53 virtual ~Initializer(); 53 54 54 bool get_maybeConstructed() { return maybeConstructed; }55 bool get_maybeConstructed() const { return maybeConstructed; } 55 56 56 57 virtual Initializer *clone() const override = 0; 57 virtual void accept( Visitor &v ) override = 0; 58 virtual void accept( Visitor & v ) override = 0; 59 virtual void accept( Visitor & v ) const override = 0; 58 60 virtual Initializer *acceptMutator( Mutator &m ) override = 0; 59 61 virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0; … … 76 78 77 79 virtual SingleInit *clone() const override { return new SingleInit( *this); } 78 virtual void accept( Visitor &v ) override { v.visit( this ); } 80 virtual void accept( Visitor & v ) override { v.visit( this ); } 81 virtual void accept( Visitor & v ) const override { v.visit( this ); } 79 82 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 80 83 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 104 107 105 108 virtual ListInit *clone() const override { return new ListInit( *this ); } 106 virtual void accept( Visitor &v ) override { v.visit( this ); } 109 virtual void accept( Visitor & v ) override { v.visit( this ); } 110 virtual void accept( Visitor & v ) const override { v.visit( this ); } 107 111 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 108 112 virtual void print( std::ostream &os, Indenter indent = {} ) const override; … … 133 137 134 138 ConstructorInit *clone() const override { return new ConstructorInit( *this ); } 135 virtual void accept( Visitor &v ) override { v.visit( this ); } 139 virtual void accept( Visitor & v ) override { v.visit( this ); } 140 virtual void accept( Visitor & v ) const override { v.visit( this ); } 136 141 virtual Initializer *acceptMutator( Mutator &m ) override { return m.mutate( this ); } 137 142 virtual void print( std::ostream &os, Indenter indent = {} ) const override; -
src/SynTree/Mutator.h
r1f1c102 rf53acdf8 52 52 virtual Statement * mutate( FinallyStmt * catchStmt ) = 0; 53 53 virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0; 54 virtual Statement* mutate( WithStmt * withStmt ) = 0;54 virtual Declaration * mutate( WithStmt * withStmt ) = 0; 55 55 virtual NullStmt * mutate( NullStmt * nullStmt ) = 0; 56 56 virtual Statement * mutate( DeclStmt * declStmt ) = 0; -
src/SynTree/Statement.cc
r1f1c102 rf53acdf8 493 493 494 494 495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}496 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Declaration("", noStorageClasses, LinkageSpec::Cforall), exprs( exprs ), stmt( stmt ) {} 496 WithStmt::WithStmt( const WithStmt & other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) { 497 497 cloneAll( other.exprs, exprs ); 498 498 } -
src/SynTree/Statement.h
r1f1c102 rf53acdf8 45 45 virtual Statement * clone() const override = 0; 46 46 virtual void accept( Visitor & v ) override = 0; 47 virtual void accept( Visitor & v ) const override = 0; 47 48 virtual Statement * acceptMutator( Mutator & m ) override = 0; 48 49 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 64 65 virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); } 65 66 virtual void accept( Visitor & v ) override { v.visit( this ); } 67 virtual void accept( Visitor & v ) const override { v.visit( this ); } 66 68 virtual CompoundStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 67 69 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 74 76 virtual NullStmt * clone() const override { return new NullStmt( *this ); } 75 77 virtual void accept( Visitor & v ) override { v.visit( this ); } 78 virtual void accept( Visitor & v ) const override { v.visit( this ); } 76 79 virtual NullStmt * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 77 80 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 91 94 virtual ExprStmt * clone() const override { return new ExprStmt( *this ); } 92 95 virtual void accept( Visitor & v ) override { v.visit( this ); } 96 virtual void accept( Visitor & v ) const override { v.visit( this ); } 93 97 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 94 98 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 120 124 void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; } 121 125 122 virtual AsmStmt * clone() const { return new AsmStmt( *this ); } 123 virtual void accept( Visitor & v ) { v.visit( this ); } 124 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 125 virtual void print( std::ostream & os, Indenter indent = {} ) const; 126 virtual AsmStmt * clone() const override { return new AsmStmt( *this ); } 127 virtual void accept( Visitor & v ) override { v.visit( this ); } 128 virtual void accept( Visitor & v ) const override { v.visit( this ); } 129 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 130 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 126 131 }; 127 132 … … 133 138 virtual ~DirectiveStmt(){} 134 139 135 virtual DirectiveStmt * clone() const { return new DirectiveStmt( *this ); } 136 virtual void accept( Visitor & v ) { v.visit( this ); } 137 virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); } 138 virtual void print( std::ostream & os, Indenter indent = {} ) const; 140 virtual DirectiveStmt * clone() const override { return new DirectiveStmt( *this ); } 141 virtual void accept( Visitor & v ) override { v.visit( this ); } 142 virtual void accept( Visitor & v ) const override { v.visit( this ); } 143 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 144 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 139 145 }; 140 146 … … 161 167 virtual IfStmt * clone() const override { return new IfStmt( *this ); } 162 168 virtual void accept( Visitor & v ) override { v.visit( this ); } 169 virtual void accept( Visitor & v ) const override { v.visit( this ); } 163 170 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 164 171 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 180 187 181 188 virtual void accept( Visitor & v ) override { v.visit( this ); } 189 virtual void accept( Visitor & v ) const override { v.visit( this ); } 182 190 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 183 191 … … 208 216 209 217 virtual void accept( Visitor & v ) override { v.visit( this ); } 218 virtual void accept( Visitor & v ) const override { v.visit( this ); } 210 219 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 211 220 … … 236 245 virtual WhileStmt * clone() const override { return new WhileStmt( *this ); } 237 246 virtual void accept( Visitor & v ) override { v.visit( this ); } 247 virtual void accept( Visitor & v ) const override { v.visit( this ); } 238 248 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 239 249 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 261 271 virtual ForStmt * clone() const override { return new ForStmt( *this ); } 262 272 virtual void accept( Visitor & v ) override { v.visit( this ); } 273 virtual void accept( Visitor & v ) const override { v.visit( this ); } 263 274 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 264 275 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 290 301 virtual BranchStmt * clone() const override { return new BranchStmt( *this ); } 291 302 virtual void accept( Visitor & v ) override { v.visit( this ); } 303 virtual void accept( Visitor & v ) const override { v.visit( this ); } 292 304 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 293 305 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 309 321 virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); } 310 322 virtual void accept( Visitor & v ) override { v.visit( this ); } 323 virtual void accept( Visitor & v ) const override { v.visit( this ); } 311 324 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 312 325 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 333 346 virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); } 334 347 virtual void accept( Visitor & v ) override { v.visit( this ); } 348 virtual void accept( Visitor & v ) const override { v.visit( this ); } 335 349 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 336 350 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 356 370 virtual TryStmt * clone() const override { return new TryStmt( *this ); } 357 371 virtual void accept( Visitor & v ) override { v.visit( this ); } 372 virtual void accept( Visitor & v ) const override { v.visit( this ); } 358 373 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 359 374 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 384 399 virtual CatchStmt * clone() const override { return new CatchStmt( *this ); } 385 400 virtual void accept( Visitor & v ) override { v.visit( this ); } 401 virtual void accept( Visitor & v ) const override { v.visit( this ); } 386 402 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 387 403 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 401 417 virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); } 402 418 virtual void accept( Visitor & v ) override { v.visit( this ); } 419 virtual void accept( Visitor & v ) const override { v.visit( this ); } 403 420 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 404 421 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 438 455 virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); } 439 456 virtual void accept( Visitor & v ) override { v.visit( this ); } 440 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 441 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 442 443 }; 444 445 class WithStmt : public Statement { 446 public: 447 std::list< Expression * > exprs; 448 Statement * stmt; 449 450 WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 451 WithStmt( const WithStmt & other ); 452 virtual ~WithStmt(); 453 454 virtual WithStmt * clone() const override { return new WithStmt( *this ); } 455 virtual void accept( Visitor & v ) override { v.visit( this ); } 456 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 457 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 458 }; 457 virtual void accept( Visitor & v ) const override { v.visit( this ); } 458 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 459 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 460 461 }; 462 463 // class WithStmt : public Statement { 464 // public: 465 // std::list< Expression * > exprs; 466 // Statement * stmt; 467 468 // WithStmt( const std::list< Expression * > & exprs, Statement * stmt ); 469 // WithStmt( const WithStmt & other ); 470 // virtual ~WithStmt(); 471 472 // virtual WithStmt * clone() const override { return new WithStmt( *this ); } 473 // virtual void accept( Visitor & v ) override { v.visit( this ); } 474 // virtual void accept( Visitor & v ) const override { v.visit( this ); } 475 // virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 476 // virtual void print( std::ostream & os, Indenter indent = {} ) const override; 477 // }; 459 478 460 479 … … 473 492 virtual DeclStmt * clone() const override { return new DeclStmt( *this ); } 474 493 virtual void accept( Visitor & v ) override { v.visit( this ); } 494 virtual void accept( Visitor & v ) const override { v.visit( this ); } 475 495 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 476 496 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 494 514 virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); } 495 515 virtual void accept( Visitor & v ) override { v.visit( this ); } 516 virtual void accept( Visitor & v ) const override { v.visit( this ); } 496 517 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 497 518 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/Type.h
r1f1c102 rf53acdf8 144 144 145 145 Qualifiers & get_qualifiers() { return tq; } 146 bool get_const() { return tq.is_const; }147 bool get_volatile() { return tq.is_volatile; }148 bool get_restrict() { return tq.is_restrict; }149 bool get_lvalue() { return tq.is_lvalue; }150 bool get_mutex() { return tq.is_mutex; }151 bool get_atomic() { return tq.is_atomic; }146 bool get_const() const { return tq.is_const; } 147 bool get_volatile() const { return tq.is_volatile; } 148 bool get_restrict() const { return tq.is_restrict; } 149 bool get_lvalue() const { return tq.is_lvalue; } 150 bool get_mutex() const { return tq.is_mutex; } 151 bool get_atomic() const { return tq.is_atomic; } 152 152 void set_const( bool newValue ) { tq.is_const = newValue; } 153 153 void set_volatile( bool newValue ) { tq.is_volatile = newValue; } … … 184 184 virtual Type *clone() const = 0; 185 185 virtual void accept( Visitor & v ) = 0; 186 virtual void accept( Visitor & v ) const = 0; 186 187 virtual Type *acceptMutator( Mutator & m ) = 0; 187 188 virtual void print( std::ostream & os, Indenter indent = {} ) const; … … 201 202 virtual VoidType *clone() const override { return new VoidType( *this ); } 202 203 virtual void accept( Visitor & v ) override { v.visit( this ); } 204 virtual void accept( Visitor & v ) const override { v.visit( this ); } 203 205 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 204 206 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 259 261 virtual BasicType *clone() const override { return new BasicType( *this ); } 260 262 virtual void accept( Visitor & v ) override { v.visit( this ); } 263 virtual void accept( Visitor & v ) const override { v.visit( this ); } 261 264 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 262 265 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 294 297 virtual PointerType *clone() const override { return new PointerType( *this ); } 295 298 virtual void accept( Visitor & v ) override { v.visit( this ); } 299 virtual void accept( Visitor & v ) const override { v.visit( this ); } 296 300 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 297 301 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 325 329 virtual ArrayType *clone() const override { return new ArrayType( *this ); } 326 330 virtual void accept( Visitor & v ) override { v.visit( this ); } 331 virtual void accept( Visitor & v ) const override { v.visit( this ); } 327 332 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 328 333 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 340 345 virtual QualifiedType *clone() const override { return new QualifiedType( *this ); } 341 346 virtual void accept( Visitor & v ) override { v.visit( this ); } 347 virtual void accept( Visitor & v ) const override { v.visit( this ); } 342 348 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 343 349 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 366 372 virtual ReferenceType *clone() const override { return new ReferenceType( *this ); } 367 373 virtual void accept( Visitor & v ) override { v.visit( this ); } 374 virtual void accept( Visitor & v ) const override { v.visit( this ); } 368 375 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 369 376 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 395 402 virtual FunctionType *clone() const override { return new FunctionType( *this ); } 396 403 virtual void accept( Visitor & v ) override { v.visit( this ); } 404 virtual void accept( Visitor & v ) const override { v.visit( this ); } 397 405 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 398 406 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 455 463 virtual StructInstType *clone() const override { return new StructInstType( *this ); } 456 464 virtual void accept( Visitor & v ) override { v.visit( this ); } 465 virtual void accept( Visitor & v ) const override { v.visit( this ); } 457 466 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 458 467 … … 492 501 virtual UnionInstType *clone() const override { return new UnionInstType( *this ); } 493 502 virtual void accept( Visitor & v ) override { v.visit( this ); } 503 virtual void accept( Visitor & v ) const override { v.visit( this ); } 494 504 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 495 505 … … 519 529 virtual EnumInstType *clone() const override { return new EnumInstType( *this ); } 520 530 virtual void accept( Visitor & v ) override { v.visit( this ); } 531 virtual void accept( Visitor & v ) const override { v.visit( this ); } 521 532 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 522 533 … … 542 553 virtual TraitInstType *clone() const override { return new TraitInstType( *this ); } 543 554 virtual void accept( Visitor & v ) override { v.visit( this ); } 555 virtual void accept( Visitor & v ) const override { v.visit( this ); } 544 556 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 545 557 private: … … 569 581 virtual TypeInstType *clone() const override { return new TypeInstType( *this ); } 570 582 virtual void accept( Visitor & v ) override { v.visit( this ); } 583 virtual void accept( Visitor & v ) const override { v.visit( this ); } 571 584 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 572 585 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 606 619 virtual TupleType *clone() const override { return new TupleType( *this ); } 607 620 virtual void accept( Visitor & v ) override { v.visit( this ); } 621 virtual void accept( Visitor & v ) const override { v.visit( this ); } 608 622 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 609 623 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 616 630 617 631 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 618 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 632 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 619 633 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 620 634 TypeofType( const TypeofType& ); … … 628 642 virtual TypeofType *clone() const override { return new TypeofType( *this ); } 629 643 virtual void accept( Visitor & v ) override { v.visit( this ); } 644 virtual void accept( Visitor & v ) const override { v.visit( this ); } 630 645 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 631 646 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 657 672 virtual AttrType *clone() const override { return new AttrType( *this ); } 658 673 virtual void accept( Visitor & v ) override { v.visit( this ); } 674 virtual void accept( Visitor & v ) const override { v.visit( this ); } 659 675 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 660 676 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 671 687 virtual VarArgsType *clone() const override { return new VarArgsType( *this ); } 672 688 virtual void accept( Visitor & v ) override { v.visit( this ); } 689 virtual void accept( Visitor & v ) const override { v.visit( this ); } 673 690 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 674 691 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 683 700 virtual ZeroType *clone() const override { return new ZeroType( *this ); } 684 701 virtual void accept( Visitor & v ) override { v.visit( this ); } 702 virtual void accept( Visitor & v ) const override { v.visit( this ); } 685 703 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 686 704 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 695 713 virtual OneType *clone() const override { return new OneType( *this ); } 696 714 virtual void accept( Visitor & v ) override { v.visit( this ); } 715 virtual void accept( Visitor & v ) const override { v.visit( this ); } 697 716 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 698 717 virtual void print( std::ostream & os, Indenter indent = {} ) const override; … … 705 724 virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); } 706 725 virtual void accept( Visitor & v ) override { v.visit( this ); } 726 virtual void accept( Visitor & v ) const override { v.visit( this ); } 707 727 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 708 728 virtual void print( std::ostream & os, Indenter indent = {} ) const override; -
src/SynTree/Visitor.h
r1f1c102 rf53acdf8 27 27 // of the given syntax node, but performs no other action. 28 28 29 virtual void visit( ObjectDecl * objectDecl ) = 0; 30 virtual void visit( FunctionDecl * functionDecl ) = 0; 31 virtual void visit( StructDecl * aggregateDecl ) = 0; 32 virtual void visit( UnionDecl * aggregateDecl ) = 0; 33 virtual void visit( EnumDecl * aggregateDecl ) = 0; 34 virtual void visit( TraitDecl * aggregateDecl ) = 0; 35 virtual void visit( TypeDecl * typeDecl ) = 0; 36 virtual void visit( TypedefDecl * typeDecl ) = 0; 37 virtual void visit( AsmDecl * asmDecl ) = 0; 38 virtual void visit( StaticAssertDecl * assertDecl ) = 0; 39 40 virtual void visit( CompoundStmt * compoundStmt ) = 0; 41 virtual void visit( ExprStmt * exprStmt ) = 0; 42 virtual void visit( AsmStmt * asmStmt ) = 0; 43 virtual void visit( DirectiveStmt * directiveStmt ) = 0; 44 virtual void visit( IfStmt * ifStmt ) = 0; 45 virtual void visit( WhileStmt * whileStmt ) = 0; 46 virtual void visit( ForStmt * forStmt ) = 0; 47 virtual void visit( SwitchStmt * switchStmt ) = 0; 48 virtual void visit( CaseStmt * caseStmt ) = 0; 49 virtual void visit( BranchStmt * branchStmt ) = 0; 50 virtual void visit( ReturnStmt * returnStmt ) = 0; 51 virtual void visit( ThrowStmt * throwStmt ) = 0; 52 virtual void visit( TryStmt * tryStmt ) = 0; 53 virtual void visit( CatchStmt * catchStmt ) = 0; 54 virtual void visit( FinallyStmt * finallyStmt ) = 0; 55 virtual void visit( WaitForStmt * waitforStmt ) = 0; 56 virtual void visit( WithStmt * withStmt ) = 0; 57 virtual void visit( NullStmt * nullStmt ) = 0; 58 virtual void visit( DeclStmt * declStmt ) = 0; 59 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0; 60 61 virtual void visit( ApplicationExpr * applicationExpr ) = 0; 62 virtual void visit( UntypedExpr * untypedExpr ) = 0; 63 virtual void visit( NameExpr * nameExpr ) = 0; 64 virtual void visit( CastExpr * castExpr ) = 0; 65 virtual void visit( KeywordCastExpr * castExpr ) = 0; 66 virtual void visit( VirtualCastExpr * castExpr ) = 0; 67 virtual void visit( AddressExpr * addressExpr ) = 0; 68 virtual void visit( LabelAddressExpr * labAddressExpr ) = 0; 69 virtual void visit( UntypedMemberExpr * memberExpr ) = 0; 70 virtual void visit( MemberExpr * memberExpr ) = 0; 71 virtual void visit( VariableExpr * variableExpr ) = 0; 72 virtual void visit( ConstantExpr * constantExpr ) = 0; 73 virtual void visit( SizeofExpr * sizeofExpr ) = 0; 74 virtual void visit( AlignofExpr * alignofExpr ) = 0; 75 virtual void visit( UntypedOffsetofExpr * offsetofExpr ) = 0; 76 virtual void visit( OffsetofExpr * offsetofExpr ) = 0; 77 virtual void visit( OffsetPackExpr * offsetPackExpr ) = 0; 78 virtual void visit( AttrExpr * attrExpr ) = 0; 79 virtual void visit( LogicalExpr * logicalExpr ) = 0; 80 virtual void visit( ConditionalExpr * conditionalExpr ) = 0; 81 virtual void visit( CommaExpr * commaExpr ) = 0; 82 virtual void visit( TypeExpr * typeExpr ) = 0; 83 virtual void visit( AsmExpr * asmExpr ) = 0; 84 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0; 85 virtual void visit( ConstructorExpr * ctorExpr ) = 0; 86 virtual void visit( CompoundLiteralExpr * compLitExpr ) = 0; 87 virtual void visit( RangeExpr * rangeExpr ) = 0; 88 virtual void visit( UntypedTupleExpr * tupleExpr ) = 0; 89 virtual void visit( TupleExpr * tupleExpr ) = 0; 90 virtual void visit( TupleIndexExpr * tupleExpr ) = 0; 91 virtual void visit( TupleAssignExpr * assignExpr ) = 0; 92 virtual void visit( StmtExpr * stmtExpr ) = 0; 93 virtual void visit( UniqueExpr * uniqueExpr ) = 0; 94 virtual void visit( UntypedInitExpr * initExpr ) = 0; 95 virtual void visit( InitExpr * initExpr ) = 0; 96 virtual void visit( DeletedExpr * delExpr ) = 0; 97 virtual void visit( DefaultArgExpr * argExpr ) = 0; 98 virtual void visit( GenericExpr * genExpr ) = 0; 99 100 virtual void visit( VoidType * basicType ) = 0; 101 virtual void visit( BasicType * basicType ) = 0; 102 virtual void visit( PointerType * pointerType ) = 0; 103 virtual void visit( ArrayType * arrayType ) = 0; 104 virtual void visit( ReferenceType * refType ) = 0; 105 virtual void visit( QualifiedType * qualType ) = 0; 106 virtual void visit( FunctionType * functionType ) = 0; 107 virtual void visit( StructInstType * aggregateUseType ) = 0; 108 virtual void visit( UnionInstType * aggregateUseType ) = 0; 109 virtual void visit( EnumInstType * aggregateUseType ) = 0; 110 virtual void visit( TraitInstType * aggregateUseType ) = 0; 111 virtual void visit( TypeInstType * aggregateUseType ) = 0; 112 virtual void visit( TupleType * tupleType ) = 0; 113 virtual void visit( TypeofType * typeofType ) = 0; 114 virtual void visit( AttrType * attrType ) = 0; 115 virtual void visit( VarArgsType * varArgsType ) = 0; 116 virtual void visit( ZeroType * zeroType ) = 0; 117 virtual void visit( OneType * oneType ) = 0; 118 virtual void visit( GlobalScopeType * globalType ) = 0; 119 120 virtual void visit( Designation * designation ) = 0; 121 virtual void visit( SingleInit * singleInit ) = 0; 122 virtual void visit( ListInit * listInit ) = 0; 123 virtual void visit( ConstructorInit * ctorInit ) = 0; 124 125 virtual void visit( Constant * constant ) = 0; 126 127 virtual void visit( Attribute * attribute ) = 0; 29 virtual void visit( ObjectDecl * node ) { visit( const_cast<const ObjectDecl *>(node) ); } 30 virtual void visit( const ObjectDecl * objectDecl ) = 0; 31 virtual void visit( FunctionDecl * node ) { visit( const_cast<const FunctionDecl *>(node) ); } 32 virtual void visit( const FunctionDecl * functionDecl ) = 0; 33 virtual void visit( StructDecl * node ) { visit( const_cast<const StructDecl *>(node) ); } 34 virtual void visit( const StructDecl * aggregateDecl ) = 0; 35 virtual void visit( UnionDecl * node ) { visit( const_cast<const UnionDecl *>(node) ); } 36 virtual void visit( const UnionDecl * aggregateDecl ) = 0; 37 virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); } 38 virtual void visit( const EnumDecl * aggregateDecl ) = 0; 39 virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); } 40 virtual void visit( const TraitDecl * aggregateDecl ) = 0; 41 virtual void visit( TypeDecl * node ) { visit( const_cast<const TypeDecl *>(node) ); } 42 virtual void visit( const TypeDecl * typeDecl ) = 0; 43 virtual void visit( TypedefDecl * node ) { visit( const_cast<const TypedefDecl *>(node) ); } 44 virtual void visit( const TypedefDecl * typeDecl ) = 0; 45 virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); } 46 virtual void visit( const AsmDecl * asmDecl ) = 0; 47 virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); } 48 virtual void visit( const StaticAssertDecl * assertDecl ) = 0; 49 50 virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); } 51 virtual void visit( const CompoundStmt * compoundStmt ) = 0; 52 virtual void visit( ExprStmt * node ) { visit( const_cast<const ExprStmt *>(node) ); } 53 virtual void visit( const ExprStmt * exprStmt ) = 0; 54 virtual void visit( AsmStmt * node ) { visit( const_cast<const AsmStmt *>(node) ); } 55 virtual void visit( const AsmStmt * asmStmt ) = 0; 56 virtual void visit( DirectiveStmt * node ) { visit( const_cast<const DirectiveStmt *>(node) ); } 57 virtual void visit( const DirectiveStmt * directiveStmt ) = 0; 58 virtual void visit( IfStmt * node ) { visit( const_cast<const IfStmt *>(node) ); } 59 virtual void visit( const IfStmt * ifStmt ) = 0; 60 virtual void visit( WhileStmt * node ) { visit( const_cast<const WhileStmt *>(node) ); } 61 virtual void visit( const WhileStmt * whileStmt ) = 0; 62 virtual void visit( ForStmt * node ) { visit( const_cast<const ForStmt *>(node) ); } 63 virtual void visit( const ForStmt * forStmt ) = 0; 64 virtual void visit( SwitchStmt * node ) { visit( const_cast<const SwitchStmt *>(node) ); } 65 virtual void visit( const SwitchStmt * switchStmt ) = 0; 66 virtual void visit( CaseStmt * node ) { visit( const_cast<const CaseStmt *>(node) ); } 67 virtual void visit( const CaseStmt * caseStmt ) = 0; 68 virtual void visit( BranchStmt * node ) { visit( const_cast<const BranchStmt *>(node) ); } 69 virtual void visit( const BranchStmt * branchStmt ) = 0; 70 virtual void visit( ReturnStmt * node ) { visit( const_cast<const ReturnStmt *>(node) ); } 71 virtual void visit( const ReturnStmt * returnStmt ) = 0; 72 virtual void visit( ThrowStmt * node ) { visit( const_cast<const ThrowStmt *>(node) ); } 73 virtual void visit( const ThrowStmt * throwStmt ) = 0; 74 virtual void visit( TryStmt * node ) { visit( const_cast<const TryStmt *>(node) ); } 75 virtual void visit( const TryStmt * tryStmt ) = 0; 76 virtual void visit( CatchStmt * node ) { visit( const_cast<const CatchStmt *>(node) ); } 77 virtual void visit( const CatchStmt * catchStmt ) = 0; 78 virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); } 79 virtual void visit( const FinallyStmt * finallyStmt ) = 0; 80 virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); } 81 virtual void visit( const WaitForStmt * waitforStmt ) = 0; 82 virtual void visit( WithStmt * node ) { visit( const_cast<const WithStmt *>(node) ); } 83 virtual void visit( const WithStmt * withStmt ) = 0; 84 virtual void visit( NullStmt * node ) { visit( const_cast<const NullStmt *>(node) ); } 85 virtual void visit( const NullStmt * nullStmt ) = 0; 86 virtual void visit( DeclStmt * node ) { visit( const_cast<const DeclStmt *>(node) ); } 87 virtual void visit( const DeclStmt * declStmt ) = 0; 88 virtual void visit( ImplicitCtorDtorStmt * node ) { visit( const_cast<const ImplicitCtorDtorStmt *>(node) ); } 89 virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0; 90 91 virtual void visit( ApplicationExpr * node ) { visit( const_cast<const ApplicationExpr *>(node) ); } 92 virtual void visit( const ApplicationExpr * applicationExpr ) = 0; 93 virtual void visit( UntypedExpr * node ) { visit( const_cast<const UntypedExpr *>(node) ); } 94 virtual void visit( const UntypedExpr * untypedExpr ) = 0; 95 virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); } 96 virtual void visit( const NameExpr * nameExpr ) = 0; 97 virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); } 98 virtual void visit( const CastExpr * castExpr ) = 0; 99 virtual void visit( KeywordCastExpr * node ) { visit( const_cast<const KeywordCastExpr *>(node) ); } 100 virtual void visit( const KeywordCastExpr * castExpr ) = 0; 101 virtual void visit( VirtualCastExpr * node ) { visit( const_cast<const VirtualCastExpr *>(node) ); } 102 virtual void visit( const VirtualCastExpr * castExpr ) = 0; 103 virtual void visit( AddressExpr * node ) { visit( const_cast<const AddressExpr *>(node) ); } 104 virtual void visit( const AddressExpr * addressExpr ) = 0; 105 virtual void visit( LabelAddressExpr * node ) { visit( const_cast<const LabelAddressExpr *>(node) ); } 106 virtual void visit( const LabelAddressExpr * labAddressExpr ) = 0; 107 virtual void visit( UntypedMemberExpr * node ) { visit( const_cast<const UntypedMemberExpr *>(node) ); } 108 virtual void visit( const UntypedMemberExpr * memberExpr ) = 0; 109 virtual void visit( MemberExpr * node ) { visit( const_cast<const MemberExpr *>(node) ); } 110 virtual void visit( const MemberExpr * memberExpr ) = 0; 111 virtual void visit( VariableExpr * node ) { visit( const_cast<const VariableExpr *>(node) ); } 112 virtual void visit( const VariableExpr * variableExpr ) = 0; 113 virtual void visit( ConstantExpr * node ) { visit( const_cast<const ConstantExpr *>(node) ); } 114 virtual void visit( const ConstantExpr * constantExpr ) = 0; 115 virtual void visit( SizeofExpr * node ) { visit( const_cast<const SizeofExpr *>(node) ); } 116 virtual void visit( const SizeofExpr * sizeofExpr ) = 0; 117 virtual void visit( AlignofExpr * node ) { visit( const_cast<const AlignofExpr *>(node) ); } 118 virtual void visit( const AlignofExpr * alignofExpr ) = 0; 119 virtual void visit( UntypedOffsetofExpr * node ) { visit( const_cast<const UntypedOffsetofExpr *>(node) ); } 120 virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) = 0; 121 virtual void visit( OffsetofExpr * node ) { visit( const_cast<const OffsetofExpr *>(node) ); } 122 virtual void visit( const OffsetofExpr * offsetofExpr ) = 0; 123 virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); } 124 virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0; 125 virtual void visit( AttrExpr * node ) { visit( const_cast<const AttrExpr *>(node) ); } 126 virtual void visit( const AttrExpr * attrExpr ) = 0; 127 virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); } 128 virtual void visit( const LogicalExpr * logicalExpr ) = 0; 129 virtual void visit( ConditionalExpr * node ) { visit( const_cast<const ConditionalExpr *>(node) ); } 130 virtual void visit( const ConditionalExpr * conditionalExpr ) = 0; 131 virtual void visit( CommaExpr * node ) { visit( const_cast<const CommaExpr *>(node) ); } 132 virtual void visit( const CommaExpr * commaExpr ) = 0; 133 virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); } 134 virtual void visit( const TypeExpr * typeExpr ) = 0; 135 virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); } 136 virtual void visit( const AsmExpr * asmExpr ) = 0; 137 virtual void visit( ImplicitCopyCtorExpr * node ) { visit( const_cast<const ImplicitCopyCtorExpr *>(node) ); } 138 virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) = 0; 139 virtual void visit( ConstructorExpr * node ) { visit( const_cast<const ConstructorExpr *>(node) ); } 140 virtual void visit( const ConstructorExpr * ctorExpr ) = 0; 141 virtual void visit( CompoundLiteralExpr * node ) { visit( const_cast<const CompoundLiteralExpr *>(node) ); } 142 virtual void visit( const CompoundLiteralExpr * compLitExpr ) = 0; 143 virtual void visit( RangeExpr * node ) { visit( const_cast<const RangeExpr *>(node) ); } 144 virtual void visit( const RangeExpr * rangeExpr ) = 0; 145 virtual void visit( UntypedTupleExpr * node ) { visit( const_cast<const UntypedTupleExpr *>(node) ); } 146 virtual void visit( const UntypedTupleExpr * tupleExpr ) = 0; 147 virtual void visit( TupleExpr * node ) { visit( const_cast<const TupleExpr *>(node) ); } 148 virtual void visit( const TupleExpr * tupleExpr ) = 0; 149 virtual void visit( TupleIndexExpr * node ) { visit( const_cast<const TupleIndexExpr *>(node) ); } 150 virtual void visit( const TupleIndexExpr * tupleExpr ) = 0; 151 virtual void visit( TupleAssignExpr * node ) { visit( const_cast<const TupleAssignExpr *>(node) ); } 152 virtual void visit( const TupleAssignExpr * assignExpr ) = 0; 153 virtual void visit( StmtExpr * node ) { visit( const_cast<const StmtExpr *>(node) ); } 154 virtual void visit( const StmtExpr * stmtExpr ) = 0; 155 virtual void visit( UniqueExpr * node ) { visit( const_cast<const UniqueExpr *>(node) ); } 156 virtual void visit( const UniqueExpr * uniqueExpr ) = 0; 157 virtual void visit( UntypedInitExpr * node ) { visit( const_cast<const UntypedInitExpr *>(node) ); } 158 virtual void visit( const UntypedInitExpr * initExpr ) = 0; 159 virtual void visit( InitExpr * node ) { visit( const_cast<const InitExpr *>(node) ); } 160 virtual void visit( const InitExpr * initExpr ) = 0; 161 virtual void visit( DeletedExpr * node ) { visit( const_cast<const DeletedExpr *>(node) ); } 162 virtual void visit( const DeletedExpr * delExpr ) = 0; 163 virtual void visit( DefaultArgExpr * node ) { visit( const_cast<const DefaultArgExpr *>(node) ); } 164 virtual void visit( const DefaultArgExpr * argExpr ) = 0; 165 virtual void visit( GenericExpr * node ) { visit( const_cast<const GenericExpr *>(node) ); } 166 virtual void visit( const GenericExpr * genExpr ) = 0; 167 168 virtual void visit( VoidType * node ) { visit( const_cast<const VoidType *>(node) ); } 169 virtual void visit( const VoidType * basicType ) = 0; 170 virtual void visit( BasicType * node ) { visit( const_cast<const BasicType *>(node) ); } 171 virtual void visit( const BasicType * basicType ) = 0; 172 virtual void visit( PointerType * node ) { visit( const_cast<const PointerType *>(node) ); } 173 virtual void visit( const PointerType * pointerType ) = 0; 174 virtual void visit( ArrayType * node ) { visit( const_cast<const ArrayType *>(node) ); } 175 virtual void visit( const ArrayType * arrayType ) = 0; 176 virtual void visit( ReferenceType * node ) { visit( const_cast<const ReferenceType *>(node) ); } 177 virtual void visit( const ReferenceType * refType ) = 0; 178 virtual void visit( QualifiedType * node ) { visit( const_cast<const QualifiedType *>(node) ); } 179 virtual void visit( const QualifiedType * qualType ) = 0; 180 virtual void visit( FunctionType * node ) { visit( const_cast<const FunctionType *>(node) ); } 181 virtual void visit( const FunctionType * functionType ) = 0; 182 virtual void visit( StructInstType * node ) { visit( const_cast<const StructInstType *>(node) ); } 183 virtual void visit( const StructInstType * aggregateUseType ) = 0; 184 virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); } 185 virtual void visit( const UnionInstType * aggregateUseType ) = 0; 186 virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); } 187 virtual void visit( const EnumInstType * aggregateUseType ) = 0; 188 virtual void visit( TraitInstType * node ) { visit( const_cast<const TraitInstType *>(node) ); } 189 virtual void visit( const TraitInstType * aggregateUseType ) = 0; 190 virtual void visit( TypeInstType * node ) { visit( const_cast<const TypeInstType *>(node) ); } 191 virtual void visit( const TypeInstType * aggregateUseType ) = 0; 192 virtual void visit( TupleType * node ) { visit( const_cast<const TupleType *>(node) ); } 193 virtual void visit( const TupleType * tupleType ) = 0; 194 virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); } 195 virtual void visit( const TypeofType * typeofType ) = 0; 196 virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); } 197 virtual void visit( const AttrType * attrType ) = 0; 198 virtual void visit( VarArgsType * node ) { visit( const_cast<const VarArgsType *>(node) ); } 199 virtual void visit( const VarArgsType * varArgsType ) = 0; 200 virtual void visit( ZeroType * node ) { visit( const_cast<const ZeroType *>(node) ); } 201 virtual void visit( const ZeroType * zeroType ) = 0; 202 virtual void visit( OneType * node ) { visit( const_cast<const OneType *>(node) ); } 203 virtual void visit( const OneType * oneType ) = 0; 204 virtual void visit( GlobalScopeType * node ) { visit( const_cast<const GlobalScopeType *>(node) ); } 205 virtual void visit( const GlobalScopeType * globalType ) = 0; 206 207 virtual void visit( Designation * node ) { visit( const_cast<const Designation *>(node) ); } 208 virtual void visit( const Designation * designation ) = 0; 209 virtual void visit( SingleInit * node ) { visit( const_cast<const SingleInit *>(node) ); } 210 virtual void visit( const SingleInit * singleInit ) = 0; 211 virtual void visit( ListInit * node ) { visit( const_cast<const ListInit *>(node) ); } 212 virtual void visit( const ListInit * listInit ) = 0; 213 virtual void visit( ConstructorInit * node ) { visit( const_cast<const ConstructorInit *>(node) ); } 214 virtual void visit( const ConstructorInit * ctorInit ) = 0; 215 216 virtual void visit( Constant * node ) { visit( const_cast<const Constant *>(node) ); } 217 virtual void visit( const Constant * constant ) = 0; 218 219 virtual void visit( Attribute * node ) { visit( const_cast<const Attribute *>(node) ); } 220 virtual void visit( const Attribute * attribute ) = 0; 128 221 }; 129 222 130 223 template< typename TreeType, typename VisitorType > 131 inline void maybeAccept( TreeType * tree, VisitorType &visitor ) {224 inline void maybeAccept( TreeType * tree, VisitorType & visitor ) { 132 225 if ( tree ) { 133 226 tree->accept( visitor ); … … 135 228 } 136 229 230 template< typename TreeType, typename VisitorType > 231 inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) { 232 if ( tree ) { 233 tree->accept( visitor ); 234 } 235 } 236 137 237 template< typename Container, typename VisitorType > 138 inline void acceptAll( Container & container, VisitorType &visitor ) {238 inline void acceptAll( Container & container, VisitorType & visitor ) { 139 239 SemanticErrorException errors; 140 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i) {240 for ( auto * i : container ) { 141 241 try { 142 if ( *i ) { 143 (*i)->accept( visitor ); 242 if ( i ) { 243 i->accept( visitor ); 244 } 245 } catch( SemanticErrorException & e ) { 246 errors.append( e ); 247 } 248 } 249 if ( ! errors.isEmpty() ) { 250 throw errors; 251 } 252 } 253 254 template< typename Container, typename VisitorType > 255 inline void acceptAll( const Container & container, VisitorType & visitor ) { 256 SemanticErrorException errors; 257 for ( const auto * i : container ) { 258 try { 259 if ( i ) { 260 i->accept( visitor ); 144 261 } 145 262 } catch( SemanticErrorException &e ) { -
src/Tuples/Explode.h
r1f1c102 rf53acdf8 51 51 template<typename OutputIterator> 52 52 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 54 54 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 55 55 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost }; … … 58 58 /// Append alternative to an ExplodedActual 59 59 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 61 61 const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 62 62 ea.exprs.emplace_back( expr ); … … 111 111 } else { 112 112 // atomic (non-tuple) type - output a clone of the expression in a new alternative 113 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 113 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 114 114 alt.cost, alt.cvtCost ); 115 115 } … … 174 174 template< typename Output > 175 175 void explodeRecursive( 176 const ast::CastExpr * expr, const ResolvExpr::Candidate & arg,177 const ast::SymbolTable & symtab, Output && out176 const ast::CastExpr *, const ResolvExpr::Candidate &, 177 const ast::SymbolTable &, Output && 178 178 ) { 179 179 } … … 239 239 /// explode list of candidates into flattened list of candidates 240 240 template< typename Output > 241 void explode( 242 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 241 void explode( 242 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 243 243 bool isTupleAssign = false 244 244 ) { -
src/Tuples/TupleAssignment.cc
r1f1c102 rf53acdf8 67 67 struct Matcher { 68 68 public: 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 70 70 const ResolvExpr::AltList& rhs ); 71 71 virtual ~Matcher() {} 72 72 73 73 virtual void match( std::list< Expression * > &out ) = 0; 74 74 ObjectDecl * newObject( UniqueName & namer, Expression * expr ); … … 83 83 for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); } 84 84 } 85 85 86 86 ResolvExpr::AltList lhs, rhs; 87 87 TupleAssignSpotter_old &spotter; … … 264 264 } 265 265 266 // extract expressions from the assignment alternatives to produce a list of assignments 266 // extract expressions from the assignment alternatives to produce a list of assignments 267 267 // that together form a single alternative 268 268 std::list< Expression *> solved_assigns; … … 271 271 matcher->combineState( alt ); 272 272 } 273 273 274 274 // xxx -- was push_front 275 275 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{ 276 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 277 matcher->openVars, 278 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 276 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 277 matcher->openVars, 278 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 279 279 ResolvExpr::sumCost( current ) + matcher->baseCost } ); 280 280 } … … 284 284 : lhs(lhs), rhs(rhs), spotter(spotter), 285 285 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 286 combineState( lhs ); 286 combineState( lhs ); 287 287 combineState( rhs ); 288 288 } … … 390 390 return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() ); 391 391 } 392 392 393 393 /// true if `expr` is of tuple type or a reference to one 394 394 bool refToTuple( const ast::Expr * expr ) { … … 421 421 } 422 422 423 Matcher( 423 Matcher( 424 424 TupleAssignSpotter_new & s, const CodeLocation & loc, 425 425 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 426 : lhs( l ), rhs( r ), spotter( s ), location( loc ), 427 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 426 : lhs( l ), rhs( r ), spotter( s ), location( loc ), 427 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 428 428 env(), open(), need() { 429 429 for ( auto & cand : lhs ) combineState( *cand ); 430 430 for ( auto & cand : rhs ) combineState( *cand ); 431 431 } 432 virtual ~Matcher() = default; 432 433 433 434 virtual std::vector< ast::ptr< ast::Expr > > match() = 0; 434 435 435 /// removes environments from subexpressions within statement expressions, which could 436 /// throw off later passes like those in Box which rely on PolyMutator, and adds the 436 /// removes environments from subexpressions within statement expressions, which could 437 /// throw off later passes like those in Box which rely on PolyMutator, and adds the 437 438 /// bindings to the env 438 439 struct EnvRemover { … … 455 456 ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) { 456 457 assert( expr->result && ! expr->result->isVoid() ); 457 458 ast::ObjectDecl * ret = new ast::ObjectDecl{ 459 location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 458 459 ast::ObjectDecl * ret = new ast::ObjectDecl{ 460 location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 460 461 ast::Storage::Classes{}, ast::Linkage::Cforall }; 461 462 462 463 // if expression type is a reference, just need an initializer, otherwise construct 463 464 if ( ! expr->result.as< ast::ReferenceType >() ) { 464 465 // resolve ctor/dtor for the new object 465 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 466 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 466 467 InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms ); 467 468 // remove environments from subexpressions of stmtExpr … … 474 475 } 475 476 476 ast::UntypedExpr * createFunc( 477 const std::string & fname, const ast::ObjectDecl * left, 478 const ast::ObjectDecl * right 477 ast::UntypedExpr * createFunc( 478 const std::string & fname, const ast::ObjectDecl * left, 479 const ast::ObjectDecl * right 479 480 ) { 480 481 assert( left ); … … 486 487 args.front() = new ast::AddressExpr{ location, args.front() }; 487 488 if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; } 488 return new ast::UntypedExpr{ 489 return new ast::UntypedExpr{ 489 490 location, new ast::NameExpr{ location, "?=?" }, std::move(args) }; 490 491 } else { 491 return new ast::UntypedExpr{ 492 return new ast::UntypedExpr{ 492 493 location, new ast::NameExpr{ location, fname }, std::move(args) }; 493 494 } … … 498 499 struct MassAssignMatcher final : public Matcher { 499 500 MassAssignMatcher( 500 TupleAssignSpotter_new & s, const CodeLocation & loc, 501 TupleAssignSpotter_new & s, const CodeLocation & loc, 501 502 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 502 503 : Matcher( s, loc, l, r ) {} … … 508 509 assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 ); 509 510 510 ast::ptr< ast::ObjectDecl > rtmp = 511 ast::ptr< ast::ObjectDecl > rtmp = 511 512 rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr; 512 513 513 514 std::vector< ast::ptr< ast::Expr > > out; 514 515 for ( ResolvExpr::CandidateRef & lhsCand : lhs ) { 515 // create a temporary object for each value in the LHS and create a call 516 // create a temporary object for each value in the LHS and create a call 516 517 // involving the RHS 517 518 ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr ); … … 528 529 struct MultipleAssignMatcher final : public Matcher { 529 530 MultipleAssignMatcher( 530 TupleAssignSpotter_new & s, const CodeLocation & loc, 531 TupleAssignSpotter_new & s, const CodeLocation & loc, 531 532 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 532 533 : Matcher( s, loc, l, r ) {} … … 538 539 if ( lhs.size() != rhs.size() ) return {}; 539 540 540 // produce a new temporary object for each value in the LHS and RHS and pairwise 541 // produce a new temporary object for each value in the LHS and RHS and pairwise 541 542 // create the calls 542 543 std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp; … … 547 548 ResolvExpr::CandidateRef & rhsCand = rhs[i]; 548 549 549 // convert RHS to LHS type minus one reference -- important for case where LHS 550 // convert RHS to LHS type minus one reference -- important for case where LHS 550 551 // is && and RHS is lvalue 551 552 auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >(); … … 557 558 rtmp.emplace_back( std::move( robj ) ); 558 559 559 // resolve the cast expression so that rhsCand return type is bound by the cast 560 // resolve the cast expression so that rhsCand return type is bound by the cast 560 561 // type as needed, and transfer the resulting environment 561 562 ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env }; … … 564 565 env = std::move( finder.candidates.front()->env ); 565 566 } 566 567 567 568 splice( tmpDecls, ltmp ); 568 569 splice( tmpDecls, rtmp ); 569 570 570 571 return out; 571 572 } … … 575 576 std::string fname; 576 577 std::unique_ptr< Matcher > matcher; 577 578 578 579 public: 579 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 580 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 580 581 : crntFinder( f ), fname(), matcher() {} 581 582 582 583 // find left- and right-hand-sides for mass or multiple assignment 583 void spot( 584 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 584 void spot( 585 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 585 586 ) { 586 587 if ( auto op = expr->func.as< ast::NameExpr >() ) { … … 599 600 if ( ! refToTuple( lhsCand->expr ) ) continue; 600 601 601 // explode is aware of casts - ensure every LHS is sent into explode with a 602 // explode is aware of casts - ensure every LHS is sent into explode with a 602 603 // reference cast 603 604 if ( ! lhsCand->expr.as< ast::CastExpr >() ) { 604 lhsCand->expr = new ast::CastExpr{ 605 lhsCand->expr = new ast::CastExpr{ 605 606 lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } }; 606 607 } … … 610 611 explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true ); 611 612 for ( ResolvExpr::CandidateRef & cand : lhs ) { 612 // each LHS value must be a reference - some come in with a cast, if not 613 // each LHS value must be a reference - some come in with a cast, if not 613 614 // just cast to reference here 614 615 if ( ! cand->expr->result.as< ast::ReferenceType >() ) { … … 629 630 // multiple assignment 630 631 explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 631 matcher.reset( 632 matcher.reset( 632 633 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 633 634 } else { 634 635 // mass assignment 635 636 rhs.emplace_back( rhsCand ); 636 matcher.reset( 637 matcher.reset( 637 638 new MassAssignMatcher{ *this, expr->location, lhs, rhs } ); 638 639 } … … 642 643 // expand all possible RHS possibilities 643 644 std::vector< ResolvExpr::CandidateList > rhsCands; 644 combos( 645 combos( 645 646 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 646 647 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { … … 648 649 ResolvExpr::CandidateList rhs; 649 650 explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 650 matcher.reset( 651 matcher.reset( 651 652 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 652 653 match(); … … 663 664 664 665 if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) { 665 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 666 // okay for newAssigns to be empty. Otherwise, return early so that no new 666 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 667 // okay for newAssigns to be empty. Otherwise, return early so that no new 667 668 // candidates are generated 668 669 if ( newAssigns.empty() ) return; … … 692 693 } 693 694 694 // extract expressions from the assignment candidates to produce a list of assignments 695 // extract expressions from the assignment candidates to produce a list of assignments 695 696 // that together form a sigle candidate 696 697 std::vector< ast::ptr< ast::Expr > > solved; … … 701 702 702 703 crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >( 703 new ast::TupleAssignExpr{ 704 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 705 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 704 new ast::TupleAssignExpr{ 705 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 706 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 706 707 ResolvExpr::sumCost( crnt ) + matcher->baseCost ) ); 707 708 } … … 709 710 } // anonymous namespace 710 711 711 void handleTupleAssignment( 712 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 712 void handleTupleAssignment( 713 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 713 714 std::vector< ResolvExpr::CandidateFinder > & args 714 715 ) { -
src/main.cc
r1f1c102 rf53acdf8 460 460 const char * descript; 461 461 } printopts[] = { 462 { "altexpr", expraltp, true, "alternatives for expressions" }, 463 { "ascodegen", codegenp, true, "as codegen rather than AST" }, 464 { "ast", astp, true, "AST after parsing" }, 465 { "astdecl", validp, true, "AST after declaration validation pass" }, 466 { "asterr", errorp, true, "AST on error" }, 467 { "astexpr", exprp, true, "AST after expression analysis" }, 468 { "astgen", genericsp, true, "AST after instantiate generics" }, 469 { "box", bboxp, true, "before box step" }, 470 { "ctordtor", ctorinitp, true, "after ctor/dtor are replaced" }, 471 { "codegen", bcodegenp, true, "before code generation" }, 462 { "ascodegen", codegenp, true, "print AST as codegen rather than AST" }, 463 { "asterr", errorp, true, "print AST on error" }, 472 464 { "declstats", declstatsp, true, "code property statistics" }, 473 465 { "parse", yydebug, true, "yacc (parsing) debug information" }, 474 466 { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" }, 475 { "resolver", bresolvep, true, "before resolver step" },476 467 { "rproto", resolvprotop, true, "resolver-proto instance" }, 477 { "rsteps", resolvep, true, "resolver steps" }, 478 { "symevt", symtabp, true, "symbol table events" }, 479 { "tree", parsep, true, "parse tree" }, 480 { "tuple", tuplep, true, "after tuple expansion" }, 468 { "rsteps", resolvep, true, "print resolver steps" }, 469 { "tree", parsep, true, "print parse tree" }, 470 // code dumps 471 { "ast", astp, true, "print AST after parsing" }, 472 { "symevt", symtabp, true, "print AST after symbol table events" }, 473 { "altexpr", expraltp, true, "print alternatives for expressions" }, 474 { "astdecl", validp, true, "print AST after declaration validation pass" }, 475 { "resolver", bresolvep, true, "print AST before resolver step" }, 476 { "astexpr", exprp, true, "print AST after expression analysis" }, 477 { "ctordtor", ctorinitp, true, "print AST after ctor/dtor are replaced" }, 478 { "tuple", tuplep, true, "print AST after tuple expansion" }, 479 { "astgen", genericsp, true, "print AST after instantiate generics" }, 480 { "box", bboxp, true, "print AST before box step" }, 481 { "codegen", bcodegenp, true, "print AST before code generation" }, 481 482 }; 482 483 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
Note:
See TracChangeset
for help on using the changeset viewer.