Changes in / [4117761:3c55fcd]
- Location:
- src
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.cpp
r4117761 r3c55fcd 203 203 } 204 204 205 bool EnumDecl::isTyped() const { return base;}206 207 bool EnumDecl::isOpague() const { return isCfa && !isTyped(); }208 205 } 209 206 -
src/AST/Decl.hpp
r4117761 r3c55fcd 308 308 class EnumDecl final : public AggregateDecl { 309 309 public: 310 // is Cfaindicated if the enum has a declaration like:310 // isTyped indicated if the enum has a declaration like: 311 311 // enum (type_optional) Name {...} 312 bool is Cfa;313 // if is Cfa == true && base.get() == nullptr, it is a "opague"enum312 bool isTyped; 313 // if isTyped == true && base.get() == nullptr, it is a "void" type enum 314 314 ptr<Type> base; 315 315 enum class EnumHiding { Visible, Hide } hide; 316 316 std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums 317 317 318 EnumDecl( const CodeLocation& loc, const std::string& name, bool is Cfa= false,318 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 319 319 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, 320 320 Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide, 321 321 std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() ) 322 : AggregateDecl( loc, name, std::move(attrs), linkage ), is Cfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}322 : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {} 323 323 324 324 /// gets the integer value for this enumerator, returning true iff value found … … 336 336 337 337 bool isSubTypeOf(const ast::EnumDecl *) const; 338 bool isTyped() const;339 bool isOpague() const;340 338 private: 341 339 EnumDecl * clone() const override { return new EnumDecl{ *this }; } -
src/AST/Stmt.hpp
r4117761 r3c55fcd 238 238 ptr<Expr> inc; 239 239 ptr<Expr> range_over; 240 bool is_inc;241 240 ptr<Stmt> body; 242 241 ptr<Stmt> else_; … … 252 251 range_over(nullptr), body(body), else_(else_) {} 253 252 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, 255 254 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_) {} 258 256 259 257 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } -
src/ControlStruct/TranslateEnumRange.cpp
r4117761 r3c55fcd 26 26 auto enumDecl = enumInst->base; 27 27 28 auto objInit = stmt->inits.front();28 auto init = stmt->inits.front(); 29 29 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>()) { 35 31 auto decl = declStmt->decl; 36 32 if ( auto objDecl = decl.as<ast::ObjectDecl>()) { … … 61 57 if ( !objDecl->init ) { 62 58 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 ) ); 67 60 auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit ); 68 61 auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit ); … … 85 78 auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>(); 86 79 auto enumDecl = enumInst->base; 87 88 // Both inc and dec check if the current posn less than the number of enumerator89 // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,90 // it wraps around and become unsigned max91 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 ) });98 80 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 }); 103 89 auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment ); 104 90 auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition ); -
src/Parser/StatementNode.cpp
r4117761 r3c55fcd 216 216 return new ast::ForStmt( location, 217 217 std::move( astinit ), 218 range_over, forctl->kind == OperKinds::LThan,218 range_over, 219 219 buildMoveSingle( stmt ), 220 220 buildMoveOptional( else_ ) -
src/Parser/StatementNode.hpp
r4117761 r3c55fcd 64 64 ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) : 65 65 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 ) {} 68 68 69 69 StatementNode * init; … … 71 71 ExpressionNode * change; 72 72 ExpressionNode * range_over; 73 OperKinds kind;74 73 }; 75 74 -
src/Parser/TypeData.cpp
r4117761 r3c55fcd 1469 1469 ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member ); 1470 1470 object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide; 1471 if ( ret->is Opague()&& cur->has_enumeratorValue() ) {1472 SemanticError( td->location, " Opaguecannot 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." ); 1473 1473 } else if ( cur->has_enumeratorValue() ) { 1474 1474 object->init = new ast::SingleInit( -
src/Parser/parser.yy
r4117761 r3c55fcd 279 279 DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) ); 280 280 assert( range_over_expr ); 281 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr , compop);281 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr ); 282 282 } else { 283 283 SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr; -
src/ResolvExpr/CandidateFinder.cpp
r4117761 r3c55fcd 698 698 void postvisit( const ast::CountExpr * countExpr ); 699 699 700 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src, 701 const ast::EnumInstType * dst 702 , const ast::Expr * expr, Cost minCost ); 703 700 704 void postvisit( const ast::InitExpr * ) { 701 705 assertf( false, "CandidateFinder should never see a resolved InitExpr." ); … … 1209 1213 } 1210 1214 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 1211 1258 void Finder::postvisit( const ast::CastExpr * castExpr ) { 1212 1259 ast::ptr< ast::Type > toType = castExpr->result; … … 1262 1309 auto argAsEnum = cand->expr->result.as<ast::EnumInstType>(); 1263 1310 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); 1267 1313 cand->expr = offsetExpr; 1268 1314 } … … 2147 2193 expr->location, 2148 2194 "?+?", 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)}); 2154 2197 CandidateFinder finder(context, env); 2155 2198 finder.find( untyped ); -
src/ResolvExpr/CastCost.cpp
r4117761 r3c55fcd 53 53 void postvisit( const ast::EnumInstType * enumInst ) { 54 54 cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env ); 55 56 if ( !enumInst->base->isCfa ) {57 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };58 Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );59 cost = intCost < cost? intCost: cost;60 } else if ( enumInst->base->isTyped() ) {61 auto baseConversionCost =62 castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );63 cost = baseConversionCost < cost? baseConversionCost: cost;64 }65 55 } 66 56 … … 73 63 cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env ); 74 64 if ( Cost::unsafe < cost ) { 75 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 76 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; 77 68 } 78 69 } … … 83 74 cost = conversionCost( zero, dst, srcIsLvalue, symtab, env ); 84 75 if ( Cost::unsafe < cost ) { 85 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {86 cost = Cost::unsafe;76 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 77 if (enumInst->base->isTyped) cost = Cost::unsafe; 87 78 } 88 79 } … … 92 83 cost = conversionCost( one, dst, srcIsLvalue, symtab, env ); 93 84 if ( Cost::unsafe < cost ) { 94 if ( dynamic_cast<const ast::EnumInstType *>(dst)) {95 cost = Cost::unsafe;85 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 86 if (enumInst->base->isTyped) cost = Cost::unsafe; 96 87 } 97 88 } -
src/ResolvExpr/CommonType.cpp
r4117761 r3c55fcd 386 386 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 387 387 const ast::EnumDecl* enumDecl = enumInst->base; 388 if ( !enumDecl-> isCfa) {388 if ( !enumDecl->base ) { 389 389 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; 390 390 if ( … … 642 642 const ast::EnumDecl* argDecl = argAsEnumInst->base; 643 643 if (argDecl->isSubTypeOf(paramDecl)) result = param; 644 } else if ( param->base && !param->base->is Cfa) {644 } else if ( param->base && !param->base->isTyped ) { 645 645 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 646 646 result = commonType( basicType, type2, tenv, need, have, open, widen); -
src/ResolvExpr/ConversionCost.cpp
r4117761 r3c55fcd 162 162 Cost conversionCost( 163 163 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env 165 165 ) { 166 166 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) { … … 235 235 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost ); 236 236 } 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 }243 237 } else { 244 238 assert( -1 == diff ); 245 239 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 246 240 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 ) ) { 253 242 if ( srcIsLvalue ) { 254 243 if ( src->qualifiers == dstAsRef->base->qualifiers ) { … … 295 284 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 296 285 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 297 } 298 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Cfa) {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; 300 289 } 301 290 } … … 377 366 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 378 367 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(); 384 379 } 385 380 … … 459 454 // assuming 0p is supposed to be used for pointers? 460 455 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 461 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Cfa) {462 cost = Cost:: safe;456 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) { 457 cost = Cost::unsafe; 463 458 } 464 459 } … … 480 475 } 481 476 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Cfa) {483 cost = Cost:: safe;477 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) { 478 cost = Cost::unsafe; 484 479 } 485 480 } -
src/ResolvExpr/Unify.cpp
r4117761 r3c55fcd 276 276 void postvisit( const ast::VoidType * ) { 277 277 result = dynamic_cast< const ast::VoidType * >( type2 ); 278 // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden()); 279 ; 278 280 } 279 281 … … 282 284 result = basic->kind == basic2->kind; 283 285 } 286 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden()); 284 287 } 285 288 … … 290 293 noWiden()); 291 294 } 295 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden()); 292 296 } 293 297 … … 308 312 result = unifyExact( 309 313 array->base, array2->base, tenv, need, have, open, noWiden()); 314 // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden()); 310 315 } 311 316 … … 602 607 603 608 result = unifyList( types, types2, tenv, need, have, open ); 609 // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden()); 604 610 } 605 611 606 612 void postvisit( const ast::VarArgsType * ) { 607 613 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 614 // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden()); 608 615 } 609 616 610 617 void postvisit( const ast::ZeroType * ) { 611 618 result = dynamic_cast< const ast::ZeroType * >( type2 ); 619 // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden()); 612 620 } 613 621 614 622 void postvisit( const ast::OneType * ) { 615 623 result = dynamic_cast< const ast::OneType * >( type2 ); 624 // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden()); 616 625 } 617 626 }; -
src/Validate/ImplementEnumFunc.cpp
r4117761 r3c55fcd 476 476 477 477 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) { 478 if (!enumDecl->body || !enumDecl->is Cfa) return;478 if (!enumDecl->body || !enumDecl->isTyped) return; 479 479 ast::EnumInstType enumInst(enumDecl->name); 480 480 enumInst.base = enumDecl;
Note: See TracChangeset
for help on using the changeset viewer.