Changes in / [d945be9:7c80a86]


Ignore:
Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.hpp

    rd945be9 r7c80a86  
    330330enum GeneratedFlag { ExplicitCast, GeneratedCast };
    331331
    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 
    338332/// A type cast, e.g. `(int)e`
    339333class CastExpr final : public Expr {
     
    342336        GeneratedFlag isGenerated;
    343337
    344         CastKind kind = CCast;
     338        enum CastKind {
     339                Default, // C
     340                Coerce, // reinterpret cast
     341                Return  // overload selection
     342        };
     343
     344        CastKind kind = Default;
    345345
    346346        CastExpr( const CodeLocation & loc, const Expr * a, const Type * to,
    347                 GeneratedFlag g = GeneratedCast, CastKind kind = CCast ) : Expr( loc, to ), arg( a ), isGenerated( g ), kind( kind ) {}
     347                GeneratedFlag g = GeneratedCast, CastKind kind = Default ) : Expr( loc, to ), arg( a ), isGenerated( g ), kind( kind ) {}
    348348        /// Cast-to-void
    349         CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast, CastKind kind = CCast );
     349        CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast, CastKind kind = Default );
    350350
    351351        /// Wrap a cast expression around an existing expression (always generated)
  • src/CodeGen/CodeGenerator.cpp

    rd945be9 r7c80a86  
    680680        extension( expr );
    681681        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 ";
     682        if ( expr->result->isVoid() ) {
     683                output << "(void)";
     684        } else {
     685                output << "(";
    702686                output << genType( expr->result, "", options );
    703687                output << ")";
    704                 break;
    705688        }
    706689        expr->arg->accept( *visitor );
  • src/GenPoly/Lvalue.cpp

    rd945be9 r7c80a86  
    315315                SemanticWarning( expr->arg->location,
    316316                        Warning::RvalueToReferenceConversion, toCString( expr->arg ) );
     317
    317318
    318319                // allowing conversion in the rvalue to const ref case
     
    365366                        ret = new ast::AddressExpr( ret->location, ret );
    366367                }
    367                 if ( !ResolvExpr::typesCompatible(
    368                                 srcType,
    369                                 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
     368                if ( expr->arg->get_lvalue() &&
     369                                !ResolvExpr::typesCompatible(
     370                                        srcType,
     371                                        strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) {
    370372                        // Must keep cast if cast-to type is different from the actual type.
    371373                        return ast::mutate_field( expr, &ast::CastExpr::arg, ret );
     
    382384                }
    383385                // Must keep cast if types are different.
    384                 if ( !ResolvExpr::typesCompatible(
     386                if ( !ResolvExpr::typesCompatibleIgnoreQualifiers(
    385387                                dstType->stripReferences(),
    386388                                srcType->stripReferences() ) ) {
     
    395397        } else {
    396398                assert( 0 == diff );
    397                 // Must keep cast if types are different. (Or it is explicit.)
    398                 if ( ast::ExplicitCast == expr->isGenerated ||
    399                                 !ResolvExpr::typesCompatible(
     399                // Remove useless generated casts.
     400                if ( expr->isGenerated == ast::GeneratedFlag::GeneratedCast &&
     401                                ResolvExpr::typesCompatible(
    400402                                        expr->result,
    401403                                        expr->arg->result ) ) {
    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() );
     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;
    411420        }
    412421}
  • src/Parser/ExpressionNode.cpp

    rd945be9 r7c80a86  
    652652                DeclarationNode * decl_node,
    653653                ExpressionNode * expr_node,
    654                 ast::CastKind kind ) {
     654                ast::CastExpr::CastKind kind ) {
    655655        ast::Type * targetType = maybeMoveBuildType( decl_node );
    656656        if ( dynamic_cast<ast::VoidType *>( targetType ) ) {
  • src/Parser/ExpressionNode.hpp

    rd945be9 r7c80a86  
    6969ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );
    7070
    71 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node, ast::CastKind kind = ast::CCast );
     71ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node, ast::CastExpr::CastKind kind = ast::CastExpr::Default );
    7272ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    7373ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
  • src/Parser/parser.yy

    rd945be9 r7c80a86  
    979979                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    980980        | '(' RETURN type_no_function ')' cast_expression       // CFA
    981                 { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::ReturnCast ) ); }
     981                { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::CastExpr::Return ) ); }
    982982        | '(' COERCE type_no_function ')' cast_expression       // CFA
    983983                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
  • src/ResolvExpr/CandidateFinder.cpp

    rd945be9 r7c80a86  
    12201220                        finder.allowVoid = true;
    12211221                }
    1222                 if ( ast::ReturnCast == castExpr->kind ) {
     1222                if ( castExpr->kind == ast::CastExpr::Return ) {
    12231223                        finder.strictMode = true;
    12241224                        finder.find( castExpr->arg, ResolveMode::withAdjustment() );
Note: See TracChangeset for help on using the changeset viewer.