Changeset b6f2e7ab
- Timestamp:
- Sep 9, 2024, 5:15:32 PM (35 hours ago)
- Branches:
- master
- Children:
- f5dbc8d
- Parents:
- 5c6d439
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
r5c6d439 rb6f2e7ab 276 276 // --- SizeofExpr 277 277 278 SizeofExpr::SizeofExpr( const CodeLocation & loc, const Expr * e )279 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( e ), type( nullptr ) {}280 281 278 SizeofExpr::SizeofExpr( const CodeLocation & loc, const Type * t ) 282 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( nullptr ),type( t ) {}279 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {} 283 280 284 281 // --- CountExpr … … 292 289 // --- AlignofExpr 293 290 294 AlignofExpr::AlignofExpr( const CodeLocation & loc, const Expr * e )295 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( e ), type( nullptr ) {}296 297 291 AlignofExpr::AlignofExpr( const CodeLocation & loc, const Type * t ) 298 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( nullptr ),type( t ) {}292 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {} 299 293 300 294 // --- OffsetofExpr -
src/AST/Expr.hpp
r5c6d439 rb6f2e7ab 480 480 class SizeofExpr final : public Expr { 481 481 public: 482 ptr<Type> type; 483 484 SizeofExpr( const CodeLocation & loc, const Type * t ); 485 486 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } 487 private: 488 SizeofExpr * clone() const override { return new SizeofExpr{ *this }; } 489 MUTATE_FRIEND 490 }; 491 492 class CountExpr final : public Expr { 493 public: 482 494 ptr<Expr> expr; 483 495 ptr<Type> type; 484 496 485 SizeofExpr( const CodeLocation & loc, const Expr * e );486 SizeofExpr( const CodeLocation & loc, const Type * t );487 // deliberately no disambiguating overload for nullptr_t488 489 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }490 private:491 SizeofExpr * clone() const override { return new SizeofExpr{ *this }; }492 MUTATE_FRIEND493 };494 495 class CountExpr final : public Expr {496 public:497 ptr<Expr> expr;498 ptr<Type> type;499 500 497 CountExpr( const CodeLocation & loc, const Expr * t ); 501 498 CountExpr( const CodeLocation & loc, const Type * t ); … … 510 507 class AlignofExpr final : public Expr { 511 508 public: 512 ptr<Expr> expr;513 509 ptr<Type> type; 514 510 515 AlignofExpr( const CodeLocation & loc, const Expr * e );516 511 AlignofExpr( const CodeLocation & loc, const Type * t ); 517 // deliberately no disambiguating overload for nullptr_t518 512 519 513 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Pass.impl.hpp
r5c6d439 rb6f2e7ab 1319 1319 maybe_accept( node, &SizeofExpr::result ); 1320 1320 } 1321 if ( node->type ) { 1322 maybe_accept( node, &SizeofExpr::type ); 1323 } else { 1324 maybe_accept( node, &SizeofExpr::expr ); 1325 } 1321 maybe_accept( node, &SizeofExpr::type ); 1326 1322 } 1327 1323 … … 1359 1355 maybe_accept( node, &AlignofExpr::result ); 1360 1356 } 1361 if ( node->type ) { 1362 maybe_accept( node, &AlignofExpr::type ); 1363 } else { 1364 maybe_accept( node, &AlignofExpr::expr ); 1365 } 1357 maybe_accept( node, &AlignofExpr::type ); 1366 1358 } 1367 1359 -
src/AST/Print.cpp
r5c6d439 rb6f2e7ab 1152 1152 os << "Sizeof Expression on: "; 1153 1153 ++indent; 1154 node->type->accept( *this ); 1155 --indent; 1156 postprint( node ); 1157 1158 return node; 1159 } 1160 1161 virtual const ast::Expr * visit( const ast::CountExpr * node ) override final { 1162 os << "Count Expression on: "; 1163 ++indent; 1154 1164 if ( node->type ) node->type->accept( *this ); 1155 1165 else safe_print( node->expr ); 1156 1166 --indent; 1157 1167 postprint( node ); 1158 1159 return node;1160 }1161 1162 virtual const ast::Expr * visit( const ast::CountExpr * node ) override final {1163 os << "Count Expression on: ";1164 ++indent;1165 if ( node->type ) node->type->accept( *this );1166 else safe_print( node->expr );1167 --indent;1168 postprint( node );1169 1168 return node; 1170 1169 } … … 1173 1172 os << "Alignof Expression on: "; 1174 1173 ++indent; 1175 if ( node->type ) node->type->accept( *this ); 1176 else safe_print( node->expr ); 1174 node->type->accept( *this ); 1177 1175 --indent; 1178 1176 postprint( node ); -
src/AST/Util.cpp
r5c6d439 rb6f2e7ab 104 104 } 105 105 assertf( false, "Member not found." ); 106 }107 108 template<typename node_t>109 void oneOfExprOrType( const node_t * node ) {110 if ( node->expr ) {111 assertf( node->expr && !node->type, "Exactly one of expr or type should be set." );112 } else {113 assertf( !node->expr && node->type, "Exactly one of expr or type should be set." );114 }115 106 } 116 107 … … 163 154 void previsit( const SizeofExpr * node ) { 164 155 previsit( (const ParseNode *)node ); 165 oneOfExprOrType( node );166 156 } 167 157 168 158 void previsit( const AlignofExpr * node ) { 169 159 previsit( (const ParseNode *)node ); 170 oneOfExprOrType( node );171 160 } 172 161 -
src/CodeGen/CodeGenerator.cpp
r5c6d439 rb6f2e7ab 744 744 extension( expr ); 745 745 output << "sizeof("; 746 if ( expr->type ) { 746 if ( auto type = expr->type.as<ast::TypeofType>() ) { 747 type->expr->accept( *visitor ); 748 } else { 747 749 output << genType( expr->type, "", options ); 748 } else {749 expr->expr->accept( *visitor );750 750 } 751 751 output << ")"; … … 756 756 extension( expr ); 757 757 output << "__alignof__("; 758 if ( expr->type ) { 758 if ( auto type = expr->type.as<ast::TypeofType>() ) { 759 type->expr->accept( *visitor ); 760 } else { 759 761 output << genType( expr->type, "", options ); 760 } else {761 expr->expr->accept( *visitor );762 762 } 763 763 output << ")"; -
src/Concurrency/Waitfor.cpp
r5c6d439 rb6f2e7ab 230 230 ast::ConstantExpr::from_int( location, 0 ), 231 231 new ast::SizeofExpr( location, 232 new ast::VariableExpr( location, acceptables ) ), 232 new ast::TypeofType( 233 new ast::VariableExpr( location, acceptables ) ) ), 233 234 } 234 235 ); -
src/GenPoly/Box.cpp
r5c6d439 rb6f2e7ab 1925 1925 ast::Expr const * PolyGenericCalculator::postvisit( 1926 1926 ast::SizeofExpr const * expr ) { 1927 ast::Type const * type = expr->type ? expr->type : expr->expr->result; 1928 ast::Expr const * gen = genSizeof( expr->location, type ); 1927 ast::Expr const * gen = genSizeof( expr->location, expr->type ); 1929 1928 return ( gen ) ? gen : expr; 1930 1929 } … … 1932 1931 ast::Expr const * PolyGenericCalculator::postvisit( 1933 1932 ast::AlignofExpr const * expr ) { 1934 ast::Type const * type = expr->type ? expr->type : expr->expr->result; 1935 ast::Expr const * gen = genAlignof( expr->location, type ); 1933 ast::Expr const * gen = genAlignof( expr->location, expr->type ); 1936 1934 return ( gen ) ? gen : expr; 1937 1935 } -
src/GenPoly/GenPoly.cpp
r5c6d439 rb6f2e7ab 299 299 ast::SizeofExpr const * r = as<ast::SizeofExpr>(rhs); 300 300 301 assert((l->type != nullptr) ^ (l->expr != nullptr)); 302 assert((r->type != nullptr) ^ (r->expr != nullptr)); 303 if ( !(l->type && r->type) ) return false; 301 assert( l->type ); 302 assert( r->type ); 304 303 305 304 // mutual recursion with type poly compatibility -
src/GenPoly/Lvalue.cpp
r5c6d439 rb6f2e7ab 607 607 ast::SizeofExpr const * ReferenceTypeElimination::previsit( 608 608 ast::SizeofExpr const * expr ) { 609 if ( expr->expr ) return expr;610 609 return ast::mutate_field( expr, &ast::SizeofExpr::type, 611 610 expr->type->stripReferences() ); … … 614 613 ast::AlignofExpr const * ReferenceTypeElimination::previsit( 615 614 ast::AlignofExpr const * expr ) { 616 if ( expr->expr ) return expr;617 615 return ast::mutate_field( expr, &ast::AlignofExpr::type, 618 616 expr->type->stripReferences() ); -
src/Parser/parser.yy
r5c6d439 rb6f2e7ab 927 927 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); } 928 928 | SIZEOF unary_expression 929 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2) ) ); }929 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, new ast::TypeofType( maybeMoveBuild( $2 ) ) ) ); } 930 930 | SIZEOF '(' type_no_function ')' 931 931 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 932 932 | ALIGNOF unary_expression // GCC, variable alignment 933 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2) ) ); }933 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, new ast::TypeofType( maybeMoveBuild( $2 ) ) ) ); } 934 934 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 935 935 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } -
src/ResolvExpr/CandidateFinder.cpp
r5c6d439 rb6f2e7ab 1482 1482 1483 1483 void Finder::postvisit( const ast::SizeofExpr * sizeofExpr ) { 1484 if ( sizeofExpr->type ) { 1485 addCandidate( 1486 new ast::SizeofExpr{ 1487 sizeofExpr->location, resolveTypeof( sizeofExpr->type, context ) }, 1488 tenv ); 1489 } else { 1490 // find all candidates for the argument to sizeof 1491 CandidateFinder finder( context, tenv ); 1492 finder.find( sizeofExpr->expr ); 1493 // find the lowest-cost candidate, otherwise ambiguous 1494 CandidateList winners = findMinCost( finder.candidates ); 1495 if ( winners.size() != 1 ) { 1496 SemanticError( 1497 sizeofExpr->expr.get(), "Ambiguous expression in sizeof operand: " ); 1498 } 1499 // return the lowest-cost candidate 1500 CandidateRef & choice = winners.front(); 1501 choice->expr = referenceToRvalueConversion( choice->expr, choice->cost ); 1502 choice->cost = Cost::zero; 1503 addCandidate( *choice, new ast::SizeofExpr{ sizeofExpr->location, choice->expr } ); 1504 } 1484 addCandidate( 1485 new ast::SizeofExpr{ 1486 sizeofExpr->location, resolveTypeof( sizeofExpr->type, context ) }, 1487 tenv ); 1505 1488 } 1506 1489 … … 1537 1520 1538 1521 void Finder::postvisit( const ast::AlignofExpr * alignofExpr ) { 1539 if ( alignofExpr->type ) { 1540 addCandidate( 1541 new ast::AlignofExpr{ 1542 alignofExpr->location, resolveTypeof( alignofExpr->type, context ) }, 1543 tenv ); 1544 } else { 1545 // find all candidates for the argument to alignof 1546 CandidateFinder finder( context, tenv ); 1547 finder.find( alignofExpr->expr ); 1548 // find the lowest-cost candidate, otherwise ambiguous 1549 CandidateList winners = findMinCost( finder.candidates ); 1550 if ( winners.size() != 1 ) { 1551 SemanticError( 1552 alignofExpr->expr.get(), "Ambiguous expression in alignof operand: " ); 1553 } 1554 // return the lowest-cost candidate 1555 CandidateRef & choice = winners.front(); 1556 choice->expr = referenceToRvalueConversion( choice->expr, choice->cost ); 1557 choice->cost = Cost::zero; 1558 addCandidate( 1559 *choice, new ast::AlignofExpr{ alignofExpr->location, choice->expr } ); 1560 } 1522 addCandidate( 1523 new ast::AlignofExpr{ 1524 alignofExpr->location, resolveTypeof( alignofExpr->type, context ) }, 1525 tenv ); 1561 1526 } 1562 1527 -
src/ResolvExpr/Unify.cpp
r5c6d439 rb6f2e7ab 234 234 if ( !e2so ) return; 235 235 236 assert((e1->type != nullptr) ^ (e1->expr != nullptr));237 assert((e2so->type != nullptr) ^ (e2so->expr != nullptr));238 if ( !(e1->type && e2so->type) ) return;239 240 236 // expression unification calls type unification (mutual recursion) 241 237 result = unifyExact( e1->type, e2so->type, tenv, need, have, open, widen ); -
src/Validate/InitializerLength.cpp
r5c6d439 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; -
tests/.expect/alloc-ERROR.txt
r5c6d439 rb6f2e7ab 11 11 ...to: 12 12 Name: dim 13 Sizeof Expression on: Applying untyped:13 Sizeof Expression on: type-of expression Applying untyped: 14 14 Name: *? 15 15 ...to: -
tests/.expect/extension.arm64.txt
r5c6d439 rb6f2e7ab 465 465 } 466 466 { 467 ((void)__extension__ sizeof( 3));467 ((void)__extension__ sizeof(signed int )); 468 468 } 469 469 … … 473 473 474 474 { 475 ((void)__extension__ __alignof__( __extension__ _X1ai_2));475 ((void)__extension__ __alignof__(signed int )); 476 476 } 477 477 -
tests/.expect/extension.x64.txt
r5c6d439 rb6f2e7ab 465 465 } 466 466 { 467 ((void)__extension__ sizeof( 3));467 ((void)__extension__ sizeof(signed int )); 468 468 } 469 469 … … 473 473 474 474 { 475 ((void)__extension__ __alignof__( __extension__ _X1ai_2));475 ((void)__extension__ __alignof__(signed int )); 476 476 } 477 477 -
tests/.expect/extension.x86.txt
r5c6d439 rb6f2e7ab 465 465 } 466 466 { 467 ((void)__extension__ sizeof( 3));467 ((void)__extension__ sizeof(signed int )); 468 468 } 469 469 … … 473 473 474 474 { 475 ((void)__extension__ __alignof__( __extension__ _X1ai_2));475 ((void)__extension__ __alignof__(signed int )); 476 476 } 477 477
Note: See TracChangeset
for help on using the changeset viewer.