Changeset 60aaa51d for src/ResolvExpr/Resolver.cc
- Timestamp:
- Jun 7, 2019, 4:14:48 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 05d55ff
- Parents:
- 5684736
- git-author:
- Aaron Moss <a3moss@…> (06/07/19 16:14:40)
- git-committer:
- Aaron Moss <a3moss@…> (06/07/19 16:14:48)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Resolver.cc
r5684736 r60aaa51d 781 781 } 782 782 783 template< typename T > 784 bool isCharType( T t ) { 783 bool isCharType( Type * t ) { 785 784 if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) { 786 785 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || … … 1071 1070 }; 1072 1071 1072 /// Swaps argument into expression pointer, saving original environment 1073 void swap_and_save_env( ast::ptr< ast::Expr > & expr, const ast::Expr * newExpr ) { 1074 ast::ptr< ast::TypeSubstitution > env = expr->env; 1075 expr.set_and_mutate( newExpr )->env = env; 1076 } 1077 1073 1078 /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts) 1074 1079 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) { … … 1076 1081 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) { 1077 1082 // cast is to the same type as its argument, remove it 1078 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1079 expr.set_and_mutate( castExpr->arg )->env = env; 1083 swap_and_save_env( expr, castExpr->arg ); 1080 1084 } 1081 1085 } … … 1175 1179 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); 1176 1180 } 1181 1182 /// check if a type is a character type 1183 bool isCharType( const ast::Type * t ) { 1184 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1185 return bt->kind == ast::BasicType::Char 1186 || bt->kind == ast::BasicType::SignedChar 1187 || bt->kind == ast::BasicType::UnsignedChar; 1188 } 1189 return false; 1190 } 1177 1191 } 1178 1192 … … 1213 1227 void previsit( const ast::WaitForStmt * ); 1214 1228 1215 voidprevisit( const ast::SingleInit * );1216 voidprevisit( const ast::ListInit * );1229 const ast::SingleInit * previsit( const ast::SingleInit * ); 1230 const ast::ListInit * previsit( const ast::ListInit * ); 1217 1231 void previsit( const ast::ConstructorInit * ); 1218 1232 }; … … 1363 1377 const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1364 1378 if ( caseStmt->cond ) { 1365 std:: vector< ast::InitAlternative > initAlts = currentObject.getOptions();1379 std::deque< ast::InitAlternative > initAlts = currentObject.getOptions(); 1366 1380 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1367 1381 "expression." ); … … 1374 1388 // whether it would perform a conversion. 1375 1389 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1376 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1377 newExpr.set_and_mutate( castExpr->arg )->env = env; 1390 swap_and_save_env( newExpr, castExpr->arg ); 1378 1391 } 1379 1392 … … 1438 1451 } 1439 1452 1440 void Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1441 #warning unimplemented; Resolver port in progress 1442 (void)singleInit; 1443 assert(false); 1444 } 1445 1446 void Resolver_new::previsit( const ast::ListInit * listInit ) { 1447 #warning unimplemented; Resolver port in progress 1448 (void)listInit; 1449 assert(false); 1453 1454 1455 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1456 visit_children = false; 1457 // resolve initialization using the possibilities as determined by the `currentObject` 1458 // cursor. 1459 ast::Expr * untyped = new ast::UntypedInitExpr{ 1460 singleInit->location, singleInit->value, currentObject.getOptions() }; 1461 ast::ptr<ast::Expr> newExpr = findKindExpression( untyped, symtab ); 1462 const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >(); 1463 1464 // move cursor to the object that is actually initialized 1465 currentObject.setNext( initExpr->designation ); 1466 1467 // discard InitExpr wrapper and retain relevant pieces. 1468 // `initExpr` may have inferred params in the case where the expression specialized a 1469 // function pointer, and newExpr may already have inferParams of its own, so a simple 1470 // swap is not sufficient 1471 ast::Expr::InferUnion inferred = initExpr->inferred; 1472 swap_and_save_env( newExpr, initExpr->expr ); 1473 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1474 1475 // get the actual object's type (may not exactly match what comes back from the resolver 1476 // due to conversions) 1477 const ast::Type * initContext = currentObject.getCurrentType(); 1478 1479 removeExtraneousCast( newExpr, symtab ); 1480 1481 // check if actual object's type is char[] 1482 if ( auto at = dynamic_cast< const ast::ArrayType * >( initContext ) ) { 1483 if ( isCharType( at->base ) ) { 1484 // check if the resolved type is char* 1485 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1486 if ( isCharType( pt->base ) ) { 1487 // strip cast if we're initializing a char[] with a char* 1488 // e.g. char x[] = "hello" 1489 if ( auto ce = newExpr.as< ast::CastExpr >() ) { 1490 swap_and_save_env( newExpr, ce->arg ); 1491 } 1492 } 1493 } 1494 } 1495 } 1496 1497 // move cursor to next object in preparation for next initializer 1498 currentObject.increment(); 1499 1500 // set initializer expression to resolved expression 1501 return ast::mutate_field( singleInit, &ast::SingleInit::value, std::move(newExpr) ); 1502 } 1503 1504 const ast::ListInit * Resolver_new::previsit( const ast::ListInit * listInit ) { 1505 // move cursor into brace-enclosed initializer-list 1506 currentObject.enterListInit( listInit->location ); 1507 1508 assert( listInit->designations.size() == listInit->initializers.size() ); 1509 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1510 // iterate designations and initializers in pairs, moving the cursor to the current 1511 // designated object and resolving the initializer against that object 1512 #warning unimplemented; Resolver port in progress 1513 assert(false); 1514 } 1515 1516 visit_children = false; 1517 return listInit; 1450 1518 } 1451 1519
Note: See TracChangeset
for help on using the changeset viewer.