- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/InitializerLength.cpp
r91a72ef rb6f2e7ab 29 29 /// int x[] = { 1, 2, 3 }; 30 30 /// int y[][2] = { { 1, 2, 3 }, { 1, 2, 3 } }; 31 /// char z[] = "hello"; 31 32 /// here x and y are known at compile-time to have length 3, so change this into 32 33 /// int x[3] = { 1, 2, 3 }; 33 34 /// int y[3][2] = { { 1, 2, 3 }, { 1, 2, 3 } }; 35 /// char z[6] = "hello"; 34 36 struct InitializerLength { 35 37 const ast::ObjectDecl * previsit( const ast::ObjectDecl * decl ); 36 38 }; 37 39 40 ast::ConstantExpr * makeDimension( const ast::ObjectDecl * decl ) { 41 if ( auto init = decl->init.as<ast::ListInit>() ) { 42 return ast::ConstantExpr::from_ulong( decl->location, init->size() ); 43 } else if ( auto init = decl->init.as<ast::SingleInit>() ) { 44 if ( auto constant = init->value.as<ast::ConstantExpr>() ) { 45 if ( auto type = constant->result.as<ast::ArrayType>() ) { 46 if ( auto dim = type->dimension.as<ast::ConstantExpr>() ) { 47 ast::ConstantExpr * dimension = ast::deepCopy( dim ); 48 dimension->location = decl->location; 49 return dimension; 50 } 51 } 52 } 53 } 54 return nullptr; 55 } 56 38 57 const ast::ObjectDecl * InitializerLength::previsit( const ast::ObjectDecl * decl ) { 39 58 if ( auto type = decl->type.as<ast::ArrayType>() ) { 40 59 if ( type->dimension ) return decl; 41 if ( auto init = decl->init.as<ast::ListInit>() ) {60 if ( auto dimension = makeDimension( decl ) ) { 42 61 ast::ObjectDecl * mutDecl = ast::mutate( decl ); 43 62 ast::ArrayType * mutType = ast::mutate( type ); 44 mutType->dimension = ast::ConstantExpr::from_ulong( 45 mutDecl->location, init->size() ); 63 mutType->dimension = dimension; 46 64 mutDecl->type = mutType; 47 65 return mutDecl;
Note: See TracChangeset
for help on using the changeset viewer.