+static void
+handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
+{
+ const char *kind_string, *option_string;
+ unsigned int option_index;
+ enum cpp_ttype token;
+ diagnostic_t kind;
+ tree x;
+
+ if (cfun)
+ {
+ error ("#pragma GCC diagnostic not allowed inside functions");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (token != CPP_NAME)
+ GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+ kind_string = IDENTIFIER_POINTER (x);
+ if (strcmp (kind_string, "error") == 0)
+ kind = DK_ERROR;
+ else if (strcmp (kind_string, "warning") == 0)
+ kind = DK_WARNING;
+ else if (strcmp (kind_string, "ignored") == 0)
+ kind = DK_IGNORED;
+ else
+ GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+
+ token = pragma_lex (&x);
+ if (token != CPP_STRING)
+ GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
+ option_string = TREE_STRING_POINTER (x);
+ for (option_index = 0; option_index < cl_options_count; option_index++)
+ if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
+ {
+ /* This overrides -Werror, for example. */
+ diagnostic_classify_diagnostic (global_dc, option_index, kind);
+ /* This makes sure the option is enabled, like -Wfoo would do. */
+ if (cl_options[option_index].var_type == CLVC_BOOLEAN
+ && cl_options[option_index].flag_var
+ && kind != DK_IGNORED)
+ *(int *) cl_options[option_index].flag_var = 1;
+ return;
+ }
+ GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
+}
+
+/* A vector of registered pragma callbacks. */
+
+DEF_VEC_O (pragma_handler);
+DEF_VEC_ALLOC_O (pragma_handler, heap);
+
+static VEC(pragma_handler, heap) *registered_pragmas;
+
+typedef struct
+{
+ const char *space;
+ const char *name;
+} pragma_ns_name;
+
+DEF_VEC_O (pragma_ns_name);
+DEF_VEC_ALLOC_O (pragma_ns_name, heap);
+
+static VEC(pragma_ns_name, heap) *registered_pp_pragmas;
+
+struct omp_pragma_def { const char *name; unsigned int id; };
+static const struct omp_pragma_def omp_pragmas[] = {
+ { "atomic", PRAGMA_OMP_ATOMIC },
+ { "barrier", PRAGMA_OMP_BARRIER },
+ { "critical", PRAGMA_OMP_CRITICAL },
+ { "flush", PRAGMA_OMP_FLUSH },
+ { "for", PRAGMA_OMP_FOR },
+ { "master", PRAGMA_OMP_MASTER },
+ { "ordered", PRAGMA_OMP_ORDERED },
+ { "parallel", PRAGMA_OMP_PARALLEL },
+ { "section", PRAGMA_OMP_SECTION },
+ { "sections", PRAGMA_OMP_SECTIONS },
+ { "single", PRAGMA_OMP_SINGLE },
+ { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
+};
+
+void
+c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
+{
+ const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
+ int i;
+
+ for (i = 0; i < n_omp_pragmas; ++i)
+ if (omp_pragmas[i].id == id)
+ {
+ *space = "omp";
+ *name = omp_pragmas[i].name;
+ return;
+ }
+
+ if (id >= PRAGMA_FIRST_EXTERNAL
+ && (id < PRAGMA_FIRST_EXTERNAL
+ + VEC_length (pragma_ns_name, registered_pp_pragmas)))
+ {
+ *space = VEC_index (pragma_ns_name, registered_pp_pragmas,
+ id - PRAGMA_FIRST_EXTERNAL)->space;
+ *name = VEC_index (pragma_ns_name, registered_pp_pragmas,
+ id - PRAGMA_FIRST_EXTERNAL)->name;
+ return;
+ }
+
+ gcc_unreachable ();