Changeset 09867ec for src/InitTweak
- Timestamp:
- Dec 23, 2020, 5:40:55 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 83c7e3c
- Parents:
- 0536c03
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r0536c03 r09867ec 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 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 124 145 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 } 126 152 fixReturnStatements( translationUnit ); 127 153 … … 196 222 197 223 // 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 ); 203 227 // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects. 204 228 // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve … … 218 242 219 243 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 * ) { 220 292 GuardValue( inFunction ); 221 293 inFunction = true;
Note: See TracChangeset
for help on using the changeset viewer.