Changes in / [bc07190:62a38e7]


Ignore:
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/enum.cfa

    rbc07190 r62a38e7  
    44#pragma GCC visibility push(default)
    55
    6 forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) {
    7         ostype & ?|?( ostype& os, E e ) {
    8                 return os | label( e );
    9         }
    10         OSTYPE_VOID_IMPL( E )
     6forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V))
     7ostype & ?|?(ostype& os, E e) {
     8    return os | type_name(e) | "." | label(e);
    119}
    1210
    13 forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
    14 ostype & ?|?( ostype & os, E e ) {
    15     return os | label( e );
     11forall(ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void))
     12ostype & ?|?(ostype& os, E e) {
     13    return os | type_name(e) | "." | label(e);
    1614}
    1715
    18 forall( E, V | CfaEnum(E, V) ) {                                                // relational operators
     16forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
    1917    int ?==?(E l, E r) { return posn(l) == posn(r); }
    20     int ?!=?(E l, E r) { return posn(l) != posn(r); }
     18    int ?<=?(E l, E r) { return posn(l) <= posn(r); }
     19    int ?>=?(E l, E r) { return posn(l) >= posn(r); }
    2120    int ?<?(E l, E r) { return posn(l) < posn(r); }
    22     int ?<=?(E l, E r) { return posn(l) <= posn(r); }
    2321    int ?>?(E l, E r) { return posn(l) > posn(r); }
    24     int ?>=?(E l, E r) { return posn(l) >= posn(r); }
    2522}
  • libcfa/src/enum.hfa

    rbc07190 r62a38e7  
    33#include "iostream.hfa"
    44
    5 forall( E ) trait Bounded {
     5forall(E) trait Bounded {
    66    E lowerBound();
    77    E upperBound();
    88};
    99
    10 forall( E | Bounded(E) ) trait Serial {
    11     unsigned fromInstance( E e );
    12     E fromInt( unsigned i );
    13     E succ( E e );
    14     E pred( E e );
     10forall(E | Bounded(E)) trait Serial {
     11    unsigned fromInstance(E e);
     12    E fromInt(unsigned i);
     13    E succ(E e);
     14    E pred(E e);
    1515};
    1616
    1717// Design one
    18 forall( E, V | Serial(E) ) trait CfaEnum {
    19     char * label( E e );
    20     unsigned int posn( E e );
    21     V value( E e );
     18forall(E, V | Serial(E)) trait CfaEnum {
     19    char * label(E e);
     20    unsigned int posn(E e);
     21    V value(E e);
     22    char * type_name(E e);
    2223};
    2324
    24 // I/O
     25forall(ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V))
     26ostype & ?|?(ostype&, E);
    2527
    26 forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) {
    27         ostype & ?|?( ostype &, E );
    28         OSTYPE_VOID( E );
    29 }
    30 
    31 forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) )
    32 ostype & ?|?( ostype &, E );
     28forall(ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void))
     29ostype & ?|?(ostype&, E);
    3330
    3431// Design two <- should go for this if we have change the cost model
     
    4239// };
    4340
    44 forall( E, V | CfaEnum(E, V) ) {                                                // relational operators
     41forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
    4542    int ?==?(E, E);
    46     int ?!=?(E, E);
     43    int ?<=?(E, E);
     44    int ?>=?(E, E);
    4745    int ?<?(E, E);
    48     int ?<=?(E, E);
    4946    int ?>?(E, E);
    50     int ?>=?(E, E);
     47
     48        // E ++?( E & lhs );
     49        // E ?++( E & lhs );
    5150}
  • src/AST/Decl.cpp

    rbc07190 r62a38e7  
    203203}
    204204
    205 bool EnumDecl::isTyped() const { return base;}
    206 
    207 bool EnumDecl::isOpague() const { return isCfa && !isTyped(); }
    208205}
    209206
  • src/AST/Decl.hpp

    rbc07190 r62a38e7  
    308308class EnumDecl final : public AggregateDecl {
    309309public:
    310         // isCfa indicated if the enum has a declaration like:
     310        // isTyped indicated if the enum has a declaration like:
    311311        // enum (type_optional) Name {...}
    312         bool isCfa;
    313         // if isCfa == true && base.get() == nullptr, it is a "opague" enum
     312        bool isTyped;
     313        // if isTyped == true && base.get() == nullptr, it is a "void" type enum
    314314        ptr<Type> base;
    315315        enum class EnumHiding { Visible, Hide } hide;
    316316        std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
    317317
    318         EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
     318        EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
    319319                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
    320320                Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
    321321                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
    322         : AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
     322        : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
    323323
    324324        /// gets the integer value for this enumerator, returning true iff value found
     
    336336
    337337        bool isSubTypeOf(const ast::EnumDecl *) const;
    338         bool isTyped() const;
    339         bool isOpague() const;
    340338private:
    341339        EnumDecl * clone() const override { return new EnumDecl{ *this }; }
  • src/AST/Stmt.hpp

    rbc07190 r62a38e7  
    238238        ptr<Expr> inc;
    239239        ptr<Expr> range_over;
    240         bool is_inc;
    241240        ptr<Stmt> body;
    242241        ptr<Stmt> else_;
     
    252251                        range_over(nullptr), body(body), else_(else_) {}
    253252
    254         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
     253        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
    255254                         const Stmt * body, const Stmt * else_ )
    256                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
    257                 body(body), else_(else_) {}
     255                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
    258256
    259257        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/Common/Stats/Heap.cpp

    rbc07190 r62a38e7  
    2121#include <iostream>
    2222
    23 // Most of the other statistics features are deactivated only by defining
    24 // NO_STATISTICS (or their NO_%_STATISTICS macro). However the heap has some
    25 // other compatability concerns and will disable itself in some cases.
    26 //
    27 // I do not claim to understand these cases. But TCMALLOC is often defined by
    28 // default and you can pass --disable-gprofiler to configure to remove it.
    29 
    30 #if defined(NO_STATISTICS) || defined(TCMALLOC) || defined(__SANITIZE_ADDRESS__)
    31         #define NO_HEAP_STATISTICS
    32 #elif defined(__has_feature)
     23#if defined(__has_feature)
    3324        #if __has_feature(address_sanitizer)
     25                #define NO_HEAP_STATISTICS
     26        # endif
     27#endif
     28
     29#if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)
     30        #if !defined(NO_HEAP_STATISTICS)
    3431                #define NO_HEAP_STATISTICS
    3532        #endif
  • src/ControlStruct/TranslateEnumRange.cpp

    rbc07190 r62a38e7  
    2626        auto enumDecl = enumInst->base;
    2727
    28         auto objInit = stmt->inits.front();
     28        auto init = stmt->inits.front();
    2929
    30         auto initLocation = objInit->location;
    31         auto rangeLocation = stmt->range_over->location;
    32         assert( stmt->inits.size() == 1 );
    33 
    34         if (auto declStmt = objInit.as<ast::DeclStmt>()) {
     30        if (auto declStmt = init.as<ast::DeclStmt>()) {
    3531            auto decl = declStmt->decl;
    3632            if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
     
    6157                if ( !objDecl->init ) {
    6258                    auto location = stmt->location;
    63                     ast::SingleInit * newInit;
    64                     newInit = new ast::SingleInit( location,
    65                         new ast::NameExpr( location,
    66                         stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
     59                    auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
    6760                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6861                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    8578    auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    8679    auto enumDecl = enumInst->base;
    87    
    88     // Both inc and dec check if the current posn less than the number of enumerator
    89     // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
    90     // it wraps around and become unsigned max
    91     ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
    92         "?<=?",
    93         {new ast::CastExpr(location,
    94             new ast::NameExpr( location, indexName ),
    95             new ast::BasicType( ast::BasicKind::UnsignedInt ),
    96             ast::GeneratedFlag::ExplicitCast),
    97         ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 ) });
    9880
    99     auto increment = ast::UntypedExpr::createCall( location,
    100         stmt->is_inc? "?++": "?--",
    101         { new ast::NameExpr( location, indexName ) });
    102    
     81    auto condition = ast::UntypedExpr::createCall( location, "?<=?", {
     82        new ast::NameExpr( location, indexName ),
     83        // ast::ConstantExpr::from_ulong( location, enumDecl->members.size() )
     84        new ast::NameExpr( location, enumDecl->members.back()->name )
     85    });
     86    auto increment = ast::UntypedExpr::createCall( location, "succ", {
     87        new ast::NameExpr( location, indexName )
     88    });
    10389    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    10490    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • src/Parser/StatementNode.cpp

    rbc07190 r62a38e7  
    216216                return new ast::ForStmt( location,
    217217                        std::move( astinit ),
    218                         range_over, forctl->kind == OperKinds::LThan,
     218                        range_over,
    219219                        buildMoveSingle( stmt ),
    220220                        buildMoveOptional( else_ )
  • src/Parser/StatementNode.hpp

    rbc07190 r62a38e7  
    6464        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    6565                init( stmt ), condition( condition ), change( change ), range_over( nullptr ) {}
    66         ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) :
    67                 init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
    6868
    6969        StatementNode * init;
     
    7171        ExpressionNode * change;
    7272        ExpressionNode * range_over;
    73         OperKinds kind;
    7473};
    7574
  • src/Parser/TypeData.cpp

    rbc07190 r62a38e7  
    14691469                ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
    14701470                object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide;
    1471                 if ( ret->isOpague() && cur->has_enumeratorValue() ) {
    1472                         SemanticError( td->location, "Opague cannot have an explicit initializer value." );
     1471                if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
     1472                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
    14731473                } else if ( cur->has_enumeratorValue() ) {
    14741474                        object->init = new ast::SingleInit(
  • src/Parser/lex.ll

    rbc07190 r62a38e7  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Jun 27 14:38:27 2024
    13  * Update Count     : 780
     12 * Last Modified On : Thu Jun 20 16:54:05 2024
     13 * Update Count     : 778
    1414 */
    1515
     
    458458
    459459"@="                    { NAMEDOP_RETURN(ATassign); }                   // CFA
    460 "+~"                    { NAMEDOP_RETURN(ErangeUp); }                   // CFA
    461460"~="                    { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
    462 "+~="                   { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
    463461"-~"                    { NAMEDOP_RETURN(ErangeDown); }                 // CFA
    464462"-~="                   { NAMEDOP_RETURN(ErangeDownEq); }               // CFA
  • src/Parser/parser.yy

    rbc07190 r62a38e7  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 27 14:45:57 2024
    13 // Update Count     : 6705
     12// Last Modified On : Mon Jun 24 22:45:20 2024
     13// Update Count     : 6684
    1414//
    1515
     
    224224#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    225225#define MISSING_ANON_FIELD "illegal syntax, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
    226 #define MISSING_LOW "illegal syntax, missing low value for ascanding range so index is uninitialized."
    227 #define MISSING_HIGH "illegal syntax, missing high value for descending range so index is uninitialized."
    228 
    229 static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     226#define MISSING_LOW "illegal syntax, missing low value for up-to range so index is uninitialized."
     227#define MISSING_HIGH "illegal syntax, missing high value for down-to range so index is uninitialized."
     228
     229static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, enum OperKinds compop,
     230                                                          ExpressionNode * comp, ExpressionNode * inc ) {
    230231        // Wrap both comp/inc if they are non-null.
    231232        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
     
    242243}
    243244
    244 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     245ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    245246        if ( index->initializer ) {
    246247                SemanticError( yylloc, "illegal syntax, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    253254} // forCtrl
    254255
    255 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     256ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    256257        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
    257258        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     
    267268#define MISSING_LOOP_INDEX "illegal syntax, only a single identifier or declaration allowed in initialization, e.g., for ( i; ... ) or for ( int i; ... ). Expression disallowed."
    268269
    269 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     270ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    270271        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
    271272                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     273        // } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
     274        //      if ( auto identifier = commaExpr->arg2.as<ast::NameExpr>() ) {
     275        //              return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     276        //      } else {
     277        //              SemanticError( yylloc, "illegal syntax, loop-index name missing. Expression disallowed." ); return nullptr;
     278        //      } // if
    272279        } else {
    273280                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
     
    275282} // forCtrl
    276283
    277 ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, __attribute__((unused)) OperKinds compop, ExpressionNode * range_over_expr ) {
     284ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, ExpressionNode * range_over_expr ) {
    278285        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index_expr->expr.get()) ) {
    279286                DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
    280287                assert( range_over_expr );
    281                 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
     288                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
     289        // } else if (auto commaExpr = dynamic_cast<ast::CommaExpr *>( index_expr->expr.get() )) {
     290        //      if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     291        //              assert( range_over_expr );
     292        //              DeclarationNode * indexDecl = distAttr(
     293        //                      DeclarationNode::newTypeof( range_over_expr, true ),
     294        //                      DeclarationNode::newName( new std::string( identifier->name) ) );
     295        //              return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
     296        //      } else {
     297        //              SemanticError( yylloc, "illegal syntax, loop-index name missing. Comma expression disallowed." ); return nullptr;
     298        //      } // if
    282299        } else {
    283300                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
     
    409426%token ANDassign        ERassign        ORassign                                // &=   ^=      |=
    410427
    411 %token ErangeUp         ErangeUpEq      ErangeDown      ErangeDownEq // +~      +~=/~=  -~      -~=
     428%token ErangeUpEq       ErangeDown      ErangeDownEq                    // ~=   -~      -~=
    412429%token ATassign                                                                                 // @=
    413430
     
    15051522                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    15061523
    1507                 // These rules accept a comma_expression for the initialization, when only an identifier is correct. Being
    1508                 // permissive allows for a better error message from forCtrl.
    15091524        | comma_expression ';' comma_expression                         // CFA
    15101525                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     
    15261541                }
    15271542        | comma_expression ';' '@' updowneq '@'                         // CFA, invalid syntax rule
    1528                 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
     1543                { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    15291544
    15301545        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
     
    15551570                }
    15561571        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1557                 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
     1572                { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    15581573
    15591574        | declaration comma_expression                                          // CFA
     
    16031618                }
    16041619        | declaration '@' updowneq '@' '~' '@'                          // CFA, invalid syntax rule
    1605                 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
     1620                { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    16061621
    16071622        | comma_expression ';' enum_key                                         // CFA, enum type
    16081623                {
    1609                         $$ = enumRangeCtrl( $1, OperKinds::LEThan, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );
     1624                        $$ = enumRangeCtrl( $1, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );
    16101625                }
    16111626        | comma_expression ';' downupdowneq enum_key            // CFA, enum type, reverse direction
    16121627                {
    1613                         if ( $3 == OperKinds::GThan ) {
    1614                                 SemanticError( yylloc, "all enumeration ranges are equal (all values). Add an equal, e.g., ~=, -~=." ); $$ = nullptr;
    1615                                 $3 = OperKinds::GEThan;
    1616                         } // if
    1617                         $$ = enumRangeCtrl( $1, $3, new ExpressionNode( new ast::TypeExpr( yylloc, $4->buildType() ) ) );
     1628                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) {
     1629                                SemanticError( yylloc, "illegal syntax, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr;
     1630                        }
     1631                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    16181632                }
    16191633        ;
     
    16281642        ;
    16291643
    1630 // This rule exists to handle the ambiguity with unary operator '~'. The rule is the same as updowneq minus the '~'.
    1631 // Specifically, "for ( ~5 )" means the complement of 5, not loop 0..4. Hence, in this case "for ( ~= 5 )", i.e., 0..5,
    1632 // it is not possible to just remove the '='. The entire '~=' must be removed.
    16331644downupdowneq:
    1634         ErangeUp
    1635                 { $$ = OperKinds::LThan; }
    1636         | ErangeDown
     1645        ErangeDown
    16371646                { $$ = OperKinds::GThan; }
    16381647        | ErangeUpEq
     
    16431652
    16441653updown:
    1645         '~'                                                                                                     // shorthand 0 ~ 10 => 0 +~ 10
    1646                 { $$ = OperKinds::LThan; }
    1647         | ErangeUp
     1654        '~'
    16481655                { $$ = OperKinds::LThan; }
    16491656        | ErangeDown
  • src/ResolvExpr/CandidateFinder.cpp

    rbc07190 r62a38e7  
    698698                void postvisit( const ast::CountExpr * countExpr );
    699699
     700                const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,
     701                        const ast::EnumInstType * dst
     702                        , const ast::Expr * expr, Cost minCost );
     703
    700704                void postvisit( const ast::InitExpr * ) {
    701705                        assertf( false, "CandidateFinder should never see a resolved InitExpr." );
     
    12091213        }
    12101214
     1215        // src is a subset of dst
     1216        const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src,
     1217                const ast::EnumInstType * dst,
     1218                const ast::Expr * expr,
     1219                Cost minCost ) {
     1220               
     1221                auto srcDecl = src->base;
     1222                auto dstDecl = dst->base;
     1223
     1224                if (srcDecl->name == dstDecl->name) return expr;
     1225
     1226                for (auto& dstChild: dstDecl->inlinedDecl) {
     1227                        Cost c = castCost(src, dstChild, false, symtab, tenv);
     1228                        ast::CastExpr * castToDst;
     1229                        if (c<minCost) {
     1230                                unsigned offset = dstDecl->calChildOffset(dstChild.get());
     1231                                if (offset > 0) {
     1232                                        auto untyped = ast::UntypedExpr::createCall(
     1233                                                expr->location,
     1234                                                "?+?",
     1235                                                { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
     1236                                                ast::ConstantExpr::from_int(expr->location, offset)});
     1237                                        CandidateFinder finder(context, tenv);
     1238                                        finder.find( untyped );
     1239                                        CandidateList winners = findMinCost( finder.candidates );
     1240                                        CandidateRef & choice = winners.front();
     1241                                        // choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
     1242                                        choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
     1243                                        // castToDst = new ast::CastExpr(choice->expr, dstChild);
     1244                                        castToDst = new ast::CastExpr(
     1245                                                makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
     1246                                         dst);
     1247
     1248                                } else {
     1249                                        castToDst = new ast::CastExpr( expr, dst );
     1250                                }
     1251                                return castToDst;
     1252                        }
     1253                }
     1254                SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
     1255                return nullptr;
     1256        }
     1257
    12111258        void Finder::postvisit( const ast::CastExpr * castExpr ) {
    12121259                ast::ptr< ast::Type > toType = castExpr->result;
     
    12621309                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    12631310                        auto toAsEnum = toType.as<ast::EnumInstType>();
    1264                         if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
    1265                                 CandidateFinder subFinder(context, tenv);
    1266                                 ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
     1311                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {     
     1312                                ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
    12671313                                cand->expr = offsetExpr;
    12681314                        }
     
    21472193                                        expr->location,
    21482194                                        "?+?",
    2149                                         { new ast::CastExpr( expr->location,
    2150                                                 expr,
    2151                                                 new ast::BasicType(ast::BasicKind::SignedInt),
    2152                                                 ast::GeneratedFlag::ExplicitCast ),
    2153                                                 ast::ConstantExpr::from_int(expr->location, offset)} );
     2195                                        { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
     2196                                        ast::ConstantExpr::from_int(expr->location, offset)});
    21542197                                CandidateFinder finder(context, env);
    21552198                                finder.find( untyped );
  • src/ResolvExpr/CastCost.cpp

    rbc07190 r62a38e7  
    5353                void postvisit( const ast::EnumInstType * enumInst ) {
    5454                        cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
    55                         if ( enumInst->base->isTyped() ) {
    56                                 auto baseConversionCost =
    57                                         castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
    58                                 cost = baseConversionCost < cost? baseConversionCost: cost;
    59                         }
    60                         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    61                         Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    62                         intCost.incSafe();
    63                         cost = intCost < cost? intCost: cost;
    6455                }
    6556
     
    7263                                cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env );
    7364                                if ( Cost::unsafe < cost ) {
    74                                         if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    75                                                 cost = Cost::unsafe;
     65                                        if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
     66                                                // Always explict cast only for typed enum
     67                                                if (enumInst->base->isTyped) cost = Cost::unsafe;
    7668                                        }
    7769                                }
     
    8274                        cost = conversionCost( zero, dst, srcIsLvalue, symtab, env );
    8375                        if ( Cost::unsafe < cost ) {
    84                                 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    85                                         cost = Cost::unsafe;
     76                                if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
     77                                        if (enumInst->base->isTyped) cost = Cost::unsafe;
    8678                                }
    8779                        }
     
    9183                        cost = conversionCost( one, dst, srcIsLvalue, symtab, env );
    9284                        if ( Cost::unsafe < cost ) {
    93                                 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {
    94                                         cost = Cost::unsafe;
     85                                if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {
     86                                        if (enumInst->base->isTyped) cost = Cost::unsafe;
    9587                                }
    9688                        }
  • src/ResolvExpr/CommonType.cpp

    rbc07190 r62a38e7  
    386386                } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    387387                        const ast::EnumDecl* enumDecl = enumInst->base;
    388                         if ( !enumDecl->isCfa ) {
     388                        if ( !enumDecl->base ) {
    389389                                ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ];
    390390                                if (
     
    642642                        const ast::EnumDecl* argDecl = argAsEnumInst->base;
    643643                        if (argDecl->isSubTypeOf(paramDecl)) result = param;
    644                 } else if ( param->base && !param->base->isCfa ) {
     644                } else if ( param->base && !param->base->isTyped ) {
    645645                        auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
    646646                        result = commonType( basicType, type2, tenv, need, have, open, widen);
  • src/ResolvExpr/ConversionCost.cpp

    rbc07190 r62a38e7  
    162162Cost conversionCost(
    163163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     164        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
    165165) {
    166166        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    235235                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
    236236                }
    237                 if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
    238                         if (srcAsInst->base && !srcAsInst->base->isCfa) {
    239                                 static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
    240                                 return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
    241                         }
    242                 }
    243237        } else {
    244238                assert( -1 == diff );
    245239                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    246240                assert( dstAsRef );
    247                 auto dstBaseType = dstAsRef->base;
    248                 const ast::Type * newSrc = src;
    249                 if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
    250                         newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
    251                 }
    252                 if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
     241                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
    253242                        if ( srcIsLvalue ) {
    254243                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
     
    295284        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    296285                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    297         } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    298                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    299                         cost = Cost::safe;
     286        }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     287                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     288                        cost = Cost::unsafe;
    300289                }
    301290        }
     
    377366        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
    378367                cost = enumCastCost(inst, dstInst, symtab, env);
    379         } else if ( !inst->base->isCfa ) {
    380                 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    381                 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    382         }
    383         // cost.incUnsafe();
     368                return;
     369        }
     370        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     371        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     372        if ( !inst->base->isTyped ) {
     373                if ( cost < Cost::unsafe ) {
     374                        cost.incSafe();
     375                }
     376                return;
     377        }
     378        cost.incUnsafe();
    384379}
    385380
     
    459454                // assuming 0p is supposed to be used for pointers?
    460455        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    461                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    462                         cost = Cost::safe;
     456                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     457                        cost = Cost::unsafe;
    463458                }
    464459        }
     
    480475                }
    481476        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    482                 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
    483                         cost = Cost::safe;
     477                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
     478                        cost = Cost::unsafe;
    484479                }
    485480        }
  • src/ResolvExpr/Unify.cpp

    rbc07190 r62a38e7  
    276276        void postvisit( const ast::VoidType * ) {
    277277                result = dynamic_cast< const ast::VoidType * >( type2 );
     278                        // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
     279                ;
    278280        }
    279281
     
    282284                        result = basic->kind == basic2->kind;
    283285                }
     286                // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    284287        }
    285288
     
    290293                                noWiden());
    291294                }
     295                // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    292296        }
    293297
     
    308312                result = unifyExact(
    309313                        array->base, array2->base, tenv, need, have, open, noWiden());
     314                        // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    310315        }
    311316
     
    602607
    603608                result = unifyList( types, types2, tenv, need, have, open );
     609                        // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    604610        }
    605611
    606612        void postvisit( const ast::VarArgsType * ) {
    607613                result = dynamic_cast< const ast::VarArgsType * >( type2 );
     614                        // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    608615        }
    609616
    610617        void postvisit( const ast::ZeroType * ) {
    611618                result = dynamic_cast< const ast::ZeroType * >( type2 );
     619                        // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    612620        }
    613621
    614622        void postvisit( const ast::OneType * ) {
    615623                result = dynamic_cast< const ast::OneType * >( type2 );
     624                        // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    616625        }
    617626};
  • src/Validate/ImplementEnumFunc.cpp

    rbc07190 r62a38e7  
    476476
    477477void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) {
    478         if (!enumDecl->body || !enumDecl->isCfa) return;
     478        if (!enumDecl->body || !enumDecl->isTyped) return;
    479479        ast::EnumInstType enumInst(enumDecl->name);
    480480        enumInst.base = enumDecl;
Note: See TracChangeset for help on using the changeset viewer.