Changes in / [d61d034:42b739d7]
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rd61d034 r42b739d7 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 initiazatior280 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_val285 Expression* expr = ((SingleInit *)(init))->value;286 while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast287 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 + 1292 output << " = " << "(" << genType(baseType, "", options) << ")";293 output << (*cur_val)++;294 }295 }296 297 275 void CodeGenerator::postvisit( EnumDecl * enumDecl ) { 298 276 extension( enumDecl ); 299 277 std::list< Declaration* > &memb = enumDecl->get_members(); 300 278 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 302 281 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 303 282 ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i ); … … 305 284 output << "static "; 306 285 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 } 308 306 output << ";" << endl; 309 307 } // for -
src/Parser/TypeData.cc
rd61d034 r42b739d7 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 Integer())) {935 if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) { 936 936 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 937 937 } -
src/SynTree/BasicType.cc
rd61d034 r42b739d7 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 31 48 bool BasicType::isInteger() const { 32 49 return kind <= UnsignedInt128; -
src/SynTree/Type.h
rd61d034 r42b739d7 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; 273 274 bool isInteger() const; 274 275 }; -
tests/enum_tests/.expect/typedIntEnum.txt
rd61d034 r42b739d7 1 0 =02 1 =13 1000 =10004 1001 =10015 2000 =20006 2001 =20017 2002 =20021 0 2 1 3 1000 4 1001 5 2000 6 2001 7 2002 -
tests/enum_tests/pointerEnum.cfa
rd61d034 r42b739d7 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
rd61d034 r42b739d7 12 12 13 13 int 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); 21 21 return 0; 22 22 }
Note:
See TracChangeset
for help on using the changeset viewer.