Ignore:
Timestamp:
Jul 19, 2019, 2:16:01 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4eb43fa
Parents:
1f1c102 (diff), 8ac3b0e (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.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r1f1c102 rf53acdf8  
    562562                // TODO: Replace *exception type with &exception type.
    563563                if ( throwStmt->get_expr() ) {
    564                         StructDecl * exception_decl =
    565                                 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     564                        const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    566565                        assert( exception_decl );
    567                         Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     566                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
    568567                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    569568                }
     
    972971                /// Calls the CandidateFinder and finds the single best candidate
    973972                CandidateRef findUnfinishedKindExpression(
    974                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 
     973                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    975974                        std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
    976975                ) {
     
    994993                        // produce invalid error if no candidates
    995994                        if ( candidates.empty() ) {
    996                                 SemanticError( untyped, 
    997                                         toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 
     995                                SemanticError( untyped,
     996                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
    998997                                        "expression: ") );
    999998                        }
     
    10311030                        if ( winners.size() != 1 ) {
    10321031                                std::ostringstream stream;
    1033                                 stream << "Cannot choose between " << winners.size() << " alternatives for " 
     1032                                stream << "Cannot choose between " << winners.size() << " alternatives for "
    10341033                                        << kind << (kind != "" ? " " : "") << "expression\n";
    10351034                                ast::print( stream, untyped );
     
    10541053                struct StripCasts_new final {
    10551054                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
    1056                                 if ( 
    1057                                         castExpr->isGenerated 
    1058                                         && typesCompatible( castExpr->arg->result, castExpr->result ) 
     1055                                if (
     1056                                        castExpr->isGenerated
     1057                                        && typesCompatible( castExpr->arg->result, castExpr->result )
    10591058                                ) {
    10601059                                        // generated cast is the same type as its argument, remove it after keeping env
    1061                                         return ast::mutate_field( 
     1060                                        return ast::mutate_field(
    10621061                                                castExpr->arg.get(), &ast::Expr::env, castExpr->env );
    10631062                                }
     
    10881087
    10891088                /// Establish post-resolver invariants for expressions
    1090                 void finishExpr( 
    1091                         ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 
     1089                void finishExpr(
     1090                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
    10921091                        const ast::TypeSubstitution * oldenv = nullptr
    10931092                ) {
    10941093                        // set up new type substitution for expression
    1095                         ast::ptr< ast::TypeSubstitution > newenv = 
     1094                        ast::ptr< ast::TypeSubstitution > newenv =
    10961095                                 oldenv ? oldenv : new ast::TypeSubstitution{};
    10971096                        env.writeToSubstitution( *newenv.get_and_mutate() );
     
    11021101        } // anonymous namespace
    11031102
    1104                
     1103
    11051104        ast::ptr< ast::Expr > resolveInVoidContext(
    11061105                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
    11071106        ) {
    11081107                assertf( expr, "expected a non-null expression" );
    1109                
     1108
    11101109                // set up and resolve expression cast to void
    11111110                ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
    1112                 CandidateRef choice = findUnfinishedKindExpression( 
     1111                CandidateRef choice = findUnfinishedKindExpression(
    11131112                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
    1114                
     1113
    11151114                // a cast expression has either 0 or 1 interpretations (by language rules);
    11161115                // if 0, an exception has already been thrown, and this code will not run
     
    11221121
    11231122        namespace {
    1124                 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 
     1123                /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    11251124                /// context.
    1126                 ast::ptr< ast::Expr > findVoidExpression( 
     1125                ast::ptr< ast::Expr > findVoidExpression(
    11271126                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11281127                ) {
     
    11341133                }
    11351134
    1136                 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 
     1135                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
    11371136                /// lowest cost, returning the resolved version
    11381137                ast::ptr< ast::Expr > findKindExpression(
    1139                         const ast::Expr * untyped, const ast::SymbolTable & symtab, 
    1140                         std::function<bool(const Candidate &)> pred = anyCandidate, 
     1138                        const ast::Expr * untyped, const ast::SymbolTable & symtab,
     1139                        std::function<bool(const Candidate &)> pred = anyCandidate,
    11411140                        const std::string & kind = "", ResolvMode mode = {}
    11421141                ) {
    11431142                        if ( ! untyped ) return {};
    1144                         CandidateRef choice = 
     1143                        CandidateRef choice =
    11451144                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
    11461145                        finishExpr( choice->expr, choice->env, untyped->env );
     
    11491148
    11501149                /// Resolve `untyped` to the single expression whose candidate is the best match
    1151                 ast::ptr< ast::Expr > findSingleExpression( 
    1152                         const ast::Expr * untyped, const ast::SymbolTable & symtab 
     1150                ast::ptr< ast::Expr > findSingleExpression(
     1151                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11531152                ) {
    11541153                        return findKindExpression( untyped, symtab );
     
    11701169                bool hasIntegralType( const Candidate & i ) {
    11711170                        const ast::Type * type = i.expr->result;
    1172                        
     1171
    11731172                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
    11741173                                return bt->isInteger();
    1175                         } else if ( 
    1176                                 dynamic_cast< const ast::EnumInstType * >( type ) 
     1174                        } else if (
     1175                                dynamic_cast< const ast::EnumInstType * >( type )
    11771176                                || dynamic_cast< const ast::ZeroType * >( type )
    11781177                                || dynamic_cast< const ast::OneType * >( type )
     
    11831182
    11841183                /// Resolve `untyped` as an integral expression, returning the resolved version
    1185                 ast::ptr< ast::Expr > findIntegralExpression( 
    1186                         const ast::Expr * untyped, const ast::SymbolTable & symtab 
     1184                ast::ptr< ast::Expr > findIntegralExpression(
     1185                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11871186                ) {
    11881187                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
     
    11921191                bool isCharType( const ast::Type * t ) {
    11931192                        if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
    1194                                 return bt->kind == ast::BasicType::Char 
    1195                                         || bt->kind == ast::BasicType::SignedChar 
     1193                                return bt->kind == ast::BasicType::Char
     1194                                        || bt->kind == ast::BasicType::SignedChar
    11961195                                        || bt->kind == ast::BasicType::UnsignedChar;
    11971196                        }
     
    12531252        }
    12541253
    1255         ast::ptr< ast::Init > resolveCtorInit( 
    1256                 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 
     1254        ast::ptr< ast::Init > resolveCtorInit(
     1255                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
    12571256        ) {
    12581257                assert( ctorInit );
     
    12611260        }
    12621261
    1263         ast::ptr< ast::Expr > resolveStmtExpr( 
    1264                 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 
     1262        ast::ptr< ast::Expr > resolveStmtExpr(
     1263                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
    12651264        ) {
    12661265                assert( stmtExpr );
     
    13031302
    13041303        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    1305                 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 
    1306                 // class-variable `initContext` is changed multiple times because the LHS is analyzed 
    1307                 // twice. The second analysis changes `initContext` because a function type can contain 
    1308                 // object declarations in the return and parameter types. Therefore each value of 
    1309                 // `initContext` is retained so the type on the first analysis is preserved and used for 
     1304                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
     1305                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     1306                // twice. The second analysis changes `initContext` because a function type can contain
     1307                // object declarations in the return and parameter types. Therefore each value of
     1308                // `initContext` is retained so the type on the first analysis is preserved and used for
    13101309                // selecting the RHS.
    13111310                GuardValue( currentObject );
    13121311                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    13131312                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    1314                         // enumerator initializers should not use the enum type to initialize, since the 
     1313                        // enumerator initializers should not use the enum type to initialize, since the
    13151314                        // enum type is still incomplete at this point. Use `int` instead.
    1316                         currentObject = ast::CurrentObject{ 
     1315                        currentObject = ast::CurrentObject{
    13171316                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13181317                }
     
    13251324        }
    13261325
    1327         const ast::StaticAssertDecl * Resolver_new::previsit( 
    1328                 const ast::StaticAssertDecl * assertDecl 
     1326        const ast::StaticAssertDecl * Resolver_new::previsit(
     1327                const ast::StaticAssertDecl * assertDecl
    13291328        ) {
    1330                 return ast::mutate_field( 
    1331                         assertDecl, &ast::StaticAssertDecl::cond, 
     1329                return ast::mutate_field(
     1330                        assertDecl, &ast::StaticAssertDecl::cond,
    13321331                        findIntegralExpression( assertDecl->cond, symtab ) );
    13331332        }
     
    13381337                        #warning should use new equivalent to Validate::SizeType rather than sizeType here
    13391338                        ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
    1340                         ast::mutate_field( 
    1341                                 type, &PtrType::dimension, 
     1339                        ast::mutate_field(
     1340                                type, &PtrType::dimension,
    13421341                                findSingleExpression( type->dimension, sizeType, symtab ) );
    13431342                }
     
    13561355                visit_children = false;
    13571356                assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
    1358                
    1359                 return ast::mutate_field( 
     1357
     1358                return ast::mutate_field(
    13601359                        exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
    13611360        }
     
    13641363                visit_children = false;
    13651364
    1366                 asmExpr = ast::mutate_field( 
     1365                asmExpr = ast::mutate_field(
    13671366                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    1368                
     1367
    13691368                if ( asmExpr->inout ) {
    13701369                        asmExpr = ast::mutate_field(
    13711370                                asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    13721371                }
    1373                
     1372
    13741373                return asmExpr;
    13751374        }
     
    13881387
    13891388        const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    1390                 return ast::mutate_field( 
     1389                return ast::mutate_field(
    13911390                        whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
    13921391        }
     
    14091408                GuardValue( currentObject );
    14101409                switchStmt = ast::mutate_field(
    1411                         switchStmt, &ast::SwitchStmt::cond, 
     1410                        switchStmt, &ast::SwitchStmt::cond,
    14121411                        findIntegralExpression( switchStmt->cond, symtab ) );
    14131412                currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
     
    14201419                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    14211420                                "expression." );
    1422                        
    1423                         ast::ptr< ast::Expr > untyped = 
     1421
     1422                        ast::ptr< ast::Expr > untyped =
    14241423                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
    14251424                        ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
    1426                        
    1427                         // case condition cannot have a cast in C, so it must be removed here, regardless of 
     1425
     1426                        // case condition cannot have a cast in C, so it must be removed here, regardless of
    14281427                        // whether it would perform a conversion.
    14291428                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
    14301429                                swap_and_save_env( newExpr, castExpr->arg );
    14311430                        }
    1432                        
     1431
    14331432                        caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
    14341433                }
     
    14431442                        ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
    14441443                        branchStmt = ast::mutate_field(
    1445                                 branchStmt, &ast::BranchStmt::computedTarget, 
     1444                                branchStmt, &ast::BranchStmt::computedTarget,
    14461445                                findSingleExpression( branchStmt->computedTarget, target, symtab ) );
    14471446                }
     
    14531452                if ( returnStmt->expr ) {
    14541453                        returnStmt = ast::mutate_field(
    1455                                 returnStmt, &ast::ReturnStmt::expr, 
     1454                                returnStmt, &ast::ReturnStmt::expr,
    14561455                                findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
    14571456                }
     
    14621461                visit_children = false;
    14631462                if ( throwStmt->expr ) {
    1464                         const ast::StructDecl * exceptionDecl = 
     1463                        const ast::StructDecl * exceptionDecl =
    14651464                                symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    14661465                        assert( exceptionDecl );
    1467                         ast::ptr< ast::Type > exceptType = 
     1466                        ast::ptr< ast::Type > exceptType =
    14681467                                new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
    14691468                        throwStmt = ast::mutate_field(
    1470                                 throwStmt, &ast::ThrowStmt::expr, 
     1469                                throwStmt, &ast::ThrowStmt::expr,
    14711470                                findSingleExpression( throwStmt->expr, exceptType, symtab ) );
    14721471                }
     
    14771476                if ( catchStmt->cond ) {
    14781477                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1479                         catchStmt = ast::mutate_field( 
    1480                                 catchStmt, &ast::CatchStmt::cond, 
     1478                        catchStmt = ast::mutate_field(
     1479                                catchStmt, &ast::CatchStmt::cond,
    14811480                                findSingleExpression( catchStmt->cond, boolType, symtab ) );
    14821481                }
     
    15061505
    15071506                        if ( clause.target.args.empty() ) {
    1508                                 SemanticError( stmt->location, 
     1507                                SemanticError( stmt->location,
    15091508                                        "Waitfor clause must have at least one mutex parameter");
    15101509                        }
    15111510
    15121511                        // Find all alternatives for all arguments in canonical form
    1513                         std::vector< CandidateFinder > argFinders = 
     1512                        std::vector< CandidateFinder > argFinders =
    15141513                                funcFinder.findSubExprs( clause.target.args );
    1515                        
     1514
    15161515                        // List all combinations of arguments
    15171516                        std::vector< CandidateList > possibilities;
     
    15191518
    15201519                        // For every possible function:
    1521                         // * try matching the arguments to the parameters, not the other way around because 
     1520                        // * try matching the arguments to the parameters, not the other way around because
    15221521                        //   more arguments than parameters
    15231522                        CandidateList funcCandidates;
     
    15261525                        for ( CandidateRef & func : funcFinder.candidates ) {
    15271526                                try {
    1528                                         auto pointerType = dynamic_cast< const ast::PointerType * >( 
     1527                                        auto pointerType = dynamic_cast< const ast::PointerType * >(
    15291528                                                func->expr->result->stripReferences() );
    15301529                                        if ( ! pointerType ) {
    1531                                                 SemanticError( stmt->location, func->expr->result.get(), 
     1530                                                SemanticError( stmt->location, func->expr->result.get(),
    15321531                                                        "candidate not viable: not a pointer type\n" );
    15331532                                        }
     
    15351534                                        auto funcType = pointerType->base.as< ast::FunctionType >();
    15361535                                        if ( ! funcType ) {
    1537                                                 SemanticError( stmt->location, func->expr->result.get(), 
     1536                                                SemanticError( stmt->location, func->expr->result.get(),
    15381537                                                        "candidate not viable: not a function type\n" );
    15391538                                        }
     
    15441543
    15451544                                                if( ! nextMutex( param, paramEnd ) ) {
    1546                                                         SemanticError( stmt->location, funcType, 
     1545                                                        SemanticError( stmt->location, funcType,
    15471546                                                                "candidate function not viable: no mutex parameters\n");
    15481547                                                }
     
    15601559                                                        ast::AssertionSet need, have;
    15611560                                                        ast::TypeEnvironment resultEnv{ func->env };
    1562                                                         // Add all type variables as open so that those not used in the 
     1561                                                        // Add all type variables as open so that those not used in the
    15631562                                                        // parameter list are still considered open
    15641563                                                        resultEnv.add( funcType->forall );
     
    15801579                                                        unsigned n_mutex_param = 0;
    15811580
    1582                                                         // For every argument of its set, check if it matches one of the 
     1581                                                        // For every argument of its set, check if it matches one of the
    15831582                                                        // parameters. The order is important
    15841583                                                        for ( auto & arg : argsList ) {
     
    15871586                                                                        // We ran out of parameters but still have arguments.
    15881587                                                                        // This function doesn't match
    1589                                                                         SemanticError( stmt->location, funcType, 
     1588                                                                        SemanticError( stmt->location, funcType,
    15901589                                                                                toString("candidate function not viable: too many mutex "
    15911590                                                                                "arguments, expected ", n_mutex_param, "\n" ) );
     
    15941593                                                                ++n_mutex_param;
    15951594
    1596                                                                 // Check if the argument matches the parameter type in the current 
     1595                                                                // Check if the argument matches the parameter type in the current
    15971596                                                                // scope
    15981597                                                                ast::ptr< ast::Type > paramType = (*param)->get_type();
    1599                                                                 if ( 
    1600                                                                         ! unify( 
    1601                                                                                 arg->expr->result, paramType, resultEnv, need, have, open, 
    1602                                                                                 symtab ) 
     1598                                                                if (
     1599                                                                        ! unify(
     1600                                                                                arg->expr->result, paramType, resultEnv, need, have, open,
     1601                                                                                symtab )
    16031602                                                                ) {
    16041603                                                                        // Type doesn't match
     
    16271626                                                                } while ( nextMutex( param, paramEnd ) );
    16281627
    1629                                                                 // We ran out of arguments but still have parameters left; this 
     1628                                                                // We ran out of arguments but still have parameters left; this
    16301629                                                                // function doesn't match
    1631                                                                 SemanticError( stmt->location, funcType, 
     1630                                                                SemanticError( stmt->location, funcType,
    16321631                                                                        toString( "candidate function not viable: too few mutex "
    16331632                                                                        "arguments, expected ", n_mutex_param, "\n" ) );
     
    16571656                        // Make sure correct number of arguments
    16581657                        if( funcCandidates.empty() ) {
    1659                                 SemanticErrorException top( stmt->location, 
     1658                                SemanticErrorException top( stmt->location,
    16601659                                        "No alternatives for function in call to waitfor" );
    16611660                                top.append( errors );
     
    16641663
    16651664                        if( argsCandidates.empty() ) {
    1666                                 SemanticErrorException top( stmt->location, 
    1667                                         "No alternatives for arguments in call to waitfor" ); 
     1665                                SemanticErrorException top( stmt->location,
     1666                                        "No alternatives for arguments in call to waitfor" );
    16681667                                top.append( errors );
    16691668                                throw top;
     
    16711670
    16721671                        if( funcCandidates.size() > 1 ) {
    1673                                 SemanticErrorException top( stmt->location, 
     1672                                SemanticErrorException top( stmt->location,
    16741673                                        "Ambiguous function in call to waitfor" );
    16751674                                top.append( errors );
     
    16861685                        // build new clause
    16871686                        ast::WaitForStmt::Clause clause2;
    1688                        
     1687
    16891688                        clause2.target.func = funcCandidates.front()->expr;
    1690                        
     1689
    16911690                        clause2.target.args.reserve( clause.target.args.size() );
    16921691                        for ( auto arg : argsCandidates.front() ) {
     
    17081707                        ast::WaitForStmt::Timeout timeout2;
    17091708
    1710                         ast::ptr< ast::Type > target = 
     1709                        ast::ptr< ast::Type > target =
    17111710                                new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
    17121711                        timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
     
    17401739        const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    17411740                visit_children = false;
    1742                 // resolve initialization using the possibilities as determined by the `currentObject` 
     1741                // resolve initialization using the possibilities as determined by the `currentObject`
    17431742                // cursor.
    1744                 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 
     1743                ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
    17451744                        singleInit->location, singleInit->value, currentObject.getOptions() };
    17461745                ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
     
    17511750
    17521751                // discard InitExpr wrapper and retain relevant pieces.
    1753                 // `initExpr` may have inferred params in the case where the expression specialized a 
    1754                 // function pointer, and newExpr may already have inferParams of its own, so a simple 
     1752                // `initExpr` may have inferred params in the case where the expression specialized a
     1753                // function pointer, and newExpr may already have inferParams of its own, so a simple
    17551754                // swap is not sufficient
    17561755                ast::Expr::InferUnion inferred = initExpr->inferred;
     
    17581757                newExpr.get_and_mutate()->inferred.splice( std::move(inferred) );
    17591758
    1760                 // get the actual object's type (may not exactly match what comes back from the resolver 
     1759                // get the actual object's type (may not exactly match what comes back from the resolver
    17611760                // due to conversions)
    17621761                const ast::Type * initContext = currentObject.getCurrentType();
     
    17701769                                if ( auto pt = newExpr->result.as< ast::PointerType >() ) {
    17711770                                        if ( isCharType( pt->base ) ) {
    1772                                                 // strip cast if we're initializing a char[] with a char* 
     1771                                                // strip cast if we're initializing a char[] with a char*
    17731772                                                // e.g. char x[] = "hello"
    17741773                                                if ( auto ce = newExpr.as< ast::CastExpr >() ) {
     
    17931792                assert( listInit->designations.size() == listInit->initializers.size() );
    17941793                for ( unsigned i = 0; i < listInit->designations.size(); ++i ) {
    1795                         // iterate designations and initializers in pairs, moving the cursor to the current 
     1794                        // iterate designations and initializers in pairs, moving the cursor to the current
    17961795                        // designated object and resolving the initializer against that object
    17971796                        listInit = ast::mutate_field_index(
    1798                                 listInit, &ast::ListInit::designations, i, 
     1797                                listInit, &ast::ListInit::designations, i,
    17991798                                currentObject.findNext( listInit->designations[i] ) );
    18001799                        listInit = ast::mutate_field_index(
     
    18181817                ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
    18191818
    1820                 // intrinsic single-parameter constructors and destructors do nothing. Since this was 
    1821                 // implicitly generated, there's no way for it to have side effects, so get rid of it to 
     1819                // intrinsic single-parameter constructors and destructors do nothing. Since this was
     1820                // implicitly generated, there's no way for it to have side effects, so get rid of it to
    18221821                // clean up generated code
    18231822                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
Note: See TracChangeset for help on using the changeset viewer.