Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r60aaa51d r2b59f55  
    781781        }
    782782
    783         bool isCharType( Type * t ) {
     783        template< typename T >
     784        bool isCharType( T t ) {
    784785                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    785786                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     
    10701071                };
    10711072
    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 
    10781073                /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
    10791074                void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
     
    10811076                                if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
    10821077                                        // cast is to the same type as its argument, remove it
    1083                                         swap_and_save_env( expr, castExpr->arg );
     1078                                        ast::ptr< ast::TypeSubstitution > env = castExpr->env;
     1079                                        expr.set_and_mutate( castExpr->arg )->env = env;
    10841080                                }
    10851081                        }
     
    11791175                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
    11801176                }
    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                 }
    11911177        }
    11921178
     
    12271213                void previsit( const ast::WaitForStmt * );
    12281214
    1229                 const ast::SingleInit * previsit( const ast::SingleInit * );
    1230                 const ast::ListInit * previsit( const ast::ListInit * );
     1215                void previsit( const ast::SingleInit * );
     1216                void previsit( const ast::ListInit * );
    12311217                void previsit( const ast::ConstructorInit * );
    12321218        };
     
    13771363        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    13781364                if ( caseStmt->cond ) {
    1379                         std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
     1365                        std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
    13801366                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    13811367                                "expression." );
     
    13881374                        // whether it would perform a conversion.
    13891375                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
    1390                                 swap_and_save_env( newExpr, castExpr->arg );
     1376                                ast::ptr< ast::TypeSubstitution > env = castExpr->env;
     1377                                newExpr.set_and_mutate( castExpr->arg )->env = env;
    13911378                        }
    13921379                       
     
    14511438        }
    14521439
    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;
     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);
    15181450        }
    15191451
Note: See TracChangeset for help on using the changeset viewer.