Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r09867ec r5465377c  
    122122        };
    123123
    124         struct HoistArrayDimension_NoResolve final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
    125                 /// hoist dimension from array types in object declaration so that it uses a single
    126                 /// const variable of type size_t, so that side effecting array dimensions are only
    127                 /// computed once.
    128                 static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    129 
    130                 void premutate( ObjectDecl * objectDecl );
    131                 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
    132                 void premutate( FunctionDecl *functionDecl );
    133                 // should not traverse into any of these declarations to find objects
    134                 // that need to be constructed or destructed
    135                 void premutate( AggregateDecl * ) { visit_children = false; }
    136                 void premutate( NamedTypeDecl * ) { visit_children = false; }
    137                 void premutate( FunctionType * ) { visit_children = false; }
    138 
    139                 void hoist( Type * type );
    140 
    141                 Type::StorageClasses storageClasses;
    142                 bool inFunction = false;
    143         };
    144 
    145124        void genInit( std::list< Declaration * > & translationUnit ) {
    146                 if (!useNewAST) {
    147                         HoistArrayDimension::hoistArrayDimension( translationUnit );
    148                 }
    149                 else {
    150                         HoistArrayDimension_NoResolve::hoistArrayDimension( translationUnit );
    151                 }
     125                HoistArrayDimension::hoistArrayDimension( translationUnit );
    152126                fixReturnStatements( translationUnit );
    153127
     
    222196
    223197                        // need to resolve array dimensions in order to accurately determine if constexpr
    224                         ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
    225                         // array is variable-length when the dimension is not constexpr
    226                         arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
     198                        if (!useNewAST) {
     199                                ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
     200                                // array is variable-length when the dimension is not constexpr
     201                                arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
     202                        }
    227203                        // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
    228204                        // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
     
    242218
    243219        void HoistArrayDimension::premutate( FunctionDecl * ) {
    244                 GuardValue( inFunction );
    245                 inFunction = true;
    246         }
    247 
    248         // precompute array dimension expression, because constructor generation may duplicate it,
    249         // which would be incorrect if it is a side-effecting computation.
    250         void HoistArrayDimension_NoResolve::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    251                 PassVisitor<HoistArrayDimension_NoResolve> hoister;
    252                 mutateAll( translationUnit, hoister );
    253         }
    254 
    255         void HoistArrayDimension_NoResolve::premutate( ObjectDecl * objectDecl ) {
    256                 GuardValue( storageClasses );
    257                 storageClasses = objectDecl->get_storageClasses();
    258         }
    259 
    260         DeclarationWithType * HoistArrayDimension_NoResolve::postmutate( ObjectDecl * objectDecl ) {
    261                 hoist( objectDecl->get_type() );
    262                 return objectDecl;
    263         }
    264 
    265         void HoistArrayDimension_NoResolve::hoist( Type * type ) {
    266                 // if in function, generate const size_t var
    267                 static UniqueName dimensionName( "_array_dim" );
    268 
    269                 // C doesn't allow variable sized arrays at global scope or for static variables, so don't hoist dimension.
    270                 if ( ! inFunction ) return;
    271                 if ( storageClasses.is_static ) return;
    272 
    273                 if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
    274                         if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
    275                         // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
    276                         // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
    277                         // still try to detect constant expressions
    278                         if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
    279 
    280                         ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
    281                         arrayDimension->get_type()->set_const( true );
    282 
    283                         arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    284                         declsToAddBefore.push_back( arrayDimension );
    285 
    286                         hoist( arrayType->get_base() );
    287                         return;
    288                 }
    289         }
    290 
    291         void HoistArrayDimension_NoResolve::premutate( FunctionDecl * ) {
    292220                GuardValue( inFunction );
    293221                inFunction = true;
Note: See TracChangeset for help on using the changeset viewer.