Changeset 8bb86ce
- Timestamp:
- Jan 13, 2023, 4:29:57 PM (5 months ago)
- Branches:
- ADT, master
- Children:
- d61d034
- Parents:
- 8fcf921
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r8fcf921 r8bb86ce 273 273 } 274 274 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 275 297 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 276 298 extension( enumDecl ); 277 299 std::list< Declaration* > &memb = enumDecl->get_members(); 278 300 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; 281 302 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 282 303 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); … … 284 305 output << "static "; 285 306 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); 306 308 output << ";" << endl; 307 309 } // for -
src/Parser/TypeData.cc
r8fcf921 r8bb86ce 933 933 member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) ); 934 934 } else if ( !cur->initializer ) { 935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->is WholeNumber())) {935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) { 936 936 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 937 937 } -
src/SynTree/BasicType.cc
r8fcf921 r8bb86ce 29 29 } 30 30 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 48 31 bool BasicType::isInteger() const { 49 32 return kind <= UnsignedInt128; -
src/SynTree/Type.h
r8fcf921 r8bb86ce 271 271 virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); } 272 272 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 273 bool isWholeNumber() const;274 273 bool isInteger() const; 275 274 }; -
tests/enum_tests/.expect/typedIntEnum.txt
r8fcf921 r8bb86ce 1 0 2 1 3 1000 4 1001 5 2000 6 2001 7 2002 1 0=0 2 1=1 3 1000=1000 4 1001=1001 5 2000=2000 6 2001=2001 7 2002=2002 -
tests/enum_tests/pointerEnum.cfa
r8fcf921 r8bb86ce 11 11 int main() { 12 12 E * v = First; 13 sout | "v: " | e.x;13 // sout | "v: " | e.x; 14 14 } -
tests/enum_tests/typedIntEnum.cfa
r8fcf921 r8bb86ce 12 12 13 13 int 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); 21 21 return 0; 22 22 }
Note: See TracChangeset
for help on using the changeset viewer.