Ignore:
Timestamp:
Jun 7, 2019, 4:14:48 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
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)
Message:

More resolver porting; mostly CurrentObject?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r5684736 r60aaa51d  
    781781        }
    782782
    783         template< typename T >
    784         bool isCharType( T t ) {
     783        bool isCharType( Type * t ) {
    785784                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    786785                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     
    10711070                };
    10721071
     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
    10731078                /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
    10741079                void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
     
    10761081                                if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
    10771082                                        // 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 );
    10801084                                }
    10811085                        }
     
    11751179                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
    11761180                }
     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                }
    11771191        }
    11781192
     
    12131227                void previsit( const ast::WaitForStmt * );
    12141228
    1215                 void previsit( const ast::SingleInit * );
    1216                 void previsit( const ast::ListInit * );
     1229                const ast::SingleInit * previsit( const ast::SingleInit * );
     1230                const ast::ListInit * previsit( const ast::ListInit * );
    12171231                void previsit( const ast::ConstructorInit * );
    12181232        };
     
    13631377        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    13641378                if ( caseStmt->cond ) {
    1365                         std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
     1379                        std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
    13661380                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    13671381                                "expression." );
     
    13741388                        // whether it would perform a conversion.
    13751389                        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 );
    13781391                        }
    13791392                       
     
    14381451        }
    14391452
    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;
    14501518        }
    14511519
Note: See TracChangeset for help on using the changeset viewer.