Changes in / [0b6c1c9:083e637]
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/enum.cfa
r0b6c1c9 r083e637 1 #include "enum.hfa"2 #include "fstream.hfa"3 4 forall(E, T| TypedEnum(E, T)) {5 // constructors6 7 // comparison8 int ?==?(E l, E r) { return posE(l) == posE(r); }9 int ?!=?(E l, E r) { return !(l == r); }10 int ?!=?(E l, zero_t) { return !( posE(l) == 0 ); }11 int ?<?(E l, E r) { return posE(l) < posE(r); }12 int ?<=?(E l, E r) { return posE(l) <= posE(r); }13 int ?>?(E l, E r) { return posE(l) > posE(r); }14 int ?>=?(E l, E r) { return posE(l) >= posE(r); }15 16 // for testing; To be removed17 // #include <string.h>18 char * typeEnumString(E e) {19 // char* out = malloc(sizeof(char) * (5 + strlen(labelE(e) + 1)));20 // return strcat(strcat(out, "Enum "), labelE(e));21 return labelE(e);22 }23 } -
libcfa/src/enum.hfa
r0b6c1c9 r083e637 6 6 }; 7 7 8 forall(E , T| Bounded(E)) trait Serial {8 forall(E | Bounded(E)) trait Serial { 9 9 unsigned fromInstance(E e); 10 10 E fromInt(unsigned i); … … 13 13 }; 14 14 15 // Opague Enum + TypedEnum 16 forall(E, T | Serial(E, T)) trait CfaEnum { 15 forall(E, T) trait TypedEnum { 16 T valueE(E e); 17 17 char * labelE(E e); 18 18 unsigned int posE(E e); 19 };20 21 forall(E, T | CfaEnum(E, T)) trait TypedEnum {22 T valueE(E e);23 19 }; 24 20 … … 32 28 int ?>?(E l, E r); 33 29 int ?>=?(E l, E r); 34 35 // for testing; To be removed36 char * typeEnumString(E e);37 30 } -
src/ResolvExpr/CandidateFinder.cpp
r0b6c1c9 r083e637 2138 2138 } 2139 2139 2140 // get the valueE(...) ApplicationExpr that returns the enum value 2141 const ast::Expr * getValueEnumCall( 2142 const ast::Expr * expr, 2143 const ResolvExpr::ResolveContext & context, const ast::TypeEnvironment & env ) { 2144 auto callExpr = new ast::UntypedExpr( 2145 expr->location, new ast::NameExpr( expr->location, "valueE"), {expr} ); 2146 CandidateFinder finder( context, env ); 2147 finder.find( callExpr ); 2148 CandidateList winners = findMinCost( finder.candidates ); 2149 if (winners.size() != 1) { 2150 SemanticError( callExpr, "Ambiguous expression in valueE..." ); 2151 } 2152 CandidateRef & choice = winners.front(); 2153 return choice->expr; 2154 } 2155 2140 2156 const ast::Expr * createCondExpr( const ast::Expr * expr ) { 2141 2157 assert( expr ); -
src/ResolvExpr/CandidateFinder.hpp
r0b6c1c9 r083e637 70 70 const ast::Expr * expr, Cost & cost ); 71 71 72 /// Get the valueE application that returns the enum's value. 73 const ast::Expr * getValueEnumCall( const ast::Expr * expr, 74 const ResolveContext & context, const ast::TypeEnvironment & env ); 75 72 76 /// Wrap an expression to convert the result to a conditional result. 73 77 const ast::Expr * createCondExpr( const ast::Expr * expr ); -
src/ResolvExpr/CastCost.cc
r0b6c1c9 r083e637 54 54 cost = conversionCost( basicType, dst, srcIsLvalue, symtab, env ); 55 55 if ( Cost::unsafe < cost ) { 56 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) {57 // Always explict cast only for typed enum58 if (enumInst->base->isTyped)cost = Cost::unsafe;56 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 57 assert(enumInst->base->base); 58 cost = Cost::unsafe; 59 59 } 60 60 } … … 63 63 64 64 void postvisit( const ast::ZeroType * zero ) { 65 // auto ptr = dynamic_cast< const ast::PointerType * >( dst ); 66 // if ( ptr && basicType->isInteger() ) { 67 // // needed for, e.g. unsigned long => void * 68 // cost = Cost::unsafe; 69 // } else { 65 70 cost = conversionCost( zero, dst, srcIsLvalue, symtab, env ); 66 71 if ( Cost::unsafe < cost ) { 67 72 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 68 if (enumInst->base->isTyped) cost = Cost::unsafe; 73 assert(enumInst->base->base); 74 cost = Cost::unsafe; 69 75 } 70 76 } 77 // } 71 78 } 72 79 73 80 void postvisit( const ast::OneType * one ) { 81 // auto ptr = dynamic_cast< const ast::PointerType * >( dst ); 82 // if ( ptr && basicType->isInteger() ) { 83 // // needed for, e.g. unsigned long => void * 84 // cost = Cost::unsafe; 85 // } else { 74 86 cost = conversionCost( one, dst, srcIsLvalue, symtab, env ); 75 87 if ( Cost::unsafe < cost ) { 76 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 77 if (enumInst->base->isTyped) cost = Cost::unsafe; 88 if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(dst)) { 89 assert(enumInst->base->base); 90 cost = Cost::unsafe; 78 91 } 79 92 } 93 // } 80 94 } 81 95 -
src/ResolvExpr/CommonType.cc
r0b6c1c9 r083e637 650 650 651 651 void postvisit( const ast::EnumInstType * enumInst ) { 652 if ( enumInst->base && !enumInst->base-> isTyped) {652 if ( enumInst->base && !enumInst->base->base ) { 653 653 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 654 654 result = commonType( basicType, type2, tenv, need, have, open, widen); -
src/ResolvExpr/ConversionCost.cc
r0b6c1c9 r083e637 283 283 cost = costCalc( basicType, integer, srcIsLvalue, symtab, env ); 284 284 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 285 if ( dstAsEnumInst->base && !dstAsEnumInst->base-> isTyped) {285 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 286 286 cost = Cost::unsafe; 287 287 } … … 480 480 // assuming 0p is supposed to be used for pointers? 481 481 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 482 if ( dstAsEnumInst->base && !dstAsEnumInst->base-> isTyped) {482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 483 483 cost = Cost::unsafe; 484 484 } … … 501 501 } 502 502 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 503 if ( dstAsEnumInst->base && !dstAsEnumInst->base-> isTyped) {503 if ( dstAsEnumInst->base && !dstAsEnumInst->base->base ) { 504 504 cost = Cost::unsafe; 505 505 } -
src/Validate/ImplementEnumFunc.cpp
r0b6c1c9 r083e637 28 28 proto_linkage{ast::Linkage::Cforall} {} 29 29 30 void genAttrFunctions(); 31 void genSuccPredPosn(); 32 // void genSuccPredDecl(); 33 34 void appendReturnThis(ast::FunctionDecl* decl) { 35 assert(1 <= decl->params.size()); 36 assert(1 == decl->returns.size()); 37 assert(decl->stmts); 38 39 const CodeLocation& location = (decl->stmts->kids.empty()) 40 ? decl->stmts->location 41 : decl->stmts->kids.back()->location; 42 const ast::DeclWithType* thisParam = decl->params.front(); 43 decl->stmts.get_and_mutate()->push_back(new ast::ReturnStmt( 44 location, new ast::VariableExpr(location, thisParam))); 45 } 46 void genAttrStandardFuncs() { 47 ast::FunctionDecl* (EnumAttrFuncGenerator::*standardProtos[4])() 48 const = {&EnumAttrFuncGenerator::genCtorProto, 49 &EnumAttrFuncGenerator::genCopyProto, 50 &EnumAttrFuncGenerator::genDtorProto, 51 &EnumAttrFuncGenerator::genAssignProto}; 52 for (auto& generator : standardProtos) { 53 ast::FunctionDecl* decl = (this->*generator)(); 54 produceForwardDecl(decl); 55 genFuncBody(decl); 56 if (CodeGen::isAssignment(decl->name)) { 57 appendReturnThis(decl); 58 } 59 produceDecl(decl); 60 } 61 } 62 30 63 private: 31 64 const CodeLocation& getLocation() const { return decl->location; } … … 40 73 const ast::Decl* getDecl() const { return decl; } 41 74 42 // Implement Bounded trait 43 void genBoundedFunctions(); 44 ast::FunctionDecl* genBoundedProto(const char *) const; 45 void genBoundedBody(ast::FunctionDecl* func) const; 46 47 // Implement Serial trait 75 // Implement Bounded trait for enum 76 void genBoundedFunctions(); 77 // Implement Serial trait for enum 48 78 void genSerialTraitFuncs(); 49 ast::FunctionDecl* genFromIntProto() const; 50 ast::FunctionDecl* genFromInstanceProto() const; 51 ast::FunctionDecl* genInstToInstFuncProto(const char* func) const; 52 void genFromIntBody(ast::FunctionDecl *) const; 53 void genFromInstanceBody(ast::FunctionDecl *) const; 54 void genSuccPredBody(ast::FunctionDecl *, const char *) const; 55 56 // Implement TypedEnum trait 57 void genTypedEnumFuncs(); 58 void genTypedEnumFunction(const ast::EnumAttribute attr); 79 80 // Bounded trait 81 ast::FunctionDecl* genLowerBoundProto() const; 82 ast::FunctionDecl* genUpperBoundProto() const; 83 void genLowerBoundBody(ast::FunctionDecl* func) const; 84 void genUpperBoundBody(ast::FunctionDecl* func) const; 85 59 86 ast::FunctionDecl* genPosnProto() const; 60 87 ast::FunctionDecl* genLabelProto() const; 61 88 ast::FunctionDecl* genValueProto() const; 62 void genValueOrLabelBody( 63 ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const; 64 void genPosnBody(ast::FunctionDecl* func) const; 65 89 90 // Serial trait 91 ast::FunctionDecl* genFromIntProto() const; 92 ast::FunctionDecl* genFromInstanceProto() const; 93 ast::FunctionDecl* genSuccProto() const; 94 ast::FunctionDecl* genPredProto() const; 95 96 void genFromIntBody(ast::FunctionDecl *) const; 97 void genFromInstanceBody(ast::FunctionDecl *) const; 66 98 //////////////// 99 100 ast::FunctionDecl* genSuccPosProto() const; 101 ast::FunctionDecl* genPredPosProto() const; 67 102 68 103 // --------------------------------------------------- … … 86 121 } 87 122 123 /// E = EnumAttrType<T>` 124 /// `void ?{}(E & _dst)`. 125 ast::FunctionDecl* genCtorProto() const { 126 return genProto("?{}", {dstParam()}, {}); 127 } 128 129 /// void ?{}(E & _dst, E _src)`. 130 ast::FunctionDecl* genCopyProto() const { 131 return genProto("?{}", {dstParam(), srcParam()}, {}); 132 } 133 134 ///`void ^?{}(E & _dst)`. 135 ast::FunctionDecl* genDtorProto() const { 136 // The destructor must be mutex on a concurrent type. 137 return genProto("^?{}", {dstParam()}, {}); 138 } 139 140 /// `E ?{}(E & _dst, E _src)`. 141 ast::FunctionDecl* genAssignProto() const { 142 // Only the name is different, so just reuse the generation function. 143 auto retval = srcParam(); 144 retval->name = "_ret"; 145 return genProto("?=?", {dstParam(), srcParam()}, {retval}); 146 } 147 148 void genFuncBody(ast::FunctionDecl* func) { 149 const CodeLocation& location = func->location; 150 auto& params = func->params; 151 if (InitTweak::isCopyConstructor(func) || 152 InitTweak::isAssignment(func)) { 153 assert(2 == params.size()); 154 auto dstParam = params.front().strict_as<ast::ObjectDecl>(); 155 auto srcParam = params.back().strict_as<ast::ObjectDecl>(); 156 func->stmts = genCopyBody(location, dstParam, srcParam); 157 } else { 158 assert(1 == params.size()); 159 // Default constructor and destructor is empty. 160 func->stmts = new ast::CompoundStmt(location); 161 // Add unused attribute to parameter to silence warnings. 162 addUnusedAttribute(params.front()); 163 164 // Just an extra step to make the forward and declaration match. 165 if (forwards.empty()) return; 166 ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>( 167 forwards.back().get_and_mutate()); 168 addUnusedAttribute(fwd->params.front()); 169 } 170 } 171 172 const ast::CompoundStmt* genCopyBody( const CodeLocation& location, 173 const ast::ObjectDecl* dstParam, const ast::ObjectDecl* srcParam) { 174 return new ast::CompoundStmt( 175 location, 176 {new ast::ExprStmt( 177 location, 178 new ast::UntypedExpr( 179 location, new ast::NameExpr(location, "__builtin_memcpy"), 180 { 181 new ast::AddressExpr( location, 182 new ast::VariableExpr( location, dstParam ) ), 183 new ast::AddressExpr( location, 184 new ast::VariableExpr( location, srcParam ) ), 185 new ast::SizeofExpr( location, srcParam->type ), 186 }))}); 187 } 188 189 void genDtorBody(ast::FunctionDecl* func) { 190 const CodeLocation& location = func->location; 191 auto& params = func->params; 192 assert(1 == params.size()); 193 func->stmts = new ast::CompoundStmt(location); 194 addUnusedAttribute(params.front()); 195 196 // Just an extra step to make the forward and declaration match. 197 if (forwards.empty()) return; 198 ast::FunctionDecl* fwd = strict_dynamic_cast<ast::FunctionDecl*>( 199 forwards.back().get_and_mutate()); 200 addUnusedAttribute(fwd->params.front()); 201 } 202 203 // ast::FunctionDecl* 88 204 // ---------------------------------------------------- 205 206 ast::FunctionDecl* genSuccPredFunc(bool succ); 89 207 90 208 const ast::Init* getAutoInit(const ast::Init* prev) const; … … 96 214 const ast::EnumAttribute attr, const CodeLocation& location, 97 215 std::vector<ast::ptr<ast::Init>>& inits) const; 216 void genValueOrLabelBody( 217 ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const; 218 void genPosnBody(ast::FunctionDecl* func) const; 219 void genAttributesDecls(const ast::EnumAttribute attr); 98 220 }; 99 221 … … 252 374 } 253 375 254 void EnumAttrFuncGenerator::genSuccPredBody(ast::FunctionDecl * func, const char* opt) const {255 auto params = func->params;256 assert( params.size() == 1 );257 auto param = params.front();258 auto enumToInt = new ast::CastExpr(259 func->location,260 new ast::VariableExpr(func->location, param),261 new ast::BasicType(ast::BasicKind::UnsignedInt),262 ast::GeneratedFlag::ExplicitCast263 );264 ast::UntypedExpr* addOneExpr = ast::UntypedExpr::createCall( func->location,265 opt,266 {enumToInt,267 ast::ConstantExpr::from_int(func->location, 1)}268 );269 auto intToEnum = new ast::CastExpr(270 func->location,271 addOneExpr,272 new ast::EnumInstType( decl ),273 ast::GeneratedFlag::ExplicitCast274 );275 func->stmts = new ast::CompoundStmt(276 func->location, {277 new ast::ReturnStmt(278 func->location,279 intToEnum280 )281 }282 );283 }284 285 286 376 void EnumAttrFuncGenerator::genSerialTraitFuncs() { 287 ast::FunctionDecl * protos[4] = { 288 genFromIntProto(), 289 genFromInstanceProto(), 290 genInstToInstFuncProto("succ"), 291 genInstToInstFuncProto("pred") 292 }; 293 for (auto& proto: protos) produceForwardDecl(proto); 294 genFromIntBody(protos[0]); 295 genFromInstanceBody(protos[1]); 296 genSuccPredBody(protos[2], "?+?"); 297 genSuccPredBody(protos[3], "?-?"); 298 } 299 300 ast::FunctionDecl* EnumAttrFuncGenerator::genInstToInstFuncProto(const char * func) const { 301 return genProto( 302 func, 377 auto fromIntProto = genFromIntProto(); 378 produceForwardDecl(fromIntProto); 379 genFromIntBody(fromIntProto); 380 produceDecl(fromIntProto); 381 382 auto fromInstanceProto = genFromInstanceProto(); 383 produceForwardDecl(fromInstanceProto); 384 genFromInstanceBody(fromInstanceProto); 385 produceDecl(fromInstanceProto); 386 387 auto succProto = genSuccProto(); 388 auto predProto = genPredProto(); 389 produceForwardDecl(succProto); 390 produceForwardDecl(predProto); 391 } 392 393 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccProto() const { 394 return genProto( 395 "succ", 303 396 {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))}, 304 397 {new ast::ObjectDecl(getLocation(), "_ret", … … 306 399 } 307 400 308 ast::FunctionDecl* EnumAttrFuncGenerator::genBoundedProto(const char * func) const { 309 return genProto(func, {}, { 401 ast::FunctionDecl* EnumAttrFuncGenerator::genPredProto() const { 402 return genProto( 403 "pred", 404 {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))}, 405 {new ast::ObjectDecl(getLocation(), "_ret", 406 new ast::EnumInstType(decl))}); 407 } 408 409 ast::FunctionDecl* EnumAttrFuncGenerator::genLowerBoundProto() const { 410 return genProto("lowerBound", {}, { 310 411 new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl)) 311 412 }); 312 413 } 313 414 314 void EnumAttrFuncGenerator::genBoundedBody(ast::FunctionDecl* func) const { 415 ast::FunctionDecl* EnumAttrFuncGenerator::genUpperBoundProto() const { 416 return genProto("upperBound", {}, { 417 new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl)) 418 }); 419 } 420 421 void EnumAttrFuncGenerator::genLowerBoundBody(ast::FunctionDecl* func) const { 315 422 const CodeLocation & loc = func->location; 316 auto mem = func->name=="lowerBound"? decl->members.front() : decl->members.back(); 423 auto mem = decl->members.front(); 424 // auto expr = new ast::QualifiedNameExpr( loc, decl, mem->name ); 425 // expr->result = new ast::EnumInstType( decl ); 317 426 auto expr = new ast::NameExpr( loc, mem->name ); 318 427 func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)}); 319 428 } 320 429 430 void EnumAttrFuncGenerator::genUpperBoundBody(ast::FunctionDecl* func) const { 431 const CodeLocation & loc = func->location; 432 auto mem = decl->members.back(); 433 auto expr = new ast::NameExpr( loc, mem->name ); 434 // expr->result = new ast::EnumInstType( decl ); 435 func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)}); 436 } 437 321 438 void EnumAttrFuncGenerator::genBoundedFunctions() { 322 ast::FunctionDecl * boundedProtos[2] = {genBoundedProto("upperBound"), genBoundedProto("lowerBound")}; 323 for (auto & protos: boundedProtos) { 324 produceForwardDecl(protos); 325 genBoundedBody(protos); 326 produceDecl(protos); 327 } 439 ast::FunctionDecl * upperDecl = genUpperBoundProto(); 440 produceForwardDecl(upperDecl); 441 genUpperBoundBody(upperDecl); 442 produceDecl(upperDecl); 443 444 ast::FunctionDecl * lowerDecl = genLowerBoundProto(); 445 produceForwardDecl(lowerDecl); 446 genLowerBoundBody(lowerDecl); 447 produceDecl(lowerDecl); 328 448 } 329 449 330 450 inline ast::EnumAttrType * getPosnType( const ast::EnumDecl * decl ) { 331 451 return new ast::EnumAttrType(new ast::EnumInstType(decl), ast::EnumAttribute::Posn); 452 } 453 454 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccPosProto() const { 455 return genProto( 456 "_successor_", 457 {new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))}, 458 {new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))} 459 ); 460 } 461 462 ast::FunctionDecl* EnumAttrFuncGenerator::genPredPosProto() const { 463 return genProto( 464 "_predessor_", 465 {new ast::ObjectDecl(getLocation(), "_i", getPosnType(decl))}, 466 {new ast::ObjectDecl(getLocation(), "_ret", getPosnType(decl))} 467 ); 332 468 } 333 469 … … 375 511 } 376 512 377 void EnumAttrFuncGenerator::gen TypedEnumFunction(const ast::EnumAttribute attr) {513 void EnumAttrFuncGenerator::genAttributesDecls(const ast::EnumAttribute attr) { 378 514 if (attr == ast::EnumAttribute::Value || 379 515 attr == ast::EnumAttribute::Label) { 380 // TypedEnum's backing arrays381 516 std::vector<ast::ptr<ast::Init>> inits = 382 517 attr == ast::EnumAttribute::Value ? genValueInit() : genLabelInit(); … … 399 534 } 400 535 401 void EnumAttrFuncGenerator::genTypedEnumFuncs() { 402 if (decl->base) genTypedEnumFunction(ast::EnumAttribute::Value); 403 genTypedEnumFunction(ast::EnumAttribute::Label); 404 genTypedEnumFunction(ast::EnumAttribute::Posn); 536 ast::FunctionDecl* EnumAttrFuncGenerator::genSuccPredFunc(bool succ) { 537 ast::FunctionDecl* funcDecl = succ ? genSuccPosProto() : genPredPosProto(); 538 produceForwardDecl(funcDecl); 539 540 const CodeLocation& location = getLocation(); 541 542 auto& params = funcDecl->params; 543 assert(params.size() == 1); 544 auto param = params.front().strict_as<ast::ObjectDecl>(); 545 546 547 auto rets = funcDecl->returns; 548 assert(params.size() == 1); 549 auto ret = rets.front().strict_as<ast::ObjectDecl>(); 550 auto retType = ret->type.strict_as<ast::EnumAttrType>(); 551 552 auto addOneExpr = ast::UntypedExpr::createCall( location, 553 succ? "?+?": "?-?", 554 {new ast::VariableExpr(location, param), 555 ast::ConstantExpr::from_int(location, 1)} 556 ); 557 558 funcDecl->stmts = new ast::CompoundStmt( 559 location, { 560 new ast::ReturnStmt( 561 location, 562 new ast::CastExpr(location, addOneExpr, retType) 563 ) 564 } 565 ); 566 567 return funcDecl; 568 } 569 570 void EnumAttrFuncGenerator::genAttrFunctions() { 571 genAttributesDecls(ast::EnumAttribute::Value); 572 genAttributesDecls(ast::EnumAttribute::Label); 573 genAttributesDecls(ast::EnumAttribute::Posn); 574 } 575 576 // void EnumAttrFuncGenerator::genSuccPredDecl() { 577 // auto succProto = genSuccProto(); 578 // auto predProto = genPredProto(); 579 580 // produceForwardDecl(succProto); 581 // produceForwardDecl(predProto); 582 // } 583 584 void EnumAttrFuncGenerator::genSuccPredPosn() { 585 ast::FunctionDecl* succ = genSuccPredFunc(true); 586 ast::FunctionDecl* pred = genSuccPredFunc(false); 587 588 produceDecl(succ); 589 produceDecl(pred); 405 590 } 406 591 … … 408 593 std::list<ast::ptr<ast::Decl>>& decls) { 409 594 // Generate the functions (they go into forwards and definitions). 410 genTypedEnumFuncs(); 595 genAttrStandardFuncs(); 596 genAttrFunctions(); 411 597 genSerialTraitFuncs(); 598 genSuccPredPosn(); 599 // problematic 412 600 genBoundedFunctions(); 413 601 // Now export the lists contents. … … 430 618 431 619 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) { 432 if (!enumDecl->body || !enumDecl->isTyped) return; 620 if (!enumDecl->body) return; 621 if (!enumDecl->base) return; 622 433 623 ast::EnumInstType enumInst(enumDecl->name); 434 624 enumInst.base = enumDecl; 625 435 626 EnumAttrFuncGenerator gen(enumDecl, &enumInst, functionNesting); 436 627 gen.generateAndAppendFunctions(declsToAddAfter); -
src/Validate/module.mk
r0b6c1c9 r083e637 53 53 Validate/VerifyCtorDtorAssign.cpp \ 54 54 Validate/VerifyCtorDtorAssign.hpp \ 55 Validate/ReplacePseudoFunc.cpp \ 56 Validate/ReplacePseudoFunc.hpp \ 55 57 Validate/ImplementEnumFunc.cpp \ 56 58 Validate/ImplementEnumFunc.hpp -
src/main.cpp
r0b6c1c9 r083e637 83 83 #include "Validate/ReturnCheck.hpp" // for checkReturnStatements 84 84 #include "Validate/VerifyCtorDtorAssign.hpp" // for verifyCtorDtorAssign 85 #include "Validate/ReplacePseudoFunc.hpp" // for replacePseudoFunc 85 86 #include "Virtual/ExpandCasts.h" // for expandCasts 86 87 #include "Virtual/VirtualDtor.hpp" // for implementVirtDtors … … 382 383 PASS( "Resolve", ResolvExpr::resolve, transUnit ); 383 384 DUMP( exprp, std::move( transUnit ) ); 385 PASS( "Replace Pseudo Func", Validate::replacePseudoFunc, transUnit ); 384 386 PASS( "Fix Init", InitTweak::fix, transUnit, buildingLibrary() ); // Here 385 387 PASS( "Erase With", ResolvExpr::eraseWith, transUnit ); -
tests/enum_tests/.expect/voidEnum.txt
r0b6c1c9 r083e637 1 Two different Opague Enum Should not be the same: 2 a and b are Not Equal 3 Default Output: 1 Not Equal 4 2 0 5 3 1 6 a7 b -
tests/enum_tests/structEnum.cfa
r0b6c1c9 r083e637 17 17 }; 18 18 19 PointEnum identity(PointEnum in) {20 return in;21 }19 // PointEnum foo(PointEnum in) { 20 // return in; 21 // } 22 22 23 23 // The only valid usage
Note: See TracChangeset
for help on using the changeset viewer.