Changeset bc07190
- Timestamp:
- Jun 29, 2024, 7:33:28 AM (9 months ago)
- Branches:
- master
- Children:
- 011c29e
- Parents:
- 62a38e7 (diff), 115ac1ce (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified libcfa/src/enum.cfa ¶
r62a38e7 rbc07190 4 4 #pragma GCC visibility push(default) 5 5 6 forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) 7 ostype & ?|?(ostype& os, E e) { 8 return os | type_name(e) | "." | label(e); 6 forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) { 7 ostype & ?|?( ostype& os, E e ) { 8 return os | label( e ); 9 } 10 OSTYPE_VOID_IMPL( E ) 9 11 } 10 12 11 forall( ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void))12 ostype & ?|?( ostype& os, E e) {13 return os | type_name(e) | "." | label(e);13 forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) ) 14 ostype & ?|?( ostype & os, E e ) { 15 return os | label( e ); 14 16 } 15 17 16 forall( ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {18 forall( E, V | CfaEnum(E, V) ) { // relational operators 17 19 int ?==?(E l, E r) { return posn(l) == posn(r); } 20 int ?!=?(E l, E r) { return posn(l) != posn(r); } 21 int ?<?(E l, E r) { return posn(l) < posn(r); } 18 22 int ?<=?(E l, E r) { return posn(l) <= posn(r); } 23 int ?>?(E l, E r) { return posn(l) > posn(r); } 19 24 int ?>=?(E l, E r) { return posn(l) >= posn(r); } 20 int ?<?(E l, E r) { return posn(l) < posn(r); }21 int ?>?(E l, E r) { return posn(l) > posn(r); }22 25 } -
TabularUnified libcfa/src/enum.hfa ¶
r62a38e7 rbc07190 3 3 #include "iostream.hfa" 4 4 5 forall( E) trait Bounded {5 forall( E ) trait Bounded { 6 6 E lowerBound(); 7 7 E upperBound(); 8 8 }; 9 9 10 forall( E | Bounded(E)) trait Serial {11 unsigned fromInstance( E e);12 E fromInt( unsigned i);13 E succ( E e);14 E pred( E e);10 forall( E | Bounded(E) ) trait Serial { 11 unsigned fromInstance( E e ); 12 E fromInt( unsigned i ); 13 E succ( E e ); 14 E pred( E e ); 15 15 }; 16 16 17 17 // Design one 18 forall(E, V | Serial(E)) trait CfaEnum { 19 char * label(E e); 20 unsigned int posn(E e); 21 V value(E e); 22 char * type_name(E e); 18 forall( E, V | Serial(E) ) trait CfaEnum { 19 char * label( E e ); 20 unsigned int posn( E e ); 21 V value( E e ); 23 22 }; 24 23 25 forall(ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V)) 26 ostype & ?|?(ostype&, E); 24 // I/O 27 25 28 forall(ostype & | basic_ostream(ostype), E| CfaEnum(E, quasi_void)) 29 ostype & ?|?(ostype&, E); 26 forall( ostype & | basic_ostream(ostype), E, V | CfaEnum(E, V) ) { 27 ostype & ?|?( ostype &, E ); 28 OSTYPE_VOID( E ); 29 } 30 31 forall( ostype & | basic_ostream(ostype), E | CfaEnum(E, quasi_void) ) 32 ostype & ?|?( ostype &, E ); 30 33 31 34 // Design two <- should go for this if we have change the cost model … … 39 42 // }; 40 43 41 forall( ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {44 forall( E, V | CfaEnum(E, V) ) { // relational operators 42 45 int ?==?(E, E); 46 int ?!=?(E, E); 47 int ?<?(E, E); 43 48 int ?<=?(E, E); 49 int ?>?(E, E); 44 50 int ?>=?(E, E); 45 int ?<?(E, E);46 int ?>?(E, E);47 48 // E ++?( E & lhs );49 // E ?++( E & lhs );50 51 } -
TabularUnified src/AST/Decl.cpp ¶
r62a38e7 rbc07190 203 203 } 204 204 205 bool EnumDecl::isTyped() const { return base;} 206 207 bool EnumDecl::isOpague() const { return isCfa && !isTyped(); } 205 208 } 206 209 -
TabularUnified src/AST/Decl.hpp ¶
r62a38e7 rbc07190 308 308 class EnumDecl final : public AggregateDecl { 309 309 public: 310 // is Typedindicated if the enum has a declaration like:310 // isCfa indicated if the enum has a declaration like: 311 311 // enum (type_optional) Name {...} 312 bool is Typed;313 // if is Typed == true && base.get() == nullptr, it is a "void" typeenum312 bool isCfa; 313 // if isCfa == true && base.get() == nullptr, it is a "opague" 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 Typed= false,318 EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = 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 Typed(isTyped), base(base), hide(hide), enumValues(enumValues) {}322 : AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), 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; 338 340 private: 339 341 EnumDecl * clone() const override { return new EnumDecl{ *this }; } -
TabularUnified src/AST/Stmt.hpp ¶
r62a38e7 rbc07190 238 238 ptr<Expr> inc; 239 239 ptr<Expr> range_over; 240 bool is_inc; 240 241 ptr<Stmt> body; 241 242 ptr<Stmt> else_; … … 251 252 range_over(nullptr), body(body), else_(else_) {} 252 253 253 ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, 254 ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc, 254 255 const Stmt * body, const Stmt * else_ ) 255 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {} 256 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc), 257 body(body), else_(else_) {} 256 258 257 259 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } -
TabularUnified src/Common/Stats/Heap.cpp ¶
r62a38e7 rbc07190 21 21 #include <iostream> 22 22 23 #if defined(__has_feature) 23 // Most of the other statistics features are deactivated only by defining 24 // NO_STATISTICS (or their NO_%_STATISTICS macro). However the heap has some 25 // other compatability concerns and will disable itself in some cases. 26 // 27 // I do not claim to understand these cases. But TCMALLOC is often defined by 28 // default and you can pass --disable-gprofiler to configure to remove it. 29 30 #if defined(NO_STATISTICS) || defined(TCMALLOC) || defined(__SANITIZE_ADDRESS__) 31 #define NO_HEAP_STATISTICS 32 #elif defined(__has_feature) 24 33 #if __has_feature(address_sanitizer) 25 #define NO_HEAP_STATISTICS26 # endif27 #endif28 29 #if defined( NO_STATISTICS ) || defined( TCMALLOC ) || defined(__SANITIZE_ADDRESS__)30 #if !defined(NO_HEAP_STATISTICS)31 34 #define NO_HEAP_STATISTICS 32 35 #endif -
TabularUnified src/ControlStruct/TranslateEnumRange.cpp ¶
r62a38e7 rbc07190 26 26 auto enumDecl = enumInst->base; 27 27 28 auto init = stmt->inits.front();28 auto objInit = stmt->inits.front(); 29 29 30 if (auto declStmt = init.as<ast::DeclStmt>()) { 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>()) { 31 35 auto decl = declStmt->decl; 32 36 if ( auto objDecl = decl.as<ast::ObjectDecl>()) { … … 57 61 if ( !objDecl->init ) { 58 62 auto location = stmt->location; 59 auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) ); 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 ) ); 60 67 auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit ); 61 68 auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit ); … … 78 85 auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>(); 79 86 auto enumDecl = enumInst->base; 87 88 // Both inc and dec check if the current posn less than the number of enumerator 89 // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow, 90 // it wraps around and become unsigned max 91 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 ) }); 80 98 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 }); 99 auto increment = ast::UntypedExpr::createCall( location, 100 stmt->is_inc? "?++": "?--", 101 { new ast::NameExpr( location, indexName ) }); 102 89 103 auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment ); 90 104 auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition ); -
TabularUnified src/Parser/StatementNode.cpp ¶
r62a38e7 rbc07190 216 216 return new ast::ForStmt( location, 217 217 std::move( astinit ), 218 range_over, 218 range_over, forctl->kind == OperKinds::LThan, 219 219 buildMoveSingle( stmt ), 220 220 buildMoveOptional( else_ ) -
TabularUnified src/Parser/StatementNode.hpp ¶
r62a38e7 rbc07190 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) :67 init( decl ), condition( nullptr ), change( nullptr ), range_over( _range_over) {}66 ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) : 67 init( decl ), condition( nullptr ), change( nullptr ), range_over( range_over ), kind( kind ) {} 68 68 69 69 StatementNode * init; … … 71 71 ExpressionNode * change; 72 72 ExpressionNode * range_over; 73 OperKinds kind; 73 74 }; 74 75 -
TabularUnified src/Parser/TypeData.cpp ¶
r62a38e7 rbc07190 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 Typed && !ret->base&& cur->has_enumeratorValue() ) {1472 SemanticError( td->location, " Enumerator of enum(void)cannot have an explicit initializer value." );1471 if ( ret->isOpague() && cur->has_enumeratorValue() ) { 1472 SemanticError( td->location, "Opague cannot have an explicit initializer value." ); 1473 1473 } else if ( cur->has_enumeratorValue() ) { 1474 1474 object->init = new ast::SingleInit( -
TabularUnified src/Parser/lex.ll ¶
r62a38e7 rbc07190 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu Jun 2 0 16:54:05202413 * Update Count : 7 7812 * Last Modified On : Thu Jun 27 14:38:27 2024 13 * Update Count : 780 14 14 */ 15 15 … … 458 458 459 459 "@=" { NAMEDOP_RETURN(ATassign); } // CFA 460 "+~" { NAMEDOP_RETURN(ErangeUp); } // CFA 460 461 "~=" { NAMEDOP_RETURN(ErangeUpEq); } // CFA 462 "+~=" { NAMEDOP_RETURN(ErangeUpEq); } // CFA 461 463 "-~" { NAMEDOP_RETURN(ErangeDown); } // CFA 462 464 "-~=" { NAMEDOP_RETURN(ErangeDownEq); } // CFA -
TabularUnified src/Parser/parser.yy ¶
r62a38e7 rbc07190 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 24 22:45:20202413 // Update Count : 6 68412 // Last Modified On : Thu Jun 27 14:45:57 2024 13 // Update Count : 6705 14 14 // 15 15 … … 224 224 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 225 225 #define MISSING_ANON_FIELD "illegal syntax, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." 226 #define MISSING_LOW "illegal syntax, missing low value for up-to range so index is uninitialized." 227 #define MISSING_HIGH "illegal syntax, missing high value for down-to range so index is uninitialized." 228 229 static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, enum OperKinds compop, 230 ExpressionNode * comp, ExpressionNode * inc ) { 226 #define MISSING_LOW "illegal syntax, missing low value for ascanding range so index is uninitialized." 227 #define MISSING_HIGH "illegal syntax, missing high value for descending range so index is uninitialized." 228 229 static ForCtrl * makeForCtrl( const CodeLocation & location, DeclarationNode * init, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 231 230 // Wrap both comp/inc if they are non-null. 232 231 if ( comp ) comp = new ExpressionNode( build_binary_val( location, … … 243 242 } 244 243 245 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enumOperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {244 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 246 245 if ( index->initializer ) { 247 246 SemanticError( yylloc, "illegal syntax, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 254 253 } // forCtrl 255 254 256 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enumOperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {255 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 257 256 ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get()); 258 257 if ( constant && (constant->rep == "0" || constant->rep == "1") ) { … … 268 267 #define MISSING_LOOP_INDEX "illegal syntax, only a single identifier or declaration allowed in initialization, e.g., for ( i; ... ) or for ( int i; ... ). Expression disallowed." 269 268 270 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enumOperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {269 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 271 270 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) { 272 271 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc ); 273 // } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {274 // if ( auto identifier = commaExpr->arg2.as<ast::NameExpr>() ) {275 // return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );276 // } else {277 // SemanticError( yylloc, "illegal syntax, loop-index name missing. Expression disallowed." ); return nullptr;278 // } // if279 272 } else { 280 273 SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr; … … 282 275 } // forCtrl 283 276 284 ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, ExpressionNode * range_over_expr ) {277 ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, __attribute__((unused)) OperKinds compop, ExpressionNode * range_over_expr ) { 285 278 if ( auto identifier = dynamic_cast<ast::NameExpr *>(index_expr->expr.get()) ) { 286 279 DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) ); 287 280 assert( range_over_expr ); 288 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr ); 289 // } else if (auto commaExpr = dynamic_cast<ast::CommaExpr *>( index_expr->expr.get() )) { 290 // if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) { 291 // assert( range_over_expr ); 292 // DeclarationNode * indexDecl = distAttr( 293 // DeclarationNode::newTypeof( range_over_expr, true ), 294 // DeclarationNode::newName( new std::string( identifier->name) ) ); 295 // return new ForCtrl( new StatementNode( indexDecl ), range_over_expr ); 296 // } else { 297 // SemanticError( yylloc, "illegal syntax, loop-index name missing. Comma expression disallowed." ); return nullptr; 298 // } // if 281 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop ); 299 282 } else { 300 283 SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr; … … 426 409 %token ANDassign ERassign ORassign // &= ^= |= 427 410 428 %token ErangeUp Eq ErangeDown ErangeDownEq //~= -~ -~=411 %token ErangeUp ErangeUpEq ErangeDown ErangeDownEq // +~ +~=/~= -~ -~= 429 412 %token ATassign // @= 430 413 … … 1522 1505 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; } 1523 1506 1507 // These rules accept a comma_expression for the initialization, when only an identifier is correct. Being 1508 // permissive allows for a better error message from forCtrl. 1524 1509 | comma_expression ';' comma_expression // CFA 1525 1510 { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); } … … 1541 1526 } 1542 1527 | comma_expression ';' '@' updowneq '@' // CFA, invalid syntax rule 1543 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-torange so index is uninitialized." ); $$ = nullptr; }1528 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; } 1544 1529 1545 1530 | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA … … 1570 1555 } 1571 1556 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA 1572 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-torange so index is uninitialized." ); $$ = nullptr; }1557 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; } 1573 1558 1574 1559 | declaration comma_expression // CFA … … 1618 1603 } 1619 1604 | declaration '@' updowneq '@' '~' '@' // CFA, invalid syntax rule 1620 { SemanticError( yylloc, "illegal syntax, missing low/high value for up/down-torange so index is uninitialized." ); $$ = nullptr; }1605 { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; } 1621 1606 1622 1607 | comma_expression ';' enum_key // CFA, enum type 1623 1608 { 1624 $$ = enumRangeCtrl( $1, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );1609 $$ = enumRangeCtrl( $1, OperKinds::LEThan, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) ); 1625 1610 } 1626 1611 | comma_expression ';' downupdowneq enum_key // CFA, enum type, reverse direction 1627 1612 { 1628 if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { 1629 SemanticError( yylloc, "illegal syntax, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; 1630 } 1631 SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr; 1613 if ( $3 == OperKinds::GThan ) { 1614 SemanticError( yylloc, "all enumeration ranges are equal (all values). Add an equal, e.g., ~=, -~=." ); $$ = nullptr; 1615 $3 = OperKinds::GEThan; 1616 } // if 1617 $$ = enumRangeCtrl( $1, $3, new ExpressionNode( new ast::TypeExpr( yylloc, $4->buildType() ) ) ); 1632 1618 } 1633 1619 ; … … 1642 1628 ; 1643 1629 1630 // This rule exists to handle the ambiguity with unary operator '~'. The rule is the same as updowneq minus the '~'. 1631 // Specifically, "for ( ~5 )" means the complement of 5, not loop 0..4. Hence, in this case "for ( ~= 5 )", i.e., 0..5, 1632 // it is not possible to just remove the '='. The entire '~=' must be removed. 1644 1633 downupdowneq: 1645 ErangeDown 1634 ErangeUp 1635 { $$ = OperKinds::LThan; } 1636 | ErangeDown 1646 1637 { $$ = OperKinds::GThan; } 1647 1638 | ErangeUpEq … … 1652 1643 1653 1644 updown: 1654 '~' 1645 '~' // shorthand 0 ~ 10 => 0 +~ 10 1646 { $$ = OperKinds::LThan; } 1647 | ErangeUp 1655 1648 { $$ = OperKinds::LThan; } 1656 1649 | ErangeDown -
TabularUnified src/ResolvExpr/CandidateFinder.cpp ¶
r62a38e7 rbc07190 698 698 void postvisit( const ast::CountExpr * countExpr ); 699 699 700 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,701 const ast::EnumInstType * dst702 , const ast::Expr * expr, Cost minCost );703 704 700 void postvisit( const ast::InitExpr * ) { 705 701 assertf( false, "CandidateFinder should never see a resolved InitExpr." ); … … 1213 1209 } 1214 1210 1215 // src is a subset of dst1216 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 1258 1211 void Finder::postvisit( const ast::CastExpr * castExpr ) { 1259 1212 ast::ptr< ast::Type > toType = castExpr->result; … … 1309 1262 auto argAsEnum = cand->expr->result.as<ast::EnumInstType>(); 1310 1263 auto toAsEnum = toType.as<ast::EnumInstType>(); 1311 if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) { 1312 ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost); 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); 1313 1267 cand->expr = offsetExpr; 1314 1268 } … … 2193 2147 expr->location, 2194 2148 "?+?", 2195 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ), 2196 ast::ConstantExpr::from_int(expr->location, offset)}); 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)} ); 2197 2154 CandidateFinder finder(context, env); 2198 2155 finder.find( untyped ); -
TabularUnified src/ResolvExpr/CastCost.cpp ¶
r62a38e7 rbc07190 53 53 void postvisit( const ast::EnumInstType * enumInst ) { 54 54 cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env ); 55 if ( enumInst->base->isTyped() ) { 56 auto baseConversionCost = 57 castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env ); 58 cost = baseConversionCost < cost? baseConversionCost: cost; 59 } 60 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 61 Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 62 intCost.incSafe(); 63 cost = intCost < cost? intCost: cost; 55 64 } 56 65 … … 63 72 cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env ); 64 73 if ( Cost::unsafe < cost ) { 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; 74 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 75 cost = Cost::unsafe; 68 76 } 69 77 } … … 74 82 cost = conversionCost( zero, dst, srcIsLvalue, symtab, env ); 75 83 if ( Cost::unsafe < cost ) { 76 if ( auto enumInst =dynamic_cast<const ast::EnumInstType *>(dst)) {77 if (enumInst->base->isTyped)cost = Cost::unsafe;84 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 85 cost = Cost::unsafe; 78 86 } 79 87 } … … 83 91 cost = conversionCost( one, dst, srcIsLvalue, symtab, env ); 84 92 if ( Cost::unsafe < cost ) { 85 if ( auto enumInst =dynamic_cast<const ast::EnumInstType *>(dst)) {86 if (enumInst->base->isTyped)cost = Cost::unsafe;93 if ( dynamic_cast<const ast::EnumInstType *>(dst)) { 94 cost = Cost::unsafe; 87 95 } 88 96 } -
TabularUnified src/ResolvExpr/CommonType.cpp ¶
r62a38e7 rbc07190 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-> base) {388 if ( !enumDecl->isCfa ) { 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 Typed) {644 } else if ( param->base && !param->base->isCfa ) { 645 645 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 646 646 result = commonType( basicType, type2, tenv, need, have, open, widen); -
TabularUnified src/ResolvExpr/ConversionCost.cpp ¶
r62a38e7 rbc07190 162 162 Cost conversionCost( 163 163 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue, 164 164 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 } 237 243 } else { 238 244 assert( -1 == diff ); 239 245 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst ); 240 246 assert( dstAsRef ); 241 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) { 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 ) ) { 242 253 if ( srcIsLvalue ) { 243 254 if ( src->qualifiers == dstAsRef->base->qualifiers ) { … … 284 295 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) { 285 296 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 286 } 287 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {288 cost = Cost:: unsafe;297 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 298 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 299 cost = Cost::safe; 289 300 } 290 301 } … … 366 377 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 367 378 cost = enumCastCost(inst, dstInst, symtab, env); 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(); 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(); 379 384 } 380 385 … … 454 459 // assuming 0p is supposed to be used for pointers? 455 460 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 456 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {457 cost = Cost:: unsafe;461 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 462 cost = Cost::safe; 458 463 } 459 464 } … … 475 480 } 476 481 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 477 if ( dstAsEnumInst->base && !dstAsEnumInst->base->is Typed) {478 cost = Cost:: unsafe;482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) { 483 cost = Cost::safe; 479 484 } 480 485 } -
TabularUnified src/ResolvExpr/Unify.cpp ¶
r62a38e7 rbc07190 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 ;280 278 } 281 279 … … 284 282 result = basic->kind == basic2->kind; 285 283 } 286 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());287 284 } 288 285 … … 293 290 noWiden()); 294 291 } 295 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());296 292 } 297 293 … … 312 308 result = unifyExact( 313 309 array->base, array2->base, tenv, need, have, open, noWiden()); 314 // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());315 310 } 316 311 … … 607 602 608 603 result = unifyList( types, types2, tenv, need, have, open ); 609 // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());610 604 } 611 605 612 606 void postvisit( const ast::VarArgsType * ) { 613 607 result = dynamic_cast< const ast::VarArgsType * >( type2 ); 614 // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());615 608 } 616 609 617 610 void postvisit( const ast::ZeroType * ) { 618 611 result = dynamic_cast< const ast::ZeroType * >( type2 ); 619 // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());620 612 } 621 613 622 614 void postvisit( const ast::OneType * ) { 623 615 result = dynamic_cast< const ast::OneType * >( type2 ); 624 // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());625 616 } 626 617 }; -
TabularUnified src/Validate/ImplementEnumFunc.cpp ¶
r62a38e7 rbc07190 476 476 477 477 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) { 478 if (!enumDecl->body || !enumDecl->is Typed) return;478 if (!enumDecl->body || !enumDecl->isCfa) return; 479 479 ast::EnumInstType enumInst(enumDecl->name); 480 480 enumInst.base = enumDecl;
Note: See TracChangeset
for help on using the changeset viewer.