Changes in / [d61d034:42b739d7]


Ignore:
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rd61d034 r42b739d7  
    273273        }
    274274
    275         template<typename pass_type>
    276         inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output,
    277         Initializer * init, long long * cur_val, Options options) {
    278                 auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr;
    279                 if ( init ) { // If value has an explicit initiazatior
    280                         output << " = ";
    281                         output << "(" << genType(baseType, "", options) << ")";
    282                         init->accept( *visitor );
    283                         if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered,
    284                         // need to update the cur_val
    285                                 Expression* expr = ((SingleInit *)(init))->value;
    286                                 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast
    287                                         expr = temp->arg;
    288                                 }
    289                                 *cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1;
    290                         }
    291                 } else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1
    292                         output << " = " << "(" << genType(baseType, "", options) << ")";
    293                         output << (*cur_val)++;
    294                 }
    295         }
    296 
    297275        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    298276                extension( enumDecl );
    299277                std::list< Declaration* > &memb = enumDecl->get_members();
    300278                if (enumDecl->base && ! memb.empty()) {
    301                         long long cur_val = 0;
     279                        unsigned long long last_val = -1; // if the first enum value has no explicit initializer,
     280                        // as other
    302281                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    303282                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
     
    305284                                output << "static ";
    306285                                output << genType(enumDecl->base, mangleName( obj ), options);
    307                                 genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options);
     286                                output << " = ";
     287                                output << "(" << genType(enumDecl->base, "", options) << ")";
     288                                if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) {
     289                                        if ( obj->get_init() ) {
     290                                                obj->get_init()->accept( *visitor );
     291                                                Expression* expr = ((SingleInit *)(obj->init))->value;
     292                                                while ( auto temp = dynamic_cast<CastExpr *>(expr) ) {
     293                                                        expr = temp->arg;
     294                                                }
     295                                                last_val = ((ConstantExpr *)expr)->constant.get_ival();
     296                                        } else {
     297                                                output << ++last_val;
     298                                        } // if
     299                                } else {
     300                                        if ( obj->get_init() ) {
     301                                                obj->get_init()->accept( *visitor );
     302                                        } else {
     303                                                // Should not reach here!
     304                                        }
     305                                }
    308306                                output << ";" << endl;
    309307                        } // for
  • src/Parser/TypeData.cc

    rd61d034 r42b739d7  
    933933                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    934934                } else if ( !cur->initializer ) {
    935                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
     935                        if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
    936936                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    937937                        }
  • src/SynTree/BasicType.cc

    rd61d034 r42b739d7  
    2929}
    3030
     31bool BasicType::isWholeNumber() const {
     32        return kind == Bool ||
     33                kind ==Char ||
     34                kind == SignedChar ||
     35                kind == UnsignedChar ||
     36                kind == ShortSignedInt ||
     37                kind == ShortUnsignedInt ||
     38                kind == SignedInt ||
     39                kind == UnsignedInt ||
     40                kind == LongSignedInt ||
     41                kind == LongUnsignedInt ||
     42                kind == LongLongSignedInt ||
     43                kind ==LongLongUnsignedInt ||
     44                kind == SignedInt128 ||
     45                kind == UnsignedInt128;
     46}
     47
    3148bool BasicType::isInteger() const {
    3249        return kind <= UnsignedInt128;
  • src/SynTree/Type.h

    rd61d034 r42b739d7  
    271271        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    272272        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     273        bool isWholeNumber() const;
    273274        bool isInteger() const;
    274275};
  • tests/enum_tests/.expect/typedIntEnum.txt

    rd61d034 r42b739d7  
    1 0=0
    2 1=1
    3 1000=1000
    4 1001=1001
    5 2000=2000
    6 2001=2001
    7 2002=2002
     10
     21
     31000
     41001
     52000
     62001
     72002
  • tests/enum_tests/pointerEnum.cfa

    rd61d034 r42b739d7  
    1111int main() {
    1212    E * v = First;
    13     // sout | "v: " | e.x;
     13    sout | "v: " | e.x;
    1414}
  • tests/enum_tests/typedIntEnum.cfa

    rd61d034 r42b739d7  
    1212
    1313int main() {
    14     printf("0=%d\n", zero);
    15     printf("1=%d\n", one);
    16     printf("1000=%d\n", thousand);
    17     printf("1001=%d\n", thousand_one);
    18     printf("2000=%d\n", two_thousand);
    19     printf("2001=%d\n", two_thousand_one);
    20     printf("2002=%d\n", two_thousand_two);
     14    printf("%d\n", zero);
     15    printf("%d\n", one);
     16    printf("%d\n", thousand);
     17    printf("%d\n", thousand_one);
     18    printf("%d\n", two_thousand);
     19    printf("%d\n", two_thousand_one);
     20    printf("%d\n", two_thousand_two);
    2121    return 0;
    2222}
Note: See TracChangeset for help on using the changeset viewer.