| 756 | } |
| 757 | |
| 758 | StructurePtr generateLambdaStruct ( const string & lambdaName, ExprBlock * block, |
| 759 | const safe_var_set & capt, |
| 760 | const vector<CaptureEntry> & capture, bool needYield ) { |
| 761 | auto lsn = lambdaName; |
| 762 | auto pStruct = new Structure(lsn); |
| 763 | pStruct->generated = true; |
| 764 | pStruct->isLambda = true; |
| 765 | pStruct->at = block->at; |
| 766 | auto btd = block->makeBlockType(); |
| 767 | btd->baseType = Type::tFunction; |
| 768 | btd->constant = false; |
| 769 | auto thisArg = new TypeDecl(pStruct); |
| 770 | btd->argTypes.insert(btd->argTypes.begin(), thisArg); |
| 771 | btd->argNames.insert(btd->argNames.begin(), "__this"); |
| 772 | pStruct->fields.emplace_back("__lambda", btd, nullptr, AnnotationArgumentList(), false, block->at); |
| 773 | pStruct->fields.back().generated = true; |
| 774 | pStruct->fields.back().type->sanitize(); |
| 775 | auto finFunc = new TypeDecl(Type::tFunction); |
| 776 | auto finArg = new TypeDecl(Type::tPointer); |
| 777 | finArg->firstType = new TypeDecl(pStruct); |
| 778 | finArg->constant = false; |
| 779 | finArg->removeConstant = true; |
| 780 | finFunc->argTypes.push_back(finArg); |
| 781 | finFunc->argNames.push_back("__this"); |
| 782 | finFunc->firstType = new TypeDecl(Type::tVoid); |
| 783 | pStruct->fields.emplace_back("__finalize", finFunc, nullptr, AnnotationArgumentList(), false, block->at); |
| 784 | pStruct->fields.back().generated = true; |
| 785 | pStruct->fields.back().type->sanitize(); |
| 786 | if ( needYield ) { |
| 787 | auto yt = new TypeDecl(Type::tInt); |
| 788 | pStruct->fields.emplace_back("__yield", yt, nullptr, AnnotationArgumentList(), false, block->at); |
| 789 | auto & fldb = pStruct->fields.back(); |
| 790 | fldb.generated = true; |
| 791 | fldb.type->sanitize(); |
| 792 | } |
| 793 | for ( auto var : capt ) { |
| 794 | auto td = new TypeDecl(*var->type); |
| 795 | td->constant = false; |
| 796 | CaptureMode mode = CaptureMode::capture_any; |
| 797 | auto it = find_if ( capture.begin(), capture.end(), [&] ( const auto & entry ){ |
| 798 | return entry.name == var->name; |
| 799 | }); |
| 800 | if ( it != capture.end() ) { |
| 801 | mode = it->mode; |
| 802 | } |
| 803 | if ( isCaptureAsRef(var) || mode==CaptureMode::capture_by_reference ) { |
| 804 | td->ref = false; |
| 805 | td->constant = var->type->constant; |
| 806 | auto ptd = new TypeDecl(Type::tPointer); |
| 807 | ptd->firstType = td; |
| 808 | td = ptd; |
| 809 | pStruct->fields.emplace_back(var->name, td, nullptr, AnnotationArgumentList(), false, var->at); |
| 810 | auto & bfld = pStruct->fields.back(); |
| 811 | bfld.capturedConstant = var->type->constant; |
| 812 | bfld.capturedRef = true; |
| 813 | bfld.type->sanitize(); |
| 814 | } else { |
| 815 | td->ref = false; |
no test coverage detected