Changeset d945be9
- Timestamp:
- Nov 20, 2024, 9:46:17 AM (3 hours ago)
- Branches:
- master
- Parents:
- 7c80a86 (diff), ecf3812 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.hpp
r7c80a86 rd945be9 330 330 enum GeneratedFlag { ExplicitCast, GeneratedCast }; 331 331 332 /// Even within the basic cast expression there are variants: 333 /// CCast - C-Style Cast: A backwards compatable cast from C. 334 /// CoerceCast - Coercion Cast: Change the type without changing the value. 335 /// ReturnCast - Ascription Cast: Requires the given expression result type. 336 enum CastKind { CCast, CoerceCast, ReturnCast }; 337 332 338 /// A type cast, e.g. `(int)e` 333 339 class CastExpr final : public Expr { … … 336 342 GeneratedFlag isGenerated; 337 343 338 enum CastKind { 339 Default, // C 340 Coerce, // reinterpret cast 341 Return // overload selection 342 }; 343 344 CastKind kind = Default; 344 CastKind kind = CCast; 345 345 346 346 CastExpr( const CodeLocation & loc, const Expr * a, const Type * to, 347 GeneratedFlag g = GeneratedCast, CastKind kind = Default ) : Expr( loc, to ), arg( a ), isGenerated( g ), kind( kind ) {}347 GeneratedFlag g = GeneratedCast, CastKind kind = CCast ) : Expr( loc, to ), arg( a ), isGenerated( g ), kind( kind ) {} 348 348 /// Cast-to-void 349 CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast, CastKind kind = Default );349 CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast, CastKind kind = CCast ); 350 350 351 351 /// Wrap a cast expression around an existing expression (always generated) -
src/CodeGen/CodeGenerator.cpp
r7c80a86 rd945be9 680 680 extension( expr ); 681 681 output << "("; 682 if ( expr->result->isVoid() ) { 683 output << "(void)"; 684 } else { 685 output << "("; 682 switch ( expr->kind ) { 683 case ast::CCast: 684 if ( expr->result->isVoid() ) { 685 output << "(void)"; 686 } else { 687 output << "("; 688 output << genType( expr->result, "", options ); 689 output << ")"; 690 } 691 break; 692 case ast::CoerceCast: 693 assertf( ast::CoerceCast != expr->kind, "Coercion cast is not implemented." ); 694 // And likely shouldn't reach code generation when it is implemented. 695 break; 696 case ast::ReturnCast: 697 // This should be invisible in the resulting C code. 698 // Can we insert a check here? 699 //assert( ResolvExpr::typesCompatable(???) ); 700 if ( options.genC ) break; 701 output << "(return "; 686 702 output << genType( expr->result, "", options ); 687 703 output << ")"; 704 break; 688 705 } 689 706 expr->arg->accept( *visitor ); -
src/GenPoly/Lvalue.cpp
r7c80a86 rd945be9 315 315 SemanticWarning( expr->arg->location, 316 316 Warning::RvalueToReferenceConversion, toCString( expr->arg ) ); 317 318 317 319 318 // allowing conversion in the rvalue to const ref case … … 366 365 ret = new ast::AddressExpr( ret->location, ret ); 367 366 } 368 if ( expr->arg->get_lvalue() && 369 !ResolvExpr::typesCompatible( 370 srcType, 371 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) { 367 if ( !ResolvExpr::typesCompatible( 368 srcType, 369 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) { 372 370 // Must keep cast if cast-to type is different from the actual type. 373 371 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); … … 384 382 } 385 383 // Must keep cast if types are different. 386 if ( !ResolvExpr::typesCompatible IgnoreQualifiers(384 if ( !ResolvExpr::typesCompatible( 387 385 dstType->stripReferences(), 388 386 srcType->stripReferences() ) ) { … … 397 395 } else { 398 396 assert( 0 == diff ); 399 // Remove useless generated casts.400 if ( expr->isGenerated == ast::GeneratedFlag::GeneratedCast &&401 ResolvExpr::typesCompatible(397 // Must keep cast if types are different. (Or it is explicit.) 398 if ( ast::ExplicitCast == expr->isGenerated || 399 !ResolvExpr::typesCompatible( 402 400 expr->result, 403 401 expr->arg->result ) ) { 404 PRINT( 405 std::cerr << "types are compatible, removing cast: " << expr << '\n'; 406 std::cerr << "-- " << expr->result << '\n'; 407 std::cerr << "-- " << expr->arg->result << std::endl; 408 ) 409 auto argAsEnum = expr->arg.as<ast::EnumInstType>(); 410 auto resultAsEnum = expr->result.as<ast::EnumInstType>(); 411 if (argAsEnum && resultAsEnum) { 412 if (argAsEnum->base->name != resultAsEnum->base->name) { 413 return expr; 414 } 415 } 416 return ast::mutate_field( expr->arg.get(), 417 &ast::Expr::env, expr->env.get() ); 418 } 419 return expr; 402 return expr; 403 } 404 PRINT( 405 std::cerr << "types are compatible, removing cast: " << expr << '\n'; 406 std::cerr << "-- " << expr->result << '\n'; 407 std::cerr << "-- " << expr->arg->result << std::endl; 408 ) 409 return ast::mutate_field( expr->arg.get(), 410 &ast::Expr::env, expr->env.get() ); 420 411 } 421 412 } -
src/Parser/ExpressionNode.cpp
r7c80a86 rd945be9 652 652 DeclarationNode * decl_node, 653 653 ExpressionNode * expr_node, 654 ast::Cast Expr::CastKind kind ) {654 ast::CastKind kind ) { 655 655 ast::Type * targetType = maybeMoveBuildType( decl_node ); 656 656 if ( dynamic_cast<ast::VoidType *>( targetType ) ) { -
src/Parser/ExpressionNode.hpp
r7c80a86 rd945be9 69 69 ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name ); 70 70 71 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node, ast::Cast Expr::CastKind kind = ast::CastExpr::Default );71 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node, ast::CastKind kind = ast::CCast ); 72 72 ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node ); 73 73 ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node ); -
src/Parser/parser.yy
r7c80a86 rd945be9 979 979 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); } 980 980 | '(' RETURN type_no_function ')' cast_expression // CFA 981 { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast:: CastExpr::Return) ); }981 { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::ReturnCast ) ); } 982 982 | '(' COERCE type_no_function ')' cast_expression // CFA 983 983 { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; } -
src/ResolvExpr/CandidateFinder.cpp
r7c80a86 rd945be9 1220 1220 finder.allowVoid = true; 1221 1221 } 1222 if ( castExpr->kind == ast::CastExpr::Return) {1222 if ( ast::ReturnCast == castExpr->kind ) { 1223 1223 finder.strictMode = true; 1224 1224 finder.find( castExpr->arg, ResolveMode::withAdjustment() );
Note: See TracChangeset
for help on using the changeset viewer.