Changes in src/InitTweak/GenInit.cc [09867ec:5465377c]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r09867ec r5465377c 122 122 }; 123 123 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 single126 /// const variable of type size_t, so that side effecting array dimensions are only127 /// 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 objects134 // that need to be constructed or destructed135 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 145 124 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 ); 152 126 fixReturnStatements( translationUnit ); 153 127 … … 222 196 223 197 // 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 } 227 203 // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects. 228 204 // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve … … 242 218 243 219 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 var267 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 resolve277 // still try to detect constant expressions278 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 * ) {292 220 GuardValue( inFunction ); 293 221 inFunction = true;
Note: See TracChangeset
for help on using the changeset viewer.