Changeset 58fe85a for src/ResolvExpr/Resolver.cc
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2b4daf2, 64aeca0
- Parents:
- 3c64c668 (diff), eef8dfb (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r3c64c668 r58fe85a 9 9 // Author : Aaron B. Moss 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Wed May 29 11:00:00 201913 // Update Count : 24 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 27 11:58:00 2020 13 // Update Count : 242 14 14 // 15 15 … … 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h" 28 29 #include "ResolvMode.h" // for ResolvMode 29 30 #include "typeops.h" // for extractResultType 30 31 #include "Unify.h" // for unify 32 #include "CompilationState.h" 31 33 #include "AST/Chain.hpp" 32 34 #include "AST/Decl.hpp" … … 38 40 #include "Common/PassVisitor.h" // for PassVisitor 39 41 #include "Common/SemanticError.h" // for SemanticError 42 #include "Common/Stats/ResolveTime.h" // for ResolveTime::start(), ResolveTime::stop() 40 43 #include "Common/utility.h" // for ValueGuard, group_iterate 41 44 #include "InitTweak/GenInit.h" … … 44 47 #include "SymTab/Autogen.h" // for SizeType 45 48 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler 46 50 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 47 51 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 560 564 // TODO: Replace *exception type with &exception type. 561 565 if ( throwStmt->get_expr() ) { 562 const StructDecl * exception_decl = indexer.lookupStruct( "__cfa abi_ehm__base_exception_t" );566 const StructDecl * exception_decl = indexer.lookupStruct( "__cfaehm_base_exception_t" ); 563 567 assert( exception_decl ); 564 568 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) ); … … 964 968 namespace { 965 969 /// Finds deleted expressions in an expression tree 966 struct DeleteFinder_new final : public ast::WithShortCircuiting {967 const ast::DeletedExpr * delExpr= nullptr;970 struct DeleteFinder_new final : public ast::WithShortCircuiting, public ast::WithVisitorRef<DeleteFinder_new> { 971 const ast::DeletedExpr * result = nullptr; 968 972 969 973 void previsit( const ast::DeletedExpr * expr ) { 970 if ( delExpr ) { visit_children = false; } 971 else { delExpr = expr; } 972 } 973 974 void previsit( const ast::Expr * ) { 975 if ( delExpr ) { visit_children = false; } 974 if ( result ) { visit_children = false; } 975 else { result = expr; } 976 } 977 978 void previsit( const ast::Expr * expr ) { 979 if ( result ) { visit_children = false; } 980 if (expr->inferred.hasParams()) { 981 for (auto & imp : expr->inferred.inferParams() ) { 982 imp.second.expr->accept(*visitor); 983 } 984 } 976 985 } 977 986 }; 978 987 } // anonymous namespace 979 980 988 /// Check if this expression is or includes a deleted expression 981 989 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 982 ast::Pass<DeleteFinder_new> finder; 983 expr->accept( finder ); 984 return finder.pass.delExpr; 990 return ast::Pass<DeleteFinder_new>::read( expr ); 985 991 } 986 992 … … 1072 1078 /// Strips extraneous casts out of an expression 1073 1079 struct StripCasts_new final { 1074 const ast::Expr * post mutate( const ast::CastExpr * castExpr ) {1080 const ast::Expr * postvisit( const ast::CastExpr * castExpr ) { 1075 1081 if ( 1076 castExpr->isGenerated 1082 castExpr->isGenerated == ast::GeneratedCast 1077 1083 && typesCompatible( castExpr->arg->result, castExpr->result ) 1078 1084 ) { … … 1106 1112 } 1107 1113 1108 /// Establish post-resolver invariants for expressions 1114 1115 } // anonymous namespace 1116 /// Establish post-resolver invariants for expressions 1109 1117 void finishExpr( 1110 1118 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, … … 1119 1127 StripCasts_new::strip( expr ); 1120 1128 } 1121 } // anonymous namespace1122 1123 1129 1124 1130 ast::ptr< ast::Expr > resolveInVoidContext( … … 1128 1134 1129 1135 // set up and resolve expression cast to void 1130 ast:: CastExpr *untyped = new ast::CastExpr{ expr };1136 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1131 1137 CandidateRef choice = findUnfinishedKindExpression( 1132 1138 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); … … 1140 1146 } 1141 1147 1142 namespace { 1143 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1148 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1144 1149 /// context. 1145 1150 ast::ptr< ast::Expr > findVoidExpression( 1146 1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1147 1152 ) { 1148 resetTyVarRenaming();1149 1153 ast::TypeEnvironment env; 1150 1154 ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env ); … … 1152 1156 return newExpr; 1153 1157 } 1158 1159 namespace { 1160 1154 1161 1155 1162 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the … … 1163 1170 CandidateRef choice = 1164 1171 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1165 finishExpr( choice->expr, choice->env, untyped->env );1172 ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env ); 1166 1173 return std::move( choice->expr ); 1167 1174 } … … 1171 1178 const ast::Expr * untyped, const ast::SymbolTable & symtab 1172 1179 ) { 1173 return findKindExpression( untyped, symtab ); 1180 Stats::ResolveTime::start( untyped ); 1181 auto res = findKindExpression( untyped, symtab ); 1182 Stats::ResolveTime::stop(); 1183 return res; 1174 1184 } 1175 1185 } // anonymous namespace 1176 1186 1177 1178 1179 1180 1181 1182 1183 1184 1185 1187 ast::ptr< ast::Expr > findSingleExpression( 1188 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab 1189 ) { 1190 assert( untyped && type ); 1191 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1192 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1193 removeExtraneousCast( newExpr, symtab ); 1194 return newExpr; 1195 } 1186 1196 1187 1197 namespace { 1198 bool structOrUnion( const Candidate & i ) { 1199 const ast::Type * t = i.expr->result->stripReferences(); 1200 return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t ); 1201 } 1188 1202 /// Predicate for "Candidate has integral type" 1189 1203 bool hasIntegralType( const Candidate & i ) { … … 1221 1235 template<typename Iter> 1222 1236 inline bool nextMutex( Iter & it, const Iter & end ) { 1223 while ( it != end && ! (*it)-> get_type()->is_mutex() ) { ++it; }1237 while ( it != end && ! (*it)->is_mutex() ) { ++it; } 1224 1238 return it != end; 1225 1239 } … … 1233 1247 ast::ptr< ast::Type > functionReturn = nullptr; 1234 1248 ast::CurrentObject currentObject; 1249 // for work previously in GenInit 1250 static InitTweak::ManagedTypes_new managedTypes; 1251 1235 1252 bool inEnumDecl = false; 1236 1253 1237 1254 public: 1255 static size_t traceId; 1238 1256 Resolver_new() = default; 1239 1257 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1240 1258 1241 voidprevisit( const ast::FunctionDecl * );1259 const ast::FunctionDecl * previsit( const ast::FunctionDecl * ); 1242 1260 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * ); 1243 void previsit( const ast::ObjectDecl * ); 1261 const ast::ObjectDecl * previsit( const ast::ObjectDecl * ); 1262 void previsit( const ast::AggregateDecl * ); 1263 void previsit( const ast::StructDecl * ); 1244 1264 void previsit( const ast::EnumDecl * ); 1245 1265 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1260 1280 const ast::ThrowStmt * previsit( const ast::ThrowStmt * ); 1261 1281 const ast::CatchStmt * previsit( const ast::CatchStmt * ); 1282 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1262 1283 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1284 const ast::WithStmt * previsit( const ast::WithStmt * ); 1263 1285 1264 1286 const ast::SingleInit * previsit( const ast::SingleInit * ); 1265 1287 const ast::ListInit * previsit( const ast::ListInit * ); 1266 1288 const ast::ConstructorInit * previsit( const ast::ConstructorInit * ); 1289 1290 void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd); 1291 1292 void beginScope() { managedTypes.beginScope(); } 1293 void endScope() { managedTypes.endScope(); } 1294 bool on_error(ast::ptr<ast::Decl> & decl); 1267 1295 }; 1268 1269 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) { 1270 ast::Pass< Resolver_new > resolver; 1271 accept_all( translationUnit, resolver ); 1296 // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver"); 1297 1298 InitTweak::ManagedTypes_new Resolver_new::managedTypes; 1299 1300 void resolve( ast::TranslationUnit& translationUnit ) { 1301 ast::Pass< Resolver_new >::run( translationUnit ); 1272 1302 } 1273 1303 … … 1280 1310 } 1281 1311 1282 ast::ptr< ast::Expr >resolveStmtExpr(1312 const ast::Expr * resolveStmtExpr( 1283 1313 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1284 1314 ) { 1285 1315 assert( stmtExpr ); 1286 1316 ast::Pass< Resolver_new > resolver{ symtab }; 1287 ast::ptr< ast::Expr > ret = stmtExpr; 1288 ret = ret->accept( resolver ); 1289 strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult(); 1317 auto ret = mutate(stmtExpr->accept(resolver)); 1318 strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult(); 1290 1319 return ret; 1291 1320 } 1292 1321 1293 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1322 namespace { 1323 const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) { 1324 std::string name = attr->normalizedName(); 1325 if (name == "constructor" || name == "destructor") { 1326 if (attr->params.size() == 1) { 1327 auto arg = attr->params.front(); 1328 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab ); 1329 auto result = eval(arg); 1330 1331 auto mutAttr = mutate(attr); 1332 mutAttr->params.front() = resolved; 1333 if (! result.second) { 1334 SemanticWarning(loc, Warning::GccAttributes, 1335 toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) ); 1336 } 1337 else { 1338 auto priority = result.first; 1339 if (priority < 101) { 1340 SemanticWarning(loc, Warning::GccAttributes, 1341 toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) ); 1342 } else if (priority < 201 && ! buildingLibrary()) { 1343 SemanticWarning(loc, Warning::GccAttributes, 1344 toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) ); 1345 } 1346 } 1347 return mutAttr; 1348 } else if (attr->params.size() > 1) { 1349 SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) ); 1350 } else { 1351 SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) ); 1352 } 1353 } 1354 return attr; 1355 } 1356 } 1357 1358 const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1294 1359 GuardValue( functionReturn ); 1360 1361 assert (functionDecl->unique()); 1362 if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) { 1363 SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations"); 1364 } 1365 1366 if (!functionDecl->isTypeFixed) { 1367 auto mutDecl = mutate(functionDecl); 1368 auto mutType = mutDecl->type.get_and_mutate(); 1369 1370 for (auto & attr: mutDecl->attributes) { 1371 attr = handleAttribute(mutDecl->location, attr, symtab); 1372 } 1373 1374 // handle assertions 1375 1376 symtab.enterScope(); 1377 mutType->forall.clear(); 1378 mutType->assertions.clear(); 1379 for (auto & typeParam : mutDecl->type_params) { 1380 symtab.addType(typeParam); 1381 mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam)); 1382 } 1383 for (auto & asst : mutDecl->assertions) { 1384 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab); 1385 symtab.addId(asst); 1386 mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst)); 1387 } 1388 1389 // temporarily adds params to symbol table. 1390 // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl) 1391 1392 std::vector<ast::ptr<ast::Type>> paramTypes; 1393 std::vector<ast::ptr<ast::Type>> returnTypes; 1394 1395 for (auto & param : mutDecl->params) { 1396 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab); 1397 symtab.addId(param); 1398 paramTypes.emplace_back(param->get_type()); 1399 } 1400 for (auto & ret : mutDecl->returns) { 1401 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab); 1402 returnTypes.emplace_back(ret->get_type()); 1403 } 1404 // since function type in decl is just a view of param types, need to update that as well 1405 mutType->params = std::move(paramTypes); 1406 mutType->returns = std::move(returnTypes); 1407 1408 auto renamedType = strict_dynamic_cast<const ast::FunctionType *>(renameTyVars(mutType, RenameMode::GEN_EXPR_ID)); 1409 1410 std::list<ast::ptr<ast::Stmt>> newStmts; 1411 resolveWithExprs (mutDecl->withExprs, newStmts); 1412 1413 if (mutDecl->stmts) { 1414 auto mutStmt = mutDecl->stmts.get_and_mutate(); 1415 mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts)); 1416 mutDecl->stmts = mutStmt; 1417 } 1418 1419 symtab.leaveScope(); 1420 1421 mutDecl->type = renamedType; 1422 mutDecl->mangleName = Mangle::mangle(mutDecl); 1423 mutDecl->isTypeFixed = true; 1424 functionDecl = mutDecl; 1425 } 1426 managedTypes.handleDWT(functionDecl); 1427 1295 1428 functionReturn = extractResultType( functionDecl->type ); 1429 return functionDecl; 1296 1430 } 1297 1431 … … 1299 1433 // default value expressions have an environment which shouldn't be there and trips up 1300 1434 // later passes. 1301 as t::ptr< ast::FunctionDecl > ret = functionDecl;1302 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {1303 const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i]; 1304 1305 if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {1435 assert( functionDecl->unique() ); 1436 ast::FunctionType * mutType = mutate( functionDecl->type.get() ); 1437 1438 for ( unsigned i = 0 ; i < mutType->params.size() ; ++i ) { 1439 if ( const ast::ObjectDecl * obj = mutType->params[i].as< ast::ObjectDecl >() ) { 1306 1440 if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) { 1307 1441 if ( init->value->env == nullptr ) continue; 1308 1442 // clone initializer minus the initializer environment 1309 ast::chain_mutate( ret ) 1310 ( &ast::FunctionDecl::type ) 1311 ( &ast::FunctionType::params )[i] 1312 ( &ast::ObjectDecl::init ) 1313 ( &ast::SingleInit::value )->env = nullptr; 1314 1315 assert( functionDecl != ret.get() || functionDecl->unique() ); 1316 assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env ); 1443 auto mutParam = mutate( mutType->params[i].strict_as< ast::ObjectDecl >() ); 1444 auto mutInit = mutate( mutParam->init.strict_as< ast::SingleInit >() ); 1445 auto mutValue = mutate( mutInit->value.get() ); 1446 1447 mutValue->env = nullptr; 1448 mutInit->value = mutValue; 1449 mutParam->init = mutInit; 1450 mutType->params[i] = mutParam; 1451 1452 assert( ! mutType->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env); 1317 1453 } 1318 1454 } 1319 1455 } 1320 return ret.get(); 1321 } 1322 1323 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1456 mutate_field(functionDecl, &ast::FunctionDecl::type, mutType); 1457 return functionDecl; 1458 } 1459 1460 const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1324 1461 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1325 1462 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1329 1466 // selecting the RHS. 1330 1467 GuardValue( currentObject ); 1331 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1468 1332 1469 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1333 1470 // enumerator initializers should not use the enum type to initialize, since the 1334 1471 // enum type is still incomplete at this point. Use `int` instead. 1472 objectDecl = fixObjectType(objectDecl, symtab); 1335 1473 currentObject = ast::CurrentObject{ 1336 1474 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1337 1475 } 1476 else { 1477 if (!objectDecl->isTypeFixed) { 1478 auto newDecl = fixObjectType(objectDecl, symtab); 1479 auto mutDecl = mutate(newDecl); 1480 1481 // generate CtorInit wrapper when necessary. 1482 // in certain cases, fixObjectType is called before reaching 1483 // this object in visitor pass, thus disabling CtorInit codegen. 1484 // this happens on aggregate members and function parameters. 1485 if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) { 1486 // constructed objects cannot be designated 1487 if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" ); 1488 // constructed objects should not have initializers nested too deeply 1489 if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " ); 1490 1491 mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl ); 1492 } 1493 1494 objectDecl = mutDecl; 1495 } 1496 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1497 } 1498 1499 return objectDecl; 1500 } 1501 1502 void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) { 1503 auto aggDecl = mutate(_aggDecl); 1504 assertf(aggDecl == _aggDecl, "type declarations must be unique"); 1505 1506 for (auto & member: aggDecl->members) { 1507 // nested type decls are hoisted already. no need to do anything 1508 if (auto obj = member.as<ast::ObjectDecl>()) { 1509 member = fixObjectType(obj, symtab); 1510 } 1511 } 1512 } 1513 1514 void Resolver_new::previsit( const ast::StructDecl * structDecl ) { 1515 previsit(static_cast<const ast::AggregateDecl *>(structDecl)); 1516 managedTypes.handleStruct(structDecl); 1338 1517 } 1339 1518 … … 1341 1520 // in case we decide to allow nested enums 1342 1521 GuardValue( inEnumDecl ); 1343 inEnumDecl = false; 1344 } 1522 inEnumDecl = true; 1523 // don't need to fix types for enum fields 1524 } 1525 1345 1526 1346 1527 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1355 1536 const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) { 1356 1537 if ( type->dimension ) { 1357 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1358 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1538 ast::ptr< ast::Type > sizeType = ast::sizeType; 1359 1539 ast::mutate_field( 1360 1540 type, &PtrType::dimension, … … 1477 1657 if ( throwStmt->expr ) { 1478 1658 const ast::StructDecl * exceptionDecl = 1479 symtab.lookupStruct( "__cfa abi_ehm__base_exception_t" );1659 symtab.lookupStruct( "__cfaehm_base_exception_t" ); 1480 1660 assert( exceptionDecl ); 1481 1661 ast::ptr< ast::Type > exceptType = … … 1489 1669 1490 1670 const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 1491 // TODO: This will need a fix for the decl/cond scoping problem. 1671 // Until we are very sure this invarent (ifs that move between passes have thenPart) 1672 // holds, check it. This allows a check for when to decode the mangling. 1673 if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) { 1674 assert( ifStmt->thenPart ); 1675 } 1676 // Encode the catchStmt so the condition can see the declaration. 1492 1677 if ( catchStmt->cond ) { 1493 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1494 catchStmt = ast::mutate_field( 1495 catchStmt, &ast::CatchStmt::cond, 1496 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1678 ast::CatchStmt * stmt = mutate( catchStmt ); 1679 stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body ); 1680 stmt->cond = nullptr; 1681 return stmt; 1682 } 1683 return catchStmt; 1684 } 1685 1686 const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) { 1687 // Decode the catchStmt so everything is stored properly. 1688 const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>(); 1689 if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) { 1690 assert( ifStmt->cond ); 1691 assert( ifStmt->elsePart ); 1692 ast::CatchStmt * stmt = ast::mutate( catchStmt ); 1693 stmt->cond = ifStmt->cond; 1694 stmt->body = ifStmt->elsePart; 1695 // ifStmt should be implicately deleted here. 1696 return stmt; 1497 1697 } 1498 1698 return catchStmt; … … 1611 1811 // Check if the argument matches the parameter type in the current 1612 1812 // scope 1613 ast::ptr< ast::Type > paramType = (*param)->get_type();1813 // ast::ptr< ast::Type > paramType = (*param)->get_type(); 1614 1814 if ( 1615 1815 ! unify( 1616 arg->expr->result, paramType, resultEnv, need, have, open,1816 arg->expr->result, *param, resultEnv, need, have, open, 1617 1817 symtab ) 1618 1818 ) { … … 1621 1821 ss << "candidate function not viable: no known conversion " 1622 1822 "from '"; 1623 ast::print( ss, (*param)->get_type());1823 ast::print( ss, *param ); 1624 1824 ss << "' to '"; 1625 1825 ast::print( ss, arg->expr->result ); … … 1751 1951 } 1752 1952 1953 const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) { 1954 auto mutStmt = mutate(withStmt); 1955 resolveWithExprs(mutStmt->exprs, stmtsToAddBefore); 1956 return mutStmt; 1957 } 1958 1959 void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) { 1960 for (auto & expr : exprs) { 1961 // only struct- and union-typed expressions are viable candidates 1962 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" ); 1963 1964 // if with expression might be impure, create a temporary so that it is evaluated once 1965 if ( Tuples::maybeImpure( expr ) ) { 1966 static UniqueName tmpNamer( "_with_tmp_" ); 1967 const CodeLocation loc = expr->location; 1968 auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) ); 1969 expr = new ast::VariableExpr( loc, tmp ); 1970 stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) ); 1971 if ( InitTweak::isConstructable( tmp->type ) ) { 1972 // generate ctor/dtor and resolve them 1973 tmp->init = InitTweak::genCtorInit( loc, tmp ); 1974 } 1975 // since tmp is freshly created, this should modify tmp in-place 1976 tmp->accept( *visitor ); 1977 } 1978 } 1979 } 1753 1980 1754 1981 … … 1846 2073 } 1847 2074 2075 // suppress error on autogen functions and mark invalid autogen as deleted. 2076 bool Resolver_new::on_error(ast::ptr<ast::Decl> & decl) { 2077 if (auto functionDecl = decl.as<ast::FunctionDecl>()) { 2078 // xxx - can intrinsic gen ever fail? 2079 if (functionDecl->linkage == ast::Linkage::AutoGen) { 2080 auto mutDecl = mutate(functionDecl); 2081 mutDecl->isDeleted = true; 2082 mutDecl->stmts = nullptr; 2083 decl = mutDecl; 2084 return false; 2085 } 2086 } 2087 return true; 2088 } 2089 1848 2090 } // namespace ResolvExpr 1849 2091
Note:
See TracChangeset
for help on using the changeset viewer.