/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2019 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "alias.h"
-#include "tree.h"
-#include "options.h"
+#include "target.h"
+#include "function.h" /* For cfun. */
+#include "c-common.h"
+#include "memmodel.h"
+#include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS. */
#include "stringpool.h"
+#include "cgraph.h"
+#include "diagnostic.h"
#include "attribs.h"
#include "varasm.h"
-#include "hard-reg-set.h"
-#include "function.h" /* For cfun. FIXME: Does the parser know
- when it is inside a function, so that
- we don't have to look at cfun? */
-#include "cpplib.h"
#include "c-pragma.h"
-#include "flags.h"
-#include "c-common.h"
-#include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS (why is
- this not a target hook?). */
-#include "target.h"
-#include "diagnostic.h"
#include "opts.h"
#include "plugin.h"
-#include "cgraph.h"
#define GCC_BAD(gmsgid) \
do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
if (flag_pack_struct)
- GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
+ GCC_BAD ("#pragma pack has no effect with %<-fpack-struct%> - ignored");
if (action != pop)
switch (align)
align = maximum_field_alignment;
break;
}
+ /* FALLTHRU */
default:
GCC_BAD2 ("alignment must be a small power of two, not %d", align);
}
}
}
+static enum scalar_storage_order_kind global_sso;
+
+void
+maybe_apply_pragma_scalar_storage_order (tree type)
+{
+ if (global_sso == SSO_NATIVE)
+ return;
+
+ gcc_assert (RECORD_OR_UNION_TYPE_P (type));
+
+ if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
+ return;
+
+ if (global_sso == SSO_BIG_ENDIAN)
+ TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
+ else if (global_sso == SSO_LITTLE_ENDIAN)
+ TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
+ else
+ gcc_unreachable ();
+}
+
+static void
+handle_pragma_scalar_storage_order (cpp_reader *ARG_UNUSED(dummy))
+{
+ const char *kind_string;
+ enum cpp_ttype token;
+ tree x;
+
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ {
+ error ("scalar_storage_order is not supported because endianness "
+ "is not uniform");
+ return;
+ }
+
+ if (c_dialect_cxx ())
+ {
+ if (warn_unknown_pragmas > in_system_header_at (input_location))
+ warning (OPT_Wunknown_pragmas,
+ "%<#pragma scalar_storage_order%> is not supported for C++");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (token != CPP_NAME)
+ GCC_BAD ("missing [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+ kind_string = IDENTIFIER_POINTER (x);
+ if (strcmp (kind_string, "default") == 0)
+ global_sso = default_sso;
+ else if (strcmp (kind_string, "big") == 0)
+ global_sso = SSO_BIG_ENDIAN;
+ else if (strcmp (kind_string, "little") == 0)
+ global_sso = SSO_LITTLE_ENDIAN;
+ else
+ GCC_BAD ("expected [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+}
+
/* GCC supports two #pragma directives for renaming the external
symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
compatibility with the Solaris and VMS system headers. GCC also
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = targetm.strip_name_encoding (name);
- if (strcmp (name, IDENTIFIER_POINTER (newname)))
+ if (!id_equal (newname, name))
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
"conflict with previous rename");
}
if (DECL_NAME (decl) == p->oldname)
{
/* Only warn if there is a conflict. */
- if (strcmp (IDENTIFIER_POINTER (p->newname), oldname))
+ if (!id_equal (p->newname, oldname))
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
"conflict with previous rename");
pending_redefine_extname->unordered_remove (ix);
break;
}
- return 0;
+ return NULL_TREE;
}
/* Find out if we have a pending #pragma redefine_extname. */
}
/* Nada. */
- return 0;
+ return NULL_TREE;
}
return;
}
- struct cl_option_handlers handlers;
- set_default_handlers (&handlers);
-
- unsigned int option_index;
const char *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)
- {
- control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
- input_location, c_family_lang_mask, &handlers,
- &global_options, &global_options_set,
- global_dc);
- return;
- }
- warning_at (loc, OPT_Wpragmas,
- "unknown option after %<#pragma GCC diagnostic%> kind");
+ unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
+ /* option_string + 1 to skip the initial '-' */
+ unsigned int option_index = find_opt (option_string + 1, lang_mask);
+ if (option_index == OPT_SPECIAL_unknown)
+ {
+ warning_at (loc, OPT_Wpragmas,
+ "unknown option after %<#pragma GCC diagnostic%> kind");
+ return;
+ }
+ else if (!(cl_options[option_index].flags & CL_WARNING))
+ {
+ warning_at (loc, OPT_Wpragmas,
+ "%qs is not an option that controls warnings", option_string);
+ return;
+ }
+ else if (!(cl_options[option_index].flags & lang_mask))
+ {
+ char *ok_langs = write_langs (cl_options[option_index].flags);
+ char *bad_lang = write_langs (c_common_option_lang_mask ());
+ warning_at (loc, OPT_Wpragmas,
+ "option %qs is valid for %s but not for %s",
+ option_string, ok_langs, bad_lang);
+ free (ok_langs);
+ free (bad_lang);
+ return;
+ }
+
+ struct cl_option_handlers handlers;
+ set_default_handlers (&handlers, NULL);
+ const char *arg = NULL;
+ if (cl_options[option_index].flags & CL_JOINED)
+ arg = option_string + 1 + cl_options[option_index].opt_len;
+ /* FIXME: input_location isn't the best location here, but it is
+ what we used to do here before and changing it breaks e.g.
+ PR69543 and PR69558. */
+ control_warning_option (option_index, (int) kind,
+ arg, kind != DK_IGNORED,
+ input_location, lang_mask, &handlers,
+ &global_options, &global_options_set,
+ global_dc);
}
/* Parse #pragma GCC target (xxx) to set target specific options. */
args = nreverse (args);
if (targetm.target_option.pragma_parse (args, NULL_TREE))
- current_target_pragma = args;
+ current_target_pragma = chainon (current_target_pragma, args);
}
}
struct omp_pragma_def { const char *name; unsigned int id; };
static const struct omp_pragma_def oacc_pragmas[] = {
+ { "atomic", PRAGMA_OACC_ATOMIC },
{ "cache", PRAGMA_OACC_CACHE },
{ "data", PRAGMA_OACC_DATA },
+ { "declare", PRAGMA_OACC_DECLARE },
{ "enter", PRAGMA_OACC_ENTER_DATA },
{ "exit", PRAGMA_OACC_EXIT_DATA },
+ { "host_data", PRAGMA_OACC_HOST_DATA },
{ "kernels", PRAGMA_OACC_KERNELS },
{ "loop", PRAGMA_OACC_LOOP },
{ "parallel", PRAGMA_OACC_PARALLEL },
+ { "routine", PRAGMA_OACC_ROUTINE },
{ "update", PRAGMA_OACC_UPDATE },
{ "wait", PRAGMA_OACC_WAIT }
};
{ "cancel", PRAGMA_OMP_CANCEL },
{ "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
{ "critical", PRAGMA_OMP_CRITICAL },
+ { "depobj", PRAGMA_OMP_DEPOBJ },
{ "end", PRAGMA_OMP_END_DECLARE_TARGET },
{ "flush", PRAGMA_OMP_FLUSH },
{ "master", PRAGMA_OMP_MASTER },
- { "ordered", PRAGMA_OMP_ORDERED },
+ { "requires", PRAGMA_OMP_REQUIRES },
{ "section", PRAGMA_OMP_SECTION },
{ "sections", PRAGMA_OMP_SECTIONS },
{ "single", PRAGMA_OMP_SINGLE },
{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
};
static const struct omp_pragma_def omp_pragmas_simd[] = {
- { "declare", PRAGMA_OMP_DECLARE_REDUCTION },
+ { "declare", PRAGMA_OMP_DECLARE },
{ "distribute", PRAGMA_OMP_DISTRIBUTE },
{ "for", PRAGMA_OMP_FOR },
+ { "ordered", PRAGMA_OMP_ORDERED },
{ "parallel", PRAGMA_OMP_PARALLEL },
{ "simd", PRAGMA_OMP_SIMD },
{ "target", PRAGMA_OMP_TARGET },
+ { "taskloop", PRAGMA_OMP_TASKLOOP },
{ "teams", PRAGMA_OMP_TEAMS },
};
return;
}
- if (id == PRAGMA_CILK_SIMD)
- {
- *space = NULL;
- *name = "simd";
- return;
- }
-
if (id >= PRAGMA_FIRST_EXTERNAL
&& (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ()))
{
id = registered_pragmas.length ();
id += PRAGMA_FIRST_EXTERNAL - 1;
- /* The C++ front end allocates 6 bits in cp_token; the C front end
- allocates 7 bits in c_token. At present this is sufficient. */
- gcc_assert (id < 64);
+ /* The C front end allocates 8 bits in c_token. The C++ front end
+ keeps the pragma kind in the form of INTEGER_CST, so no small
+ limit applies. At present this is sufficient. */
+ gcc_assert (id < 256);
}
cpp_register_deferred_pragma (parse_in, space, name, id,
omp_pragmas_simd[i].id, true, true);
}
- if (flag_cilkplus)
- cpp_register_deferred_pragma (parse_in, NULL, "simd", PRAGMA_CILK_SIMD,
- true, false);
-
if (!flag_preprocess_only)
cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
PRAGMA_GCC_PCH_PREPROCESS, false, false);
cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
false);
- if (flag_cilkplus && !flag_preprocess_only)
- cpp_register_deferred_pragma (parse_in, "cilk", "grainsize",
- PRAGMA_CILK_GRAINSIZE, true, false);
+ if (!flag_preprocess_only)
+ cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
+ false, false);
#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
c_register_pragma (0, "pack", handle_pragma_pack);
#endif
c_register_pragma (0, "weak", handle_pragma_weak);
+
c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
REGISTER_TARGET_PRAGMAS ();
#endif
+ global_sso = default_sso;
+ c_register_pragma (0, "scalar_storage_order",
+ handle_pragma_scalar_storage_order);
+
/* Allow plugins to register their own pragmas. */
invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
}