diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -2842,6 +2842,8 @@ /// This field is true for the first(postfix) form of the expression and false /// otherwise. bool IsPostfixUpdate = false; + /// + bool IsSignedOp = true; /// Build directive with the given start and end location. /// @@ -2863,6 +2865,8 @@ POS_V, POS_E, POS_UpdateExpr, + POS_D, + POS_Cond, }; /// Set 'x' part of the associated expression/statement. @@ -2877,6 +2881,10 @@ void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } /// Set 'expr' part of the associated expression/statement. void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } + /// Set 'd' part of the associated expression/statement. + void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } + /// Set conditional expression in `atomic compare`. + void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } public: /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' @@ -2894,14 +2902,18 @@ /// \param UE Helper expression of the form /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. + /// \param D 'd' part of the associated expression/statement. + /// \param Cond Conditional expression in `atomic compare` construct. /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the /// second. /// \param IsPostfixUpdate true if original value of 'x' must be stored in /// 'v', not an updated one. + /// \param IsSignedOp true if the comparison operation is signed. static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, - Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); + Expr *E, Expr *UE, Expr *D, Expr *Cond, bool IsXLHSInRHSPart, + bool IsPostfixUpdate, bool IsSignedOp); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -2951,6 +2963,13 @@ const Expr *getExpr() const { return cast_or_null(Data->getChildren()[DataPositionTy::POS_E]); } + /// Get 'd' part of the associated expression/statement. + Expr *getD() { + return cast_or_null(Data->getChildren()[DataPositionTy::POS_D]); + } + Expr *getD() const { + return cast_or_null(Data->getChildren()[DataPositionTy::POS_D]); + } static bool classof(const Stmt *T) { return T->getStmtClass() == OMPAtomicDirectiveClass; diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -863,18 +863,23 @@ !IsStandalone); } -OMPAtomicDirective *OMPAtomicDirective::Create( - const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, - Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate) { +OMPAtomicDirective * +OMPAtomicDirective::Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, ArrayRef Clauses, + Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, + Expr *UE, Expr *D, Expr *Cond, bool IsXLHSInRHSPart, + bool IsPostfixUpdate, bool IsSignedOp) { auto *Dir = createDirective( - C, Clauses, AssociatedStmt, /*NumChildren=*/4, StartLoc, EndLoc); + C, Clauses, AssociatedStmt, /*NumChildren=*/6, StartLoc, EndLoc); Dir->setX(X); Dir->setV(V); Dir->setExpr(E); Dir->setUpdateExpr(UE); + Dir->setD(D); + Dir->setCond(Cond); Dir->IsXLHSInRHSPart = IsXLHSInRHSPart; Dir->IsPostfixUpdate = IsPostfixUpdate; + Dir->IsSignedOp = IsSignedOp; return Dir; } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -11363,8 +11363,11 @@ Expr *V = nullptr; Expr *E = nullptr; Expr *UE = nullptr; + Expr *D = nullptr; + Expr *CE = nullptr; bool IsXLHSInRHSPart = false; bool IsPostfixUpdate = false; + bool IsSignedOp = true; // OpenMP [2.12.6, atomic Construct] // In the next expressions: // * x and v (as applicable) are both l-value expressions with scalar type. @@ -11759,18 +11762,20 @@ << ErrorInfo.Error << ErrorInfo.NoteRange; return StmtError(); } - // TODO: For now we emit an error here and in emitOMPAtomicExpr we ignore - // code gen. - unsigned DiagID = Diags.getCustomDiagID( - DiagnosticsEngine::Error, "atomic compare is not supported for now"); - Diag(AtomicKindLoc, DiagID); + X = Checker.getX(); + E = Checker.getE(); + CE = Checker.getCond(); + D = Checker.getD(); + IsSignedOp = Checker.isSignedOp(); + // We reuse this boolean variable. + IsXLHSInRHSPart = Checker.isXBinopExpr(); } setFunctionHasBranchProtectedScope(); return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, - X, V, E, UE, IsXLHSInRHSPart, - IsPostfixUpdate); + X, V, E, UE, D, CE, IsXLHSInRHSPart, + IsPostfixUpdate, IsSignedOp); } StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef Clauses,