Changes in src/ResolvExpr/Resolver.cc [7583c02:665f432]
- File:
-
- 1 edited
-
src/ResolvExpr/Resolver.cc (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r7583c02 r665f432 9 9 // Author : Aaron B. Moss 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Fri Mar 27 11:58:00 202013 // Update Count : 24 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Wed May 29 11:00:00 2019 13 // Update Count : 241 14 14 // 15 15 … … 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h"29 28 #include "ResolvMode.h" // for ResolvMode 30 29 #include "typeops.h" // for extractResultType 31 30 #include "Unify.h" // for unify 32 #include "CompilationState.h"33 31 #include "AST/Chain.hpp" 34 32 #include "AST/Decl.hpp" … … 40 38 #include "Common/PassVisitor.h" // for PassVisitor 41 39 #include "Common/SemanticError.h" // for SemanticError 42 #include "Common/Stats/ResolveTime.h" // for ResolveTime::start(), ResolveTime::stop()43 40 #include "Common/utility.h" // for ValueGuard, group_iterate 44 41 #include "InitTweak/GenInit.h" … … 47 44 #include "SymTab/Autogen.h" // for SizeType 48 45 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler50 46 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 51 47 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 88 84 void previsit( ThrowStmt * throwStmt ); 89 85 void previsit( CatchStmt * catchStmt ); 90 void postvisit( CatchStmt * catchStmt );91 86 void previsit( WaitForStmt * stmt ); 92 87 … … 564 559 // TODO: Replace *exception type with &exception type. 565 560 if ( throwStmt->get_expr() ) { 566 const StructDecl * exception_decl = indexer.lookupStruct( "__cfa ehm_base_exception_t" );561 const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 567 562 assert( exception_decl ); 568 563 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) ); … … 572 567 573 568 void Resolver_old::previsit( CatchStmt * catchStmt ) { 574 // Until we are very sure this invarent (ifs that move between passes have thenPart)575 // holds, check it. This allows a check for when to decode the mangling.576 if ( IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ) ) {577 assert( ifStmt->thenPart );578 }579 // Encode the catchStmt so the condition can see the declaration.580 569 if ( catchStmt->cond ) { 581 IfStmt * ifStmt = new IfStmt( catchStmt->cond, nullptr, catchStmt->body ); 582 catchStmt->cond = nullptr; 583 catchStmt->body = ifStmt; 584 } 585 } 586 587 void Resolver_old::postvisit( CatchStmt * catchStmt ) { 588 // Decode the catchStmt so everything is stored properly. 589 IfStmt * ifStmt = dynamic_cast<IfStmt *>( catchStmt->body ); 590 if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) { 591 assert( ifStmt->condition ); 592 assert( ifStmt->elsePart ); 593 catchStmt->cond = ifStmt->condition; 594 catchStmt->body = ifStmt->elsePart; 595 ifStmt->condition = nullptr; 596 ifStmt->elsePart = nullptr; 597 delete ifStmt; 570 findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer ); 598 571 } 599 572 } … … 968 941 namespace { 969 942 /// Finds deleted expressions in an expression tree 970 struct DeleteFinder_new final : public ast::WithShortCircuiting , public ast::WithVisitorRef<DeleteFinder_new>{971 const ast::DeletedExpr * result= nullptr;943 struct DeleteFinder_new final : public ast::WithShortCircuiting { 944 const ast::DeletedExpr * delExpr = nullptr; 972 945 973 946 void previsit( const ast::DeletedExpr * expr ) { 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 } 947 if ( delExpr ) { visit_children = false; } 948 else { delExpr = expr; } 949 } 950 951 void previsit( const ast::Expr * ) { 952 if ( delExpr ) { visit_children = false; } 985 953 } 986 954 }; 987 955 } // anonymous namespace 956 988 957 /// Check if this expression is or includes a deleted expression 989 958 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 990 return ast::Pass<DeleteFinder_new>::read( expr ); 959 ast::Pass<DeleteFinder_new> finder; 960 expr->accept( finder ); 961 return finder.pass.delExpr; 991 962 } 992 963 … … 1078 1049 /// Strips extraneous casts out of an expression 1079 1050 struct StripCasts_new final { 1080 const ast::Expr * post visit( const ast::CastExpr * castExpr ) {1051 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1081 1052 if ( 1082 castExpr->isGenerated == ast::GeneratedCast1053 castExpr->isGenerated 1083 1054 && typesCompatible( castExpr->arg->result, castExpr->result ) 1084 1055 ) { … … 1112 1083 } 1113 1084 1114 1115 } // anonymous namespace 1116 /// Establish post-resolver invariants for expressions 1085 /// Establish post-resolver invariants for expressions 1117 1086 void finishExpr( 1118 1087 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, … … 1127 1096 StripCasts_new::strip( expr ); 1128 1097 } 1098 } // anonymous namespace 1099 1129 1100 1130 1101 ast::ptr< ast::Expr > resolveInVoidContext( … … 1134 1105 1135 1106 // set up and resolve expression cast to void 1136 ast:: ptr< ast::CastExpr >untyped = new ast::CastExpr{ expr };1107 ast::CastExpr * untyped = new ast::CastExpr{ expr }; 1137 1108 CandidateRef choice = findUnfinishedKindExpression( 1138 1109 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); … … 1146 1117 } 1147 1118 1148 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1119 namespace { 1120 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1149 1121 /// context. 1150 1122 ast::ptr< ast::Expr > findVoidExpression( 1151 1123 const ast::Expr * untyped, const ast::SymbolTable & symtab 1152 1124 ) { 1125 resetTyVarRenaming(); 1153 1126 ast::TypeEnvironment env; 1154 1127 ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env ); … … 1156 1129 return newExpr; 1157 1130 } 1158 1159 namespace {1160 1161 1131 1162 1132 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the … … 1170 1140 CandidateRef choice = 1171 1141 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1172 ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env );1142 finishExpr( choice->expr, choice->env, untyped->env ); 1173 1143 return std::move( choice->expr ); 1174 1144 } … … 1178 1148 const ast::Expr * untyped, const ast::SymbolTable & symtab 1179 1149 ) { 1180 Stats::ResolveTime::start( untyped ); 1181 auto res = findKindExpression( untyped, symtab ); 1182 Stats::ResolveTime::stop(); 1183 return res; 1150 return findKindExpression( untyped, symtab ); 1184 1151 } 1185 1152 } // anonymous namespace 1186 1153 1187 ast::ptr< ast::Expr > findSingleExpression(1188 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab1189 ) {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 }1154 ast::ptr< ast::Expr > findSingleExpression( 1155 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab 1156 ) { 1157 assert( untyped && type ); 1158 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1159 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1160 removeExtraneousCast( newExpr, symtab ); 1161 return newExpr; 1162 } 1196 1163 1197 1164 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 }1202 1165 /// Predicate for "Candidate has integral type" 1203 1166 bool hasIntegralType( const Candidate & i ) { … … 1235 1198 template<typename Iter> 1236 1199 inline bool nextMutex( Iter & it, const Iter & end ) { 1237 while ( it != end && ! (*it)-> is_mutex() ) { ++it; }1200 while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; } 1238 1201 return it != end; 1239 1202 } … … 1247 1210 ast::ptr< ast::Type > functionReturn = nullptr; 1248 1211 ast::CurrentObject currentObject; 1249 // for work previously in GenInit1250 static InitTweak::ManagedTypes_new managedTypes;1251 1252 1212 bool inEnumDecl = false; 1253 1213 1254 1214 public: 1255 static size_t traceId;1256 1215 Resolver_new() = default; 1257 1216 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1258 1217 1259 const ast::FunctionDecl *previsit( const ast::FunctionDecl * );1218 void previsit( const ast::FunctionDecl * ); 1260 1219 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * ); 1261 const ast::ObjectDecl * previsit( const ast::ObjectDecl * ); 1262 void previsit( const ast::AggregateDecl * ); 1263 void previsit( const ast::StructDecl * ); 1220 void previsit( const ast::ObjectDecl * ); 1264 1221 void previsit( const ast::EnumDecl * ); 1265 1222 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1280 1237 const ast::ThrowStmt * previsit( const ast::ThrowStmt * ); 1281 1238 const ast::CatchStmt * previsit( const ast::CatchStmt * ); 1282 const ast::CatchStmt * postvisit( const ast::CatchStmt * );1283 1239 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1284 const ast::WithStmt * previsit( const ast::WithStmt * );1285 1240 1286 1241 const ast::SingleInit * previsit( const ast::SingleInit * ); 1287 1242 const ast::ListInit * previsit( const ast::ListInit * ); 1288 1243 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);1295 1244 }; 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 ); 1245 1246 void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) { 1247 ast::Pass< Resolver_new > resolver; 1248 accept_all( translationUnit, resolver ); 1302 1249 } 1303 1250 … … 1310 1257 } 1311 1258 1312 const ast::Expr *resolveStmtExpr(1259 ast::ptr< ast::Expr > resolveStmtExpr( 1313 1260 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1314 1261 ) { 1315 1262 assert( stmtExpr ); 1316 1263 ast::Pass< Resolver_new > resolver{ symtab }; 1317 auto ret = mutate(stmtExpr->accept(resolver)); 1318 strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult(); 1264 ast::ptr< ast::Expr > ret = stmtExpr; 1265 ret = ret->accept( resolver ); 1266 strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult(); 1319 1267 return ret; 1320 1268 } 1321 1269 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 ) { 1270 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1359 1271 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 assertions1375 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 well1405 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 1428 1272 functionReturn = extractResultType( functionDecl->type ); 1429 return functionDecl;1430 1273 } 1431 1274 … … 1433 1276 // default value expressions have an environment which shouldn't be there and trips up 1434 1277 // later passes. 1435 as sert( 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 >() ) {1278 ast::ptr< ast::FunctionDecl > ret = functionDecl; 1279 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) { 1280 const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i]; 1281 1282 if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) { 1440 1283 if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) { 1441 1284 if ( init->value->env == nullptr ) continue; 1442 1285 // clone initializer minus the initializer environment 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); 1286 ast::chain_mutate( ret ) 1287 ( &ast::FunctionDecl::type ) 1288 ( &ast::FunctionType::params )[i] 1289 ( &ast::ObjectDecl::init ) 1290 ( &ast::SingleInit::value )->env = nullptr; 1291 1292 assert( functionDecl != ret.get() || functionDecl->unique() ); 1293 assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env ); 1453 1294 } 1454 1295 } 1455 1296 } 1456 mutate_field(functionDecl, &ast::FunctionDecl::type, mutType); 1457 return functionDecl; 1458 } 1459 1460 const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1297 return ret.get(); 1298 } 1299 1300 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1461 1301 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1462 1302 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1466 1306 // selecting the RHS. 1467 1307 GuardValue( currentObject ); 1468 1308 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1469 1309 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1470 1310 // enumerator initializers should not use the enum type to initialize, since the 1471 1311 // enum type is still incomplete at this point. Use `int` instead. 1472 objectDecl = fixObjectType(objectDecl, symtab);1473 1312 currentObject = ast::CurrentObject{ 1474 1313 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1475 1314 } 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 reaching1483 // 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 designated1487 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 deeply1489 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 anything1508 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);1517 1315 } 1518 1316 … … 1520 1318 // in case we decide to allow nested enums 1521 1319 GuardValue( inEnumDecl ); 1522 inEnumDecl = true; 1523 // don't need to fix types for enum fields 1524 } 1525 1320 inEnumDecl = false; 1321 } 1526 1322 1527 1323 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1536 1332 const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) { 1537 1333 if ( type->dimension ) { 1538 ast::ptr< ast::Type > sizeType = ast::sizeType; 1334 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1335 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1539 1336 ast::mutate_field( 1540 1337 type, &PtrType::dimension, … … 1657 1454 if ( throwStmt->expr ) { 1658 1455 const ast::StructDecl * exceptionDecl = 1659 symtab.lookupStruct( "__cfa ehm_base_exception_t" );1456 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1660 1457 assert( exceptionDecl ); 1661 1458 ast::ptr< ast::Type > exceptType = … … 1669 1466 1670 1467 const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) { 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.1677 1468 if ( catchStmt->cond ) { 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; 1469 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1470 catchStmt = ast::mutate_field( 1471 catchStmt, &ast::CatchStmt::cond, 1472 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1697 1473 } 1698 1474 return catchStmt; … … 1811 1587 // Check if the argument matches the parameter type in the current 1812 1588 // scope 1813 //ast::ptr< ast::Type > paramType = (*param)->get_type();1589 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1814 1590 if ( 1815 1591 ! unify( 1816 arg->expr->result, *param, resultEnv, need, have, open,1592 arg->expr->result, paramType, resultEnv, need, have, open, 1817 1593 symtab ) 1818 1594 ) { … … 1821 1597 ss << "candidate function not viable: no known conversion " 1822 1598 "from '"; 1823 ast::print( ss, *param);1599 ast::print( ss, (*param)->get_type() ); 1824 1600 ss << "' to '"; 1825 1601 ast::print( ss, arg->expr->result ); … … 1951 1727 } 1952 1728 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 candidates1962 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );1963 1964 // if with expression might be impure, create a temporary so that it is evaluated once1965 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 them1973 tmp->init = InitTweak::genCtorInit( loc, tmp );1974 }1975 // since tmp is freshly created, this should modify tmp in-place1976 tmp->accept( *visitor );1977 }1978 }1979 }1980 1729 1981 1730 … … 2073 1822 } 2074 1823 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 2090 1824 } // namespace ResolvExpr 2091 1825
Note:
See TracChangeset
for help on using the changeset viewer.