Changeset b6f2e7ab


Ignore:
Timestamp:
Sep 9, 2024, 5:15:32 PM (35 hours ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
f5dbc8d
Parents:
5c6d439
Message:

Removed SizeofExpr::expr and AlignofExpr::expr, expressions that would be stored there are wrapped in TypeofType? and stored in the type field. Some special cases to hide the typeof in code generation were added. In addition, initializer length is calculated in more cases so that the full type of more arrays is known sooner. Other than that, most of the code changes were just stripping out the conditional code and checks no longer needed. Some tests had to be updated, because the typeof is not hidden in dumps and the resolver replaces known typeof expressions with the type. The extension case caused some concern but it appears that just hides warnings in the expression which no longer exists.

Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r5c6d439 rb6f2e7ab  
    276276// --- SizeofExpr
    277277
    278 SizeofExpr::SizeofExpr( const CodeLocation & loc, const Expr * e )
    279 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( e ), type( nullptr ) {}
    280 
    281278SizeofExpr::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 ) {}
    283280
    284281// --- CountExpr
     
    292289// --- AlignofExpr
    293290
    294 AlignofExpr::AlignofExpr( const CodeLocation & loc, const Expr * e )
    295 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( e ), type( nullptr ) {}
    296 
    297291AlignofExpr::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 ) {}
    299293
    300294// --- OffsetofExpr
  • src/AST/Expr.hpp

    r5c6d439 rb6f2e7ab  
    480480class SizeofExpr final : public Expr {
    481481public:
     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 ); }
     487private:
     488        SizeofExpr * clone() const override { return new SizeofExpr{ *this }; }
     489        MUTATE_FRIEND
     490};
     491
     492class CountExpr final : public Expr {
     493public:
    482494        ptr<Expr> expr;
    483495        ptr<Type> type;
    484496
    485         SizeofExpr( const CodeLocation & loc, const Expr * e );
    486         SizeofExpr( const CodeLocation & loc, const Type * t );
    487         // deliberately no disambiguating overload for nullptr_t
    488 
    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_FRIEND
    493 };
    494 
    495 class CountExpr final : public Expr {
    496 public:
    497         ptr<Expr> expr;
    498         ptr<Type> type;
    499 
    500497        CountExpr( const CodeLocation & loc, const Expr * t );
    501498        CountExpr( const CodeLocation & loc, const Type * t );
     
    510507class AlignofExpr final : public Expr {
    511508public:
    512         ptr<Expr> expr;
    513509        ptr<Type> type;
    514510
    515         AlignofExpr( const CodeLocation & loc, const Expr * e );
    516511        AlignofExpr( const CodeLocation & loc, const Type * t );
    517         // deliberately no disambiguating overload for nullptr_t
    518512
    519513        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Pass.impl.hpp

    r5c6d439 rb6f2e7ab  
    13191319                        maybe_accept( node, &SizeofExpr::result );
    13201320                }
    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 );
    13261322        }
    13271323
     
    13591355                        maybe_accept( node, &AlignofExpr::result );
    13601356                }
    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 );
    13661358        }
    13671359
  • src/AST/Print.cpp

    r5c6d439 rb6f2e7ab  
    11521152                os << "Sizeof Expression on: ";
    11531153                ++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;
    11541164                if ( node->type ) node->type->accept( *this );
    11551165                else safe_print( node->expr );
    11561166                --indent;
    11571167                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 );
    11691168                return node;
    11701169        }
     
    11731172                os << "Alignof Expression on: ";
    11741173                ++indent;
    1175                 if ( node->type ) node->type->accept( *this );
    1176                 else safe_print( node->expr );
     1174                node->type->accept( *this );
    11771175                --indent;
    11781176                postprint( node );
  • src/AST/Util.cpp

    r5c6d439 rb6f2e7ab  
    104104        }
    105105        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         }
    115106}
    116107
     
    163154        void previsit( const SizeofExpr * node ) {
    164155                previsit( (const ParseNode *)node );
    165                 oneOfExprOrType( node );
    166156        }
    167157
    168158        void previsit( const AlignofExpr * node ) {
    169159                previsit( (const ParseNode *)node );
    170                 oneOfExprOrType( node );
    171160        }
    172161
  • src/CodeGen/CodeGenerator.cpp

    r5c6d439 rb6f2e7ab  
    744744        extension( expr );
    745745        output << "sizeof(";
    746         if ( expr->type ) {
     746        if ( auto type = expr->type.as<ast::TypeofType>() ) {
     747                type->expr->accept( *visitor );
     748        } else {
    747749                output << genType( expr->type, "", options );
    748         } else {
    749                 expr->expr->accept( *visitor );
    750750        }
    751751        output << ")";
     
    756756        extension( expr );
    757757        output << "__alignof__(";
    758         if ( expr->type ) {
     758        if ( auto type = expr->type.as<ast::TypeofType>() ) {
     759                type->expr->accept( *visitor );
     760        } else {
    759761                output << genType( expr->type, "", options );
    760         } else {
    761                 expr->expr->accept( *visitor );
    762762        }
    763763        output << ")";
  • src/Concurrency/Waitfor.cpp

    r5c6d439 rb6f2e7ab  
    230230                        ast::ConstantExpr::from_int( location, 0 ),
    231231                        new ast::SizeofExpr( location,
    232                                 new ast::VariableExpr( location, acceptables ) ),
     232                                new ast::TypeofType(
     233                                        new ast::VariableExpr( location, acceptables ) ) ),
    233234                }
    234235        );
  • src/GenPoly/Box.cpp

    r5c6d439 rb6f2e7ab  
    19251925ast::Expr const * PolyGenericCalculator::postvisit(
    19261926                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 );
    19291928        return ( gen ) ? gen : expr;
    19301929}
     
    19321931ast::Expr const * PolyGenericCalculator::postvisit(
    19331932                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 );
    19361934        return ( gen ) ? gen : expr;
    19371935}
  • src/GenPoly/GenPoly.cpp

    r5c6d439 rb6f2e7ab  
    299299                ast::SizeofExpr const * r = as<ast::SizeofExpr>(rhs);
    300300
    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 );
    304303
    305304                // mutual recursion with type poly compatibility
  • src/GenPoly/Lvalue.cpp

    r5c6d439 rb6f2e7ab  
    607607ast::SizeofExpr const * ReferenceTypeElimination::previsit(
    608608                ast::SizeofExpr const * expr ) {
    609         if ( expr->expr ) return expr;
    610609        return ast::mutate_field( expr, &ast::SizeofExpr::type,
    611610                expr->type->stripReferences() );
     
    614613ast::AlignofExpr const * ReferenceTypeElimination::previsit(
    615614                ast::AlignofExpr const * expr ) {
    616         if ( expr->expr ) return expr;
    617615        return ast::mutate_field( expr, &ast::AlignofExpr::type,
    618616                expr->type->stripReferences() );
  • src/Parser/parser.yy

    r5c6d439 rb6f2e7ab  
    927927                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    928928        | SIZEOF unary_expression
    929                 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     929                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, new ast::TypeofType( maybeMoveBuild( $2 ) ) ) ); }
    930930        | SIZEOF '(' type_no_function ')'
    931931                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    932932        | 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 ) ) ) ); }
    934934        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    935935                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
  • src/ResolvExpr/CandidateFinder.cpp

    r5c6d439 rb6f2e7ab  
    14821482
    14831483        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 );
    15051488        }
    15061489
     
    15371520
    15381521        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 );
    15611526        }
    15621527
  • src/ResolvExpr/Unify.cpp

    r5c6d439 rb6f2e7ab  
    234234                        if ( !e2so ) return;
    235235
    236                         assert((e1->type != nullptr) ^ (e1->expr != nullptr));
    237                         assert((e2so->type != nullptr) ^ (e2so->expr != nullptr));
    238                         if ( !(e1->type && e2so->type) ) return;
    239 
    240236                        // expression unification calls type unification (mutual recursion)
    241237                        result = unifyExact( e1->type, e2so->type, tenv, need, have, open, widen );
  • src/Validate/InitializerLength.cpp

    r5c6d439 rb6f2e7ab  
    2929///   int x[] = { 1, 2, 3 };
    3030///   int y[][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
     31///   char z[] = "hello";
    3132/// here x and y are known at compile-time to have length 3, so change this into
    3233///   int x[3] = { 1, 2, 3 };
    3334///   int y[3][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
     35///   char z[6] = "hello";
    3436struct InitializerLength {
    3537        const ast::ObjectDecl * previsit( const ast::ObjectDecl * decl );
    3638};
    3739
     40ast::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
    3857const ast::ObjectDecl * InitializerLength::previsit( const ast::ObjectDecl * decl ) {
    3958        if ( auto type = decl->type.as<ast::ArrayType>() ) {
    4059                if ( type->dimension ) return decl;
    41                 if ( auto init = decl->init.as<ast::ListInit>() ) {
     60                if ( auto dimension = makeDimension( decl ) ) {
    4261                        ast::ObjectDecl * mutDecl = ast::mutate( decl );
    4362                        ast::ArrayType * mutType = ast::mutate( type );
    44                         mutType->dimension = ast::ConstantExpr::from_ulong(
    45                                 mutDecl->location, init->size() );
     63                        mutType->dimension = dimension;
    4664                        mutDecl->type = mutType;
    4765                        return mutDecl;
  • tests/.expect/alloc-ERROR.txt

    r5c6d439 rb6f2e7ab  
    1111    ...to:
    1212      Name: dim
    13       Sizeof Expression on: Applying untyped:
     13      Sizeof Expression on: type-of expression Applying untyped:
    1414          Name: *?
    1515        ...to:
  • tests/.expect/extension.arm64.txt

    r5c6d439 rb6f2e7ab  
    465465    }
    466466    {
    467         ((void)__extension__ sizeof(3));
     467        ((void)__extension__ sizeof(signed int ));
    468468    }
    469469
     
    473473
    474474    {
    475         ((void)__extension__ __alignof__(__extension__ _X1ai_2));
     475        ((void)__extension__ __alignof__(signed int ));
    476476    }
    477477
  • tests/.expect/extension.x64.txt

    r5c6d439 rb6f2e7ab  
    465465    }
    466466    {
    467         ((void)__extension__ sizeof(3));
     467        ((void)__extension__ sizeof(signed int ));
    468468    }
    469469
     
    473473
    474474    {
    475         ((void)__extension__ __alignof__(__extension__ _X1ai_2));
     475        ((void)__extension__ __alignof__(signed int ));
    476476    }
    477477
  • tests/.expect/extension.x86.txt

    r5c6d439 rb6f2e7ab  
    465465    }
    466466    {
    467         ((void)__extension__ sizeof(3));
     467        ((void)__extension__ sizeof(signed int ));
    468468    }
    469469
     
    473473
    474474    {
    475         ((void)__extension__ __alignof__(__extension__ _X1ai_2));
     475        ((void)__extension__ __alignof__(signed int ));
    476476    }
    477477
Note: See TracChangeset for help on using the changeset viewer.