================ @@ -4529,6 +4529,191 @@ void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { emitMaster(*this, S); } +static Expr *replaceWithNewTraitsOrDirectCall(CapturedDecl *CDecl, + Expr *NewExpr) { + Expr *CurrentCallExpr = nullptr; + Stmt *CallExprStmt = CDecl->getBody(); + + if (BinaryOperator *BinaryCopyOpr = dyn_cast<BinaryOperator>(CallExprStmt)) { + CurrentCallExpr = BinaryCopyOpr->getRHS(); + BinaryCopyOpr->setRHS(NewExpr); + } else { + CurrentCallExpr = dyn_cast<Expr>(CallExprStmt); + CDecl->setBody(NewExpr); + } + + return CurrentCallExpr; +} + +static Expr *transformCallInStmt(Stmt *StmtP, bool NoContext = false) { + Expr *CurrentExpr = nullptr; + if (auto *CptStmt = dyn_cast<CapturedStmt>(StmtP)) { + CapturedDecl *CDecl = CptStmt->getCapturedDecl(); + + CallExpr *NewCallExpr = nullptr; + for (const auto *attr : CDecl->attrs()) { + if (NoContext) { + if (const auto *annotateAttr = + llvm::dyn_cast<clang::AnnotateAttr>(attr); + annotateAttr && annotateAttr->getAnnotation() == "NoContextAttr") { + NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin()); + } + } else { + if (const auto *annotateAttr = + llvm::dyn_cast<clang::AnnotateAttr>(attr); + annotateAttr && annotateAttr->getAnnotation() == "NoVariantsAttr") { + NewCallExpr = llvm::dyn_cast<CallExpr>(*annotateAttr->args_begin()); + } + } + } + + CurrentExpr = replaceWithNewTraitsOrDirectCall(CDecl, NewCallExpr); + } + return CurrentExpr; +} + +// emitIfElse is used for the following conditions: +// +// NoVariants = 0 && NoContext = 1 +// if (Condition_NoContext) { +// foo_variant2(); // Present in AnnotationAttr +// } else { +// foo_variant(); +// } +// +// NoVariants = 1 && NoContext = 0 +// if (Condition_NoVariants) { +// foo(); +// } else { +// foo_variant(); +// } +// +// NoVariants = 1 && NoContext = 1 +// if (Condition_NoVariants) { // ==> label if.then.NoVariants +// foo(); +// } else { // ==> label else.NoVariants +// if (Condition_NoContext) { // ==> label if.then.NoContext +// foo_variant2(); // Present in AnnotationAttr +// } else { // ==> label else +// foo_variant(); +// } +// } +// +static void emitIfElse(CodeGenFunction *CGF, Stmt *AssociatedStmt, ---------------- dreachem wrote:
Thanks for the clarification. So something like this? ```c++ #include <iostream> int main() { class IsPositive { public: IsPositive(int x) : _x(x) { std::cout << "constructing IsPositive(" << x << ") object\n"; } ~IsPositive() { std::cout << "destructing IsPositive(" << _x << ") object\n"; } operator bool() const { return _x > 0; } private: int _x; }; // case 1 #pragma omp parallel if(IsPositive(10)) { std::cout << "[1] in parallel\n"; } // case 2 auto cond1 = IsPositive(5); #pragma omp parallel if(cond1) { std::cout << "[2] in parallel\n"; } // case 3 #pragma omp parallel if(IsPositive(-10)) { std::cout << "[3] in parallel\n"; } // case 4 auto cond2 = IsPositive(-5); #pragma omp parallel if(cond2) { std::cout << "[4] in parallel\n"; } ``` The output for the above with `OMP_NUM_THREADS=2` is: ``` constructing IsPositive(10) object [1] in parallel [1] in parallel destructing IsPositive(10) object constructing IsPositive(5) object [2] in parallel [2] in parallel constructing IsPositive(-10) object [3] in parallel destructing IsPositive(-10) object constructing IsPositive(-5) object [4] in parallel destructing IsPositive(-5) object destructing IsPositive(5) object ``` So, the destructor for the instantiated class object used in the `if` condition is called upon completing each `parallel` region. On the other hand, if I move the condition expression outside the directive (as for cases 2 and 4), then the destructor for the instantiated class is called at the end of the function. Does this match the expected behavior? https://github.com/llvm/llvm-project/pull/131838 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits