Changes in / [83c7e3c:4c19647]
- Location:
- src
- Files:
-
- 4 edited
-
InitTweak/GenInit.cc (modified) (3 diffs)
-
ResolvExpr/CandidateFinder.cpp (modified) (1 diff)
-
ResolvExpr/ResolvMode.h (modified) (1 diff)
-
SymTab/Validate.cc (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r83c7e3c r4c19647 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; -
src/ResolvExpr/CandidateFinder.cpp
r83c7e3c r4c19647 905 905 // xxx - is it possible that handleTupleAssignment and main finder both produce candidates? 906 906 // 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() ); 913 908 // short-circuit if no candidates 914 909 // if ( funcFinder.candidates.empty() ) return; -
src/ResolvExpr/ResolvMode.h
r83c7e3c r4c19647 23 23 const bool failFast; ///< Fail on no resulting alternatives? [true] 24 24 25 private: 25 26 constexpr ResolvMode(bool a, bool p, bool ff) 26 27 : adjust(a), prune(p), failFast(ff) {} 27 28 29 public: 28 30 /// Default settings 29 31 constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {} -
src/SymTab/Validate.cc
r83c7e3c r4c19647 271 271 }; 272 272 273 struct InitializerLength{273 struct ArrayLength : public WithIndexer { 274 274 /// for array types without an explicit length, compute the length and store it so that it 275 275 /// is known to the rest of the phases. For example, … … 282 282 283 283 void previsit( ObjectDecl * objDecl ); 284 };285 286 struct ArrayLength : public WithIndexer {287 static void computeLength( std::list< Declaration * > & translationUnit );288 289 284 void previsit( ArrayType * arrayType ); 290 285 }; … … 387 382 FixObjectType::fix, translationUnit); 388 383 } 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); 395 386 Stats::Time::TimeCall("Find Special Declarations", 396 387 Validate::findSpecialDecls, translationUnit); … … 1341 1332 } 1342 1333 1343 void InitializerLength::computeLength( std::list< Declaration * > & translationUnit ) {1344 PassVisitor<InitializerLength> len;1345 acceptAll( translationUnit, len );1346 }1347 1348 1334 void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) { 1349 1335 PassVisitor<ArrayLength> len; … … 1351 1337 } 1352 1338 1353 void InitializerLength::previsit( ObjectDecl * objDecl ) {1339 void ArrayLength::previsit( ObjectDecl * objDecl ) { 1354 1340 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) { 1355 1341 if ( at->dimension ) return; … … 1361 1347 1362 1348 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 } 1371 1359 } 1372 1360 }
Note:
See TracChangeset
for help on using the changeset viewer.