Changeset 8bb86ce


Ignore:
Timestamp:
Jan 13, 2023, 4:29:57 PM (15 months ago)
Author:
JiadaL <j82liang@…>
Branches:
ADT, ast-experimental, master
Children:
d61d034
Parents:
8fcf921
Message:

Clean up some code related to Enum codegen

Files:
2 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r8fcf921 r8bb86ce  
    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
    275297        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    276298                extension( enumDecl );
    277299                std::list< Declaration* > &memb = enumDecl->get_members();
    278300                if (enumDecl->base && ! memb.empty()) {
    279                         unsigned long long last_val = -1; // if the first enum value has no explicit initializer,
    280                         // as other
     301                        long long cur_val = 0;
    281302                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    282303                                ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
     
    284305                                output << "static ";
    285306                                output << genType(enumDecl->base, mangleName( obj ), 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                                 }
     307                                genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options);
    306308                                output << ";" << endl;
    307309                        } // for
  • src/Parser/TypeData.cc

    r8fcf921 r8bb86ce  
    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)->isWholeNumber())) {
     935                        if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
    936936                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    937937                        }
  • src/SynTree/BasicType.cc

    r8fcf921 r8bb86ce  
    2929}
    3030
    31 bool 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 
    4831bool BasicType::isInteger() const {
    4932        return kind <= UnsignedInt128;
  • src/SynTree/Type.h

    r8fcf921 r8bb86ce  
    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;
    274273        bool isInteger() const;
    275274};
  • tests/enum_tests/.expect/typedIntEnum.txt

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

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

    r8fcf921 r8bb86ce  
    1212
    1313int main() {
    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);
     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);
    2121    return 0;
    2222}
Note: See TracChangeset for help on using the changeset viewer.