[flang-commits] [flang] 1e054e6 - [OPENMP5.1] Initial support for severity clause

Jennifer Yu via flang-commits flang-commits at lists.llvm.org
Thu Nov 17 16:17:32 PST 2022


Author: Jennifer Yu
Date: 2022-11-17T16:05:02-08:00
New Revision: 1e054e6b522b3f7e13c30caebfa63aafc7173220

URL: https://github.com/llvm/llvm-project/commit/1e054e6b522b3f7e13c30caebfa63aafc7173220
DIFF: https://github.com/llvm/llvm-project/commit/1e054e6b522b3f7e13c30caebfa63aafc7173220.diff

LOG: [OPENMP5.1] Initial support for severity clause

Differential Revision:https://reviews.llvm.org/D138227

Added: 
    

Modified: 
    clang/include/clang/AST/OpenMPClause.h
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/include/clang/Basic/OpenMPKinds.def
    clang/include/clang/Basic/OpenMPKinds.h
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/AST/StmtProfile.cpp
    clang/lib/Basic/OpenMPKinds.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 ac0a6aa240aff..e7dc5e72b3a82 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1642,6 +1642,86 @@ class OMPAtClause final : public OMPClause {
   }
 };
 
+/// This represents 'severity' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error severity(fatal)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'severity' clause with kind 'fatal'.
+class OMPSeverityClause final : public OMPClause {
+  friend class OMPClauseReader;
+
+  /// Location of '('
+  SourceLocation LParenLoc;
+
+  /// A kind of the 'severity' clause.
+  OpenMPSeverityClauseKind Kind = OMPC_SEVERITY_unknown;
+
+  /// Start location of the kind in source code.
+  SourceLocation KindKwLoc;
+
+  /// Set kind of the clause.
+  ///
+  /// \param K Kind of clause.
+  void setSeverityKind(OpenMPSeverityClauseKind K) { Kind = K; }
+
+  /// Set clause kind location.
+  ///
+  /// \param KLoc Kind location.
+  void setSeverityKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+  /// Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+  /// Build 'severity' clause with argument \a A ('fatal' or 'warning').
+  ///
+  /// \param A Argument of the clause ('fatal' or 'warning').
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  OMPSeverityClause(OpenMPSeverityClauseKind A, SourceLocation ALoc,
+                    SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation EndLoc)
+      : OMPClause(llvm::omp::OMPC_severity, StartLoc, EndLoc),
+        LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+
+  /// Build an empty clause.
+  OMPSeverityClause()
+      : OMPClause(llvm::omp::OMPC_severity, SourceLocation(),
+                  SourceLocation()) {}
+
+  /// Returns the locaiton of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// Returns kind of the clause.
+  OpenMPSeverityClauseKind getSeverityKind() const { return Kind; }
+
+  /// Returns location of clause kind.
+  SourceLocation getSeverityKindKwLoc() const { return KindKwLoc; }
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  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_severity;
+  }
+};
+
 /// 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 b7c7e77d1d97e..9baee8b72fa11 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3315,6 +3315,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
+  return true;
+}
+
 template <typename Derived>
 bool
 RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {

diff  --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 567dd4fd192c2..0f023b33992de 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -44,6 +44,9 @@
 #ifndef OPENMP_AT_KIND
 #define OPENMP_AT_KIND(Name)
 #endif
+#ifndef OPENMP_SEVERITY_KIND
+#define OPENMP_SEVERITY_KIND(Name)
+#endif
 #ifndef OPENMP_DEFAULTMAP_MODIFIER
 #define OPENMP_DEFAULTMAP_MODIFIER(Name)
 #endif
@@ -126,6 +129,10 @@ OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed)
 OPENMP_AT_KIND(compilation)
 OPENMP_AT_KIND(execution)
 
+// Modifiers for 'severity' clause.
+OPENMP_SEVERITY_KIND(fatal)
+OPENMP_SEVERITY_KIND(warning)
+
 // Map types for 'map' clause.
 OPENMP_MAP_KIND(alloc)
 OPENMP_MAP_KIND(to)
@@ -187,6 +194,7 @@ OPENMP_BIND_KIND(thread)
 #undef OPENMP_SCHEDULE_KIND
 #undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
 #undef OPENMP_AT_KIND
+#undef OPENMP_SEVERITY_KIND
 #undef OPENMP_MAP_KIND
 #undef OPENMP_MAP_MODIFIER_KIND
 #undef OPENMP_MOTION_MODIFIER_KIND

diff  --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 1833e37cf3549..4a8417c6bffcd 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -138,6 +138,13 @@ enum OpenMPAtClauseKind {
   OMPC_AT_unknown
 };
 
+/// OpenMP attributes for 'severity' clause.
+enum OpenMPSeverityClauseKind {
+#define OPENMP_SEVERITY_KIND(Name) OMPC_SEVERITY_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_SEVERITY_unknown
+};
+
 /// OpenMP device type for 'device_type' clause.
 enum OpenMPDeviceType {
 #define OPENMP_DEVICE_TYPE_KIND(Name) \

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a299223fc917e..4250d38869ddc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11836,6 +11836,13 @@ class Sema final {
                                  SourceLocation LParenLoc,
                                  SourceLocation EndLoc);
 
+  /// Called on well-formed 'severity' clause.
+  OMPClause *ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
+                                       SourceLocation KindLoc,
+                                       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 471236a060db0..eb4e79748844a 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -153,6 +153,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
   case OMPC_dynamic_allocators:
   case OMPC_atomic_default_mem_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_device_type:
   case OMPC_match:
   case OMPC_nontemporal:
@@ -253,6 +254,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
   case OMPC_dynamic_allocators:
   case OMPC_atomic_default_mem_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_device_type:
   case OMPC_match:
   case OMPC_nontemporal:
@@ -1788,6 +1790,12 @@ void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
      << ")";
 }
 
+void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
+  OS << "severity("
+     << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
+     << ")";
+}
+
 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 b87fdac704fdf..1b674b16246b5 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -532,6 +532,8 @@ void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
 
 void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
 
+void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
+
 void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
   VistOMPClauseWithPreInit(C);
   if (auto *S = C->getChunkSize())

diff  --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 85b8be2d45599..bb1c2318b554d 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -109,6 +109,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
 #define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)
 #include "clang/Basic/OpenMPKinds.def"
         .Default(OMPC_AT_unknown);
+  case OMPC_severity:
+    return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str)
+#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+        .Default(OMPC_SEVERITY_unknown);
   case OMPC_lastprivate:
     return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)
 #define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
@@ -351,7 +356,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'at' clause type");
-    llvm_unreachable("Invalid OpenMP 'at' clause type");
+  case OMPC_severity:
+    switch (Type) {
+    case OMPC_SEVERITY_unknown:
+      return "unknown";
+#define OPENMP_SEVERITY_KIND(Name)                                             \
+  case OMPC_SEVERITY_##Name:                                                   \
+    return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+    }
+    llvm_unreachable("Invalid OpenMP 'severity' clause type");
   case OMPC_lastprivate:
     switch (Type) {
     case OMPC_LASTPRIVATE_unknown:

diff  --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 4818576da8e65..56c3db7728781 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6513,6 +6513,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
   case OMPC_dynamic_allocators:
   case OMPC_atomic_default_mem_order:
   case OMPC_at:
+  case OMPC_severity:
   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 82f86dae00843..489cfea7d3823 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3237,6 +3237,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   case OMPC_proc_bind:
   case OMPC_atomic_default_mem_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_order:
   case OMPC_bind:
     // OpenMP [2.14.3.1, Restrictions]
@@ -3247,8 +3248,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
     // OpenMP [5.0, Requires directive, Restrictions]
     //  At most one atomic_default_mem_order clause can appear
     //  on the directive
-    // OpenMP [5.1, Requires directive, Restrictions]
+    // OpenMP [5.1, error directive, Restrictions]
     //  At most one at clause can appear on the directive
+    //  At most one severity clause can appear on the directive
     // OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
     // At most one bind clause can appear on a loop directive.
     if (!FirstClause && CKind != OMPC_order) {

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 26658a684d1d7..7df2750c5e2b4 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6720,6 +6720,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
       case OMPC_match:
       case OMPC_when:
       case OMPC_at:
+      case OMPC_severity:
       default:
         llvm_unreachable("Unexpected clause");
       }
@@ -11039,10 +11040,19 @@ StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
     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());
+
   if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
-    Diag(AtC ? AtC->getBeginLoc() : StartLoc, diag::err_diagnose_if_succeeded)
-        << "ERROR";
-    return StmtError();
+    if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
+      Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
+          << "WARNING";
+    else
+      Diag(StartLoc, diag::err_diagnose_if_succeeded) << "ERROR";
+    if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
+      return StmtError();
   }
   return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
 }
@@ -15187,6 +15197,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
   case OMPC_nontemporal:
   case OMPC_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_destroy:
   case OMPC_inclusive:
   case OMPC_exclusive:
@@ -16113,6 +16124,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
   case OMPC_nontemporal:
   case OMPC_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_destroy:
   case OMPC_detach:
   case OMPC_inclusive:
@@ -16519,6 +16531,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
     Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_severity:
+    Res = ActOnOpenMPSeverityClause(
+        static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
+        LParenLoc, EndLoc);
+    break;
   case OMPC_if:
   case OMPC_final:
   case OMPC_num_threads:
@@ -16713,6 +16730,22 @@ OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
       OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
 }
 
+OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
+                                           SourceLocation KindKwLoc,
+                                           SourceLocation StartLoc,
+                                           SourceLocation LParenLoc,
+                                           SourceLocation EndLoc) {
+  if (Kind == OMPC_SEVERITY_unknown) {
+    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+        << getListOfPossibleValues(OMPC_severity, /*First=*/0,
+                                   /*Last=*/OMPC_SEVERITY_unknown)
+        << getOpenMPClauseName(OMPC_severity);
+    return nullptr;
+  }
+  return new (Context)
+      OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
                                         SourceLocation KindKwLoc,
                                         SourceLocation StartLoc,
@@ -16913,6 +16946,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
   case OMPC_nontemporal:
   case OMPC_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_destroy:
   case OMPC_novariants:
   case OMPC_nocontext:
@@ -17170,6 +17204,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
   case OMPC_nontemporal:
   case OMPC_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_novariants:
   case OMPC_nocontext:
   case OMPC_detach:
@@ -17725,6 +17760,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
   case OMPC_match:
   case OMPC_order:
   case OMPC_at:
+  case OMPC_severity:
   case OMPC_destroy:
   case OMPC_novariants:
   case OMPC_nocontext:

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 265e419adddae..7c85a8cbc89a7 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2362,6 +2362,20 @@ class TreeTransform {
     return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
                                          EndLoc);
   }
+
+  /// Build a new OpenMP 'severity' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide 
diff erent behavior.
+  OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
+                                      SourceLocation KwLoc,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
+                                               EndLoc);
+  }
+
   /// Rebuild the operand to an Objective-C \@synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -9873,6 +9887,14 @@ OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
                                          C->getEndLoc());
 }
 
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
+  return getDerived().RebuildOMPSeverityClause(
+      C->getSeverityKind(), C->getSeverityKindKwLoc(), 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 befd17912cb50..5e853fbf3b5cf 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -9952,6 +9952,9 @@ OMPClause *OMPClauseReader::readClause() {
   case llvm::omp::OMPC_at:
     C = new (Context) OMPAtClause();
     break;
+  case llvm::omp::OMPC_severity:
+    C = new (Context) OMPSeverityClause();
+    break;
   case llvm::omp::OMPC_private:
     C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
     break;
@@ -10360,6 +10363,12 @@ void OMPClauseReader::VisitOMPAtClause(OMPAtClause *C) {
   C->setAtKindKwLoc(Record.readSourceLocation());
 }
 
+void OMPClauseReader::VisitOMPSeverityClause(OMPSeverityClause *C) {
+  C->setSeverityKind(static_cast<OpenMPSeverityClauseKind>(Record.readInt()));
+  C->setLParenLoc(Record.readSourceLocation());
+  C->setSeverityKindKwLoc(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 7fe9cf9576b84..95ed51a90c181 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6987,6 +6987,12 @@ void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
   Record.AddSourceLocation(C->getAtKindKwLoc());
 }
 
+void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
+  Record.push_back(C->getSeverityKind());
+  Record.AddSourceLocation(C->getLParenLoc());
+  Record.AddSourceLocation(C->getSeverityKindKwLoc());
+}
+
 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 30a1678a4ea37..9028cc8d290dd 100644
--- a/clang/test/OpenMP/error_ast_print.cpp
+++ b/clang/test/OpenMP/error_ast_print.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -fopenmp-version=51 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-version=51 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
-// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -fopenmp-version=51 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -fopenmp-version=51 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
@@ -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)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
 // CHECK-NEXT: a = argv[0][0];
 // CHECK-NEXT: ++a;
-// CHECK-NEXT: #pragma omp error at(execution)
+// CHECK-NEXT: #pragma omp error at(execution) severity(warning)
 // 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)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
 // 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)
+#pragma omp error at(execution) severity(fatal)
   a = argv[0][0];
   ++a;
-#pragma omp error at(execution)
+#pragma omp error at(execution) severity(warning)
   {
     int b = 10;
     T c = 100;
     a = b + c;
   }
-#pragma omp  error at(execution)
+#pragma omp  error at(execution) severity(fatal)
   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)
+// CHECK-NEXT: #pragma omp error at(execution) severity(fatal)
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp error at(execution)
+// CHECK-NEXT: #pragma omp error at(execution) severity(warning)
 // 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)
+#pragma omp error at(execution) severity(fatal)
    a=2;
-#pragma omp error at(execution)
+#pragma omp error at(execution) severity(warning)
   foo();
 }
 #endif

diff  --git a/clang/test/OpenMP/error_message.cpp b/clang/test/OpenMP/error_message.cpp
index 90030b42814e7..d462da21a5140 100644
--- a/clang/test/OpenMP/error_message.cpp
+++ b/clang/test/OpenMP/error_message.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized
 
 template <class T>
 T tmain(T argc) {
@@ -67,6 +67,33 @@ if (1)
 #pragma omp error at(execution) // no error
 
 #pragma omp error at(compilation) // expected-error {{ERROR}}
+
+// expected-error at +1 {{ERROR}}
+#pragma omp error at(compilation) at(execution) //expected-error {{directive '#pragma omp error' cannot contain more than one 'at' clause}}
+
+// expected-error at +1 {{ERROR}}
+#pragma omp error severity() // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error severity(xyz) // expected-error {{expected 'fatal' or 'warning' in OpenMP clause 'severity'}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error severity(fatal) severity(warning) // expected-error {{directive '#pragma omp error' cannot contain more than one 'severity' clause}}
+
+// expected-error at +1 {{ERROR}}
+#pragma omp error severity(fatal) severity(fatal) // expected-error {{directive '#pragma omp error' cannot contain more than one 'severity' clause}}
+
+// expected-warning at +2 {{WARNING}}
+// expected-warning at +1 {{WARNING}}
+#pragma omp error severity(warning) severity(warning) // expected-error {{directive '#pragma omp error' cannot contain more than one 'severity' clause}}
+
+// expected-warning at +1 {{WARNING}}
+#pragma omp error severity(warning) // expected-warning {{WARNING}}
+#pragma omp error severity(fatal) // expected-error {{ERROR}}
+
+// expected-warning at +1 {{WARNING}}
+#pragma omp error at(compilation) severity(warning) // expected-warning {{WARNING}}
+#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
   return T();
 }
 
@@ -146,5 +173,5 @@ if (1)
   label2:
 #pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
 
-  return tmain(argc);
+  return tmain(argc);// expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}}
 }

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 64991171eb093..52aa03edc8796 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2445,6 +2445,8 @@ void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
 
 void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}
 
+void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause *) {}
+
 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 c7fcd9f58c7f4..a9b1120776f59 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1869,6 +1869,7 @@ CHECK_SIMPLE_CLAUSE(Use, OMPC_use)
 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(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 21c0714b9c579..0e76fc13fee33 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -304,6 +304,9 @@ def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
 def OMPC_At : Clause<"at"> {
   let clangClass = "OMPAtClause";
 }
+def OMPC_Severity : Clause<"severity"> {
+  let clangClass = "OMPSeverityClause";
+}
 def OMPC_Allocate : Clause<"allocate"> {
   let clangClass = "OMPAllocateClause";
   let flangClass = "OmpAllocateClause";
@@ -532,7 +535,8 @@ def OMP_TaskYield : Directive<"taskyield"> {}
 def OMP_Barrier : Directive<"barrier"> {}
 def OMP_Error : Directive<"error"> {
   let allowedClauses = [
-    VersionedClause<OMPC_At>
+    VersionedClause<OMPC_At, 51>,
+    VersionedClause<OMPC_Severity, 51>
   ];
 }
 def OMP_TaskWait : Directive<"taskwait"> {


        


More information about the flang-commits mailing list