Changeset 09867ec for src/InitTweak


Ignore:
Timestamp:
Dec 23, 2020, 5:40:55 PM (11 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
83c7e3c
Parents:
0536c03
Message:

do not instantiate unused old AST symtab

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r0536c03 r09867ec  
    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
    124145        void genInit( std::list< Declaration * > & translationUnit ) {
    125                 HoistArrayDimension::hoistArrayDimension( translationUnit );
     146                if (!useNewAST) {
     147                        HoistArrayDimension::hoistArrayDimension( translationUnit );
     148                }
     149                else {
     150                        HoistArrayDimension_NoResolve::hoistArrayDimension( translationUnit );
     151                }
    126152                fixReturnStatements( translationUnit );
    127153
     
    196222
    197223                        // need to resolve array dimensions in order to accurately determine if constexpr
    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                         }
     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 );
    203227                        // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
    204228                        // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
     
    218242
    219243        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 * ) {
    220292                GuardValue( inFunction );
    221293                inFunction = true;
Note: See TracChangeset for help on using the changeset viewer.