Changes in src/ResolvExpr/Resolver.cc [b230091:4559b34]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (39 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
rb230091 r4559b34 9 9 // Author : Aaron B. Moss 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Mar 18 10:41:00202213 // Update Count : 24 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 1 16:27:14 2022 13 // Update Count : 245 14 14 // 15 15 … … 997 997 /// Calls the CandidateFinder and finds the single best candidate 998 998 CandidateRef findUnfinishedKindExpression( 999 const ast::Expr * untyped, const ResolveContext & context, const std::string & kind,999 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 1000 1000 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 1001 1001 ) { … … 1007 1007 ++recursion_level; 1008 1008 ast::TypeEnvironment env; 1009 CandidateFinder finder ( context, env );1009 CandidateFinder finder{ symtab, env }; 1010 1010 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 1011 1011 --recursion_level; … … 1129 1129 1130 1130 ast::ptr< ast::Expr > resolveInVoidContext( 1131 const ast::Expr * expr, const ResolveContext & context, 1132 ast::TypeEnvironment & env 1131 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1133 1132 ) { 1134 1133 assertf( expr, "expected a non-null expression" ); … … 1137 1136 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1138 1137 CandidateRef choice = findUnfinishedKindExpression( 1139 untyped, context, "", anyCandidate, ResolvMode::withAdjustment() );1138 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1140 1139 1141 1140 // a cast expression has either 0 or 1 interpretations (by language rules); … … 1150 1149 /// context. 1151 1150 ast::ptr< ast::Expr > findVoidExpression( 1152 const ast::Expr * untyped, const ResolveContext & context1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1153 1152 ) { 1154 1153 ast::TypeEnvironment env; 1155 ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, context, env );1154 ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env ); 1156 1155 finishExpr( newExpr, env, untyped->env ); 1157 1156 return newExpr; … … 1164 1163 /// lowest cost, returning the resolved version 1165 1164 ast::ptr< ast::Expr > findKindExpression( 1166 const ast::Expr * untyped, const ResolveContext & context,1165 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1167 1166 std::function<bool(const Candidate &)> pred = anyCandidate, 1168 1167 const std::string & kind = "", ResolvMode mode = {} … … 1170 1169 if ( ! untyped ) return {}; 1171 1170 CandidateRef choice = 1172 findUnfinishedKindExpression( untyped, context, kind, pred, mode );1171 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1173 1172 ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env ); 1174 1173 return std::move( choice->expr ); … … 1177 1176 /// Resolve `untyped` to the single expression whose candidate is the best match 1178 1177 ast::ptr< ast::Expr > findSingleExpression( 1179 const ast::Expr * untyped, const ResolveContext & context1178 const ast::Expr * untyped, const ast::SymbolTable & symtab 1180 1179 ) { 1181 1180 Stats::ResolveTime::start( untyped ); 1182 auto res = findKindExpression( untyped, context);1181 auto res = findKindExpression( untyped, symtab ); 1183 1182 Stats::ResolveTime::stop(); 1184 1183 return res; … … 1187 1186 1188 1187 ast::ptr< ast::Expr > findSingleExpression( 1189 const ast::Expr * untyped, const ast::Type * type, 1190 const ResolveContext & context 1188 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab 1191 1189 ) { 1192 1190 assert( untyped && type ); 1193 1191 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1194 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, context);1195 removeExtraneousCast( newExpr, context.symtab );1192 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1193 removeExtraneousCast( newExpr, symtab ); 1196 1194 return newExpr; 1197 1195 } … … 1219 1217 /// Resolve `untyped` as an integral expression, returning the resolved version 1220 1218 ast::ptr< ast::Expr > findIntegralExpression( 1221 const ast::Expr * untyped, const ResolveContext & context1219 const ast::Expr * untyped, const ast::SymbolTable & symtab 1222 1220 ) { 1223 return findKindExpression( untyped, context, hasIntegralType, "condition" );1221 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); 1224 1222 } 1225 1223 … … 1251 1249 // for work previously in GenInit 1252 1250 static InitTweak::ManagedTypes_new managedTypes; 1253 ResolveContext context;1254 1251 1255 1252 bool inEnumDecl = false; … … 1257 1254 public: 1258 1255 static size_t traceId; 1259 Resolver_new( const ast::TranslationGlobal & global ) : 1260 context{ symtab, global } {} 1261 Resolver_new( const ResolveContext & context ) : 1262 ast::WithSymbolTable{ context.symtab }, 1263 context{ symtab, context.global } {} 1256 Resolver_new() = default; 1257 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1264 1258 1265 1259 const ast::FunctionDecl * previsit( const ast::FunctionDecl * ); … … 1278 1272 const ast::AsmStmt * previsit( const ast::AsmStmt * ); 1279 1273 const ast::IfStmt * previsit( const ast::IfStmt * ); 1280 const ast::WhileDoStmt * previsit( const ast::WhileDoStmt * );1274 const ast::WhileDoStmt * previsit( const ast::WhileDoStmt * ); 1281 1275 const ast::ForStmt * previsit( const ast::ForStmt * ); 1282 1276 const ast::SwitchStmt * previsit( const ast::SwitchStmt * ); 1283 const ast::Case Clause * previsit( const ast::CaseClause* );1277 const ast::CaseStmt * previsit( const ast::CaseStmt * ); 1284 1278 const ast::BranchStmt * previsit( const ast::BranchStmt * ); 1285 1279 const ast::ReturnStmt * previsit( const ast::ReturnStmt * ); 1286 1280 const ast::ThrowStmt * previsit( const ast::ThrowStmt * ); 1287 const ast::Catch Clause * previsit( const ast::CatchClause* );1288 const ast::Catch Clause * postvisit( const ast::CatchClause* );1281 const ast::CatchStmt * previsit( const ast::CatchStmt * ); 1282 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1289 1283 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1290 1284 const ast::WithStmt * previsit( const ast::WithStmt * ); … … 1305 1299 1306 1300 void resolve( ast::TranslationUnit& translationUnit ) { 1307 ast::Pass< Resolver_new >::run( translationUnit , translationUnit.global);1301 ast::Pass< Resolver_new >::run( translationUnit ); 1308 1302 } 1309 1303 1310 1304 ast::ptr< ast::Init > resolveCtorInit( 1311 const ast::ConstructorInit * ctorInit, const ResolveContext & context1305 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1312 1306 ) { 1313 1307 assert( ctorInit ); 1314 ast::Pass< Resolver_new > resolver ( context );1308 ast::Pass< Resolver_new > resolver{ symtab }; 1315 1309 return ctorInit->accept( resolver ); 1316 1310 } 1317 1311 1318 1312 const ast::Expr * resolveStmtExpr( 1319 const ast::StmtExpr * stmtExpr, const ResolveContext & context1313 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1320 1314 ) { 1321 1315 assert( stmtExpr ); 1322 ast::Pass< Resolver_new > resolver ( context );1316 ast::Pass< Resolver_new > resolver{ symtab }; 1323 1317 auto ret = mutate(stmtExpr->accept(resolver)); 1324 1318 strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult(); … … 1327 1321 1328 1322 namespace { 1329 const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ResolveContext & context) {1323 const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) { 1330 1324 std::string name = attr->normalizedName(); 1331 1325 if (name == "constructor" || name == "destructor") { 1332 1326 if (attr->params.size() == 1) { 1333 1327 auto arg = attr->params.front(); 1334 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), context);1328 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab ); 1335 1329 auto result = eval(arg); 1336 1330 … … 1375 1369 1376 1370 for (auto & attr: mutDecl->attributes) { 1377 attr = handleAttribute(mutDecl->location, attr, context);1371 attr = handleAttribute(mutDecl->location, attr, symtab); 1378 1372 } 1379 1373 … … 1385 1379 for (auto & typeParam : mutDecl->type_params) { 1386 1380 symtab.addType(typeParam); 1387 mutType->forall.emplace_back(new ast::TypeInstType(typeParam ));1381 mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam)); 1388 1382 } 1389 1383 for (auto & asst : mutDecl->assertions) { 1390 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), context);1384 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab); 1391 1385 symtab.addId(asst); 1392 1386 mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst)); … … 1400 1394 1401 1395 for (auto & param : mutDecl->params) { 1402 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), context);1396 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab); 1403 1397 symtab.addId(param); 1404 1398 paramTypes.emplace_back(param->get_type()); 1405 1399 } 1406 1400 for (auto & ret : mutDecl->returns) { 1407 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), context);1401 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab); 1408 1402 returnTypes.emplace_back(ret->get_type()); 1409 1403 } … … 1476 1470 // enumerator initializers should not use the enum type to initialize, since the 1477 1471 // enum type is still incomplete at this point. Use `int` instead. 1478 objectDecl = fixObjectType(objectDecl, context); 1479 currentObject = ast::CurrentObject{ 1480 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1472 1473 if (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base) { // const ast::PointerType & 1474 const ast::Type * enumBase = (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base.get()); 1475 const ast::PointerType * enumBaseAsPtr = dynamic_cast<const ast::PointerType *>(enumBase); 1476 1477 if ( enumBaseAsPtr ) { 1478 const ast::Type * pointerBase = enumBaseAsPtr->base.get(); 1479 if ( dynamic_cast<const ast::BasicType *>(pointerBase) ) { 1480 objectDecl = fixObjectType(objectDecl, symtab); 1481 if (dynamic_cast<const ast::BasicType *>(pointerBase)->kind == ast::BasicType::Char) 1482 currentObject = ast::CurrentObject{ 1483 objectDecl->location, new ast::PointerType{ 1484 new ast::BasicType{ ast::BasicType::Char } 1485 } }; 1486 } else { 1487 objectDecl = fixObjectType(objectDecl, symtab); 1488 currentObject = ast::CurrentObject{objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1489 } 1490 } 1491 } else { 1492 objectDecl = fixObjectType(objectDecl, symtab); 1493 currentObject = ast::CurrentObject{ 1494 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1495 } 1496 1481 1497 } 1482 1498 else { 1483 1499 if (!objectDecl->isTypeFixed) { 1484 auto newDecl = fixObjectType(objectDecl, context);1500 auto newDecl = fixObjectType(objectDecl, symtab); 1485 1501 auto mutDecl = mutate(newDecl); 1486 1502 … … 1513 1529 // nested type decls are hoisted already. no need to do anything 1514 1530 if (auto obj = member.as<ast::ObjectDecl>()) { 1515 member = fixObjectType(obj, context);1531 member = fixObjectType(obj, symtab); 1516 1532 } 1517 1533 } … … 1536 1552 return ast::mutate_field( 1537 1553 assertDecl, &ast::StaticAssertDecl::cond, 1538 findIntegralExpression( assertDecl->cond, context) );1554 findIntegralExpression( assertDecl->cond, symtab ) ); 1539 1555 } 1540 1556 1541 1557 template< typename PtrType > 1542 const PtrType * handlePtrType( const PtrType * type, const ResolveContext & context) {1558 const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) { 1543 1559 if ( type->dimension ) { 1544 ast::ptr< ast::Type > sizeType = context.global.sizeType;1560 ast::ptr< ast::Type > sizeType = ast::sizeType; 1545 1561 ast::mutate_field( 1546 1562 type, &PtrType::dimension, 1547 findSingleExpression( type->dimension, sizeType, context) );1563 findSingleExpression( type->dimension, sizeType, symtab ) ); 1548 1564 } 1549 1565 return type; … … 1551 1567 1552 1568 const ast::ArrayType * Resolver_new::previsit( const ast::ArrayType * at ) { 1553 return handlePtrType( at, context);1569 return handlePtrType( at, symtab ); 1554 1570 } 1555 1571 1556 1572 const ast::PointerType * Resolver_new::previsit( const ast::PointerType * pt ) { 1557 return handlePtrType( pt, context);1573 return handlePtrType( pt, symtab ); 1558 1574 } 1559 1575 … … 1563 1579 1564 1580 return ast::mutate_field( 1565 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, context) );1581 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1566 1582 } 1567 1583 … … 1570 1586 1571 1587 asmExpr = ast::mutate_field( 1572 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, context) );1588 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1573 1589 1574 1590 return asmExpr; … … 1584 1600 const ast::IfStmt * Resolver_new::previsit( const ast::IfStmt * ifStmt ) { 1585 1601 return ast::mutate_field( 1586 ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, context) );1602 ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, symtab ) ); 1587 1603 } 1588 1604 1589 1605 const ast::WhileDoStmt * Resolver_new::previsit( const ast::WhileDoStmt * whileDoStmt ) { 1590 1606 return ast::mutate_field( 1591 whileDoStmt, &ast::WhileDoStmt::cond, findIntegralExpression( whileDoStmt->cond, context) );1607 whileDoStmt, &ast::WhileDoStmt::cond, findIntegralExpression( whileDoStmt->cond, symtab ) ); 1592 1608 } 1593 1609 … … 1595 1611 if ( forStmt->cond ) { 1596 1612 forStmt = ast::mutate_field( 1597 forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, context) );1613 forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, symtab ) ); 1598 1614 } 1599 1615 1600 1616 if ( forStmt->inc ) { 1601 1617 forStmt = ast::mutate_field( 1602 forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, context) );1618 forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, symtab ) ); 1603 1619 } 1604 1620 … … 1610 1626 switchStmt = ast::mutate_field( 1611 1627 switchStmt, &ast::SwitchStmt::cond, 1612 findIntegralExpression( switchStmt->cond, context) );1628 findIntegralExpression( switchStmt->cond, symtab ) ); 1613 1629 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; 1614 1630 return switchStmt; 1615 1631 } 1616 1632 1617 const ast::Case Clause * Resolver_new::previsit( const ast::CaseClause* caseStmt ) {1633 const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1618 1634 if ( caseStmt->cond ) { 1619 1635 std::deque< ast::InitAlternative > initAlts = currentObject.getOptions(); … … 1623 1639 ast::ptr< ast::Expr > untyped = 1624 1640 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1625 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, context);1641 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab ); 1626 1642 1627 1643 // case condition cannot have a cast in C, so it must be removed here, regardless of … … 1631 1647 } 1632 1648 1633 caseStmt = ast::mutate_field( caseStmt, &ast::Case Clause::cond, newExpr );1649 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1634 1650 } 1635 1651 return caseStmt; … … 1644 1660 branchStmt = ast::mutate_field( 1645 1661 branchStmt, &ast::BranchStmt::computedTarget, 1646 findSingleExpression( branchStmt->computedTarget, target, context) );1662 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1647 1663 } 1648 1664 return branchStmt; … … 1654 1670 returnStmt = ast::mutate_field( 1655 1671 returnStmt, &ast::ReturnStmt::expr, 1656 findSingleExpression( returnStmt->expr, functionReturn, context) );1672 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1657 1673 } 1658 1674 return returnStmt; … … 1669 1685 throwStmt = ast::mutate_field( 1670 1686 throwStmt, &ast::ThrowStmt::expr, 1671 findSingleExpression( throwStmt->expr, exceptType, context) );1687 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1672 1688 } 1673 1689 return throwStmt; 1674 1690 } 1675 1691 1676 const ast::Catch Clause * Resolver_new::previsit( const ast::CatchClause * catchClause) {1692 const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 1677 1693 // Until we are very sure this invarent (ifs that move between passes have then) 1678 1694 // holds, check it. This allows a check for when to decode the mangling. 1679 if ( auto ifStmt = catch Clause->body.as<ast::IfStmt>() ) {1695 if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) { 1680 1696 assert( ifStmt->then ); 1681 1697 } 1682 1698 // Encode the catchStmt so the condition can see the declaration. 1683 if ( catch Clause->cond ) {1684 ast::Catch Clause * clause = mutate( catchClause);1685 clause->body = new ast::IfStmt( clause->location, clause->cond, nullptr, clause->body );1686 clause->cond = nullptr;1687 return clause;1688 } 1689 return catch Clause;1690 } 1691 1692 const ast::Catch Clause * Resolver_new::postvisit( const ast::CatchClause * catchClause) {1699 if ( catchStmt->cond ) { 1700 ast::CatchStmt * stmt = mutate( catchStmt ); 1701 stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body ); 1702 stmt->cond = nullptr; 1703 return stmt; 1704 } 1705 return catchStmt; 1706 } 1707 1708 const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) { 1693 1709 // Decode the catchStmt so everything is stored properly. 1694 const ast::IfStmt * ifStmt = catch Clause->body.as<ast::IfStmt>();1710 const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>(); 1695 1711 if ( nullptr != ifStmt && nullptr == ifStmt->then ) { 1696 1712 assert( ifStmt->cond ); 1697 1713 assert( ifStmt->else_ ); 1698 ast::Catch Clause * clause = ast::mutate( catchClause);1699 clause->cond = ifStmt->cond;1700 clause->body = ifStmt->else_;1714 ast::CatchStmt * stmt = ast::mutate( catchStmt ); 1715 stmt->cond = ifStmt->cond; 1716 stmt->body = ifStmt->else_; 1701 1717 // ifStmt should be implicately deleted here. 1702 return clause;1703 } 1704 return catch Clause;1718 return stmt; 1719 } 1720 return catchStmt; 1705 1721 } 1706 1722 … … 1713 1729 1714 1730 ast::TypeEnvironment env; 1715 CandidateFinder funcFinder ( context, env );1731 CandidateFinder funcFinder{ symtab, env }; 1716 1732 1717 1733 // Find all candidates for a function in canonical form … … 1927 1943 ); 1928 1944 1929 clause2.target.args.emplace_back( findSingleExpression( init, context) );1945 clause2.target.args.emplace_back( findSingleExpression( init, symtab ) ); 1930 1946 } 1931 1947 1932 1948 // Resolve the conditions as if it were an IfStmt, statements normally 1933 clause2.cond = findSingleExpression( clause.cond, context);1949 clause2.cond = findSingleExpression( clause.cond, symtab ); 1934 1950 clause2.stmt = clause.stmt->accept( *visitor ); 1935 1951 … … 1946 1962 ast::ptr< ast::Type > target = 1947 1963 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1948 timeout2.time = findSingleExpression( stmt->timeout.time, target, context);1949 timeout2.cond = findSingleExpression( stmt->timeout.cond, context);1964 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); 1965 timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab ); 1950 1966 timeout2.stmt = stmt->timeout.stmt->accept( *visitor ); 1951 1967 … … 1960 1976 ast::WaitForStmt::OrElse orElse2; 1961 1977 1962 orElse2.cond = findSingleExpression( stmt->orElse.cond, context);1978 orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab ); 1963 1979 orElse2.stmt = stmt->orElse.stmt->accept( *visitor ); 1964 1980 … … 1981 1997 for (auto & expr : exprs) { 1982 1998 // only struct- and union-typed expressions are viable candidates 1983 expr = findKindExpression( expr, context, structOrUnion, "with expression" );1999 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" ); 1984 2000 1985 2001 // if with expression might be impure, create a temporary so that it is evaluated once … … 2007 2023 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 2008 2024 singleInit->location, singleInit->value, currentObject.getOptions() }; 2009 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, context);2025 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); 2010 2026 const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >(); 2011 2027
Note:
See TracChangeset
for help on using the changeset viewer.