[flang-commits] [flang] 9d90cf2 - [OPENMP5.1] Initial support for message clause.
Jennifer Yu via flang-commits
flang-commits at lists.llvm.org
Fri Nov 18 18:12:17 PST 2022
Author: Jennifer Yu
Date: 2022-11-18T17:59:23-08:00
New Revision: 9d90cf2fca4446f5c227f6e3217e96c00665cb72
URL: https://github.com/llvm/llvm-project/commit/9d90cf2fca4446f5c227f6e3217e96c00665cb72
DIFF: https://github.com/llvm/llvm-project/commit/9d90cf2fca4446f5c227f6e3217e96c00665cb72.diff
LOG: [OPENMP5.1] Initial support for message clause.
Added:
Modified:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/OpenMP/error_ast_print.cpp
clang/test/OpenMP/error_message.cpp
clang/tools/libclang/CIndex.cpp
flang/lib/Semantics/check-omp-structure.cpp
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 21d9f740eddf1..2bf3e91a15a20 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1722,6 +1722,72 @@ class OMPSeverityClause final : public OMPClause {
}
};
+/// This represents 'message' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error message("GNU compiler required.")
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'message' clause with user error message of "GNU compiler required.".
+class OMPMessageClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ // Expression of the 'message' clause.
+ Stmt *MessageString = nullptr;
+
+ /// Set message string of the clause.
+ void setMessageString(Expr *MS) { MessageString = MS; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'message' clause with message string argument
+ ///
+ /// \param A Argument of the clause (message string).
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_message, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), MessageString(MS) {}
+
+ /// Build an empty clause.
+ OMPMessageClause()
+ : OMPClause(llvm::omp::OMPC_message, SourceLocation(), SourceLocation()) {
+ }
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns message string of the clause.
+ Expr *getMessageString() const { return cast_or_null<Expr>(MessageString); }
+
+ child_range children() {
+ return child_range(&MessageString, &MessageString + 1);
+ }
+
+ const_child_range children() const {
+ return const_child_range(&MessageString, &MessageString + 1);
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_message;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 9baee8b72fa11..7475d29cd98d0 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3320,6 +3320,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
+ TRY_TO(TraverseStmt(C->getMessageString()));
+ return true;
+}
+
template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 6f46ede56f66c..ffbc859162270 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1342,6 +1342,8 @@ def err_omp_unexpected_directive : Error<
"unexpected OpenMP directive %select{|'#pragma omp %1'}0">;
def err_omp_expected_punc : Error<
"expected ',' or ')' in '%0' %select{clause|directive}1">;
+def warn_clause_expected_string : Warning<
+ "expected string literal in 'clause %0' - ignoring">, InGroup<IgnoredPragmas>;
def err_omp_unexpected_clause : Error<
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
def err_omp_immediate_directive : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 82d5ae169c7b3..7ed9a31648d1f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11862,6 +11862,12 @@ class Sema final {
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'message' clause.
+ /// passing string for message.
+ OMPClause *ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
/// Data used for processing a list of variables in OpenMP clauses.
struct OpenMPVarListDataTy final {
Expr *DepModOrTailExpr = nullptr;
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 1bf14806ce836..203e0ab463b01 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -154,6 +154,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_atomic_default_mem_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -255,6 +256,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_atomic_default_mem_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -1796,6 +1798,11 @@ void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
<< ")";
}
+void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
+ OS << "message(\""
+ << cast<StringLiteral>(Node->getMessageString())->getString() << "\")";
+}
+
void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
OS << "schedule(";
if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 1b674b16246b5..98c98aac40626 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -534,6 +534,11 @@ void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
+void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause *C) {
+ if (C->getMessageString())
+ Profiler->VisitStmt(C->getMessageString());
+}
+
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
VistOMPClauseWithPreInit(C);
if (auto *S = C->getChunkSize())
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 56c3db7728781..ee0bae415c901 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6514,6 +6514,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_atomic_default_mem_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index e8b60ce81fcbb..4054ec29d1cbd 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3192,6 +3192,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_filter:
case OMPC_partial:
case OMPC_align:
+ case OMPC_message:
// OpenMP [2.5, Restrictions]
// At most one num_threads clause can appear on the directive.
// OpenMP [2.8.1, simd construct, Restrictions]
@@ -3217,6 +3218,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
// OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
// At most one novariants clause can appear on a dispatch directive.
// At most one nocontext clause can appear on a dispatch directive.
+ // OpenMP [5.1, error directive, Restrictions]
+ // At most one message clause can appear on the directive
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index e150b0d65ad34..89f7a6be81fa4 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6721,6 +6721,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPC_when:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
default:
llvm_unreachable("Unexpected clause");
}
@@ -11032,25 +11033,27 @@ StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc,
bool InExContext) {
- auto AtClauses =
- OMPExecutableDirective::getClausesOfKind<OMPAtClause>(Clauses);
- const OMPAtClause *AtC = AtClauses.empty() ? nullptr : (*AtClauses.begin());
+ const OMPAtClause *AtC =
+ OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
return StmtError();
}
- auto SeverityClauses =
- OMPExecutableDirective::getClausesOfKind<OMPSeverityClause>(Clauses);
+
const OMPSeverityClause *SeverityC =
- SeverityClauses.empty() ? nullptr : (*SeverityClauses.begin());
+ OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
+ const OMPMessageClause *MessageC =
+ OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
+ Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
- << "WARNING";
+ << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
else
- Diag(StartLoc, diag::err_diagnose_if_succeeded) << "ERROR";
+ Diag(StartLoc, diag::err_diagnose_if_succeeded)
+ << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
return StmtError();
}
@@ -15131,6 +15134,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_partial:
Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_message:
+ Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_align:
Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
@@ -16121,6 +16127,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
@@ -16607,6 +16614,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_uses_allocators:
case OMPC_affinity:
case OMPC_when:
+ case OMPC_message:
default:
llvm_unreachable("Clause is not allowed.");
}
@@ -16742,6 +16750,18 @@ OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ assert(ME && "NULL expr in Message clause");
+ if (!isa<StringLiteral>(ME)) {
+ Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
+ << getOpenMPClauseName(OMPC_message);
+ return nullptr;
+ }
+ return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
SourceLocation KindKwLoc,
SourceLocation StartLoc,
@@ -16955,6 +16975,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
@@ -17213,6 +17234,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_novariants:
case OMPC_nocontext:
case OMPC_detach:
@@ -17769,6 +17791,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
case OMPC_order:
case OMPC_at:
case OMPC_severity:
+ case OMPC_message:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index a917007ee82cf..019ea3efd1a6b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2380,6 +2380,16 @@ class TreeTransform {
EndLoc);
}
+ /// Build a new OpenMP 'message' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide
diff erent behavior.
+ OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
+ }
+
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -9899,6 +9909,17 @@ TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
C->getLParenLoc(), C->getEndLoc());
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
+ ExprResult E = getDerived().TransformExpr(C->getMessageString());
+ if (E.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPMessageClause(
+ C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
+ C->getEndLoc());
+}
+
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 7dc935a68c083..cb418372ed589 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9955,6 +9955,9 @@ OMPClause *OMPClauseReader::readClause() {
case llvm::omp::OMPC_severity:
C = new (Context) OMPSeverityClause();
break;
+ case llvm::omp::OMPC_message:
+ C = new (Context) OMPMessageClause();
+ break;
case llvm::omp::OMPC_private:
C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
break;
@@ -10369,6 +10372,11 @@ void OMPClauseReader::VisitOMPSeverityClause(OMPSeverityClause *C) {
C->setSeverityKindKwLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPMessageClause(OMPMessageClause *C) {
+ C->setMessageString(Record.readSubExpr());
+ C->setLParenLoc(Record.readSourceLocation());
+}
+
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
C->setLParenLoc(Record.readSourceLocation());
unsigned NumVars = C->varlist_size();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 329407a30f5f9..dd464f5507854 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7000,6 +7000,11 @@ void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
Record.AddSourceLocation(C->getSeverityKindKwLoc());
}
+void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) {
+ Record.AddStmt(C->getMessageString());
+ Record.AddSourceLocation(C->getLParenLoc());
+}
+
void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
Record.push_back(C->varlist_size());
Record.AddSourceLocation(C->getLParenLoc());
diff --git a/clang/test/OpenMP/error_ast_print.cpp b/clang/test/OpenMP/error_ast_print.cpp
index 9028cc8d290dd..c6d361b1a3b8b 100644
--- a/clang/test/OpenMP/error_ast_print.cpp
+++ b/clang/test/OpenMP/error_ast_print.cpp
@@ -13,16 +13,16 @@
void foo() {}
// CHECK: template <typename T, int N> int tmain(T argc, char **argv)
// CHECK: static int a;
-// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal) message("GNU compiler required.")
// CHECK-NEXT: a = argv[0][0];
// CHECK-NEXT: ++a;
-// CHECK-NEXT: #pragma omp error at(execution) severity(warning)
+// CHECK-NEXT: #pragma omp error at(execution) severity(warning) message("Notice: add for loop.")
// CHECK-NEXT: {
// CHECK-NEXT: int b = 10;
// CHECK-NEXT: T c = 100;
// CHECK-NEXT: a = b + c;
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
// CHECK-NEXT: foo();
// CHECK-NEXT: return N;
@@ -30,16 +30,16 @@ template <typename T, int N>
int tmain(T argc, char **argv) {
T b = argc, c, d, e, f, g;
static int a;
-#pragma omp error at(execution) severity(fatal)
+#pragma omp error at(execution) severity(fatal) message("GNU compiler required.")
a = argv[0][0];
++a;
-#pragma omp error at(execution) severity(warning)
+#pragma omp error at(execution) severity(warning) message("Notice: add for loop.")
{
int b = 10;
T c = 100;
a = b + c;
}
-#pragma omp error at(execution) severity(fatal)
+#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
foo();
return N;
}
@@ -47,16 +47,16 @@ return N;
// CHECK: int main(int argc, char **argv)
// CHECK-NEXT: int b = argc, c, d, e, f, g;
// CHECK-NEXT: static int a;
-// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp error at(execution) severity(warning)
+// CHECK-NEXT: #pragma omp error at(execution) severity(warning) message("Note this is functioncall.")
// CHECK-NEXT: foo();
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
-#pragma omp error at(execution) severity(fatal)
+#pragma omp error at(execution) severity(fatal) message("GPU compiler required.")
a=2;
-#pragma omp error at(execution) severity(warning)
+#pragma omp error at(execution) severity(warning) message("Note this is functioncall.")
foo();
}
#endif
diff --git a/clang/test/OpenMP/error_message.cpp b/clang/test/OpenMP/error_message.cpp
index d462da21a5140..40f1db40fb63a 100644
--- a/clang/test/OpenMP/error_message.cpp
+++ b/clang/test/OpenMP/error_message.cpp
@@ -94,6 +94,26 @@ if (1)
#pragma omp error at(execution) severity(warning) // no error, diagnosic at runtime
#pragma omp error at(compilation) severity(fatal) // expected-error {{ERROR}}
#pragma omp error at(execution) severity(fatal) // no error, error at runtime
+
+#pragma omp error message("GPU compiler is needed.") // expected-error {{GPU compiler is needed}}
+#pragma omp error at(compilation) message("GPU compiler is needed.") // expected-error {{GPU compiler is needed}}
+#pragma omp error at(execution) message("GPU compiler is needed.") // no error
+// expected-warning at +1 {{GPU compiler is needed.}}
+#pragma omp error severity(warning) message("GPU compiler is needed.") // expected-warning {{GPU compiler is needed.}}
+#pragma omp error severity(fatal) message("GPU compiler is needed.") // expected-error {{GPU compiler is needed}}
+// expected-warning at +1 {{GPU compiler is needed.}}
+#pragma omp error at(compilation) severity(warning) message("GPU compiler is needed.") // expected-warning {{GPU compiler is needed.}}
+#pragma omp error at(compilation) severity(fatal) message("GPU compiler is needed.") // expected-error {{GPU compiler is needed.}}
+#pragma omp error at(execution) severity(warning) message("GPU compiler is needed.") // no warning warning will emit at runtime.
+#pragma omp error at(execution) severity(fatal) message("GPU compiler is needed.") // no warning warning will emit at runtime.
+
+// expected-error at +1 {{GPU compiler is needed.}}
+#pragma omp error message("GPU compiler is needed.") message("GPU compiler is needed.") // expected-error {{directive '#pragma omp error' cannot contain more than one 'message' clause}}
+ int a;
+// expected-warning at +1 {{expected string literal in 'clause message' - ignoring}}
+#pragma omp error message(a) // expected-error {{ERROR}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message() // expected-error {{expected expression}}
return T();
}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 52aa03edc8796..dec7efd7bfb14 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2447,6 +2447,8 @@ void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}
void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause *) {}
+void OMPClauseEnqueue::VisitOMPMessageClause(const OMPMessageClause *) {}
+
void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
Visitor->AddStmt(C->getDevice());
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index a9b1120776f59..883515c16d4ad 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1870,6 +1870,7 @@ CHECK_SIMPLE_CLAUSE(Novariants, OMPC_novariants)
CHECK_SIMPLE_CLAUSE(Nocontext, OMPC_nocontext)
CHECK_SIMPLE_CLAUSE(At, OMPC_at)
CHECK_SIMPLE_CLAUSE(Severity, OMPC_severity)
+CHECK_SIMPLE_CLAUSE(Message, OMPC_message)
CHECK_SIMPLE_CLAUSE(Filter, OMPC_filter)
CHECK_SIMPLE_CLAUSE(When, OMPC_when)
CHECK_SIMPLE_CLAUSE(AdjustArgs, OMPC_adjust_args)
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 49faa945b8358..a43e9f6cd68f3 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -325,6 +325,9 @@ def OMPC_At : Clause<"at"> {
def OMPC_Severity : Clause<"severity"> {
let clangClass = "OMPSeverityClause";
}
+def OMPC_Message : Clause<"message"> {
+ let clangClass = "OMPMessageClause";
+}
def OMPC_Allocate : Clause<"allocate"> {
let clangClass = "OMPAllocateClause";
let flangClass = "OmpAllocateClause";
@@ -554,7 +557,8 @@ def OMP_Barrier : Directive<"barrier"> {}
def OMP_Error : Directive<"error"> {
let allowedClauses = [
VersionedClause<OMPC_At, 51>,
- VersionedClause<OMPC_Severity, 51>
+ VersionedClause<OMPC_Severity, 51>,
+ VersionedClause<OMPC_Message, 51>
];
}
def OMP_TaskWait : Directive<"taskwait"> {
More information about the flang-commits
mailing list