[clang-tools-extra] [OpenACC] Initial commits to support OpenACC (PR #70234)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 26 10:36:07 PDT 2023


https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/70234

>From b3d64b3f744ccb37e334e3aae8d6874cd8391c56 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Mon, 23 Oct 2023 11:09:11 -0700
Subject: [PATCH 1/5] [OpenACC] Initial commit for OpenACC Support

This is the initial commit to support OpenACC in Clang, which adds a
clang-command line argument '-fopenacc', and starts to define _OPENACC,
albeit to '1' instead of the standardized value (since we don't
properly implement OpenACC yet).
---
 clang/docs/ReleaseNotes.rst               | 12 ++++++++++++
 clang/include/clang/Basic/LangOptions.def |  2 ++
 clang/include/clang/Driver/Options.td     | 10 ++++++++--
 clang/lib/Driver/ToolChains/Clang.cpp     | 11 +++++++++++
 clang/lib/Frontend/CompilerInvocation.cpp |  7 +++++++
 clang/lib/Frontend/InitPreprocessor.cpp   |  6 ++++++
 clang/test/Driver/openacc.c               |  2 ++
 clang/test/Preprocessor/openacc.c         |  4 ++++
 8 files changed, 52 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Driver/openacc.c
 create mode 100644 clang/test/Preprocessor/openacc.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f94e4e10b805911..8f40872b539322a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -211,6 +211,11 @@ New Compiler Flags
   the preprocessed text to the output. This can greatly reduce the size of the
   preprocessed output, which can be helpful when trying to reduce a test case.
 
+* ``-Wbitfield-conversion`` was added to detect assignments of integral
+  types to a bitfield that may change the value.
+
+* ``-fopenacc`` was added as a part of the effort to support OpenACC in clang.
+
 Deprecated Compiler Flags
 -------------------------
 
@@ -665,6 +670,13 @@ Miscellaneous Clang Crashes Fixed
 - Fixed a crash when an ObjC ivar has an invalid type. See
   (`#68001 <https://github.com/llvm/llvm-project/pull/68001>`_)
 
+OpenACC Specific Changes
+------------------------
+- OpenACC Implementation effort is beginning with semantic analysis and parsing
+  of OpenACC pragmas. The ``-fopenacc`` flag was added to enable these new,
+  albeit incomplete changes. The ``_OPENACC`` macro is currently defined to
+  ``1``, as support is too incomplete to update to a standards-required value.
+
 Target Specific Changes
 -----------------------
 
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index c0ea4ecb9806a5b..872d693cc3ebbff 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -283,6 +283,8 @@ LANGOPT(OffloadUniformBlock, 1, 0, "Assume that kernels are launched with unifor
 LANGOPT(HIPStdPar, 1, 0, "Enable Standard Parallel Algorithm Acceleration for HIP (experimental)")
 LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with HIP RT calls when Standard Parallel Algorithm Acceleration for HIP is enabled (Experimental)")
 
+LANGOPT(OpenACC           , 1, 0, "OpenACC Enabled")
+
 LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
 LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
 LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c6b1903a32a0621..ab28c3e394afe93 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3340,6 +3340,14 @@ def fno_openmp_target_debug : Flag<["-"], "fno-openmp-target-debug">;
 } // let Visibility = [ClangOption, CC1Option, FC1Option]
 } // let Flags = [NoArgumentUnused]
 
+//===----------------------------------------------------------------------===//
+// FlangOption + FC1 + ClangOption + CC1Option
+//===----------------------------------------------------------------------===//
+let Visibility = [FC1Option, FlangOption, CC1Option, ClangOption] in {
+def fopenacc : Flag<["-"], "fopenacc">, Group<f_Group>,
+  HelpText<"Enable OpenACC">;
+} // let Visibility = [FC1Option, FlangOption, CC1Option, ClangOption]
+
 //===----------------------------------------------------------------------===//
 // Optimisation remark options
 //===----------------------------------------------------------------------===//
@@ -6256,8 +6264,6 @@ file}]>;
 def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<f_Group>, Alias<ffixed_line_length_EQ>;
 def fconvert_EQ : Joined<["-"], "fconvert=">, Group<f_Group>,
   HelpText<"Set endian conversion of data for unformatted files">;
-def fopenacc : Flag<["-"], "fopenacc">, Group<f_Group>,
-  HelpText<"Enable OpenACC">;
 def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group<f_Group>,
   HelpText<"Set the default double precision kind to an 8 byte wide type">;
 def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group<f_Group>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 601bbfb927746fc..cf65773de0d010d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3633,6 +3633,14 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
     CmdArgs.push_back("-finclude-default-header");
 }
 
+static void RenderOpenACCOptions(const ArgList &Args, ArgStringList &CmdArgs,
+                                 types::ID InputType) {
+  if (!Args.hasArg(options::OPT_fopenacc))
+    return;
+
+  CmdArgs.push_back("-fopenacc");
+}
+
 static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args,
                                         ArgStringList &CmdArgs) {
   bool ARCMTEnabled = false;
@@ -6597,6 +6605,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   // Forward hlsl options to -cc1
   RenderHLSLOptions(Args, CmdArgs, InputType);
 
+  // Forward OpenACC options to -cc1
+  RenderOpenACCOptions(Args, CmdArgs, InputType);
+
   if (IsHIP) {
     if (Args.hasFlag(options::OPT_fhip_new_launch_api,
                      options::OPT_fno_hip_new_launch_api, true))
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 4e6d7bb16f51beb..44f15e094d64593 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3532,6 +3532,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
   if (Opts.OpenMPCUDAMode)
     GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
 
+  if (Opts.OpenACC)
+    GenerateArg(Consumer, OPT_fopenacc);
+
   // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
   // generated from CodeGenOptions.
 
@@ -4001,6 +4004,10 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
                         (T.isNVPTX() || T.isAMDGCN()) &&
                         Args.hasArg(options::OPT_fopenmp_cuda_mode);
 
+  // OpenACC Configuration.
+  if (Args.hasArg(options::OPT_fopenacc))
+    Opts.OpenACC = true;
+
   // FIXME: Eliminate this dependency.
   unsigned Opt = getOptimizationLevel(Args, IK, Diags),
        OptSize = getOptimizationLevelSize(Args);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 846e5fce6de7b2c..182a9e53af589c0 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -605,6 +605,12 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
       Builder.defineMacro("HIP_API_PER_THREAD_DEFAULT_STREAM");
     }
   }
+
+  if (LangOpts.OpenACC) {
+    // FIXME: When we have full support for OpenACC, we should set this to the
+    // version we support. Until then, set as '1'.
+    Builder.defineMacro("_OPENACC", "1");
+  }
 }
 
 /// Initialize the predefined C++ language feature test macros defined in
diff --git a/clang/test/Driver/openacc.c b/clang/test/Driver/openacc.c
new file mode 100644
index 000000000000000..f46e2a32bcab253
--- /dev/null
+++ b/clang/test/Driver/openacc.c
@@ -0,0 +1,2 @@
+// RUN: %clang -S -### -fopenacc %s 2>&1 | FileCheck %s --check-prefix=CHECK-DRIVER
+// CHECK-DRIVER: "-cc1" {{.*}} "-fopenacc"
diff --git a/clang/test/Preprocessor/openacc.c b/clang/test/Preprocessor/openacc.c
new file mode 100644
index 000000000000000..2b749d14a5f9ce3
--- /dev/null
+++ b/clang/test/Preprocessor/openacc.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E -fopenacc %s | FileCheck %s --check-prefix=DEFAULT
+
+// DEFAULT: OpenACC:1:
+OpenACC:_OPENACC:

>From 895fd15c90069a00b192ebf11e7b8e83e7027818 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Mon, 23 Oct 2023 14:11:46 -0700
Subject: [PATCH 2/5] [OpenACC] Add OpenACC Macro Override functionality

The OpenACC spec defines `_OPENACC` to be equal to the latest standard
implemented. However, since we're not done implementing any standard,
we've defined this by default to be `1`. As it is useful to run our
compiler against existing OpenACC workloads, we're providing a
temporary override flag to change the `_OPENACC` value to be any
entirely digit value, permitting testing against any existing OpenACC
project.
---
 clang/docs/ReleaseNotes.rst               |  4 ++++
 clang/include/clang/Basic/LangOptions.h   |  5 +++++
 clang/include/clang/Driver/Options.td     | 13 +++++++++++++
 clang/lib/Driver/ToolChains/Clang.cpp     | 14 +++++++++++---
 clang/lib/Frontend/CompilerInvocation.cpp | 12 ++++++++++--
 clang/lib/Frontend/InitPreprocessor.cpp   |  9 +++++++--
 clang/test/Driver/openacc.c               | 12 ++++++++++++
 clang/test/Preprocessor/openacc.c         |  2 ++
 8 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8f40872b539322a..2010d6d21e4daf9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -676,6 +676,10 @@ OpenACC Specific Changes
   of OpenACC pragmas. The ``-fopenacc`` flag was added to enable these new,
   albeit incomplete changes. The ``_OPENACC`` macro is currently defined to
   ``1``, as support is too incomplete to update to a standards-required value.
+- Added ``-fexperimental-openacc-macro-override``, a command line option to
+  permit overriding the ``_OPENACC`` macro to be any digit-only value specified
+  by the user, which permits testing the compiler against existing OpenACC
+  workloads in order to evaluate implementation progress.
 
 Target Specific Changes
 -----------------------
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 20a8ada60e0fe51..f6482f5ee6697c3 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -502,6 +502,11 @@ class LangOptions : public LangOptionsBase {
   // received as a result of a standard operator new (-fcheck-new)
   bool CheckNew = false;
 
+  // In OpenACC mode, contains a user provided override for the _OPENACC macro.
+  // This exists so that we can override the macro value and test our incomplete
+  // implementation on real-world examples.
+  std::string OpenACCMacroOverride;
+
   LangOptions();
 
   /// Set language defaults for the given input language and
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ab28c3e394afe93..df87bdab32f48b2 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1349,6 +1349,19 @@ def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">,
   HelpText<"Do not override toolchain to compile HIP source to relocatable">;
 }
 
+// Clang specific/exclusive options for OpenACC.
+def openacc_macro_override
+    : Separate<["-"], "fexperimental-openacc-macro-override">,
+      Visibility<[ClangOption, CC1Option]>,
+      Group<f_Group>,
+      HelpText<"Overrides the _OPENACC macro value for experimental testing "
+               "during OpenACC support development">;
+def openacc_macro_override_EQ
+    : Joined<["-"], "fexperimental-openacc-macro-override=">,
+      Alias<openacc_macro_override>;
+
+// End Clang specific/exclusive options for OpenACC.
+
 def libomptarget_amdgpu_bc_path_EQ : Joined<["--"], "libomptarget-amdgpu-bc-path=">, Group<i_Group>,
   HelpText<"Path to libomptarget-amdgcn bitcode library">;
 def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path=">, Group<i_Group>,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index cf65773de0d010d..6bee10c08cf631d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3633,12 +3633,20 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
     CmdArgs.push_back("-finclude-default-header");
 }
 
-static void RenderOpenACCOptions(const ArgList &Args, ArgStringList &CmdArgs,
-                                 types::ID InputType) {
+static void RenderOpenACCOptions(const Driver &D, const ArgList &Args,
+                                 ArgStringList &CmdArgs, types::ID InputType) {
   if (!Args.hasArg(options::OPT_fopenacc))
     return;
 
   CmdArgs.push_back("-fopenacc");
+
+  if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override)) {
+    StringRef Value = A->getValue();
+    if (llvm::find_if_not(Value, isdigit) == Value.end())
+      A->renderAsInput(Args, CmdArgs);
+    else
+      D.Diag(diag::err_drv_clang_unsupported) << Value;
+  }
 }
 
 static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args,
@@ -6606,7 +6614,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   RenderHLSLOptions(Args, CmdArgs, InputType);
 
   // Forward OpenACC options to -cc1
-  RenderOpenACCOptions(Args, CmdArgs, InputType);
+  RenderOpenACCOptions(D, Args, CmdArgs, InputType);
 
   if (IsHIP) {
     if (Args.hasFlag(options::OPT_fhip_new_launch_api,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 44f15e094d64593..8db78528bbe561c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3532,8 +3532,12 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
   if (Opts.OpenMPCUDAMode)
     GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
 
-  if (Opts.OpenACC)
+  if (Opts.OpenACC) {
     GenerateArg(Consumer, OPT_fopenacc);
+    if (!Opts.OpenACCMacroOverride.empty())
+      GenerateArg(Consumer, OPT_openacc_macro_override,
+                  Opts.OpenACCMacroOverride);
+  }
 
   // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
   // generated from CodeGenOptions.
@@ -4005,9 +4009,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
                         Args.hasArg(options::OPT_fopenmp_cuda_mode);
 
   // OpenACC Configuration.
-  if (Args.hasArg(options::OPT_fopenacc))
+  if (Args.hasArg(options::OPT_fopenacc)) {
     Opts.OpenACC = true;
 
+    if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
+      Opts.OpenACCMacroOverride = A->getValue();
+  }
+
   // FIXME: Eliminate this dependency.
   unsigned Opt = getOptimizationLevel(Args, IK, Diags),
        OptSize = getOptimizationLevelSize(Args);
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 182a9e53af589c0..17948dcebd7e55a 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -608,8 +608,13 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
 
   if (LangOpts.OpenACC) {
     // FIXME: When we have full support for OpenACC, we should set this to the
-    // version we support. Until then, set as '1'.
-    Builder.defineMacro("_OPENACC", "1");
+    // version we support. Until then, set as '1' by default, but provide a
+    // temporary mechanism for users to override this so real-world examples can
+    // be tested against.
+    if (!LangOpts.OpenACCMacroOverride.empty())
+      Builder.defineMacro("_OPENACC", LangOpts.OpenACCMacroOverride);
+    else
+      Builder.defineMacro("_OPENACC", "1");
   }
 }
 
diff --git a/clang/test/Driver/openacc.c b/clang/test/Driver/openacc.c
index f46e2a32bcab253..c7f1d2545bd03ac 100644
--- a/clang/test/Driver/openacc.c
+++ b/clang/test/Driver/openacc.c
@@ -1,2 +1,14 @@
 // RUN: %clang -S -### -fopenacc %s 2>&1 | FileCheck %s --check-prefix=CHECK-DRIVER
 // CHECK-DRIVER: "-cc1" {{.*}} "-fopenacc"
+
+// RUN: %clang -S -### -fopenacc -fexperimental-openacc-macro-override=202211 %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACRO-OVERRIDE
+// RUN: %clang -S -### -fopenacc -fexperimental-openacc-macro-override 202211 %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACRO-OVERRIDE
+// CHECK-MACRO-OVERRIDE: "-cc1"{{.*}} "-fexperimental-openacc-macro-override" "202211"
+
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override=202211L %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override 202211L %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override=L202211 %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override L202211 %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override=2022L11 %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not %clang -S -fopenacc -fexperimental-openacc-macro-override 2022L11 %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// INVALID: error: the clang compiler does not support
diff --git a/clang/test/Preprocessor/openacc.c b/clang/test/Preprocessor/openacc.c
index 2b749d14a5f9ce3..888ce3ab292c6bd 100644
--- a/clang/test/Preprocessor/openacc.c
+++ b/clang/test/Preprocessor/openacc.c
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -E -fopenacc %s | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 -E -fopenacc -fexperimental-openacc-macro-override 202211 %s | FileCheck %s --check-prefix=OVERRIDE
 
 // DEFAULT: OpenACC:1:
+// OVERRIDE: OpenACC:202211:
 OpenACC:_OPENACC:

>From ccb4f3b8eb2e9606b463b904a581abe08e18443b Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Tue, 24 Oct 2023 10:05:38 -0700
Subject: [PATCH 3/5] [OpenACC] Add initial Parsing Infrastructure

Exactly like the OpenMP parser, the OpenACC pragma parser needs to
consume and reprocess the tokens. This patch sets up the infrastructure
to do so by refactoring the OpenMP version of this into a more general
version that works for OpenACC as well.

Additionally, this adds a few diagnostics and token kinds to get us
started.
---
 clang/include/clang/Basic/DiagnosticGroups.td |  4 +
 .../clang/Basic/DiagnosticParseKinds.td       |  9 ++
 clang/include/clang/Basic/TokenKinds.def      |  6 ++
 clang/include/clang/Parse/Parser.h            | 13 +++
 clang/lib/Parse/CMakeLists.txt                |  1 +
 clang/lib/Parse/ParseDecl.cpp                 |  5 +
 clang/lib/Parse/ParseDeclCXX.cpp              |  2 +
 clang/lib/Parse/ParseOpenACC.cpp              | 27 ++++++
 clang/lib/Parse/ParsePragma.cpp               | 92 ++++++++++++++-----
 clang/lib/Parse/ParseStmt.cpp                 |  3 +
 clang/lib/Parse/Parser.cpp                    |  8 ++
 clang/lib/Serialization/ASTReader.cpp         |  2 +
 clang/lib/Serialization/ASTWriter.cpp         |  2 +
 clang/test/ParserOpenACC/disabled.c           |  4 +
 clang/test/ParserOpenACC/unimplemented.c      | 20 ++++
 clang/test/ParserOpenACC/unimplemented.cpp    | 20 ++++
 16 files changed, 193 insertions(+), 25 deletions(-)
 create mode 100644 clang/lib/Parse/ParseOpenACC.cpp
 create mode 100644 clang/test/ParserOpenACC/disabled.c
 create mode 100644 clang/test/ParserOpenACC/unimplemented.c
 create mode 100644 clang/test/ParserOpenACC/unimplemented.cpp

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 318eb0d6f889065..5dc1b5b718ad528 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1311,6 +1311,10 @@ def OpenMP : DiagGroup<"openmp", [
     OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException
   ]>;
 
+// OpenACC warnings.
+def SourceUsesOpenACC : DiagGroup<"source-uses-openacc">;
+def OpenACC : DiagGroup<"openacc", [SourceUsesOpenACC]>;
+
 // Backend warnings.
 def BackendInlineAsm : DiagGroup<"inline-asm">;
 def BackendSourceMgr : DiagGroup<"source-mgr">;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index d6652e6a610c1be..7567d9b8a0aa099 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1342,6 +1342,15 @@ def err_opencl_logical_exclusive_or : Error<
 def err_openclcxx_virtual_function : Error<
   "virtual functions are not supported in C++ for OpenCL">;
 
+// OpenACC Support.
+def warn_pragma_acc_ignored : Warning<
+  "unexpected '#pragma acc ...' in program">, InGroup<SourceUsesOpenACC>, DefaultIgnore;
+def err_acc_unexpected_directive : Error<
+  "unexpected OpenACC directive %select{|'#pragma acc %1'}0">;
+def warn_pragma_acc_unimplemented
+    : Warning<"OpenACC Directives not yet implemented, pragma ignored">,
+      InGroup<SourceUsesOpenACC>;
+
 // OpenMP support.
 def warn_pragma_omp_ignored : Warning<
   "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 3ce317d318f9bb6..bbfb5cfccac2f48 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -943,6 +943,12 @@ ANNOTATION(attr_openmp)
 PRAGMA_ANNOTATION(pragma_openmp)
 PRAGMA_ANNOTATION(pragma_openmp_end)
 
+// Annotations for OpenACC pragma directives - #pragma acc.
+// Like with OpenMP, these are produced by the lexer when it parses a
+// #pragma acc directive so it can be handled during parsing of the directives.
+PRAGMA_ANNOTATION(pragma_openacc)
+PRAGMA_ANNOTATION(pragma_openacc_end)
+
 // Annotations for loop pragma directives #pragma clang loop ...
 // The lexer produces these so that they only take effect when the parser
 // handles #pragma loop ... directives.
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 79ac622fd03e24e..7a394507f862c92 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -175,6 +175,7 @@ class Parser : public CodeCompletionHandler {
   std::unique_ptr<PragmaHandler> FPContractHandler;
   std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
   std::unique_ptr<PragmaHandler> OpenMPHandler;
+  std::unique_ptr<PragmaHandler> OpenACCHandler;
   std::unique_ptr<PragmaHandler> PCSectionHandler;
   std::unique_ptr<PragmaHandler> MSCommentHandler;
   std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
@@ -229,6 +230,9 @@ class Parser : public CodeCompletionHandler {
   /// Parsing OpenMP directive mode.
   bool OpenMPDirectiveParsing = false;
 
+  /// Parsing OpenACC directive mode.
+  bool OpenACCDirectiveParsing = false;
+
   /// When true, we are directly inside an Objective-C message
   /// send expression.
   ///
@@ -3524,6 +3528,15 @@ class Parser : public CodeCompletionHandler {
   /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
   bool parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data);
 
+  //===--------------------------------------------------------------------===//
+  // OpenACC Parsing.
+
+  /// Placeholder for now, should just ignore the directives after emitting a
+  /// diagnostic. Eventually will be split into a few functions to parse
+  /// different situations.
+  DeclGroupPtrTy ParseOpenACCDirective();
+  StmtResult ParseOpenACCDirectiveStmt();
+
 private:
   //===--------------------------------------------------------------------===//
   // C++ 14: Templates [temp]
diff --git a/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt
index 5a20e9da974fa9b..22e902f7e1bc500 100644
--- a/clang/lib/Parse/CMakeLists.txt
+++ b/clang/lib/Parse/CMakeLists.txt
@@ -23,6 +23,7 @@ add_clang_library(clangParse
   ParseTemplate.cpp
   ParseTentative.cpp
   Parser.cpp
+  ParseOpenACC.cpp
 
   LINK_LIBS
   clangAST
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 78c3ab72979a007..f265faa8a73f7d4 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4748,6 +4748,11 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
       continue;
     }
 
+    if (Tok.is(tok::annot_pragma_openacc)) {
+      ParseOpenACCDirective();
+      continue;
+    }
+
     if (tok::isPragmaAnnotation(Tok.getKind())) {
       Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
           << DeclSpec::getSpecifierName(
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 35b1a93a54a6aab..e12215d74bcc8ed 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3429,6 +3429,8 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
   case tok::annot_pragma_openmp:
     return ParseOpenMPDeclarativeDirectiveWithExtDecl(
         AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl);
+  case tok::annot_pragma_openacc:
+    return ParseOpenACCDirective();
 
   default:
     if (tok::isPragmaAnnotation(Tok.getKind())) {
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
new file mode 100644
index 000000000000000..2fba6cd2805cf97
--- /dev/null
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -0,0 +1,27 @@
+//===--- ParseOpenACC.cpp - OpenACC-specific parsing support --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the parsing logic for OpenACC language features.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
+
+using namespace clang;
+
+Parser::DeclGroupPtrTy Parser::ParseOpenACCDirective() {
+  Diag(Tok, diag::warn_pragma_acc_unimplemented);
+  SkipUntil(tok::annot_pragma_openacc_end);
+  return nullptr;
+}
+StmtResult Parser::ParseOpenACCDirectiveStmt() {
+  Diag(Tok, diag::warn_pragma_acc_unimplemented);
+  SkipUntil(tok::annot_pragma_openacc_end);
+  return StmtEmpty();
+}
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index b3178aef64d72d7..d3fb7fcc8dfac6e 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -166,18 +166,51 @@ struct PragmaFPHandler : public PragmaHandler {
                     Token &FirstToken) override;
 };
 
-struct PragmaNoOpenMPHandler : public PragmaHandler {
-  PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
+// A pragma handler to be the base of the NoOpenMPHandler and NoOpenACCHandler,
+// which are identical other than the name given to them, and the diagnostic
+// emitted.
+template <diag::kind IgnoredDiag>
+struct PragmaNoSupportHandler : public PragmaHandler {
+  PragmaNoSupportHandler(StringRef Name) : PragmaHandler(Name) {}
   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                     Token &FirstToken) override;
 };
 
-struct PragmaOpenMPHandler : public PragmaHandler {
-  PragmaOpenMPHandler() : PragmaHandler("omp") { }
+struct PragmaNoOpenMPHandler
+    : public PragmaNoSupportHandler<diag::warn_pragma_omp_ignored> {
+  PragmaNoOpenMPHandler() : PragmaNoSupportHandler("omp") {}
+};
+
+struct PragmaNoOpenACCHandler
+    : public PragmaNoSupportHandler<diag::warn_pragma_acc_ignored> {
+  PragmaNoOpenACCHandler() : PragmaNoSupportHandler("acc") {}
+};
+
+// A pragma handler to be the base for the OpenMPHandler and OpenACCHandler,
+// which are identical other than the tokens used for the start/end of a pragma
+// section, and some diagnostics.
+template <tok::TokenKind StartTok, tok::TokenKind EndTok,
+          diag::kind UnexpectedDiag>
+struct PragmaSupportHandler : public PragmaHandler {
+  PragmaSupportHandler(StringRef Name) : PragmaHandler(Name) {}
   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                     Token &FirstToken) override;
 };
 
+struct PragmaOpenMPHandler
+    : public PragmaSupportHandler<tok::annot_pragma_openmp,
+                                  tok::annot_pragma_openmp_end,
+                                  diag::err_omp_unexpected_directive> {
+  PragmaOpenMPHandler() : PragmaSupportHandler("omp") {}
+};
+
+struct PragmaOpenACCHandler
+    : public PragmaSupportHandler<tok::annot_pragma_openacc,
+                                  tok::annot_pragma_openacc_end,
+                                  diag::err_acc_unexpected_directive> {
+  PragmaOpenACCHandler() : PragmaSupportHandler("acc") {}
+};
+
 /// PragmaCommentHandler - "\#pragma comment ...".
 struct PragmaCommentHandler : public PragmaHandler {
   PragmaCommentHandler(Sema &Actions)
@@ -423,6 +456,12 @@ void Parser::initializePragmaHandlers() {
     OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
   PP.AddPragmaHandler(OpenMPHandler.get());
 
+  if (getLangOpts().OpenACC)
+    OpenACCHandler = std::make_unique<PragmaOpenACCHandler>();
+  else
+    OpenACCHandler = std::make_unique<PragmaNoOpenACCHandler>();
+  PP.AddPragmaHandler(OpenACCHandler.get());
+
   if (getLangOpts().MicrosoftExt ||
       getTargetInfo().getTriple().isOSBinFormatELF()) {
     MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
@@ -542,6 +581,9 @@ void Parser::resetPragmaHandlers() {
   PP.RemovePragmaHandler(OpenMPHandler.get());
   OpenMPHandler.reset();
 
+  PP.RemovePragmaHandler(OpenACCHandler.get());
+  OpenACCHandler.reset();
+
   if (getLangOpts().MicrosoftExt ||
       getTargetInfo().getTriple().isOSBinFormatELF()) {
     PP.RemovePragmaHandler(MSCommentHandler.get());
@@ -2610,42 +2652,42 @@ void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
                                                StateLoc, State);
 }
 
-/// Handle '#pragma omp ...' when OpenMP is disabled.
-///
-void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
-                                         PragmaIntroducer Introducer,
-                                         Token &FirstTok) {
-  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
-                                     FirstTok.getLocation())) {
-    PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
-    PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
-                                    diag::Severity::Ignored, SourceLocation());
+/// Handle '#pragma omp ...' when OpenMP is disabled and '#pragma acc ...' when
+/// OpenACC is disabled.
+template <diag::kind IgnoredDiag>
+void PragmaNoSupportHandler<IgnoredDiag>::HandlePragma(
+    Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstTok) {
+  if (!PP.getDiagnostics().isIgnored(IgnoredDiag, FirstTok.getLocation())) {
+    PP.Diag(FirstTok, IgnoredDiag);
+    PP.getDiagnostics().setSeverity(IgnoredDiag, diag::Severity::Ignored,
+                                    SourceLocation());
   }
   PP.DiscardUntilEndOfDirective();
 }
 
-/// Handle '#pragma omp ...' when OpenMP is enabled.
-///
-void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
-                                       PragmaIntroducer Introducer,
-                                       Token &FirstTok) {
+/// Handle '#pragma omp ...' when OpenMP is enabled, and handle '#pragma acc...'
+/// when OpenACC is enabled.
+template <tok::TokenKind StartTok, tok::TokenKind EndTok,
+          diag::kind UnexpectedDiag>
+void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
+    Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstTok) {
   SmallVector<Token, 16> Pragma;
   Token Tok;
   Tok.startToken();
-  Tok.setKind(tok::annot_pragma_openmp);
+  Tok.setKind(StartTok);
   Tok.setLocation(Introducer.Loc);
 
   while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
     Pragma.push_back(Tok);
     PP.Lex(Tok);
-    if (Tok.is(tok::annot_pragma_openmp)) {
-      PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
+    if (Tok.is(StartTok)) {
+      PP.Diag(Tok, UnexpectedDiag) << 0;
       unsigned InnerPragmaCnt = 1;
       while (InnerPragmaCnt != 0) {
         PP.Lex(Tok);
-        if (Tok.is(tok::annot_pragma_openmp))
+        if (Tok.is(StartTok))
           ++InnerPragmaCnt;
-        else if (Tok.is(tok::annot_pragma_openmp_end))
+        else if (Tok.is(EndTok))
           --InnerPragmaCnt;
       }
       PP.Lex(Tok);
@@ -2653,7 +2695,7 @@ void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
   }
   SourceLocation EodLoc = Tok.getLocation();
   Tok.startToken();
-  Tok.setKind(tok::annot_pragma_openmp_end);
+  Tok.setKind(EndTok);
   Tok.setLocation(EodLoc);
   Pragma.push_back(Tok);
 
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 2531147c23196ae..924f27da8b52c88 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -475,6 +475,9 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
     // Do not prohibit attributes if they were OpenMP attributes.
     return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
 
+  case tok::annot_pragma_openacc:
+    return ParseOpenACCDirectiveStmt();
+
   case tok::annot_pragma_ms_pointers_to_members:
     ProhibitAttributes(CXX11Attrs);
     ProhibitAttributes(GNUAttrs);
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0f930248e77174b..9ffe807a9640145 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -317,6 +317,12 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
         return false;
       ConsumeAnnotationToken();
       break;
+    case tok::annot_pragma_openacc:
+    case tok::annot_pragma_openacc_end:
+      if (OpenACCDirectiveParsing)
+        return false;
+      ConsumeAnnotationToken();
+      break;
     case tok::annot_module_begin:
     case tok::annot_module_end:
     case tok::annot_module_include:
@@ -850,6 +856,8 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
     AccessSpecifier AS = AS_none;
     return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
   }
+  case tok::annot_pragma_openacc:
+    return ParseOpenACCDirective();
   case tok::annot_pragma_ms_pointers_to_members:
     HandlePragmaMSPointersToMembers();
     return nullptr;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 42b48d230af7a97..dbc2d0b56c46d9c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1819,6 +1819,8 @@ Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record,
     case tok::annot_pragma_openmp:
     case tok::annot_pragma_openmp_end:
     case tok::annot_pragma_unused:
+    case tok::annot_pragma_openacc:
+    case tok::annot_pragma_openacc_end:
       break;
     default:
       llvm_unreachable("missing deserialization code for annotation token");
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 739344b9a128dcf..02ac27fce27849b 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4499,6 +4499,8 @@ void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) {
     case tok::annot_pragma_openmp:
     case tok::annot_pragma_openmp_end:
     case tok::annot_pragma_unused:
+    case tok::annot_pragma_openacc:
+    case tok::annot_pragma_openacc_end:
       break;
     default:
       llvm_unreachable("missing serialization code for annotation token");
diff --git a/clang/test/ParserOpenACC/disabled.c b/clang/test/ParserOpenACC/disabled.c
new file mode 100644
index 000000000000000..a25192ff3467cc5
--- /dev/null
+++ b/clang/test/ParserOpenACC/disabled.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -verify -Wsource-uses-openacc
+// expected-warning at +1{{unexpected '#pragma acc ...' in program}}
+#pragma acc foo bar baz blitz.
+int foo;
diff --git a/clang/test/ParserOpenACC/unimplemented.c b/clang/test/ParserOpenACC/unimplemented.c
new file mode 100644
index 000000000000000..5663e14b3a95a12
--- /dev/null
+++ b/clang/test/ParserOpenACC/unimplemented.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -verify -fopenacc
+
+// Parser::ParseExternalDeclaration
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+int foo;
+
+struct S {
+// Parser::ParseStructUnionBody
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+  int foo;
+};
+
+void func() {
+// Parser::ParseStmtOrDeclarationAfterAttributes
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+  while(0) {}
+}
diff --git a/clang/test/ParserOpenACC/unimplemented.cpp b/clang/test/ParserOpenACC/unimplemented.cpp
new file mode 100644
index 000000000000000..a91c7f9f8548f80
--- /dev/null
+++ b/clang/test/ParserOpenACC/unimplemented.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -verify -fopenacc
+
+// Parser::ParseExternalDeclaration
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+int foo;
+
+struct S {
+// Parser::ParseCXXClassMemberDeclarationWithPragmas
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+  int foo;
+};
+
+void func() {
+// Parser::ParseStmtOrDeclarationAfterAttributes
+// expected-warning at +1{{OpenACC Directives not yet implemented, pragma ignored}}
+#pragma acc not yet implemented
+  while(false) {}
+}

>From fb2c16b7e504734ce68ed48c4437ca6b5a88954d Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Wed, 25 Oct 2023 13:44:43 -0700
Subject: [PATCH 4/5] Remove inadvertantly included release note, came from a
 bad rebase

---
 clang/docs/ReleaseNotes.rst | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2010d6d21e4daf9..ffecd85dd9de61b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -211,9 +211,6 @@ New Compiler Flags
   the preprocessed text to the output. This can greatly reduce the size of the
   preprocessed output, which can be helpful when trying to reduce a test case.
 
-* ``-Wbitfield-conversion`` was added to detect assignments of integral
-  types to a bitfield that may change the value.
-
 * ``-fopenacc`` was added as a part of the effort to support OpenACC in clang.
 
 Deprecated Compiler Flags

>From 8f060a1a3a7d7bc48c131755dd9e86394d35d636 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Wed, 25 Oct 2023 13:45:51 -0700
Subject: [PATCH 5/5] Remove trailing whitespace character that the buildbots
 decided to incorrectly blame on me.

---
 clang/include/clang/Basic/DiagnosticParseKinds.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 7567d9b8a0aa099..f4e6dde0ed2916e 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1358,7 +1358,7 @@ def warn_omp_extra_tokens_at_eol : Warning<
   "extra tokens at the end of '#pragma omp %0' are ignored">,
   InGroup<ExtraTokens>;
 def err_omp_multiple_step_or_linear_modifier : Error<
-  "multiple %select{'step size'|'linear modifier'}0 found in linear clause">; 
+  "multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
 def warn_pragma_expected_colon_r_paren : Warning<
   "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
 def err_omp_unknown_directive : Error<



More information about the cfe-commits mailing list