Changeset c333ed2 for src/Validate
- Timestamp:
- May 7, 2024, 7:04:17 PM (9 months ago)
- Branches:
- master
- Children:
- 0b6c1c9
- Parents:
- 164a6b6
- Location:
- src/Validate
- Files:
-
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/ImplementEnumFunc.cpp
r164a6b6 rc333ed2 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->location41 : 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 63 30 private: 64 31 const CodeLocation& getLocation() const { return decl->location; } … … 73 40 const ast::Decl* getDecl() const { return decl; } 74 41 75 // Implement Bounded trait for enum 76 void genBoundedFunctions(); 77 // Implement Serial trait for enum 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 78 48 void genSerialTraitFuncs(); 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 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); 86 59 ast::FunctionDecl* genPosnProto() const; 87 60 ast::FunctionDecl* genLabelProto() const; 88 61 ast::FunctionDecl* genValueProto() const; 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; 62 void genValueOrLabelBody( 63 ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const; 64 void genPosnBody(ast::FunctionDecl* func) const; 65 98 66 //////////////// 99 100 ast::FunctionDecl* genSuccPosProto() const;101 ast::FunctionDecl* genPredPosProto() const;102 67 103 68 // --------------------------------------------------- … … 121 86 } 122 87 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*204 88 // ---------------------------------------------------- 205 206 ast::FunctionDecl* genSuccPredFunc(bool succ);207 89 208 90 const ast::Init* getAutoInit(const ast::Init* prev) const; … … 214 96 const ast::EnumAttribute attr, const CodeLocation& location, 215 97 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);220 98 }; 221 99 … … 374 252 } 375 253 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::ExplicitCast 263 ); 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::ExplicitCast 274 ); 275 func->stmts = new ast::CompoundStmt( 276 func->location, { 277 new ast::ReturnStmt( 278 func->location, 279 intToEnum 280 ) 281 } 282 ); 283 } 284 285 376 286 void EnumAttrFuncGenerator::genSerialTraitFuncs() { 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 { 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 { 394 301 return genProto( 395 "succ",302 func, 396 303 {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))}, 397 304 {new ast::ObjectDecl(getLocation(), "_ret", … … 399 306 } 400 307 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", {}, { 308 ast::FunctionDecl* EnumAttrFuncGenerator::genBoundedProto(const char * func) const { 309 return genProto(func, {}, { 411 310 new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl)) 412 311 }); 413 312 } 414 313 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 { 314 void EnumAttrFuncGenerator::genBoundedBody(ast::FunctionDecl* func) const { 422 315 const CodeLocation & loc = func->location; 423 auto mem = decl->members.front(); 424 // auto expr = new ast::QualifiedNameExpr( loc, decl, mem->name ); 425 // expr->result = new ast::EnumInstType( decl ); 316 auto mem = func->name=="lowerBound"? decl->members.front() : decl->members.back(); 426 317 auto expr = new ast::NameExpr( loc, mem->name ); 427 318 func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)}); 428 319 } 429 320 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 438 321 void EnumAttrFuncGenerator::genBoundedFunctions() { 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); 322 ast::FunctionDecl * boundedProtos[2] = {genBoundedProto("upperBound"), genBoundedProto("lowerBound")}; 323 for (auto & protos: boundedProtos) { 324 produceForwardDecl(protos); 325 genBoundedBody(protos); 326 produceDecl(protos); 327 } 448 328 } 449 329 450 330 inline ast::EnumAttrType * getPosnType( const ast::EnumDecl * decl ) { 451 331 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 );468 332 } 469 333 … … 511 375 } 512 376 513 void EnumAttrFuncGenerator::gen AttributesDecls(const ast::EnumAttribute attr) {377 void EnumAttrFuncGenerator::genTypedEnumFunction(const ast::EnumAttribute attr) { 514 378 if (attr == ast::EnumAttribute::Value || 515 379 attr == ast::EnumAttribute::Label) { 380 // TypedEnum's backing arrays 516 381 std::vector<ast::ptr<ast::Init>> inits = 517 382 attr == ast::EnumAttribute::Value ? genValueInit() : genLabelInit(); … … 534 399 } 535 400 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); 401 void EnumAttrFuncGenerator::genTypedEnumFuncs() { 402 if (decl->base) genTypedEnumFunction(ast::EnumAttribute::Value); 403 genTypedEnumFunction(ast::EnumAttribute::Label); 404 genTypedEnumFunction(ast::EnumAttribute::Posn); 590 405 } 591 406 … … 593 408 std::list<ast::ptr<ast::Decl>>& decls) { 594 409 // Generate the functions (they go into forwards and definitions). 595 genAttrStandardFuncs(); 596 genAttrFunctions(); 410 genTypedEnumFuncs(); 597 411 genSerialTraitFuncs(); 598 genSuccPredPosn();599 // problematic600 412 genBoundedFunctions(); 601 413 // Now export the lists contents. … … 618 430 619 431 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) { 620 if (!enumDecl->body) return; 621 if (!enumDecl->base) return; 622 432 if (!enumDecl->body || !enumDecl->isTyped) return; 623 433 ast::EnumInstType enumInst(enumDecl->name); 624 434 enumInst.base = enumDecl; 625 626 435 EnumAttrFuncGenerator gen(enumDecl, &enumInst, functionNesting); 627 436 gen.generateAndAppendFunctions(declsToAddAfter); -
src/Validate/module.mk
r164a6b6 rc333ed2 53 53 Validate/VerifyCtorDtorAssign.cpp \ 54 54 Validate/VerifyCtorDtorAssign.hpp \ 55 Validate/ReplacePseudoFunc.cpp \56 Validate/ReplacePseudoFunc.hpp \57 55 Validate/ImplementEnumFunc.cpp \ 58 56 Validate/ImplementEnumFunc.hpp
Note: See TracChangeset
for help on using the changeset viewer.