Changes in / [83c7e3c:4c19647]


Ignore:
Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r83c7e3c r4c19647  
    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;
  • src/ResolvExpr/CandidateFinder.cpp

    r83c7e3c r4c19647  
    905905                        // xxx - is it possible that handleTupleAssignment and main finder both produce candidates?
    906906                        // this means there exists ctor/assign functions with a tuple as first parameter.
    907                         ResolvMode mode = {
    908                                 true, // adjust
    909                                 !untypedExpr->func.as<ast::NameExpr>(), // prune if not calling by name
    910                                 selfFinder.candidates.empty() // failfast if other options are not found
    911                         };
    912                         funcFinder.find( untypedExpr->func, mode );
     907                        funcFinder.find( untypedExpr->func, selfFinder.candidates.empty() ? ResolvMode::withAdjustment() : ResolvMode::withoutFailFast() );
    913908                        // short-circuit if no candidates
    914909                        // if ( funcFinder.candidates.empty() ) return;
  • src/ResolvExpr/ResolvMode.h

    r83c7e3c r4c19647  
    2323                const bool failFast;         ///< Fail on no resulting alternatives? [true]
    2424
     25        private:
    2526                constexpr ResolvMode(bool a, bool p, bool ff)
    2627                : adjust(a), prune(p), failFast(ff) {}
    2728
     29        public:
    2830                /// Default settings
    2931                constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {}
  • src/SymTab/Validate.cc

    r83c7e3c r4c19647  
    271271        };
    272272
    273         struct InitializerLength {
     273        struct ArrayLength : public WithIndexer {
    274274                /// for array types without an explicit length, compute the length and store it so that it
    275275                /// is known to the rest of the phases. For example,
     
    282282
    283283                void previsit( ObjectDecl * objDecl );
    284         };
    285 
    286         struct ArrayLength : public WithIndexer {
    287                 static void computeLength( std::list< Declaration * > & translationUnit );
    288 
    289284                void previsit( ArrayType * arrayType );
    290285        };
     
    387382                                        FixObjectType::fix, translationUnit);
    388383                        }
    389                         Stats::Time::TimeCall("Initializer Length",
    390                                 InitializerLength::computeLength, translationUnit);
    391                         if (!useNewAST) {
    392                                 Stats::Time::TimeCall("Array Length",
    393                                         ArrayLength::computeLength, translationUnit);
    394                         }
     384                        Stats::Time::TimeCall("Array Length",
     385                                ArrayLength::computeLength, translationUnit);
    395386                        Stats::Time::TimeCall("Find Special Declarations",
    396387                                Validate::findSpecialDecls, translationUnit);
     
    13411332        }
    13421333
    1343         void InitializerLength::computeLength( std::list< Declaration * > & translationUnit ) {
    1344                 PassVisitor<InitializerLength> len;
    1345                 acceptAll( translationUnit, len );
    1346         }
    1347 
    13481334        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    13491335                PassVisitor<ArrayLength> len;
     
    13511337        }
    13521338
    1353         void InitializerLength::previsit( ObjectDecl * objDecl ) {
     1339        void ArrayLength::previsit( ObjectDecl * objDecl ) {
    13541340                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
    13551341                        if ( at->dimension ) return;
     
    13611347
    13621348        void ArrayLength::previsit( ArrayType * type ) {
    1363                 if ( type->dimension ) {
    1364                         // need to resolve array dimensions early so that constructor code can correctly determine
    1365                         // if a type is a VLA (and hence whether its elements need to be constructed)
    1366                         ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
    1367 
    1368                         // must re-evaluate whether a type is a VLA, now that more information is available
    1369                         // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
    1370                         type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
     1349                if (!useNewAST) {
     1350                        if ( type->dimension ) {
     1351                                // need to resolve array dimensions early so that constructor code can correctly determine
     1352                                // if a type is a VLA (and hence whether its elements need to be constructed)
     1353                                ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
     1354
     1355                                // must re-evaluate whether a type is a VLA, now that more information is available
     1356                                // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
     1357                                type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
     1358                        }
    13711359                }
    13721360        }
Note: See TracChangeset for help on using the changeset viewer.