Home | History | Annotate | Line # | Download | only in c-family
      1 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
      2    Copyright (C) 1992-2024 Free Software Foundation, Inc.
      3 
      4 This file is part of GCC.
      5 
      6 GCC is free software; you can redistribute it and/or modify it under
      7 the terms of the GNU General Public License as published by the Free
      8 Software Foundation; either version 3, or (at your option) any later
      9 version.
     10 
     11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14 for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with GCC; see the file COPYING3.  If not see
     18 <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "config.h"
     21 #include "system.h"
     22 #include "coretypes.h"
     23 #include "target.h"
     24 #include "function.h"		/* For cfun.  */
     25 #include "c-common.h"
     26 #include "memmodel.h"
     27 #include "tm_p.h"		/* For REGISTER_TARGET_PRAGMAS.  */
     28 #include "stringpool.h"
     29 #include "cgraph.h"
     30 #include "diagnostic.h"
     31 #include "attribs.h"
     32 #include "varasm.h"
     33 #include "c-pragma.h"
     34 #include "opts.h"
     35 #include "plugin.h"
     36 #include "opt-suggestions.h"
     37 
     38 #define GCC_BAD(gmsgid) \
     39   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
     40 #define GCC_BAD2(gmsgid, arg) \
     41   do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
     42 #define GCC_BAD_AT(loc, gmsgid)					\
     43   do { warning_at (loc, OPT_Wpragmas, gmsgid); return; } while (0)
     44 #define GCC_BAD2_AT(loc, gmsgid, arg)			\
     45   do { warning_at (loc, OPT_Wpragmas, gmsgid, arg); return; } while (0)
     46 
     47 struct GTY(()) align_stack {
     48   int		       alignment;
     49   tree		       id;
     50   struct align_stack * prev;
     51 };
     52 
     53 static GTY(()) struct align_stack * alignment_stack;
     54 
     55 static void handle_pragma_pack (cpp_reader *);
     56 
     57 /* If we have a "global" #pragma pack(<n>) in effect when the first
     58    #pragma pack(push,<n>) is encountered, this stores the value of
     59    maximum_field_alignment in effect.  When the final pop_alignment()
     60    happens, we restore the value to this, not to a value of 0 for
     61    maximum_field_alignment.  Value is in bits.  */
     62 static int default_alignment;
     63 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
     64 	? &default_alignment \
     65 	: &alignment_stack->alignment) = (ALIGN))
     66 
     67 static void push_alignment (int, tree);
     68 static void pop_alignment (tree);
     69 
     70 /* Push an alignment value onto the stack.  */
     71 static void
     72 push_alignment (int alignment, tree id)
     73 {
     74   align_stack * entry = ggc_alloc<align_stack> ();
     75 
     76   entry->alignment  = alignment;
     77   entry->id	    = id;
     78   entry->prev	    = alignment_stack;
     79 
     80   /* The current value of maximum_field_alignment is not necessarily
     81      0 since there may be a #pragma pack(<n>) in effect; remember it
     82      so that we can restore it after the final #pragma pop().  */
     83   if (alignment_stack == NULL)
     84     default_alignment = maximum_field_alignment;
     85 
     86   alignment_stack = entry;
     87 
     88   maximum_field_alignment = alignment;
     89 }
     90 
     91 /* Undo a push of an alignment onto the stack.  */
     92 static void
     93 pop_alignment (tree id)
     94 {
     95   align_stack * entry;
     96 
     97   if (alignment_stack == NULL)
     98     GCC_BAD ("%<#pragma pack (pop)%> encountered without matching "
     99 	     "%<#pragma pack (push)%>");
    100 
    101   /* If we got an identifier, strip away everything above the target
    102      entry so that the next step will restore the state just below it.  */
    103   if (id)
    104     {
    105       for (entry = alignment_stack; entry; entry = entry->prev)
    106 	if (entry->id == id)
    107 	  {
    108 	    alignment_stack = entry;
    109 	    break;
    110 	  }
    111       if (entry == NULL)
    112 	warning (OPT_Wpragmas,
    113 		 "%<#pragma pack(pop, %E)%> encountered without matching "
    114 		 "%<#pragma pack(push, %E)%>"
    115 		 , id, id);
    116     }
    117 
    118   entry = alignment_stack->prev;
    119 
    120   maximum_field_alignment = entry ? entry->alignment : default_alignment;
    121 
    122   alignment_stack = entry;
    123 }
    124 
    125 /* #pragma pack ()
    126    #pragma pack (N)
    127 
    128    #pragma pack (push)
    129    #pragma pack (push, N)
    130    #pragma pack (push, ID)
    131    #pragma pack (push, ID, N)
    132    #pragma pack (pop)
    133    #pragma pack (pop, ID) */
    134 static void
    135 handle_pragma_pack (cpp_reader *)
    136 {
    137   location_t loc;
    138   tree x, id = 0;
    139   int align = -1;
    140   enum cpp_ttype token;
    141   enum { set, push, pop } action;
    142 
    143   if (pragma_lex (&x) != CPP_OPEN_PAREN)
    144     GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
    145 
    146   token = pragma_lex (&x, &loc);
    147   if (token == CPP_CLOSE_PAREN)
    148     {
    149       action = set;
    150       align = initial_max_fld_align;
    151     }
    152   else if (token == CPP_NUMBER)
    153     {
    154       if (TREE_CODE (x) != INTEGER_CST)
    155 	GCC_BAD_AT (loc, "invalid constant in %<#pragma pack%> - ignored");
    156       align = TREE_INT_CST_LOW (x);
    157       action = set;
    158       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
    159 	GCC_BAD ("malformed %<#pragma pack%> - ignored");
    160     }
    161   else if (token == CPP_NAME)
    162     {
    163 #define GCC_BAD_ACTION do { if (action != pop) \
    164 	  GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
    165 	else \
    166 	  GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
    167 	} while (0)
    168 
    169       const char *op = IDENTIFIER_POINTER (x);
    170       if (!strcmp (op, "push"))
    171 	action = push;
    172       else if (!strcmp (op, "pop"))
    173 	action = pop;
    174       else
    175 	GCC_BAD2_AT (loc, "unknown action %qE for %<#pragma pack%> - ignored",
    176 		     x);
    177 
    178       while ((token = pragma_lex (&x)) == CPP_COMMA)
    179 	{
    180 	  token = pragma_lex (&x, &loc);
    181 	  if (token == CPP_NAME && id == 0)
    182 	    {
    183 	      id = x;
    184 	    }
    185 	  else if (token == CPP_NUMBER && action == push && align == -1)
    186 	    {
    187 	      if (TREE_CODE (x) != INTEGER_CST)
    188 		GCC_BAD_AT (loc,
    189 			    "invalid constant in %<#pragma pack%> - ignored");
    190 	      align = TREE_INT_CST_LOW (x);
    191 	      if (align == -1)
    192 		action = set;
    193 	    }
    194 	  else
    195 	    GCC_BAD_ACTION;
    196 	}
    197 
    198       if (token != CPP_CLOSE_PAREN)
    199 	GCC_BAD_ACTION;
    200 #undef GCC_BAD_ACTION
    201     }
    202   else
    203     GCC_BAD ("malformed %<#pragma pack%> - ignored");
    204 
    205   if (pragma_lex (&x, &loc) != CPP_EOF)
    206     warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma pack%>");
    207 
    208   if (flag_pack_struct)
    209     GCC_BAD ("%<#pragma pack%> has no effect with %<-fpack-struct%> - ignored");
    210 
    211   if (action != pop)
    212     switch (align)
    213       {
    214       case 0:
    215       case 1:
    216       case 2:
    217       case 4:
    218       case 8:
    219       case 16:
    220 	align *= BITS_PER_UNIT;
    221 	break;
    222       case -1:
    223 	if (action == push)
    224 	  {
    225 	    align = maximum_field_alignment;
    226 	    break;
    227 	  }
    228 	/* FALLTHRU */
    229       default:
    230 	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
    231       }
    232 
    233   switch (action)
    234     {
    235     case set:   SET_GLOBAL_ALIGNMENT (align);  break;
    236     case push:  push_alignment (align, id);    break;
    237     case pop:   pop_alignment (id);	       break;
    238     }
    239 }
    240 
    241 struct GTY(()) pending_weak
    242 {
    243   tree name;
    244   tree value;
    245 };
    246 
    247 
    248 static GTY(()) vec<pending_weak, va_gc> *pending_weaks;
    249 
    250 static void apply_pragma_weak (tree, tree);
    251 static void handle_pragma_weak (cpp_reader *);
    252 
    253 static void
    254 apply_pragma_weak (tree decl, tree value)
    255 {
    256   if (value)
    257     {
    258       value = build_string (IDENTIFIER_LENGTH (value),
    259 			    IDENTIFIER_POINTER (value));
    260       decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
    261 					       build_tree_list (NULL, value)),
    262 		       0);
    263     }
    264 
    265   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
    266       && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
    267       && DECL_ASSEMBLER_NAME_SET_P (decl)
    268       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
    269     warning (OPT_Wpragmas, "applying %<#pragma weak %+D%> after first use "
    270 	     "results in unspecified behavior", decl);
    271 
    272   declare_weak (decl);
    273 }
    274 
    275 void
    276 maybe_apply_pragma_weak (tree decl)
    277 {
    278   tree id;
    279   int i;
    280   pending_weak *pe;
    281 
    282   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
    283 
    284   /* No weak symbols pending, take the short-cut.  */
    285   if (vec_safe_is_empty (pending_weaks))
    286     return;
    287   /* If it's not visible outside this file, it doesn't matter whether
    288      it's weak.  */
    289   if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
    290     return;
    291   /* If it's not a function or a variable, it can't be weak.
    292      FIXME: what kinds of things are visible outside this file but
    293      aren't functions or variables?   Should this be an assert instead?  */
    294   if (!VAR_OR_FUNCTION_DECL_P (decl))
    295     return;
    296 
    297   if (DECL_ASSEMBLER_NAME_SET_P (decl))
    298     id = DECL_ASSEMBLER_NAME (decl);
    299   else
    300     {
    301       id = DECL_ASSEMBLER_NAME (decl);
    302       SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
    303     }
    304 
    305   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
    306     if (id == pe->name)
    307       {
    308 	apply_pragma_weak (decl, pe->value);
    309 	pending_weaks->unordered_remove (i);
    310 	break;
    311       }
    312 }
    313 
    314 /* Process all "#pragma weak A = B" directives where we have not seen
    315    a decl for A.  */
    316 void
    317 maybe_apply_pending_pragma_weaks (void)
    318 {
    319   tree alias_id, id, decl;
    320   int i;
    321   pending_weak *pe;
    322   symtab_node *target;
    323 
    324   if (vec_safe_is_empty (pending_weaks))
    325     return;
    326 
    327   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
    328     {
    329       alias_id = pe->name;
    330       id = pe->value;
    331 
    332       if (id == NULL)
    333 	continue;
    334 
    335       target = symtab_node::get_for_asmname (id);
    336       decl = build_decl (UNKNOWN_LOCATION,
    337 			 target ? TREE_CODE (target->decl) : FUNCTION_DECL,
    338 			 alias_id, default_function_type);
    339 
    340       DECL_ARTIFICIAL (decl) = 1;
    341       TREE_PUBLIC (decl) = 1;
    342       DECL_WEAK (decl) = 1;
    343       if (VAR_P (decl))
    344 	TREE_STATIC (decl) = 1;
    345       if (!target)
    346 	{
    347 	  error ("%q+D aliased to undefined symbol %qE",
    348 		 decl, id);
    349 	  continue;
    350 	}
    351 
    352       assemble_alias (decl, id);
    353     }
    354 }
    355 
    356 /* #pragma weak name [= value] */
    357 static void
    358 handle_pragma_weak (cpp_reader *)
    359 {
    360   tree name, value, x, decl;
    361   enum cpp_ttype t;
    362 
    363   value = 0;
    364 
    365   if (pragma_lex (&name) != CPP_NAME)
    366     GCC_BAD ("malformed %<#pragma weak%>, ignored");
    367   t = pragma_lex (&x);
    368   if (t == CPP_EQ)
    369     {
    370       if (pragma_lex (&value) != CPP_NAME)
    371 	GCC_BAD ("malformed %<#pragma weak%>, ignored");
    372       t = pragma_lex (&x);
    373     }
    374   if (t != CPP_EOF)
    375     warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
    376 
    377   decl = identifier_global_value (name);
    378   if (decl && DECL_P (decl))
    379     {
    380       if (!VAR_OR_FUNCTION_DECL_P (decl))
    381 	GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed,"
    382 		  " ignored", decl);
    383       apply_pragma_weak (decl, value);
    384       if (value)
    385 	{
    386 	  DECL_EXTERNAL (decl) = 0;
    387 	  if (VAR_P (decl))
    388 	    TREE_STATIC (decl) = 1;
    389 	  assemble_alias (decl, value);
    390 	}
    391     }
    392   else
    393     {
    394       pending_weak pe = {name, value};
    395       vec_safe_push (pending_weaks, pe);
    396     }
    397 }
    398 
    399 static enum scalar_storage_order_kind global_sso;
    400 
    401 void
    402 maybe_apply_pragma_scalar_storage_order (tree type)
    403 {
    404   if (global_sso == SSO_NATIVE)
    405     return;
    406 
    407   gcc_assert (RECORD_OR_UNION_TYPE_P (type));
    408 
    409   if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
    410     return;
    411 
    412   if (global_sso == SSO_BIG_ENDIAN)
    413     TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
    414   else if (global_sso == SSO_LITTLE_ENDIAN)
    415     TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
    416   else
    417     gcc_unreachable ();
    418 }
    419 
    420 static void
    421 handle_pragma_scalar_storage_order (cpp_reader *)
    422 {
    423   const char *kind_string;
    424   enum cpp_ttype token;
    425   tree x;
    426 
    427   if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
    428     {
    429       error ("%<scalar_storage_order%> is not supported because endianness "
    430 	     "is not uniform");
    431       return;
    432     }
    433 
    434   if (c_dialect_cxx ())
    435     {
    436       if (warn_unknown_pragmas > in_system_header_at (input_location))
    437 	warning (OPT_Wunknown_pragmas,
    438 		 "%<#pragma scalar_storage_order%> is not supported for C++");
    439       return;
    440     }
    441 
    442   token = pragma_lex (&x);
    443   if (token != CPP_NAME)
    444     GCC_BAD ("missing %<big-endian%>, %<little-endian%>, or %<default%> after "
    445 	     "%<#pragma scalar_storage_order%>");
    446   kind_string = IDENTIFIER_POINTER (x);
    447   if (strcmp (kind_string, "default") == 0)
    448     global_sso = default_sso;
    449   else if (strcmp (kind_string, "big") == 0)
    450     global_sso = SSO_BIG_ENDIAN;
    451   else if (strcmp (kind_string, "little") == 0)
    452     global_sso = SSO_LITTLE_ENDIAN;
    453   else
    454     GCC_BAD ("expected %<big-endian%>, %<little-endian%>, or %<default%> after "
    455 	     "%<#pragma scalar_storage_order%>");
    456 }
    457 
    458 /* GCC supports two #pragma directives for renaming the external
    459    symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
    460    compatibility with the Solaris and VMS system headers.  GCC also
    461    has its own notation for this, __asm__("name") annotations.
    462 
    463    Corner cases of these features and their interaction:
    464 
    465    1) Both pragmas silently apply only to declarations with external
    466       linkage (that is, TREE_PUBLIC || DECL_EXTERNAL).  Asm labels
    467       do not have this restriction.
    468 
    469    2) In C++, both #pragmas silently apply only to extern "C" declarations.
    470       Asm labels do not have this restriction.
    471 
    472    3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
    473       applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
    474       new name is different, a warning issues and the name does not change.
    475 
    476    4) The "source name" for #pragma redefine_extname is the DECL_NAME,
    477       *not* the DECL_ASSEMBLER_NAME.
    478 
    479    5) If #pragma extern_prefix is in effect and a declaration occurs
    480       with an __asm__ name, the #pragma extern_prefix is silently
    481       ignored for that declaration.
    482 
    483    6) If #pragma extern_prefix and #pragma redefine_extname apply to
    484       the same declaration, whichever triggered first wins, and a warning
    485       is issued.  (We would like to have #pragma redefine_extname always
    486       win, but it can appear either before or after the declaration, and
    487       if it appears afterward, we have no way of knowing whether a modified
    488       DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.)  */
    489 
    490 struct GTY(()) pending_redefinition {
    491   tree oldname;
    492   tree newname;
    493 };
    494 
    495 
    496 static GTY(()) vec<pending_redefinition, va_gc> *pending_redefine_extname;
    497 
    498 static void handle_pragma_redefine_extname (cpp_reader *);
    499 
    500 /* #pragma redefine_extname oldname newname */
    501 static void
    502 handle_pragma_redefine_extname (cpp_reader *)
    503 {
    504   tree oldname, newname, decls, x;
    505   enum cpp_ttype t;
    506   bool found;
    507 
    508   if (pragma_lex (&oldname) != CPP_NAME)
    509     GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
    510   if (pragma_lex (&newname) != CPP_NAME)
    511     GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
    512   t = pragma_lex (&x);
    513   if (t != CPP_EOF)
    514     warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
    515 
    516   found = false;
    517   for (decls = c_linkage_bindings (oldname);
    518        decls; )
    519     {
    520       tree decl;
    521       if (TREE_CODE (decls) == TREE_LIST)
    522 	{
    523 	  decl = TREE_VALUE (decls);
    524 	  decls = TREE_CHAIN (decls);
    525 	}
    526       else
    527 	{
    528 	  decl = decls;
    529 	  decls = NULL_TREE;
    530 	}
    531 
    532       if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
    533 	  && VAR_OR_FUNCTION_DECL_P (decl))
    534 	{
    535 	  found = true;
    536 	  if (DECL_ASSEMBLER_NAME_SET_P (decl))
    537 	    {
    538 	      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    539 	      name = targetm.strip_name_encoding (name);
    540 
    541 	      if (!id_equal (newname, name))
    542 		warning (OPT_Wpragmas, "%<#pragma redefine_extname%> "
    543 			 "ignored due to conflict with previous rename");
    544 	    }
    545 	  else
    546 	    symtab->change_decl_assembler_name (decl, newname);
    547 	}
    548     }
    549 
    550   if (!found)
    551     /* We have to add this to the rename list even if there's already
    552        a global value that doesn't meet the above criteria, because in
    553        C++ "struct foo {...};" puts "foo" in the current namespace but
    554        does *not* conflict with a subsequent declaration of a function
    555        or variable foo.  See g++.dg/other/pragma-re-2.C.  */
    556     add_to_renaming_pragma_list (oldname, newname);
    557 }
    558 
    559 /* This is called from here and from ia64-c.cc.  */
    560 void
    561 add_to_renaming_pragma_list (tree oldname, tree newname)
    562 {
    563   unsigned ix;
    564   pending_redefinition *p;
    565 
    566   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
    567     if (oldname == p->oldname)
    568       {
    569 	if (p->newname != newname)
    570 	  warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored due to "
    571 		   "conflict with previous %<#pragma redefine_extname%>");
    572 	return;
    573       }
    574 
    575   pending_redefinition e = {oldname, newname};
    576   vec_safe_push (pending_redefine_extname, e);
    577 }
    578 
    579 /* The current prefix set by #pragma extern_prefix.  */
    580 GTY(()) tree pragma_extern_prefix;
    581 
    582 /* Hook from the front ends to apply the results of one of the preceding
    583    pragmas that rename variables.  */
    584 
    585 tree
    586 maybe_apply_renaming_pragma (tree decl, tree asmname)
    587 {
    588   unsigned ix;
    589   pending_redefinition *p;
    590 
    591   /* The renaming pragmas are only applied to declarations with
    592      external linkage.  */
    593   if (!VAR_OR_FUNCTION_DECL_P (decl)
    594       || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
    595       || !has_c_linkage (decl))
    596     return asmname;
    597 
    598   /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
    599      but we may warn about a rename that conflicts.  */
    600   if (DECL_ASSEMBLER_NAME_SET_P (decl))
    601     {
    602       const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    603       oldname = targetm.strip_name_encoding (oldname);
    604 
    605       if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
    606 	  warning (OPT_Wpragmas, "%<asm%> declaration ignored due to "
    607 		   "conflict with previous rename");
    608 
    609       /* Take any pending redefine_extname off the list.  */
    610       FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
    611 	if (DECL_NAME (decl) == p->oldname)
    612 	  {
    613 	    /* Only warn if there is a conflict.  */
    614 	    if (!id_equal (p->newname, oldname))
    615 	      warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored "
    616 		       "due to conflict with previous rename");
    617 
    618 	    pending_redefine_extname->unordered_remove (ix);
    619 	    break;
    620 	  }
    621       return NULL_TREE;
    622     }
    623 
    624   /* Find out if we have a pending #pragma redefine_extname.  */
    625   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
    626     if (DECL_NAME (decl) == p->oldname)
    627       {
    628 	tree newname = p->newname;
    629 	pending_redefine_extname->unordered_remove (ix);
    630 
    631 	/* If we already have an asmname, #pragma redefine_extname is
    632 	   ignored (with a warning if it conflicts).  */
    633 	if (asmname)
    634 	  {
    635 	    if (strcmp (TREE_STRING_POINTER (asmname),
    636 			IDENTIFIER_POINTER (newname)) != 0)
    637 	      warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored "
    638 		       "due to conflict with %<asm%> declaration");
    639 	    return asmname;
    640 	  }
    641 
    642 	/* Otherwise we use what we've got; #pragma extern_prefix is
    643 	   silently ignored.  */
    644 	return build_string (IDENTIFIER_LENGTH (newname),
    645 			     IDENTIFIER_POINTER (newname));
    646       }
    647 
    648   /* If we've got an asmname, #pragma extern_prefix is silently ignored.  */
    649   if (asmname)
    650     return asmname;
    651 
    652   /* If #pragma extern_prefix is in effect, apply it.  */
    653   if (pragma_extern_prefix)
    654     {
    655       const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
    656       size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
    657 
    658       const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
    659       size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
    660 
    661       char *newname = (char *) alloca (plen + ilen + 1);
    662 
    663       memcpy (newname,        prefix, plen);
    664       memcpy (newname + plen, id, ilen + 1);
    665 
    666       return build_string (plen + ilen, newname);
    667     }
    668 
    669   /* Nada.  */
    670   return NULL_TREE;
    671 }
    672 
    673 
    674 static void handle_pragma_visibility (cpp_reader *);
    675 
    676 static vec<int> visstack;
    677 
    678 /* Push the visibility indicated by STR onto the top of the #pragma
    679    visibility stack.  KIND is 0 for #pragma GCC visibility, 1 for
    680    C++ namespace with visibility attribute and 2 for C++ builtin
    681    ABI namespace.  push_visibility/pop_visibility calls must have
    682    matching KIND, it is not allowed to push visibility using one
    683    KIND and pop using a different one.  */
    684 
    685 void
    686 push_visibility (const char *str, int kind)
    687 {
    688   visstack.safe_push (((int) default_visibility) | (kind << 8));
    689   if (!strcmp (str, "default"))
    690     default_visibility = VISIBILITY_DEFAULT;
    691   else if (!strcmp (str, "internal"))
    692     default_visibility = VISIBILITY_INTERNAL;
    693   else if (!strcmp (str, "hidden"))
    694     default_visibility = VISIBILITY_HIDDEN;
    695   else if (!strcmp (str, "protected"))
    696     default_visibility = VISIBILITY_PROTECTED;
    697   else
    698     GCC_BAD ("%<#pragma GCC visibility push()%> must specify %<default%>, "
    699 	     "%<internal%>, %<hidden%> or %<protected%>");
    700   visibility_options.inpragma = 1;
    701 }
    702 
    703 /* Pop a level of the #pragma visibility stack.  Return true if
    704    successful.  */
    705 
    706 bool
    707 pop_visibility (int kind)
    708 {
    709   if (!visstack.length ())
    710     return false;
    711   if ((visstack.last () >> 8) != kind)
    712     return false;
    713   default_visibility
    714     = (enum symbol_visibility) (visstack.pop () & 0xff);
    715   visibility_options.inpragma
    716     = visstack.length () != 0;
    717   return true;
    718 }
    719 
    720 /* Sets the default visibility for symbols to something other than that
    721    specified on the command line.  */
    722 
    723 static void
    724 handle_pragma_visibility (cpp_reader *)
    725 {
    726   /* Form is #pragma GCC visibility push(hidden)|pop */
    727   tree x;
    728   enum cpp_ttype token;
    729   enum { bad, push, pop } action = bad;
    730 
    731   token = pragma_lex (&x);
    732   if (token == CPP_NAME)
    733     {
    734       const char *op = IDENTIFIER_POINTER (x);
    735       if (!strcmp (op, "push"))
    736 	action = push;
    737       else if (!strcmp (op, "pop"))
    738 	action = pop;
    739     }
    740   if (bad == action)
    741     GCC_BAD ("%<#pragma GCC visibility%> must be followed by %<push%> "
    742 	     "or %<pop%>");
    743   else
    744     {
    745       if (pop == action)
    746 	{
    747 	  if (! pop_visibility (0))
    748 	    GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
    749 	}
    750       else
    751 	{
    752 	  if (pragma_lex (&x) != CPP_OPEN_PAREN)
    753 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
    754 	  token = pragma_lex (&x);
    755 	  if (token != CPP_NAME)
    756 	    GCC_BAD ("malformed %<#pragma GCC visibility push%>");
    757 	  else
    758 	    push_visibility (IDENTIFIER_POINTER (x), 0);
    759 	  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
    760 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
    761 	}
    762     }
    763   if (pragma_lex (&x) != CPP_EOF)
    764     warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
    765 }
    766 
    767 /* Helper routines for parsing #pragma GCC diagnostic.  */
    768 class pragma_diagnostic_data
    769 {
    770   pragma_diagnostic_data (const pragma_diagnostic_data &) = delete;
    771   pragma_diagnostic_data& operator= (const pragma_diagnostic_data &) = delete;
    772 
    773 public:
    774   bool valid;
    775   location_t loc_kind, loc_option;
    776   enum pd_kind_t
    777     {
    778       PK_INVALID,
    779       PK_PUSH,
    780       PK_POP,
    781       PK_IGNORED_ATTRIBUTES,
    782       PK_DIAGNOSTIC,
    783     } pd_kind;
    784   diagnostic_t diagnostic_kind;
    785   const char *kind_str;
    786   const char *option_str;
    787   bool own_option_str;
    788 
    789   pragma_diagnostic_data () { clear (); }
    790   void clear ()
    791   {
    792     valid = false;
    793     loc_kind = loc_option = UNKNOWN_LOCATION;
    794     pd_kind = PK_INVALID;
    795     diagnostic_kind = DK_UNSPECIFIED;
    796     kind_str = option_str = nullptr;
    797     own_option_str = false;
    798   }
    799 
    800   ~pragma_diagnostic_data ()
    801   {
    802     if (own_option_str && option_str)
    803       XDELETEVEC (const_cast<char *> (option_str));
    804   }
    805 
    806   void set_kind (const char *kind_string)
    807   {
    808     kind_str = kind_string;
    809 
    810     pd_kind = PK_INVALID;
    811     diagnostic_kind = DK_UNSPECIFIED;
    812     if (strcmp (kind_str, "push") == 0)
    813       pd_kind = PK_PUSH;
    814     else if (strcmp (kind_str, "pop") == 0)
    815       pd_kind = PK_POP;
    816     else if (strcmp (kind_str, "ignored_attributes") == 0)
    817       pd_kind = PK_IGNORED_ATTRIBUTES;
    818     else if (strcmp (kind_str, "error") == 0)
    819       {
    820 	pd_kind = PK_DIAGNOSTIC;
    821 	diagnostic_kind = DK_ERROR;
    822       }
    823     else if (strcmp (kind_str, "warning") == 0)
    824       {
    825 	pd_kind = PK_DIAGNOSTIC;
    826 	diagnostic_kind = DK_WARNING;
    827       }
    828     else if (strcmp (kind_str, "ignored") == 0)
    829       {
    830 	pd_kind = PK_DIAGNOSTIC;
    831 	diagnostic_kind = DK_IGNORED;
    832       }
    833   }
    834 
    835   bool needs_option () const
    836   {
    837     return pd_kind == PK_IGNORED_ATTRIBUTES
    838       || pd_kind == PK_DIAGNOSTIC;
    839   }
    840 
    841 };
    842 
    843 /* This will call into either the C or C++ frontends as appropriate to get
    844    tokens from libcpp for the pragma.  */
    845 
    846 static void
    847 pragma_diagnostic_lex (pragma_diagnostic_data *result)
    848 {
    849   result->clear ();
    850   tree x;
    851   auto ttype = pragma_lex (&x, &result->loc_kind);
    852   if (ttype != CPP_NAME)
    853     return;
    854   result->set_kind (IDENTIFIER_POINTER (x));
    855   if (result->pd_kind == pragma_diagnostic_data::PK_INVALID)
    856     return;
    857 
    858   if (result->needs_option ())
    859     {
    860       ttype = pragma_lex (&x, &result->loc_option);
    861       if (ttype != CPP_STRING)
    862 	return;
    863       result->option_str = TREE_STRING_POINTER (x);
    864     }
    865 
    866   result->valid = true;
    867 }
    868 
    869 /* Handle #pragma GCC diagnostic.  Early mode is used by frontends (such as C++)
    870    that do not process the deferred pragma while they are consuming tokens; they
    871    can use early mode to make sure diagnostics affecting the preprocessor itself
    872    are correctly modified by the #pragma.  */
    873 template<bool early, bool is_pp> static void
    874 handle_pragma_diagnostic_impl ()
    875 {
    876   static const bool want_diagnostics = (is_pp || !early);
    877 
    878   pragma_diagnostic_data data;
    879   pragma_diagnostic_lex (&data);
    880 
    881   if (!data.kind_str)
    882     {
    883       if (want_diagnostics)
    884 	warning_at (data.loc_kind, OPT_Wpragmas,
    885 		    "missing %<error%>, %<warning%>, %<ignored%>, %<push%>, "
    886 		    "%<pop%>, or %<ignored_attributes%> after "
    887 		    "%<#pragma GCC diagnostic%>");
    888       return;
    889     }
    890 
    891   switch (data.pd_kind)
    892     {
    893 
    894     case pragma_diagnostic_data::PK_PUSH:
    895       diagnostic_push_diagnostics (global_dc, input_location);
    896       return;
    897 
    898     case pragma_diagnostic_data::PK_POP:
    899       diagnostic_pop_diagnostics (global_dc, input_location);
    900       return;
    901 
    902     case pragma_diagnostic_data::PK_IGNORED_ATTRIBUTES:
    903       {
    904 	if (early)
    905 	  return;
    906 	if (!data.option_str)
    907 	  {
    908 	    warning_at (data.loc_option, OPT_Wpragmas,
    909 		       "missing attribute name after %<#pragma GCC diagnostic "
    910 			"ignored_attributes%>");
    911 	    return;
    912 	  }
    913 	char *args = xstrdup (data.option_str);
    914 	const size_t l = strlen (args);
    915 	if (l == 0)
    916 	  {
    917 	    warning_at (data.loc_option, OPT_Wpragmas,
    918 			"missing argument to %<#pragma GCC "
    919 			"diagnostic ignored_attributes%>");
    920 	    free (args);
    921 	    return;
    922 	  }
    923 	else if (args[l - 1] == ',')
    924 	  {
    925 	    warning_at (data.loc_option, OPT_Wpragmas,
    926 			"trailing %<,%> in arguments for "
    927 			"%<#pragma GCC diagnostic ignored_attributes%>");
    928 	    free (args);
    929 	    return;
    930 	  }
    931 	auto_vec<char *> v;
    932 	for (char *p = strtok (args, ","); p; p = strtok (NULL, ","))
    933 	  v.safe_push (p);
    934 	handle_ignored_attributes_option (&v);
    935 	free (args);
    936 	return;
    937       }
    938 
    939     case pragma_diagnostic_data::PK_DIAGNOSTIC:
    940       if (!data.option_str)
    941 	{
    942 	  if (want_diagnostics)
    943 	    warning_at (data.loc_option, OPT_Wpragmas,
    944 			"missing option after %<#pragma GCC diagnostic%> kind");
    945 	  return;
    946 	}
    947       break;
    948 
    949     default:
    950       if (want_diagnostics)
    951 	warning_at (data.loc_kind, OPT_Wpragmas,
    952 		    "expected %<error%>, %<warning%>, %<ignored%>, %<push%>, "
    953 		    "%<pop%>, %<ignored_attributes%> after "
    954 		    "%<#pragma GCC diagnostic%>");
    955       return;
    956 
    957     }
    958 
    959   gcc_assert (data.pd_kind == pragma_diagnostic_data::PK_DIAGNOSTIC);
    960   gcc_assert (data.valid);
    961 
    962   unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
    963   /* option_string + 1 to skip the initial '-' */
    964   unsigned int option_index = find_opt (data.option_str + 1, lang_mask);
    965 
    966   if (early && !(c_option_is_from_cpp_diagnostics (option_index)
    967 		 || option_index == OPT_Wunknown_pragmas))
    968     return;
    969 
    970   if (option_index == OPT_SPECIAL_unknown)
    971     {
    972       if (want_diagnostics)
    973 	{
    974 	  auto_diagnostic_group d;
    975 	  if (warning_at (data.loc_option, OPT_Wpragmas,
    976 			"unknown option after %<#pragma GCC diagnostic%> kind"))
    977 	    {
    978 	      option_proposer op;
    979 	      const char *hint = op.suggest_option (data.option_str + 1);
    980 	      if (hint)
    981 		inform (data.loc_option, "did you mean %<-%s%>?", hint);
    982 	    }
    983 	}
    984       return;
    985     }
    986   else if (!(cl_options[option_index].flags & CL_WARNING))
    987     {
    988       if (want_diagnostics)
    989 	warning_at (data.loc_option, OPT_Wpragmas,
    990 		    "%qs is not an option that controls warnings",
    991 		    data.option_str);
    992       return;
    993     }
    994   else if (!(cl_options[option_index].flags & lang_mask))
    995     {
    996       if (want_diagnostics)
    997 	{
    998 	  char *ok_langs = write_langs (cl_options[option_index].flags);
    999 	  char *bad_lang = write_langs (c_common_option_lang_mask ());
   1000 	  warning_at (data.loc_option, OPT_Wpragmas,
   1001 		      "option %qs is valid for %s but not for %s",
   1002 		      data.option_str, ok_langs, bad_lang);
   1003 	  free (ok_langs);
   1004 	  free (bad_lang);
   1005 	}
   1006       return;
   1007     }
   1008 
   1009   const char *arg = NULL;
   1010   if (cl_options[option_index].flags & CL_JOINED)
   1011     arg = data.option_str + 1 + cl_options[option_index].opt_len;
   1012 
   1013   struct cl_option_handlers handlers;
   1014   set_default_handlers (&handlers, NULL);
   1015   /* FIXME: input_location isn't the best location here, but it is
   1016      what we used to do here before and changing it breaks e.g.
   1017      PR69543 and PR69558.  */
   1018   control_warning_option (option_index, (int) data.diagnostic_kind,
   1019 			  arg, data.diagnostic_kind != DK_IGNORED,
   1020 			  input_location, lang_mask, &handlers,
   1021 			  &global_options, &global_options_set,
   1022 			  global_dc);
   1023 }
   1024 
   1025 static void
   1026 handle_pragma_diagnostic (cpp_reader *)
   1027 {
   1028   handle_pragma_diagnostic_impl<false, false> ();
   1029 }
   1030 
   1031 static void
   1032 handle_pragma_diagnostic_early (cpp_reader *)
   1033 {
   1034   handle_pragma_diagnostic_impl<true, false> ();
   1035 }
   1036 
   1037 static void
   1038 handle_pragma_diagnostic_early_pp (cpp_reader *)
   1039 {
   1040   handle_pragma_diagnostic_impl<true, true> ();
   1041 }
   1042 
   1043 /*  Parse #pragma GCC target (xxx) to set target specific options.  */
   1044 static void
   1045 handle_pragma_target(cpp_reader *)
   1046 {
   1047   location_t loc;
   1048   enum cpp_ttype token;
   1049   tree x;
   1050   bool close_paren_needed_p = false;
   1051 
   1052   if (cfun)
   1053     {
   1054       error ("%<#pragma GCC option%> is not allowed inside functions");
   1055       return;
   1056     }
   1057 
   1058   token = pragma_lex (&x, &loc);
   1059   if (token == CPP_OPEN_PAREN)
   1060     {
   1061       close_paren_needed_p = true;
   1062       token = pragma_lex (&x, &loc);
   1063     }
   1064 
   1065   if (token != CPP_STRING)
   1066     GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string");
   1067 
   1068   /* Strings are user options.  */
   1069   else
   1070     {
   1071       tree args = NULL_TREE;
   1072 
   1073       do
   1074 	{
   1075 	  /* Build up the strings now as a tree linked list.  Skip empty
   1076 	     strings.  */
   1077 	  if (TREE_STRING_LENGTH (x) > 0)
   1078 	    args = tree_cons (NULL_TREE, x, args);
   1079 
   1080 	  token = pragma_lex (&x);
   1081 	  while (token == CPP_COMMA)
   1082 	    token = pragma_lex (&x);
   1083 	}
   1084       while (token == CPP_STRING);
   1085 
   1086       if (close_paren_needed_p)
   1087 	{
   1088 	  if (token == CPP_CLOSE_PAREN)
   1089 	    token = pragma_lex (&x);
   1090 	  else
   1091 	    GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
   1092 		     "not have a final %<)%>");
   1093 	}
   1094 
   1095       if (token != CPP_EOF)
   1096 	{
   1097 	  error ("%<#pragma GCC target%> string is badly formed");
   1098 	  return;
   1099 	}
   1100 
   1101       /* put arguments in the order the user typed them.  */
   1102       args = nreverse (args);
   1103 
   1104       if (targetm.target_option.pragma_parse (args, NULL_TREE))
   1105 	current_target_pragma = chainon (current_target_pragma, args);
   1106 
   1107       /* A target pragma can also influence optimization options. */
   1108       tree current_optimize
   1109 	= build_optimization_node (&global_options, &global_options_set);
   1110       if (current_optimize != optimization_current_node)
   1111 	optimization_current_node = current_optimize;
   1112     }
   1113 }
   1114 
   1115 /* Handle #pragma GCC optimize to set optimization options.  */
   1116 static void
   1117 handle_pragma_optimize (cpp_reader *)
   1118 {
   1119   enum cpp_ttype token;
   1120   tree x;
   1121   bool close_paren_needed_p = false;
   1122   tree optimization_previous_node = optimization_current_node;
   1123 
   1124   if (cfun)
   1125     {
   1126       error ("%<#pragma GCC optimize%> is not allowed inside functions");
   1127       return;
   1128     }
   1129 
   1130   token = pragma_lex (&x);
   1131   if (token == CPP_OPEN_PAREN)
   1132     {
   1133       close_paren_needed_p = true;
   1134       token = pragma_lex (&x);
   1135     }
   1136 
   1137   if (token != CPP_STRING && token != CPP_NUMBER)
   1138     GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
   1139 
   1140   /* Strings/numbers are user options.  */
   1141   else
   1142     {
   1143       tree args = NULL_TREE;
   1144 
   1145       do
   1146 	{
   1147 	  /* Build up the numbers/strings now as a list.  */
   1148 	  if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
   1149 	    args = tree_cons (NULL_TREE, x, args);
   1150 
   1151 	  token = pragma_lex (&x);
   1152 	  while (token == CPP_COMMA)
   1153 	    token = pragma_lex (&x);
   1154 	}
   1155       while (token == CPP_STRING || token == CPP_NUMBER);
   1156 
   1157       if (close_paren_needed_p)
   1158 	{
   1159 	  if (token == CPP_CLOSE_PAREN)
   1160 	    token = pragma_lex (&x);
   1161 	  else
   1162 	    GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
   1163 		     "not have a final %<)%>");
   1164 	}
   1165 
   1166       if (token != CPP_EOF)
   1167 	{
   1168 	  error ("%<#pragma GCC optimize%> string is badly formed");
   1169 	  return;
   1170 	}
   1171 
   1172       /* put arguments in the order the user typed them.  */
   1173       args = nreverse (args);
   1174 
   1175       parse_optimize_options (args, false);
   1176       current_optimize_pragma = chainon (current_optimize_pragma, args);
   1177       optimization_current_node
   1178 	= build_optimization_node (&global_options, &global_options_set);
   1179       c_cpp_builtins_optimize_pragma (parse_in,
   1180 				      optimization_previous_node,
   1181 				      optimization_current_node);
   1182     }
   1183 }
   1184 
   1185 /* Stack of the #pragma GCC options created with #pragma GCC push_option.  Save
   1186    both the binary representation of the options and the TREE_LIST of
   1187    strings that will be added to the function's attribute list.  */
   1188 struct GTY(()) opt_stack {
   1189   struct opt_stack *prev;
   1190   tree target_binary;
   1191   tree target_strings;
   1192   tree optimize_binary;
   1193   tree optimize_strings;
   1194   gcc_options * GTY ((skip)) saved_global_options;
   1195 };
   1196 
   1197 static GTY(()) struct opt_stack * options_stack;
   1198 
   1199 /* Handle #pragma GCC push_options to save the current target and optimization
   1200    options.  */
   1201 
   1202 static void
   1203 handle_pragma_push_options (cpp_reader *)
   1204 {
   1205   enum cpp_ttype token;
   1206   tree x = 0;
   1207 
   1208   token = pragma_lex (&x);
   1209   if (token != CPP_EOF)
   1210     {
   1211       warning (OPT_Wpragmas, "junk at end of %<#pragma GCC push_options%>");
   1212       return;
   1213     }
   1214 
   1215   opt_stack *p = ggc_alloc<opt_stack> ();
   1216   p->prev = options_stack;
   1217   options_stack = p;
   1218 
   1219   /* Save optimization and target flags in binary format.  */
   1220   if (flag_checking)
   1221     {
   1222       p->saved_global_options = XNEW (gcc_options);
   1223       *p->saved_global_options = global_options;
   1224     }
   1225   p->optimize_binary = build_optimization_node (&global_options,
   1226 						&global_options_set);
   1227   p->target_binary = build_target_option_node (&global_options,
   1228 					       &global_options_set);
   1229 
   1230   /* Save optimization and target flags in string list format.  */
   1231   p->optimize_strings = copy_list (current_optimize_pragma);
   1232   p->target_strings = copy_list (current_target_pragma);
   1233 }
   1234 
   1235 /* Handle #pragma GCC pop_options to restore the current target and
   1236    optimization options from a previous push_options.  */
   1237 
   1238 static void
   1239 handle_pragma_pop_options (cpp_reader *)
   1240 {
   1241   enum cpp_ttype token;
   1242   tree x = 0;
   1243   opt_stack *p;
   1244 
   1245   token = pragma_lex (&x);
   1246   if (token != CPP_EOF)
   1247     {
   1248       warning (OPT_Wpragmas, "junk at end of %<#pragma GCC pop_options%>");
   1249       return;
   1250     }
   1251 
   1252   if (! options_stack)
   1253     {
   1254       warning (OPT_Wpragmas,
   1255 	       "%<#pragma GCC pop_options%> without a corresponding "
   1256 	       "%<#pragma GCC push_options%>");
   1257       return;
   1258     }
   1259 
   1260   p = options_stack;
   1261   options_stack = p->prev;
   1262 
   1263   if (p->target_binary != target_option_current_node)
   1264     {
   1265       (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
   1266       target_option_current_node = p->target_binary;
   1267     }
   1268 
   1269   /* Always restore optimization options as optimization_current_node is
   1270    * overwritten by invoke_set_current_function_hook.  */
   1271   cl_optimization_restore (&global_options, &global_options_set,
   1272 			   TREE_OPTIMIZATION (p->optimize_binary));
   1273   cl_target_option_restore (&global_options, &global_options_set,
   1274 			    TREE_TARGET_OPTION (p->target_binary));
   1275 
   1276   if (p->optimize_binary != optimization_current_node)
   1277     {
   1278       c_cpp_builtins_optimize_pragma (parse_in, optimization_current_node,
   1279 				      p->optimize_binary);
   1280       optimization_current_node = p->optimize_binary;
   1281     }
   1282   if (flag_checking && !seen_error ())
   1283     {
   1284       cl_optimization_compare (p->saved_global_options, &global_options);
   1285       free (p->saved_global_options);
   1286     }
   1287 
   1288   current_target_pragma = p->target_strings;
   1289   current_optimize_pragma = p->optimize_strings;
   1290 }
   1291 
   1292 /* This is mostly a helper for handle_pragma_reset_options () to do the actual
   1293    work, but the C++ frontend, for example, needs an external interface to
   1294    perform this operation, since it processes target pragmas twice.  (Once for
   1295    preprocessing purposes, and then again during compilation.)  */
   1296 
   1297 void
   1298 c_reset_target_pragmas ()
   1299 {
   1300   tree new_optimize = optimization_default_node;
   1301   tree new_target = target_option_default_node;
   1302   if (new_target != target_option_current_node)
   1303     {
   1304       (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
   1305       target_option_current_node = new_target;
   1306     }
   1307 
   1308   if (new_optimize != optimization_current_node)
   1309     {
   1310       tree old_optimize = optimization_current_node;
   1311       cl_optimization_restore (&global_options, &global_options_set,
   1312 			       TREE_OPTIMIZATION (new_optimize));
   1313       c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
   1314       optimization_current_node = new_optimize;
   1315     }
   1316 
   1317   current_target_pragma = NULL_TREE;
   1318   current_optimize_pragma = NULL_TREE;
   1319 }
   1320 
   1321 /* Handle #pragma GCC reset_options to restore the current target and
   1322    optimization options to the original options used on the command line.  */
   1323 
   1324 static void
   1325 handle_pragma_reset_options (cpp_reader *)
   1326 {
   1327   tree x;
   1328   if (pragma_lex (&x) != CPP_EOF)
   1329     warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
   1330   else
   1331     c_reset_target_pragmas ();
   1332 }
   1333 
   1334 /* Print a plain user-specified message.  */
   1335 
   1336 static void
   1337 handle_pragma_message (cpp_reader *)
   1338 {
   1339   location_t loc;
   1340   enum cpp_ttype token;
   1341   tree x, message = 0;
   1342 
   1343   token = pragma_lex (&x);
   1344   if (token == CPP_OPEN_PAREN)
   1345     {
   1346       token = pragma_lex (&x);
   1347       if (token == CPP_STRING)
   1348         message = x;
   1349       else
   1350         GCC_BAD ("expected a string after %<#pragma message%>");
   1351       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
   1352         GCC_BAD ("malformed %<#pragma message%>, ignored");
   1353     }
   1354   else if (token == CPP_STRING)
   1355     message = x;
   1356   else if (token == CPP_STRING_USERDEF)
   1357     GCC_BAD ("string literal with user-defined suffix is invalid in this "
   1358 	     "context");
   1359   else
   1360     GCC_BAD ("expected a string after %<#pragma message%>");
   1361 
   1362   gcc_assert (message);
   1363 
   1364   if (pragma_lex (&x, &loc) != CPP_EOF)
   1365     warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>");
   1366 
   1367   if (TREE_STRING_LENGTH (message) > 1)
   1368     inform (input_location, "%<#pragma message: %s%>",
   1369 	    TREE_STRING_POINTER (message));
   1370 }
   1371 
   1372 /* Ignore a no-op pragma that GCC recognizes, but which has no effect.  */
   1373 static void
   1374 handle_pragma_ignore (cpp_reader *)
   1375 {
   1376 }
   1377 
   1378 /* Mark whether the current location is valid for a STDC pragma.  */
   1379 
   1380 static bool valid_location_for_stdc_pragma;
   1381 
   1382 void
   1383 mark_valid_location_for_stdc_pragma (bool flag)
   1384 {
   1385   valid_location_for_stdc_pragma = flag;
   1386 }
   1387 
   1388 /* Return true if the current location is valid for a STDC pragma.  */
   1389 
   1390 bool
   1391 valid_location_for_stdc_pragma_p (void)
   1392 {
   1393   return valid_location_for_stdc_pragma;
   1394 }
   1395 
   1396 enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
   1397 
   1398 /* A STDC pragma must appear outside of external declarations or
   1399    preceding all explicit declarations and statements inside a compound
   1400    statement; its behavior is undefined if used in any other context.
   1401    It takes a switch of ON, OFF, or DEFAULT.  */
   1402 
   1403 static enum pragma_switch_t
   1404 handle_stdc_pragma (const char *pname)
   1405 {
   1406   const char *arg;
   1407   tree t;
   1408   enum pragma_switch_t ret;
   1409 
   1410   if (!valid_location_for_stdc_pragma_p ())
   1411     {
   1412       warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
   1413 	       pname);
   1414       return PRAGMA_BAD;
   1415     }
   1416 
   1417   if (pragma_lex (&t) != CPP_NAME)
   1418     {
   1419       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
   1420       return PRAGMA_BAD;
   1421     }
   1422 
   1423   arg = IDENTIFIER_POINTER (t);
   1424 
   1425   if (!strcmp (arg, "ON"))
   1426     ret = PRAGMA_ON;
   1427   else if (!strcmp (arg, "OFF"))
   1428     ret = PRAGMA_OFF;
   1429   else if (!strcmp (arg, "DEFAULT"))
   1430     ret = PRAGMA_DEFAULT;
   1431   else
   1432     {
   1433       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
   1434       return PRAGMA_BAD;
   1435     }
   1436 
   1437   if (pragma_lex (&t) != CPP_EOF)
   1438     {
   1439       warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
   1440       return PRAGMA_BAD;
   1441     }
   1442 
   1443   return ret;
   1444 }
   1445 
   1446 /* #pragma STDC FLOAT_CONST_DECIMAL64 ON
   1447    #pragma STDC FLOAT_CONST_DECIMAL64 OFF
   1448    #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
   1449 
   1450 static void
   1451 handle_pragma_float_const_decimal64 (cpp_reader *)
   1452 {
   1453   if (c_dialect_cxx ())
   1454     {
   1455       if (warn_unknown_pragmas > in_system_header_at (input_location))
   1456 	warning (OPT_Wunknown_pragmas,
   1457 		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
   1458 		 " for C++");
   1459       return;
   1460     }
   1461 
   1462   if (!targetm.decimal_float_supported_p ())
   1463     {
   1464       if (warn_unknown_pragmas > in_system_header_at (input_location))
   1465 	warning (OPT_Wunknown_pragmas,
   1466 		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
   1467 		 " on this target");
   1468       return;
   1469     }
   1470 
   1471   pedwarn (input_location, OPT_Wpedantic,
   1472 	   "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
   1473 
   1474   switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
   1475     {
   1476     case PRAGMA_ON:
   1477       set_float_const_decimal64 ();
   1478       break;
   1479     case PRAGMA_OFF:
   1480     case PRAGMA_DEFAULT:
   1481       clear_float_const_decimal64 ();
   1482       break;
   1483     case PRAGMA_BAD:
   1484       break;
   1485     }
   1486 }
   1487 
   1488 /* A vector of registered pragma callbacks, which is never freed.   */
   1489 
   1490 static vec<internal_pragma_handler> registered_pragmas;
   1491 
   1492 struct pragma_pp_data
   1493 {
   1494   const char *space;
   1495   const char *name;
   1496   pragma_handler_1arg early_handler;
   1497 };
   1498 
   1499 
   1500 static vec<pragma_pp_data> registered_pp_pragmas;
   1501 
   1502 struct omp_pragma_def { const char *name; unsigned int id; };
   1503 static const struct omp_pragma_def oacc_pragmas[] = {
   1504   { "atomic", PRAGMA_OACC_ATOMIC },
   1505   { "cache", PRAGMA_OACC_CACHE },
   1506   { "data", PRAGMA_OACC_DATA },
   1507   { "declare", PRAGMA_OACC_DECLARE },
   1508   { "enter", PRAGMA_OACC_ENTER_DATA },
   1509   { "exit", PRAGMA_OACC_EXIT_DATA },
   1510   { "host_data", PRAGMA_OACC_HOST_DATA },
   1511   { "kernels", PRAGMA_OACC_KERNELS },
   1512   { "loop", PRAGMA_OACC_LOOP },
   1513   { "parallel", PRAGMA_OACC_PARALLEL },
   1514   { "routine", PRAGMA_OACC_ROUTINE },
   1515   { "serial", PRAGMA_OACC_SERIAL },
   1516   { "update", PRAGMA_OACC_UPDATE },
   1517   { "wait", PRAGMA_OACC_WAIT }
   1518 };
   1519 static const struct omp_pragma_def omp_pragmas[] = {
   1520   { "allocate", PRAGMA_OMP_ALLOCATE },
   1521   { "assumes", PRAGMA_OMP_ASSUMES },
   1522   { "atomic", PRAGMA_OMP_ATOMIC },
   1523   { "barrier", PRAGMA_OMP_BARRIER },
   1524   { "begin", PRAGMA_OMP_BEGIN },
   1525   { "cancel", PRAGMA_OMP_CANCEL },
   1526   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
   1527   { "critical", PRAGMA_OMP_CRITICAL },
   1528   { "depobj", PRAGMA_OMP_DEPOBJ },
   1529   { "error", PRAGMA_OMP_ERROR },
   1530   { "end", PRAGMA_OMP_END },
   1531   { "flush", PRAGMA_OMP_FLUSH },
   1532   { "nothing", PRAGMA_OMP_NOTHING },
   1533   { "requires", PRAGMA_OMP_REQUIRES },
   1534   { "scope", PRAGMA_OMP_SCOPE },
   1535   { "section", PRAGMA_OMP_SECTION },
   1536   { "sections", PRAGMA_OMP_SECTIONS },
   1537   { "single", PRAGMA_OMP_SINGLE },
   1538   { "task", PRAGMA_OMP_TASK },
   1539   { "taskgroup", PRAGMA_OMP_TASKGROUP },
   1540   { "taskwait", PRAGMA_OMP_TASKWAIT },
   1541   { "taskyield", PRAGMA_OMP_TASKYIELD },
   1542   { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
   1543 };
   1544 static const struct omp_pragma_def omp_pragmas_simd[] = {
   1545   { "assume", PRAGMA_OMP_ASSUME },
   1546   { "declare", PRAGMA_OMP_DECLARE },
   1547   { "distribute", PRAGMA_OMP_DISTRIBUTE },
   1548   { "for", PRAGMA_OMP_FOR },
   1549   { "loop", PRAGMA_OMP_LOOP },
   1550   { "masked", PRAGMA_OMP_MASKED },
   1551   { "master", PRAGMA_OMP_MASTER },
   1552   { "ordered", PRAGMA_OMP_ORDERED },
   1553   { "parallel", PRAGMA_OMP_PARALLEL },
   1554   { "scan", PRAGMA_OMP_SCAN },
   1555   { "simd", PRAGMA_OMP_SIMD },
   1556   { "target", PRAGMA_OMP_TARGET },
   1557   { "taskloop", PRAGMA_OMP_TASKLOOP },
   1558   { "teams", PRAGMA_OMP_TEAMS },
   1559 };
   1560 
   1561 void
   1562 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
   1563 {
   1564   const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
   1565   const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
   1566   const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
   1567 				 / sizeof (*omp_pragmas);
   1568   int i;
   1569 
   1570   for (i = 0; i < n_oacc_pragmas; ++i)
   1571     if (oacc_pragmas[i].id == id)
   1572       {
   1573 	*space = "acc";
   1574 	*name = oacc_pragmas[i].name;
   1575 	return;
   1576       }
   1577 
   1578   for (i = 0; i < n_omp_pragmas; ++i)
   1579     if (omp_pragmas[i].id == id)
   1580       {
   1581 	*space = "omp";
   1582 	*name = omp_pragmas[i].name;
   1583 	return;
   1584       }
   1585 
   1586   for (i = 0; i < n_omp_pragmas_simd; ++i)
   1587     if (omp_pragmas_simd[i].id == id)
   1588       {
   1589 	*space = "omp";
   1590 	*name = omp_pragmas_simd[i].name;
   1591 	return;
   1592       }
   1593 
   1594   if (id >= PRAGMA_FIRST_EXTERNAL
   1595       && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ()))
   1596     {
   1597       *space = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].space;
   1598       *name = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].name;
   1599       return;
   1600     }
   1601 
   1602   gcc_unreachable ();
   1603 }
   1604 
   1605 /* Front-end wrappers for pragma registration to avoid dragging
   1606    cpplib.h in almost everywhere.  */
   1607 
   1608 static void
   1609 c_register_pragma_1 (const char *space, const char *name,
   1610                      internal_pragma_handler ihandler, bool allow_expansion)
   1611 {
   1612   unsigned id;
   1613 
   1614   if (flag_preprocess_only)
   1615     {
   1616       if (cpp_get_options (parse_in)->directives_only
   1617 	  || !(allow_expansion || ihandler.early_handler.handler_1arg))
   1618 	return;
   1619 
   1620       pragma_pp_data pp_data;
   1621       pp_data.space = space;
   1622       pp_data.name = name;
   1623       pp_data.early_handler = ihandler.early_handler.handler_1arg;
   1624       registered_pp_pragmas.safe_push (pp_data);
   1625       id = registered_pp_pragmas.length ();
   1626       id += PRAGMA_FIRST_EXTERNAL - 1;
   1627     }
   1628   else
   1629     {
   1630       registered_pragmas.safe_push (ihandler);
   1631       id = registered_pragmas.length ();
   1632       id += PRAGMA_FIRST_EXTERNAL - 1;
   1633 
   1634       /* The C front end allocates 8 bits in c_token.  The C++ front end
   1635 	 keeps the pragma kind in the form of INTEGER_CST, so no small
   1636 	 limit applies.  At present this is sufficient.  */
   1637       gcc_assert (id < 256);
   1638     }
   1639 
   1640   cpp_register_deferred_pragma (parse_in, space, name, id,
   1641 				allow_expansion, false);
   1642 }
   1643 
   1644 /* Register a C pragma handler, using a space and a name.  It disallows pragma
   1645    expansion (if you want it, use c_register_pragma_with_expansion instead).  */
   1646 void
   1647 c_register_pragma (const char *space, const char *name,
   1648                    pragma_handler_1arg handler)
   1649 {
   1650   c_register_pragma_with_early_handler (space, name, handler, nullptr);
   1651 }
   1652 void c_register_pragma_with_early_handler (const char *space, const char *name,
   1653 					   pragma_handler_1arg handler,
   1654 					   pragma_handler_1arg early_handler)
   1655 {
   1656   internal_pragma_handler ihandler;
   1657 
   1658   ihandler.handler.handler_1arg = handler;
   1659   ihandler.early_handler.handler_1arg = early_handler;
   1660   ihandler.extra_data = false;
   1661   ihandler.data = NULL;
   1662   c_register_pragma_1 (space, name, ihandler, false);
   1663 }
   1664 
   1665 /* Register a C pragma handler, using a space and a name, it also carries an
   1666    extra data field which can be used by the handler.  It disallows pragma
   1667    expansion (if you want it, use c_register_pragma_with_expansion_and_data
   1668    instead).  */
   1669 void
   1670 c_register_pragma_with_data (const char *space, const char *name,
   1671                              pragma_handler_2arg handler, void * data)
   1672 {
   1673   internal_pragma_handler ihandler;
   1674 
   1675   ihandler.handler.handler_2arg = handler;
   1676   ihandler.early_handler.handler_2arg = nullptr;
   1677   ihandler.extra_data = true;
   1678   ihandler.data = data;
   1679   c_register_pragma_1 (space, name, ihandler, false);
   1680 }
   1681 
   1682 /* Register a C pragma handler, using a space and a name.  It allows pragma
   1683    expansion as in the following example:
   1684 
   1685    #define NUMBER 10
   1686    #pragma count (NUMBER)
   1687 
   1688    Name expansion is still disallowed.  */
   1689 void
   1690 c_register_pragma_with_expansion (const char *space, const char *name,
   1691 				  pragma_handler_1arg handler)
   1692 {
   1693   internal_pragma_handler ihandler;
   1694 
   1695   ihandler.handler.handler_1arg = handler;
   1696   ihandler.early_handler.handler_1arg = nullptr;
   1697   ihandler.extra_data = false;
   1698   ihandler.data = NULL;
   1699   c_register_pragma_1 (space, name, ihandler, true);
   1700 }
   1701 
   1702 /* Register a C pragma handler, using a space and a name, it also carries an
   1703    extra data field which can be used by the handler.  It allows pragma
   1704    expansion as in the following example:
   1705 
   1706    #define NUMBER 10
   1707    #pragma count (NUMBER)
   1708 
   1709    Name expansion is still disallowed.  */
   1710 void
   1711 c_register_pragma_with_expansion_and_data (const char *space, const char *name,
   1712                                            pragma_handler_2arg handler,
   1713                                            void *data)
   1714 {
   1715   internal_pragma_handler ihandler;
   1716 
   1717   ihandler.handler.handler_2arg = handler;
   1718   ihandler.early_handler.handler_2arg = nullptr;
   1719   ihandler.extra_data = true;
   1720   ihandler.data = data;
   1721   c_register_pragma_1 (space, name, ihandler, true);
   1722 }
   1723 
   1724 void
   1725 c_invoke_pragma_handler (unsigned int id)
   1726 {
   1727   internal_pragma_handler *ihandler;
   1728   pragma_handler_1arg handler_1arg;
   1729   pragma_handler_2arg handler_2arg;
   1730 
   1731   id -= PRAGMA_FIRST_EXTERNAL;
   1732   ihandler = &registered_pragmas[id];
   1733   if (ihandler->extra_data)
   1734     {
   1735       handler_2arg = ihandler->handler.handler_2arg;
   1736       handler_2arg (parse_in, ihandler->data);
   1737     }
   1738   else
   1739     {
   1740       handler_1arg = ihandler->handler.handler_1arg;
   1741       handler_1arg (parse_in);
   1742     }
   1743 }
   1744 
   1745 /* In contrast to the normal handler, the early handler is optional.  */
   1746 void
   1747 c_invoke_early_pragma_handler (unsigned int id)
   1748 {
   1749   internal_pragma_handler *ihandler;
   1750   pragma_handler_1arg handler_1arg;
   1751   pragma_handler_2arg handler_2arg;
   1752 
   1753   id -= PRAGMA_FIRST_EXTERNAL;
   1754   ihandler = &registered_pragmas[id];
   1755   if (ihandler->extra_data)
   1756     {
   1757       handler_2arg = ihandler->early_handler.handler_2arg;
   1758       if (handler_2arg)
   1759 	handler_2arg (parse_in, ihandler->data);
   1760     }
   1761   else
   1762     {
   1763       handler_1arg = ihandler->early_handler.handler_1arg;
   1764       if (handler_1arg)
   1765 	handler_1arg (parse_in);
   1766     }
   1767 }
   1768 
   1769 void
   1770 c_pp_invoke_early_pragma_handler (unsigned int id)
   1771 {
   1772   const auto data = &registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL];
   1773   if (data->early_handler)
   1774     {
   1775       data->early_handler (parse_in);
   1776       pragma_lex_discard_to_eol ();
   1777     }
   1778 }
   1779 
   1780 /* Set up front-end pragmas.  */
   1781 void
   1782 init_pragma (void)
   1783 {
   1784 
   1785   if (!cpp_get_options (parse_in)->directives_only)
   1786     {
   1787       if (flag_openacc)
   1788 	{
   1789 	  const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
   1790 	  int i;
   1791 
   1792 	  for (i = 0; i < n_oacc_pragmas; ++i)
   1793 	    cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
   1794 					  oacc_pragmas[i].id, true, true);
   1795 	}
   1796 
   1797       if (flag_openmp)
   1798 	{
   1799 	  const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
   1800 	  int i;
   1801 
   1802 	  for (i = 0; i < n_omp_pragmas; ++i)
   1803 	    cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
   1804 					  omp_pragmas[i].id, true, true);
   1805 	}
   1806       if (flag_openmp || flag_openmp_simd)
   1807 	{
   1808 	  const int n_omp_pragmas_simd
   1809 	    = sizeof (omp_pragmas_simd) / sizeof (*omp_pragmas);
   1810 	  int i;
   1811 
   1812 	  for (i = 0; i < n_omp_pragmas_simd; ++i)
   1813 	    cpp_register_deferred_pragma (parse_in, "omp",
   1814 					  omp_pragmas_simd[i].name,
   1815 					  omp_pragmas_simd[i].id, true, true);
   1816 	}
   1817     }
   1818 
   1819   if (!flag_preprocess_only)
   1820     cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
   1821 				  PRAGMA_GCC_PCH_PREPROCESS, false, false);
   1822 
   1823   if (!flag_preprocess_only)
   1824     cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
   1825 				  false);
   1826 
   1827   if (!flag_preprocess_only)
   1828     cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
   1829 				  false, false);
   1830 
   1831   if (!flag_preprocess_only)
   1832     cpp_register_deferred_pragma (parse_in, "GCC", "novector", PRAGMA_NOVECTOR,
   1833 				  false, false);
   1834 
   1835 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
   1836   c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
   1837 #else
   1838   c_register_pragma (0, "pack", handle_pragma_pack);
   1839 #endif
   1840   c_register_pragma (0, "weak", handle_pragma_weak);
   1841 
   1842   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
   1843 
   1844   if (flag_preprocess_only)
   1845     c_register_pragma_with_early_handler ("GCC", "diagnostic",
   1846 					  nullptr,
   1847 					  handle_pragma_diagnostic_early_pp);
   1848   else
   1849     c_register_pragma_with_early_handler ("GCC", "diagnostic",
   1850 					  handle_pragma_diagnostic,
   1851 					  handle_pragma_diagnostic_early);
   1852   c_register_pragma_with_early_handler ("GCC", "target",
   1853 					handle_pragma_target,
   1854 					handle_pragma_target);
   1855   c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
   1856   c_register_pragma_with_early_handler ("GCC", "push_options",
   1857 					handle_pragma_push_options,
   1858 					handle_pragma_push_options);
   1859   c_register_pragma_with_early_handler ("GCC", "pop_options",
   1860 					handle_pragma_pop_options,
   1861 					handle_pragma_pop_options);
   1862   c_register_pragma_with_early_handler ("GCC", "reset_options",
   1863 					handle_pragma_reset_options,
   1864 					handle_pragma_reset_options);
   1865 
   1866   c_register_pragma (0, "region", handle_pragma_ignore);
   1867   c_register_pragma (0, "endregion", handle_pragma_ignore);
   1868 
   1869   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
   1870 		     handle_pragma_float_const_decimal64);
   1871 
   1872   c_register_pragma_with_expansion (0, "redefine_extname",
   1873 				    handle_pragma_redefine_extname);
   1874 
   1875   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
   1876 
   1877 #ifdef REGISTER_TARGET_PRAGMAS
   1878   REGISTER_TARGET_PRAGMAS ();
   1879 #endif
   1880 
   1881   global_sso = default_sso;
   1882   c_register_pragma (0, "scalar_storage_order",
   1883 		     handle_pragma_scalar_storage_order);
   1884 
   1885   /* Allow plugins to register their own pragmas. */
   1886   invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
   1887 }
   1888 
   1889 #include "gt-c-family-c-pragma.h"
   1890