LCOV - code coverage report
Current view: top level - gcc/c-family - c-pragma.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.7 % 811 719
Test Date: 2026-08-22 16:33:35 Functions: 95.8 % 48 46
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
       2              :    Copyright (C) 1992-2026 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           22 : push_alignment (int alignment, tree id)
      73              : {
      74           22 :   align_stack * entry = ggc_alloc<align_stack> ();
      75              : 
      76           22 :   entry->alignment  = alignment;
      77           22 :   entry->id      = id;
      78           22 :   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           22 :   if (alignment_stack == NULL)
      84           19 :     default_alignment = maximum_field_alignment;
      85              : 
      86           22 :   alignment_stack = entry;
      87              : 
      88           22 :   maximum_field_alignment = alignment;
      89           22 : }
      90              : 
      91              : /* Undo a push of an alignment onto the stack.  */
      92              : static void
      93           24 : pop_alignment (tree id)
      94              : {
      95           24 :   align_stack * entry;
      96              : 
      97           24 :   if (alignment_stack == NULL)
      98            2 :     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           22 :   if (id)
     104              :     {
     105            9 :       for (entry = alignment_stack; entry; entry = entry->prev)
     106            6 :         if (entry->id == id)
     107              :           {
     108            2 :             alignment_stack = entry;
     109            2 :             break;
     110              :           }
     111            5 :       if (entry == NULL)
     112            3 :         warning (OPT_Wpragmas,
     113              :                  "%<#pragma pack(pop, %E)%> encountered without matching "
     114              :                  "%<#pragma pack(push, %E)%>"
     115              :                  , id, id);
     116              :     }
     117              : 
     118           22 :   entry = alignment_stack->prev;
     119              : 
     120           22 :   maximum_field_alignment = entry ? entry->alignment : default_alignment;
     121              : 
     122           22 :   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          187 : handle_pragma_pack (cpp_reader *)
     136              : {
     137          187 :   location_t loc;
     138          187 :   tree x, id = 0;
     139          187 :   int align = -1;
     140          187 :   enum cpp_ttype token;
     141          187 :   enum { set, push, pop } action;
     142              : 
     143          187 :   if (pragma_lex (&x) != CPP_OPEN_PAREN)
     144           13 :     GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
     145              : 
     146          186 :   token = pragma_lex (&x, &loc);
     147          186 :   if (token == CPP_CLOSE_PAREN)
     148              :     {
     149           15 :       action = set;
     150           15 :       align = initial_max_fld_align;
     151              :     }
     152          171 :   else if (token == CPP_NUMBER)
     153              :     {
     154          116 :       if (TREE_CODE (x) != INTEGER_CST)
     155            2 :         GCC_BAD_AT (loc, "invalid constant in %<#pragma pack%> - ignored");
     156          114 :       align = TREE_INT_CST_LOW (x);
     157          114 :       action = set;
     158          114 :       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
     159            1 :         GCC_BAD ("malformed %<#pragma pack%> - ignored");
     160              :     }
     161           55 :   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           54 :       const char *op = IDENTIFIER_POINTER (x);
     170           54 :       if (!strcmp (op, "push"))
     171           51 :         action = push;
     172           28 :       else if (!strcmp (op, "pop"))
     173              :         action = pop;
     174              :       else
     175            3 :         GCC_BAD2_AT (loc, "unknown action %qE for %<#pragma pack%> - ignored",
     176              :                      x);
     177              : 
     178           75 :       while ((token = pragma_lex (&x)) == CPP_COMMA)
     179              :         {
     180           28 :           token = pragma_lex (&x, &loc);
     181           28 :           if (token == CPP_NAME && id == 0)
     182              :             {
     183           16 :               id = x;
     184              :             }
     185           12 :           else if (token == CPP_NUMBER && action == push && align == -1)
     186              :             {
     187           11 :               if (TREE_CODE (x) != INTEGER_CST)
     188            3 :                 GCC_BAD_AT (loc,
     189              :                             "invalid constant in %<#pragma pack%> - ignored");
     190            8 :               align = TREE_INT_CST_LOW (x);
     191            8 :               if (align == -1)
     192            0 :                 action = set;
     193              :             }
     194              :           else
     195           76 :             GCC_BAD_ACTION;
     196              :         }
     197              : 
     198           47 :       if (token != CPP_CLOSE_PAREN)
     199            0 :         GCC_BAD_ACTION;
     200              : #undef GCC_BAD_ACTION
     201              :     }
     202              :   else
     203            1 :     GCC_BAD ("malformed %<#pragma pack%> - ignored");
     204              : 
     205          175 :   if (pragma_lex (&x, &loc) != CPP_EOF)
     206            1 :     warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma pack%>");
     207              : 
     208          175 :   if (flag_pack_struct)
     209            0 :     GCC_BAD ("%<#pragma pack%> has no effect with %<-fpack-struct%> - ignored");
     210              : 
     211          175 :   if (action != pop)
     212          151 :     switch (align)
     213              :       {
     214          135 :       case 0:
     215          135 :       case 1:
     216          135 :       case 2:
     217          135 :       case 4:
     218          135 :       case 8:
     219          135 :       case 16:
     220          135 :         align *= BITS_PER_UNIT;
     221          135 :         break;
     222           15 :       case -1:
     223           15 :         if (action == push)
     224              :           {
     225           15 :             align = maximum_field_alignment;
     226           15 :             break;
     227              :           }
     228              :         /* FALLTHRU */
     229            1 :       default:
     230            1 :         GCC_BAD2 ("alignment must be a small power of two, not %d", align);
     231              :       }
     232              : 
     233          150 :   switch (action)
     234              :     {
     235          128 :     case set:   SET_GLOBAL_ALIGNMENT (align);  break;
     236           22 :     case push:  push_alignment (align, id);    break;
     237           24 :     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           97 : apply_pragma_weak (tree decl, tree value)
     255              : {
     256           97 :   if (value)
     257              :     {
     258            7 :       value = build_string (IDENTIFIER_LENGTH (value),
     259            7 :                             IDENTIFIER_POINTER (value));
     260            7 :       decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
     261              :                                                build_tree_list (NULL, value)),
     262              :                        0);
     263              :     }
     264              : 
     265          176 :   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
     266           17 :       && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
     267            3 :       && DECL_ASSEMBLER_NAME_SET_P (decl)
     268           97 :       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
     269            0 :     warning (OPT_Wpragmas, "applying %<#pragma weak %+D%> after first use "
     270              :              "results in unspecified behavior", decl);
     271              : 
     272           97 :   declare_weak (decl);
     273           97 : }
     274              : 
     275              : void
     276    248832186 : maybe_apply_pragma_weak (tree decl)
     277              : {
     278    248832186 :   tree id;
     279    248832186 :   int i;
     280    248832186 :   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    248832186 :   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          683 :   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          114 :   if (!VAR_OR_FUNCTION_DECL_P (decl))
     295              :     return;
     296              : 
     297          114 :   if (DECL_ASSEMBLER_NAME_SET_P (decl))
     298            7 :     id = DECL_ASSEMBLER_NAME (decl);
     299              :   else
     300              :     {
     301          107 :       id = DECL_ASSEMBLER_NAME (decl);
     302          107 :       SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
     303              :     }
     304              : 
     305          203 :   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
     306          114 :     if (id == pe->name)
     307              :       {
     308           25 :         apply_pragma_weak (decl, pe->value);
     309           25 :         pending_weaks->unordered_remove (i);
     310           25 :         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       205231 : maybe_apply_pending_pragma_weaks (void)
     318              : {
     319       205231 :   tree alias_id, id, decl;
     320       205231 :   int i;
     321       205231 :   pending_weak *pe;
     322       205231 :   symtab_node *target;
     323              : 
     324       205231 :   if (vec_safe_is_empty (pending_weaks))
     325       205231 :     return;
     326              : 
     327           42 :   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
     328              :     {
     329           21 :       alias_id = pe->name;
     330           21 :       id = pe->value;
     331              : 
     332           21 :       if (id == NULL)
     333           16 :         continue;
     334              : 
     335            5 :       target = symtab_node::get_for_asmname (id);
     336           10 :       decl = build_decl (UNKNOWN_LOCATION,
     337            5 :                          target ? TREE_CODE (target->decl) : FUNCTION_DECL,
     338              :                          alias_id, default_function_type);
     339              : 
     340            5 :       DECL_ARTIFICIAL (decl) = 1;
     341            5 :       TREE_PUBLIC (decl) = 1;
     342            5 :       DECL_WEAK (decl) = 1;
     343            5 :       if (VAR_P (decl))
     344            1 :         TREE_STATIC (decl) = 1;
     345            5 :       if (!target)
     346              :         {
     347            0 :           error ("%q+D aliased to undefined symbol %qE",
     348              :                  decl, id);
     349            0 :           continue;
     350              :         }
     351              : 
     352            5 :       assemble_alias (decl, id);
     353              :     }
     354              : }
     355              : 
     356              : /* #pragma weak name [= value] */
     357              : static void
     358          122 : handle_pragma_weak (cpp_reader *)
     359              : {
     360          122 :   tree name, value, x, decl;
     361          122 :   enum cpp_ttype t;
     362              : 
     363          122 :   value = 0;
     364              : 
     365          122 :   if (pragma_lex (&name) != CPP_NAME)
     366            4 :     GCC_BAD ("malformed %<#pragma weak%>, ignored");
     367          122 :   t = pragma_lex (&x);
     368          122 :   if (t == CPP_EQ)
     369              :     {
     370           16 :       if (pragma_lex (&value) != CPP_NAME)
     371            3 :         GCC_BAD ("malformed %<#pragma weak%>, ignored");
     372           13 :       t = pragma_lex (&x);
     373              :     }
     374          119 :   if (t != CPP_EOF)
     375            0 :     warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
     376              : 
     377          119 :   decl = identifier_global_value (name);
     378          119 :   if (decl && DECL_P (decl))
     379              :     {
     380           73 :       if (!VAR_OR_FUNCTION_DECL_P (decl))
     381            1 :         GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed,"
     382              :                   " ignored", decl);
     383           72 :       apply_pragma_weak (decl, value);
     384           72 :       if (value)
     385              :         {
     386            3 :           DECL_EXTERNAL (decl) = 0;
     387            3 :           if (VAR_P (decl))
     388            2 :             TREE_STATIC (decl) = 1;
     389            3 :           assemble_alias (decl, value);
     390              :         }
     391              :     }
     392              :   else
     393              :     {
     394           46 :       pending_weak pe = {name, value};
     395           46 :       vec_safe_push (pending_weaks, pe);
     396              :     }
     397              : }
     398              : 
     399              : static enum scalar_storage_order_kind global_sso;
     400              : 
     401              : void
     402      1185245 : maybe_apply_pragma_scalar_storage_order (tree type)
     403              : {
     404      1185245 :   if (global_sso == SSO_NATIVE)
     405              :     return;
     406              : 
     407           12 :   gcc_assert (RECORD_OR_UNION_TYPE_P (type));
     408              : 
     409           12 :   if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
     410              :     return;
     411              : 
     412           10 :   if (global_sso == SSO_BIG_ENDIAN)
     413            6 :     TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
     414            4 :   else if (global_sso == SSO_LITTLE_ENDIAN)
     415            4 :     TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
     416              :   else
     417            0 :     gcc_unreachable ();
     418              : }
     419              : 
     420              : static void
     421           13 : handle_pragma_scalar_storage_order (cpp_reader *)
     422              : {
     423           13 :   const char *kind_string;
     424           13 :   enum cpp_ttype token;
     425           13 :   tree x;
     426              : 
     427           13 :   if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
     428              :     {
     429              :       error ("%<scalar_storage_order%> is not supported because endianness "
     430              :              "is not uniform");
     431            5 :       return;
     432              :     }
     433              : 
     434           13 :   if (c_dialect_cxx ())
     435              :     {
     436            3 :       if (warn_unknown_pragmas > in_system_header_at (input_location))
     437            3 :         warning (OPT_Wunknown_pragmas,
     438              :                  "%<#pragma scalar_storage_order%> is not supported for C++");
     439              :       return;
     440              :     }
     441              : 
     442           10 :   token = pragma_lex (&x);
     443           10 :   if (token != CPP_NAME)
     444            1 :     GCC_BAD ("missing %<big-endian%>, %<little-endian%>, or %<default%> after "
     445              :              "%<#pragma scalar_storage_order%>");
     446            9 :   kind_string = IDENTIFIER_POINTER (x);
     447            9 :   if (strcmp (kind_string, "default") == 0)
     448            3 :     global_sso = default_sso;
     449            6 :   else if (strcmp (kind_string, "big") == 0)
     450            3 :     global_sso = SSO_BIG_ENDIAN;
     451            3 :   else if (strcmp (kind_string, "little") == 0)
     452            2 :     global_sso = SSO_LITTLE_ENDIAN;
     453              :   else
     454            9 :     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           30 : handle_pragma_redefine_extname (cpp_reader *)
     503              : {
     504           30 :   tree oldname, newname, decls, x;
     505           30 :   enum cpp_ttype t;
     506           30 :   bool found;
     507              : 
     508           30 :   if (pragma_lex (&oldname) != CPP_NAME)
     509            7 :     GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
     510           25 :   if (pragma_lex (&newname) != CPP_NAME)
     511            2 :     GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
     512           23 :   t = pragma_lex (&x);
     513           23 :   if (t != CPP_EOF)
     514            1 :     warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
     515              : 
     516           23 :   found = false;
     517           23 :   for (decls = c_linkage_bindings (oldname);
     518           33 :        decls; )
     519              :     {
     520           10 :       tree decl;
     521           10 :       if (TREE_CODE (decls) == TREE_LIST)
     522              :         {
     523            3 :           decl = TREE_VALUE (decls);
     524            3 :           decls = TREE_CHAIN (decls);
     525              :         }
     526              :       else
     527              :         {
     528              :           decl = decls;
     529              :           decls = NULL_TREE;
     530              :         }
     531              : 
     532            0 :       if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
     533           10 :           && VAR_OR_FUNCTION_DECL_P (decl))
     534              :         {
     535           10 :           found = true;
     536           10 :           if (DECL_ASSEMBLER_NAME_SET_P (decl))
     537              :             {
     538            0 :               const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     539            0 :               name = targetm.strip_name_encoding (name);
     540              : 
     541            0 :               if (!id_equal (newname, name))
     542            0 :                 warning (OPT_Wpragmas, "%<#pragma redefine_extname%> "
     543              :                          "ignored due to conflict with previous rename");
     544              :             }
     545              :           else
     546           10 :             symtab->change_decl_assembler_name (decl, newname);
     547              :         }
     548              :     }
     549              : 
     550           23 :   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           16 :     add_to_renaming_pragma_list (oldname, newname);
     557              : }
     558              : 
     559              : /* This is called from here and from ia64-c.cc.  */
     560              : void
     561           16 : add_to_renaming_pragma_list (tree oldname, tree newname)
     562              : {
     563           16 :   unsigned ix;
     564           16 :   pending_redefinition *p;
     565              : 
     566           20 :   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
     567            4 :     if (oldname == p->oldname)
     568              :       {
     569            0 :         if (p->newname != newname)
     570            0 :           warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored due to "
     571              :                    "conflict with previous %<#pragma redefine_extname%>");
     572            0 :         return;
     573              :       }
     574              : 
     575           16 :   pending_redefinition e = {oldname, newname};
     576           16 :   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     89729284 : maybe_apply_renaming_pragma (tree decl, tree asmname)
     587              : {
     588     89729284 :   unsigned ix;
     589     89729284 :   pending_redefinition *p;
     590              : 
     591              :   /* The renaming pragmas are only applied to declarations with
     592              :      external linkage.  */
     593     64313083 :   if (!VAR_OR_FUNCTION_DECL_P (decl)
     594     79635844 :       || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
     595    169245974 :       || !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     45956559 :   if (DECL_ASSEMBLER_NAME_SET_P (decl))
     601              :     {
     602         4584 :       const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     603         4584 :       oldname = targetm.strip_name_encoding (oldname);
     604              : 
     605         5163 :       if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
     606            7 :           warning (OPT_Wpragmas, "%<asm%> declaration ignored due to "
     607              :                    "conflict with previous rename");
     608              : 
     609              :       /* Take any pending redefine_extname off the list.  */
     610         4587 :       FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
     611            3 :         if (DECL_NAME (decl) == p->oldname)
     612              :           {
     613              :             /* Only warn if there is a conflict.  */
     614            0 :             if (!id_equal (p->newname, oldname))
     615            0 :               warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored "
     616              :                        "due to conflict with previous rename");
     617              : 
     618            0 :             pending_redefine_extname->unordered_remove (ix);
     619            0 :             break;
     620              :           }
     621              :       return NULL_TREE;
     622              :     }
     623              : 
     624              :   /* Find out if we have a pending #pragma redefine_extname.  */
     625     45951988 :   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
     626           25 :     if (DECL_NAME (decl) == p->oldname)
     627              :       {
     628           12 :         tree newname = p->newname;
     629           12 :         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           12 :         if (asmname)
     634              :           {
     635            0 :             if (strcmp (TREE_STRING_POINTER (asmname),
     636            0 :                         IDENTIFIER_POINTER (newname)) != 0)
     637            0 :               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           12 :         return build_string (IDENTIFIER_LENGTH (newname),
     645           12 :                              IDENTIFIER_POINTER (newname));
     646              :       }
     647              : 
     648              :   /* If we've got an asmname, #pragma extern_prefix is silently ignored.  */
     649     45951963 :   if (asmname)
     650              :     return asmname;
     651              : 
     652              :   /* If #pragma extern_prefix is in effect, apply it.  */
     653     44490130 :   if (pragma_extern_prefix)
     654              :     {
     655            0 :       const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
     656            0 :       size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
     657              : 
     658            0 :       const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
     659            0 :       size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
     660              : 
     661            0 :       char *newname = (char *) alloca (plen + ilen + 1);
     662              : 
     663            0 :       memcpy (newname,        prefix, plen);
     664            0 :       memcpy (newname + plen, id, ilen + 1);
     665              : 
     666            0 :       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      3348826 : push_visibility (const char *str, int kind)
     687              : {
     688      3348826 :   visstack.safe_push (((int) default_visibility) | (kind << 8));
     689      3348826 :   if (!strcmp (str, "default"))
     690      3347227 :     default_visibility = VISIBILITY_DEFAULT;
     691         1599 :   else if (!strcmp (str, "internal"))
     692            0 :     default_visibility = VISIBILITY_INTERNAL;
     693         1599 :   else if (!strcmp (str, "hidden"))
     694         1599 :     default_visibility = VISIBILITY_HIDDEN;
     695            0 :   else if (!strcmp (str, "protected"))
     696            0 :     default_visibility = VISIBILITY_PROTECTED;
     697              :   else
     698            0 :     GCC_BAD ("%<#pragma GCC visibility push()%> must specify %<default%>, "
     699              :              "%<internal%>, %<hidden%> or %<protected%>");
     700      3348826 :   visibility_options.inpragma = 1;
     701              : }
     702              : 
     703              : /* Pop a level of the #pragma visibility stack.  Return true if
     704              :    successful.  */
     705              : 
     706              : bool
     707      3348810 : pop_visibility (int kind)
     708              : {
     709      3348810 :   if (!visstack.length ())
     710              :     return false;
     711      3348810 :   if ((visstack.last () >> 8) != kind)
     712              :     return false;
     713      3348807 :   default_visibility
     714      3348807 :     = (enum symbol_visibility) (visstack.pop () & 0xff);
     715      3348807 :   visibility_options.inpragma
     716      3348807 :     = visstack.length () != 0;
     717      3348807 :   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       255928 : handle_pragma_visibility (cpp_reader *)
     725              : {
     726              :   /* Form is #pragma GCC visibility push(hidden)|pop */
     727       255928 :   tree x;
     728       255928 :   enum cpp_ttype token;
     729       255928 :   enum { bad, push, pop } action = bad;
     730              : 
     731       255928 :   token = pragma_lex (&x);
     732       255928 :   if (token == CPP_NAME)
     733              :     {
     734       255928 :       const char *op = IDENTIFIER_POINTER (x);
     735       255928 :       if (!strcmp (op, "push"))
     736              :         action = push;
     737       127956 :       else if (!strcmp (op, "pop"))
     738              :         action = pop;
     739              :     }
     740              :   if (bad == action)
     741            3 :     GCC_BAD ("%<#pragma GCC visibility%> must be followed by %<push%> "
     742              :              "or %<pop%>");
     743              :   else
     744              :     {
     745       255928 :       if (pop == action)
     746              :         {
     747       127956 :           if (! pop_visibility (0))
     748            3 :             GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
     749              :         }
     750              :       else
     751              :         {
     752       127972 :           if (pragma_lex (&x) != CPP_OPEN_PAREN)
     753            0 :             GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
     754       127972 :           token = pragma_lex (&x);
     755       127972 :           if (token != CPP_NAME)
     756            0 :             GCC_BAD ("malformed %<#pragma GCC visibility push%>");
     757              :           else
     758       127972 :             push_visibility (IDENTIFIER_POINTER (x), 0);
     759       127972 :           if (pragma_lex (&x) != CPP_CLOSE_PAREN)
     760            0 :             GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
     761              :         }
     762              :     }
     763       255925 :   if (pragma_lex (&x) != CPP_EOF)
     764            0 :     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              :   enum diagnostics::kind diagnostic_kind;
     785              :   const char *kind_str;
     786              :   const char *option_str;
     787              :   bool own_option_str;
     788              : 
     789     15349862 :   pragma_diagnostic_data () { clear (); }
     790     30699724 :   void clear ()
     791              :   {
     792     30699724 :     valid = false;
     793     30699724 :     loc_kind = loc_option = UNKNOWN_LOCATION;
     794     30699724 :     pd_kind = PK_INVALID;
     795     30699724 :     diagnostic_kind = diagnostics::kind::unspecified;
     796     30699724 :     kind_str = option_str = nullptr;
     797     30699724 :     own_option_str = false;
     798              :   }
     799              : 
     800     15349862 :   ~pragma_diagnostic_data ()
     801              :   {
     802     15349862 :     if (own_option_str && option_str)
     803            0 :       XDELETEVEC (const_cast<char *> (option_str));
     804     15349862 :   }
     805              : 
     806     15349852 :   void set_kind (const char *kind_string)
     807              :   {
     808     15349852 :     kind_str = kind_string;
     809              : 
     810     15349852 :     pd_kind = PK_INVALID;
     811     15349852 :     diagnostic_kind = diagnostics::kind::unspecified;
     812     15349852 :     if (strcmp (kind_str, "push") == 0)
     813      4904817 :       pd_kind = PK_PUSH;
     814     10445035 :     else if (strcmp (kind_str, "pop") == 0)
     815      4904126 :       pd_kind = PK_POP;
     816      5540909 :     else if (strcmp (kind_str, "ignored_attributes") == 0)
     817           77 :       pd_kind = PK_IGNORED_ATTRIBUTES;
     818      5540832 :     else if (strcmp (kind_str, "error") == 0)
     819              :       {
     820           63 :         pd_kind = PK_DIAGNOSTIC;
     821           63 :         diagnostic_kind = diagnostics::kind::error;
     822              :       }
     823      5540769 :     else if (strcmp (kind_str, "warning") == 0)
     824              :       {
     825           63 :         pd_kind = PK_DIAGNOSTIC;
     826           63 :         diagnostic_kind = diagnostics::kind::warning;
     827              :       }
     828      5540706 :     else if (strcmp (kind_str, "ignored") == 0)
     829              :       {
     830      5540698 :         pd_kind = PK_DIAGNOSTIC;
     831      5540698 :         diagnostic_kind = diagnostics::kind::ignored;
     832              :       }
     833     15349852 :   }
     834              : 
     835     15349844 :   bool needs_option () const
     836              :   {
     837     15349844 :     return pd_kind == PK_IGNORED_ATTRIBUTES
     838     15349844 :       || 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     15349862 : pragma_diagnostic_lex (pragma_diagnostic_data *result)
     848              : {
     849     15349862 :   result->clear ();
     850     15349862 :   tree x;
     851     15349862 :   auto ttype = pragma_lex (&x, &result->loc_kind);
     852     15349862 :   if (ttype != CPP_NAME)
     853           18 :     return;
     854     15349852 :   result->set_kind (IDENTIFIER_POINTER (x));
     855     15349852 :   if (result->pd_kind == pragma_diagnostic_data::PK_INVALID)
     856              :     return;
     857              : 
     858     15349844 :   if (result->needs_option ())
     859              :     {
     860      5540901 :       ttype = pragma_lex (&x, &result->loc_option);
     861      5540901 :       if (ttype != CPP_STRING)
     862              :         return;
     863      5540901 :       result->option_str = TREE_STRING_POINTER (x);
     864              :     }
     865              : 
     866     15349844 :   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     15349862 : handle_pragma_diagnostic_impl ()
     875              : {
     876              :   static const bool want_diagnostics = (is_pp || !early);
     877              : 
     878     15349862 :   pragma_diagnostic_data data;
     879     15349862 :   pragma_diagnostic_lex (&data);
     880              : 
     881     15349862 :   if (!data.kind_str)
     882              :     {
     883              :       if (want_diagnostics)
     884            7 :         warning_at (data.loc_kind, OPT_Wpragmas,
     885              :                     "missing %<error%>, %<warning%>, %<ignored%>, %<push%>, "
     886              :                     "%<pop%>, or %<ignored_attributes%> after "
     887              :                     "%<#pragma GCC diagnostic%>");
     888            7 :       return;
     889              :     }
     890              : 
     891     15349852 :   switch (data.pd_kind)
     892              :     {
     893              : 
     894      4904817 :     case pragma_diagnostic_data::PK_PUSH:
     895      4904817 :       diagnostic_push_diagnostics (global_dc, input_location);
     896      4904817 :       return;
     897              : 
     898      4904126 :     case pragma_diagnostic_data::PK_POP:
     899      4904126 :       diagnostic_pop_diagnostics (global_dc, input_location);
     900      4904126 :       return;
     901              : 
     902              :     case pragma_diagnostic_data::PK_IGNORED_ATTRIBUTES:
     903              :       {
     904              :         if (early)
     905              :           return;
     906           44 :         if (!data.option_str)
     907              :           {
     908            0 :             warning_at (data.loc_option, OPT_Wpragmas,
     909              :                        "missing attribute name after %<#pragma GCC diagnostic "
     910              :                         "ignored_attributes%>");
     911            0 :             return;
     912              :           }
     913           44 :         char *args = xstrdup (data.option_str);
     914           44 :         const size_t l = strlen (args);
     915           44 :         if (l == 0)
     916              :           {
     917            0 :             warning_at (data.loc_option, OPT_Wpragmas,
     918              :                         "missing argument to %<#pragma GCC "
     919              :                         "diagnostic ignored_attributes%>");
     920            0 :             free (args);
     921            0 :             return;
     922              :           }
     923           44 :         else if (args[l - 1] == ',')
     924              :           {
     925            0 :             warning_at (data.loc_option, OPT_Wpragmas,
     926              :                         "trailing %<,%> in arguments for "
     927              :                         "%<#pragma GCC diagnostic ignored_attributes%>");
     928            0 :             free (args);
     929            0 :             return;
     930              :           }
     931           44 :         auto_vec<char *> v;
     932          108 :         for (char *p = strtok (args, ","); p; p = strtok (NULL, ","))
     933           64 :           v.safe_push (p);
     934           44 :         handle_ignored_attributes_option (&v);
     935           44 :         free (args);
     936              :         return;
     937           44 :       }
     938              : 
     939      5540824 :     case pragma_diagnostic_data::PK_DIAGNOSTIC:
     940      5540824 :       if (!data.option_str)
     941              :         {
     942              :           if (want_diagnostics)
     943            0 :             warning_at (data.loc_option, OPT_Wpragmas,
     944              :                         "missing option after %<#pragma GCC diagnostic%> kind");
     945            0 :           return;
     946              :         }
     947              :       break;
     948              : 
     949            5 :     default:
     950              :       if (want_diagnostics)
     951            5 :         warning_at (data.loc_kind, OPT_Wpragmas,
     952              :                     "expected %<error%>, %<warning%>, %<ignored%>, %<push%>, "
     953              :                     "%<pop%>, %<ignored_attributes%> after "
     954              :                     "%<#pragma GCC diagnostic%>");
     955            5 :       return;
     956              : 
     957              :     }
     958              : 
     959              :   gcc_assert (data.pd_kind == pragma_diagnostic_data::PK_DIAGNOSTIC);
     960      5540824 :   gcc_assert (data.valid);
     961              : 
     962      5540824 :   unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
     963              :   /* option_string + 1 to skip the initial '-' */
     964      5540824 :   unsigned int option_index = find_opt (data.option_str + 1, lang_mask);
     965              : 
     966      2718848 :   if (early && !(c_option_is_from_cpp_diagnostics (option_index)
     967      2718848 :                  || option_index == OPT_Wunknown_pragmas))
     968              :     return;
     969              : 
     970      4525447 :   if (option_index == OPT_SPECIAL_unknown)
     971              :     {
     972              :       if (want_diagnostics)
     973              :         {
     974           11 :           auto_diagnostic_group d;
     975           11 :           if (warning_at (data.loc_option, OPT_Wpragmas,
     976              :                         "unknown option after %<#pragma GCC diagnostic%> kind"))
     977              :             {
     978           11 :               option_proposer op;
     979           11 :               const char *hint = op.suggest_option (data.option_str + 1);
     980           11 :               if (hint)
     981            4 :                 inform (data.loc_option, "did you mean %<-%s%>?", hint);
     982           11 :             }
     983           11 :         }
     984           11 :       return;
     985              :     }
     986      4525436 :   else if (!(cl_options[option_index].flags & CL_WARNING))
     987              :     {
     988              :       if (want_diagnostics)
     989           11 :         warning_at (data.loc_option, OPT_Wpragmas,
     990              :                     "%qs is not an option that controls warnings",
     991              :                     data.option_str);
     992           11 :       return;
     993              :     }
     994      4525425 :   else if (!(cl_options[option_index].flags & lang_mask))
     995              :     {
     996              :       if (want_diagnostics)
     997              :         {
     998            1 :           char *ok_langs = write_langs (cl_options[option_index].flags);
     999            1 :           char *bad_lang = write_langs (c_common_option_lang_mask ());
    1000            1 :           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            1 :           free (ok_langs);
    1004            1 :           free (bad_lang);
    1005              :         }
    1006            1 :       return;
    1007              :     }
    1008              : 
    1009      4525424 :   const char *arg = NULL;
    1010      4525424 :   if (cl_options[option_index].flags & CL_JOINED)
    1011           17 :     arg = data.option_str + 1 + cl_options[option_index].opt_len;
    1012              : 
    1013              :   struct cl_option_handlers handlers;
    1014      4525424 :   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      4525424 :   control_warning_option (option_index, (int) data.diagnostic_kind,
    1019              :                           arg,
    1020      4525424 :                           data.diagnostic_kind != diagnostics::kind::ignored,
    1021              :                           input_location, lang_mask, &handlers,
    1022              :                           &global_options, &global_options_set,
    1023              :                           global_dc);
    1024     15349862 : }
    1025              : 
    1026              : static void
    1027      7831580 : handle_pragma_diagnostic (cpp_reader *)
    1028              : {
    1029      7831580 :   handle_pragma_diagnostic_impl<false, false> ();
    1030      7831580 : }
    1031              : 
    1032              : static void
    1033      7485281 : handle_pragma_diagnostic_early (cpp_reader *)
    1034              : {
    1035      7485281 :   handle_pragma_diagnostic_impl<true, false> ();
    1036      7485281 : }
    1037              : 
    1038              : static void
    1039        33001 : handle_pragma_diagnostic_early_pp (cpp_reader *)
    1040              : {
    1041        33001 :   handle_pragma_diagnostic_impl<true, true> ();
    1042        33001 : }
    1043              : 
    1044              : /* Parse #pragma GCC suppress_coverage begin|end to stop lines from contributing
    1045              :    towards (missing) coverage.  */
    1046              : static void
    1047          698 : handle_pragma_suppress_coverage (cpp_reader*)
    1048              : {
    1049          698 :   tree x;
    1050          698 :   location_t loc;
    1051          698 :   auto token = pragma_lex (&x);
    1052          698 :   enum { bad, begin, end } action = bad;
    1053              : 
    1054          698 :   if (token == CPP_NAME)
    1055              :     {
    1056          697 :       const char *op = IDENTIFIER_POINTER (x);
    1057          697 :       if (!strcmp (op, "begin"))
    1058              :         action = begin;
    1059          348 :       else if (!strcmp (op, "end"))
    1060              :         action = end;
    1061              :     }
    1062              : 
    1063              :   if (bad == action)
    1064            4 :     GCC_BAD ("%<#pragma GCC suppress_coverage%> must be followed by %<begin%> "
    1065              :              "or %<end%>");
    1066          697 :   else if (end == action)
    1067              :     {
    1068          348 :       if (!suppress_coverage_end (input_location))
    1069            1 :         GCC_BAD ("no matching begin for %<#pragma GCC suppress_coverage end%>");
    1070              :     }
    1071              :   else
    1072              :     {
    1073          349 :       if (!suppress_coverage_begin (input_location))
    1074            1 :         GCC_BAD ("%<#pragma GCC suppress_coverage begin%> "
    1075              :                  "was already in effect, ignored");
    1076              :     }
    1077          695 :   if (pragma_lex (&x, &loc) != CPP_EOF)
    1078          695 :     GCC_BAD_AT (loc, "junk at end of %<#pragma GCC suppress_coverage%>");
    1079              : }
    1080              : 
    1081              : /*  Parse #pragma GCC target (xxx) to set target specific options.  */
    1082              : static void
    1083       561932 : handle_pragma_target(cpp_reader *)
    1084              : {
    1085       561932 :   location_t loc;
    1086       561932 :   enum cpp_ttype token;
    1087       561932 :   tree x;
    1088       561932 :   bool close_paren_needed_p = false;
    1089              : 
    1090       561932 :   if (cfun)
    1091              :     {
    1092            0 :       error ("%<#pragma GCC option%> is not allowed inside functions");
    1093            2 :       return;
    1094              :     }
    1095              : 
    1096       561932 :   token = pragma_lex (&x, &loc);
    1097       561932 :   if (token == CPP_OPEN_PAREN)
    1098              :     {
    1099       561876 :       close_paren_needed_p = true;
    1100       561876 :       token = pragma_lex (&x, &loc);
    1101              :     }
    1102              : 
    1103       561932 :   if (token != CPP_STRING)
    1104            2 :     GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string");
    1105              : 
    1106              :   /* Strings are user options.  */
    1107              :   else
    1108              :     {
    1109              :       tree args = NULL_TREE;
    1110              : 
    1111       561948 :       do
    1112              :         {
    1113              :           /* Build up the strings now as a tree linked list.  Skip empty
    1114              :              strings.  */
    1115       561948 :           if (TREE_STRING_LENGTH (x) > 0)
    1116       561948 :             args = tree_cons (NULL_TREE, x, args);
    1117              : 
    1118       561948 :           token = pragma_lex (&x);
    1119      1123914 :           while (token == CPP_COMMA)
    1120           18 :             token = pragma_lex (&x);
    1121              :         }
    1122       561948 :       while (token == CPP_STRING);
    1123              : 
    1124       561930 :       if (close_paren_needed_p)
    1125              :         {
    1126       561875 :           if (token == CPP_CLOSE_PAREN)
    1127       561875 :             token = pragma_lex (&x);
    1128              :           else
    1129       561875 :             GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
    1130              :                      "not have a final %<)%>");
    1131              :         }
    1132              : 
    1133       561930 :       if (token != CPP_EOF)
    1134              :         {
    1135            0 :           error ("%<#pragma GCC target%> string is badly formed");
    1136            0 :           return;
    1137              :         }
    1138              : 
    1139              :       /* put arguments in the order the user typed them.  */
    1140       561930 :       args = nreverse (args);
    1141              : 
    1142       561930 :       if (targetm.target_option.pragma_parse (args, NULL_TREE))
    1143       561661 :         current_target_pragma = chainon (current_target_pragma, args);
    1144              : 
    1145              :       /* A target pragma can also influence optimization options. */
    1146       561930 :       tree current_optimize
    1147       561930 :         = build_optimization_node (&global_options, &global_options_set);
    1148       561930 :       if (current_optimize != optimization_current_node)
    1149           78 :         optimization_current_node = current_optimize;
    1150              :     }
    1151              : }
    1152              : 
    1153              : /* Handle #pragma GCC optimize to set optimization options.  */
    1154              : static void
    1155          533 : handle_pragma_optimize (cpp_reader *)
    1156              : {
    1157          533 :   enum cpp_ttype token;
    1158          533 :   tree x;
    1159          533 :   bool close_paren_needed_p = false;
    1160          533 :   tree optimization_previous_node = optimization_current_node;
    1161              : 
    1162          533 :   if (cfun)
    1163              :     {
    1164            0 :       error ("%<#pragma GCC optimize%> is not allowed inside functions");
    1165            0 :       return;
    1166              :     }
    1167              : 
    1168          533 :   token = pragma_lex (&x);
    1169          533 :   if (token == CPP_OPEN_PAREN)
    1170              :     {
    1171          126 :       close_paren_needed_p = true;
    1172          126 :       token = pragma_lex (&x);
    1173              :     }
    1174              : 
    1175          533 :   if (token != CPP_STRING && token != CPP_NUMBER)
    1176            0 :     GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
    1177              : 
    1178              :   /* Strings/numbers are user options.  */
    1179              :   else
    1180              :     {
    1181              :       tree args = NULL_TREE;
    1182              : 
    1183          549 :       do
    1184              :         {
    1185              :           /* Build up the numbers/strings now as a list.  */
    1186          549 :           if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
    1187          549 :             args = tree_cons (NULL_TREE, x, args);
    1188              : 
    1189          549 :           token = pragma_lex (&x);
    1190         1114 :           while (token == CPP_COMMA)
    1191           16 :             token = pragma_lex (&x);
    1192              :         }
    1193          549 :       while (token == CPP_STRING || token == CPP_NUMBER);
    1194              : 
    1195          533 :       if (close_paren_needed_p)
    1196              :         {
    1197          126 :           if (token == CPP_CLOSE_PAREN)
    1198          126 :             token = pragma_lex (&x);
    1199              :           else
    1200          126 :             GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
    1201              :                      "not have a final %<)%>");
    1202              :         }
    1203              : 
    1204          533 :       if (token != CPP_EOF)
    1205              :         {
    1206            0 :           error ("%<#pragma GCC optimize%> string is badly formed");
    1207            0 :           return;
    1208              :         }
    1209              : 
    1210              :       /* put arguments in the order the user typed them.  */
    1211          533 :       args = nreverse (args);
    1212              : 
    1213          533 :       parse_optimize_options (args, false);
    1214          533 :       current_optimize_pragma = chainon (current_optimize_pragma, args);
    1215          533 :       optimization_current_node
    1216          533 :         = build_optimization_node (&global_options, &global_options_set);
    1217          533 :       c_cpp_builtins_optimize_pragma (parse_in,
    1218              :                                       optimization_previous_node,
    1219              :                                       optimization_current_node);
    1220              :     }
    1221              : }
    1222              : 
    1223              : /* Stack of the #pragma GCC options created with #pragma GCC push_option.  Save
    1224              :    both the binary representation of the options and the TREE_LIST of
    1225              :    strings that will be added to the function's attribute list.  */
    1226              : struct GTY(()) opt_stack {
    1227              :   struct opt_stack *prev;
    1228              :   tree target_binary;
    1229              :   tree target_strings;
    1230              :   tree optimize_binary;
    1231              :   tree optimize_strings;
    1232              :   gcc_options * GTY ((skip)) saved_global_options;
    1233              : };
    1234              : 
    1235              : static GTY(()) struct opt_stack * options_stack;
    1236              : 
    1237              : /* Handle #pragma GCC push_options to save the current target and optimization
    1238              :    options.  */
    1239              : 
    1240              : static void
    1241       562142 : handle_pragma_push_options (cpp_reader *)
    1242              : {
    1243       562142 :   enum cpp_ttype token;
    1244       562142 :   tree x = 0;
    1245              : 
    1246       562142 :   token = pragma_lex (&x);
    1247       562142 :   if (token != CPP_EOF)
    1248              :     {
    1249            0 :       warning (OPT_Wpragmas, "junk at end of %<#pragma GCC push_options%>");
    1250            0 :       return;
    1251              :     }
    1252              : 
    1253       562142 :   opt_stack *p = ggc_alloc<opt_stack> ();
    1254       562142 :   p->prev = options_stack;
    1255       562142 :   options_stack = p;
    1256              : 
    1257              :   /* Save optimization and target flags in binary format.  */
    1258       562142 :   if (flag_checking)
    1259              :     {
    1260       562142 :       p->saved_global_options = XNEW (gcc_options);
    1261       562142 :       *p->saved_global_options = global_options;
    1262              :     }
    1263       562142 :   p->optimize_binary = build_optimization_node (&global_options,
    1264              :                                                 &global_options_set);
    1265       562142 :   p->target_binary = build_target_option_node (&global_options,
    1266              :                                                &global_options_set);
    1267              : 
    1268              :   /* Save optimization and target flags in string list format.  */
    1269       562142 :   p->optimize_strings = copy_list (current_optimize_pragma);
    1270       562142 :   p->target_strings = copy_list (current_target_pragma);
    1271              : }
    1272              : 
    1273              : /* Handle #pragma GCC pop_options to restore the current target and
    1274              :    optimization options from a previous push_options.  */
    1275              : 
    1276              : static void
    1277       562141 : handle_pragma_pop_options (cpp_reader *)
    1278              : {
    1279       562141 :   enum cpp_ttype token;
    1280       562141 :   tree x = 0;
    1281       562141 :   opt_stack *p;
    1282              : 
    1283       562141 :   token = pragma_lex (&x);
    1284       562141 :   if (token != CPP_EOF)
    1285              :     {
    1286            0 :       warning (OPT_Wpragmas, "junk at end of %<#pragma GCC pop_options%>");
    1287            0 :       return;
    1288              :     }
    1289              : 
    1290       562141 :   if (! options_stack)
    1291              :     {
    1292            0 :       warning (OPT_Wpragmas,
    1293              :                "%<#pragma GCC pop_options%> without a corresponding "
    1294              :                "%<#pragma GCC push_options%>");
    1295            0 :       return;
    1296              :     }
    1297              : 
    1298       562141 :   p = options_stack;
    1299       562141 :   options_stack = p->prev;
    1300              : 
    1301       562141 :   if (p->target_binary != target_option_current_node)
    1302              :     {
    1303       556929 :       (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
    1304       556929 :       target_option_current_node = p->target_binary;
    1305              :     }
    1306              : 
    1307              :   /* Always restore optimization options as optimization_current_node is
    1308              :    * overwritten by invoke_set_current_function_hook.  */
    1309      1124282 :   cl_optimization_restore (&global_options, &global_options_set,
    1310       562141 :                            TREE_OPTIMIZATION (p->optimize_binary));
    1311      1124282 :   cl_target_option_restore (&global_options, &global_options_set,
    1312       562141 :                             TREE_TARGET_OPTION (p->target_binary));
    1313              : 
    1314       562141 :   if (p->optimize_binary != optimization_current_node)
    1315              :     {
    1316           52 :       c_cpp_builtins_optimize_pragma (parse_in, optimization_current_node,
    1317              :                                       p->optimize_binary);
    1318           52 :       optimization_current_node = p->optimize_binary;
    1319              :     }
    1320       562141 :   if (flag_checking && !seen_error ())
    1321              :     {
    1322       562137 :       cl_optimization_compare (p->saved_global_options, &global_options);
    1323       562137 :       free (p->saved_global_options);
    1324              :     }
    1325              : 
    1326       562141 :   current_target_pragma = p->target_strings;
    1327       562141 :   current_optimize_pragma = p->optimize_strings;
    1328              : }
    1329              : 
    1330              : /* This is mostly a helper for handle_pragma_reset_options () to do the actual
    1331              :    work, but the C++ frontend, for example, needs an external interface to
    1332              :    perform this operation, since it processes target pragmas twice.  (Once for
    1333              :    preprocessing purposes, and then again during compilation.)  */
    1334              : 
    1335              : void
    1336        99222 : c_reset_target_pragmas ()
    1337              : {
    1338        99222 :   tree new_optimize = optimization_default_node;
    1339        99222 :   tree new_target = target_option_default_node;
    1340        99222 :   if (new_target != target_option_current_node)
    1341              :     {
    1342           41 :       (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
    1343           41 :       target_option_current_node = new_target;
    1344              :     }
    1345              : 
    1346        99222 :   if (new_optimize != optimization_current_node)
    1347              :     {
    1348           49 :       tree old_optimize = optimization_current_node;
    1349           49 :       cl_optimization_restore (&global_options, &global_options_set,
    1350           49 :                                TREE_OPTIMIZATION (new_optimize));
    1351           49 :       c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
    1352           49 :       optimization_current_node = new_optimize;
    1353              :     }
    1354              : 
    1355        99222 :   current_target_pragma = NULL_TREE;
    1356        99222 :   current_optimize_pragma = NULL_TREE;
    1357        99222 : }
    1358              : 
    1359              : /* Handle #pragma GCC reset_options to restore the current target and
    1360              :    optimization options to the original options used on the command line.  */
    1361              : 
    1362              : static void
    1363            4 : handle_pragma_reset_options (cpp_reader *)
    1364              : {
    1365            4 :   tree x;
    1366            4 :   if (pragma_lex (&x) != CPP_EOF)
    1367            0 :     warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
    1368              :   else
    1369            4 :     c_reset_target_pragmas ();
    1370            4 : }
    1371              : 
    1372              : /* Print a plain user-specified message.  */
    1373              : 
    1374              : static void
    1375           56 : handle_pragma_message (cpp_reader *)
    1376              : {
    1377           56 :   location_t loc;
    1378           56 :   enum cpp_ttype token;
    1379           56 :   tree x, message = 0;
    1380              : 
    1381           56 :   token = pragma_lex (&x);
    1382           56 :   if (token == CPP_OPEN_PAREN)
    1383              :     {
    1384           21 :       token = pragma_lex (&x);
    1385           21 :       if (token == CPP_STRING)
    1386           14 :         message = x;
    1387              :       else
    1388           20 :         GCC_BAD ("expected a string after %<#pragma message%>");
    1389           14 :       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
    1390            1 :         GCC_BAD ("malformed %<#pragma message%>, ignored");
    1391              :     }
    1392           35 :   else if (token == CPP_STRING)
    1393           23 :     message = x;
    1394           12 :   else if (token == CPP_STRING_USERDEF)
    1395            3 :     GCC_BAD ("string literal with user-defined suffix is invalid in this "
    1396              :              "context");
    1397              :   else
    1398            9 :     GCC_BAD ("expected a string after %<#pragma message%>");
    1399              : 
    1400           36 :   gcc_assert (message);
    1401              : 
    1402           36 :   if (pragma_lex (&x, &loc) != CPP_EOF)
    1403            3 :     warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>");
    1404              : 
    1405           36 :   if (TREE_STRING_LENGTH (message) > 1)
    1406           32 :     inform (input_location, "%<#pragma message: %s%>",
    1407           32 :             TREE_STRING_POINTER (message));
    1408              : }
    1409              : 
    1410              : /* Ignore a no-op pragma that GCC recognizes, but which has no effect.  */
    1411              : static void
    1412           16 : handle_pragma_ignore (cpp_reader *)
    1413              : {
    1414           16 : }
    1415              : 
    1416              : /* Mark whether the current location is valid for a STDC pragma.  */
    1417              : 
    1418              : static bool valid_location_for_stdc_pragma;
    1419              : 
    1420              : void
    1421    131205115 : mark_valid_location_for_stdc_pragma (bool flag)
    1422              : {
    1423    131205115 :   valid_location_for_stdc_pragma = flag;
    1424    131205115 : }
    1425              : 
    1426              : /* Return true if the current location is valid for a STDC pragma.  */
    1427              : 
    1428              : bool
    1429     38290864 : valid_location_for_stdc_pragma_p (void)
    1430              : {
    1431     38290864 :   return valid_location_for_stdc_pragma;
    1432              : }
    1433              : 
    1434              : enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
    1435              : 
    1436              : /* A STDC pragma must appear outside of external declarations or
    1437              :    preceding all explicit declarations and statements inside a compound
    1438              :    statement; its behavior is undefined if used in any other context.
    1439              :    It takes a switch of ON, OFF, or DEFAULT.  */
    1440              : 
    1441              : static enum pragma_switch_t
    1442           66 : handle_stdc_pragma (const char *pname)
    1443              : {
    1444           66 :   const char *arg;
    1445           66 :   tree t;
    1446           66 :   enum pragma_switch_t ret;
    1447              : 
    1448           66 :   if (!valid_location_for_stdc_pragma_p ())
    1449              :     {
    1450           12 :       warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
    1451              :                pname);
    1452           12 :       return PRAGMA_BAD;
    1453              :     }
    1454              : 
    1455           54 :   if (pragma_lex (&t) != CPP_NAME)
    1456              :     {
    1457            2 :       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
    1458            2 :       return PRAGMA_BAD;
    1459              :     }
    1460              : 
    1461           52 :   arg = IDENTIFIER_POINTER (t);
    1462              : 
    1463           52 :   if (!strcmp (arg, "ON"))
    1464              :     ret = PRAGMA_ON;
    1465           30 :   else if (!strcmp (arg, "OFF"))
    1466              :     ret = PRAGMA_OFF;
    1467           11 :   else if (!strcmp (arg, "DEFAULT"))
    1468              :     ret = PRAGMA_DEFAULT;
    1469              :   else
    1470              :     {
    1471            2 :       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
    1472            2 :       return PRAGMA_BAD;
    1473              :     }
    1474              : 
    1475           50 :   if (pragma_lex (&t) != CPP_EOF)
    1476              :     {
    1477            2 :       warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
    1478            2 :       return PRAGMA_BAD;
    1479              :     }
    1480              : 
    1481              :   return ret;
    1482              : }
    1483              : 
    1484              : /* #pragma STDC FLOAT_CONST_DECIMAL64 ON
    1485              :    #pragma STDC FLOAT_CONST_DECIMAL64 OFF
    1486              :    #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
    1487              : 
    1488              : static void
    1489           69 : handle_pragma_float_const_decimal64 (cpp_reader *)
    1490              : {
    1491           69 :   if (c_dialect_cxx ())
    1492              :     {
    1493            3 :       if (warn_unknown_pragmas > in_system_header_at (input_location))
    1494            3 :         warning (OPT_Wunknown_pragmas,
    1495              :                  "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
    1496              :                  " for C++");
    1497              :       return;
    1498              :     }
    1499              : 
    1500           66 :   if (!targetm.decimal_float_supported_p ())
    1501              :     {
    1502            0 :       if (warn_unknown_pragmas > in_system_header_at (input_location))
    1503            0 :         warning (OPT_Wunknown_pragmas,
    1504              :                  "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
    1505              :                  " on this target");
    1506              :       return;
    1507              :     }
    1508              : 
    1509           66 :   pedwarn (input_location, OPT_Wpedantic,
    1510              :            "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
    1511              : 
    1512           66 :   switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
    1513              :     {
    1514           20 :     case PRAGMA_ON:
    1515           20 :       set_float_const_decimal64 ();
    1516           20 :       break;
    1517           28 :     case PRAGMA_OFF:
    1518           28 :     case PRAGMA_DEFAULT:
    1519           28 :       clear_float_const_decimal64 ();
    1520           28 :       break;
    1521              :     case PRAGMA_BAD:
    1522              :       break;
    1523              :     }
    1524              : }
    1525              : 
    1526              : /* A vector of registered pragma callbacks, which is never freed.   */
    1527              : 
    1528              : 
    1529              : struct pragma_data
    1530              : {
    1531              :   const char *space;
    1532              :   const char *name;
    1533              :   struct internal_pragma_handler ihandler;
    1534              : };
    1535              : 
    1536              : static vec<pragma_data> registered_pragmas;
    1537              : 
    1538              : struct omp_pragma_def { const char *name; unsigned int id; };
    1539              : static const struct omp_pragma_def oacc_pragmas[] = {
    1540              :   { "atomic", PRAGMA_OACC_ATOMIC },
    1541              :   { "cache", PRAGMA_OACC_CACHE },
    1542              :   { "data", PRAGMA_OACC_DATA },
    1543              :   { "declare", PRAGMA_OACC_DECLARE },
    1544              :   { "enter", PRAGMA_OACC_ENTER_DATA },
    1545              :   { "exit", PRAGMA_OACC_EXIT_DATA },
    1546              :   { "host_data", PRAGMA_OACC_HOST_DATA },
    1547              :   { "kernels", PRAGMA_OACC_KERNELS },
    1548              :   { "loop", PRAGMA_OACC_LOOP },
    1549              :   { "parallel", PRAGMA_OACC_PARALLEL },
    1550              :   { "routine", PRAGMA_OACC_ROUTINE },
    1551              :   { "serial", PRAGMA_OACC_SERIAL },
    1552              :   { "update", PRAGMA_OACC_UPDATE },
    1553              :   { "wait", PRAGMA_OACC_WAIT }
    1554              : };
    1555              : static const struct omp_pragma_def omp_pragmas[] = {
    1556              :   { "allocate", PRAGMA_OMP_ALLOCATE },
    1557              :   { "assumes", PRAGMA_OMP_ASSUMES },
    1558              :   { "atomic", PRAGMA_OMP_ATOMIC },
    1559              :   { "barrier", PRAGMA_OMP_BARRIER },
    1560              :   { "begin", PRAGMA_OMP_BEGIN },
    1561              :   { "cancel", PRAGMA_OMP_CANCEL },
    1562              :   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
    1563              :   { "critical", PRAGMA_OMP_CRITICAL },
    1564              :   { "depobj", PRAGMA_OMP_DEPOBJ },
    1565              :   { "dispatch", PRAGMA_OMP_DISPATCH },
    1566              :   { "error", PRAGMA_OMP_ERROR },
    1567              :   { "end", PRAGMA_OMP_END },
    1568              :   { "flush", PRAGMA_OMP_FLUSH },
    1569              :   { "groupprivate", PRAGMA_OMP_GROUPPRIVATE },
    1570              :   { "interop", PRAGMA_OMP_INTEROP },
    1571              :   { "metadirective", PRAGMA_OMP_METADIRECTIVE },
    1572              :   { "nothing", PRAGMA_OMP_NOTHING },
    1573              :   { "requires", PRAGMA_OMP_REQUIRES },
    1574              :   { "scope", PRAGMA_OMP_SCOPE },
    1575              :   { "section", PRAGMA_OMP_SECTION },
    1576              :   { "sections", PRAGMA_OMP_SECTIONS },
    1577              :   { "single", PRAGMA_OMP_SINGLE },
    1578              :   { "task", PRAGMA_OMP_TASK },
    1579              :   { "taskgroup", PRAGMA_OMP_TASKGROUP },
    1580              :   { "taskwait", PRAGMA_OMP_TASKWAIT },
    1581              :   { "taskyield", PRAGMA_OMP_TASKYIELD },
    1582              :   { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
    1583              : };
    1584              : static const struct omp_pragma_def omp_pragmas_simd[] = {
    1585              :   { "assume", PRAGMA_OMP_ASSUME },
    1586              :   { "declare", PRAGMA_OMP_DECLARE },
    1587              :   { "distribute", PRAGMA_OMP_DISTRIBUTE },
    1588              :   { "for", PRAGMA_OMP_FOR },
    1589              :   { "loop", PRAGMA_OMP_LOOP },
    1590              :   { "masked", PRAGMA_OMP_MASKED },
    1591              :   { "master", PRAGMA_OMP_MASTER },
    1592              :   { "ordered", PRAGMA_OMP_ORDERED },
    1593              :   { "parallel", PRAGMA_OMP_PARALLEL },
    1594              :   { "scan", PRAGMA_OMP_SCAN },
    1595              :   { "simd", PRAGMA_OMP_SIMD },
    1596              :   { "target", PRAGMA_OMP_TARGET },
    1597              :   { "taskloop", PRAGMA_OMP_TASKLOOP },
    1598              :   { "teams", PRAGMA_OMP_TEAMS },
    1599              :   { "tile", PRAGMA_OMP_TILE },
    1600              :   { "unroll", PRAGMA_OMP_UNROLL },
    1601              : };
    1602              : 
    1603              : void
    1604        40541 : c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
    1605              : {
    1606        40541 :   const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
    1607        40541 :   const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
    1608        40541 :   const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
    1609        40541 :   int i;
    1610              : 
    1611       608115 :   for (i = 0; i < n_oacc_pragmas; ++i)
    1612       567574 :     if (oacc_pragmas[i].id == id)
    1613              :       {
    1614            0 :         *space = "acc";
    1615            0 :         *name = oacc_pragmas[i].name;
    1616            0 :         return;
    1617              :       }
    1618              : 
    1619      1134926 :   for (i = 0; i < n_omp_pragmas; ++i)
    1620      1094413 :     if (omp_pragmas[i].id == id)
    1621              :       {
    1622           28 :         *space = "omp";
    1623           28 :         *name = omp_pragmas[i].name;
    1624           28 :         return;
    1625              :       }
    1626              : 
    1627       688151 :   for (i = 0; i < n_omp_pragmas_simd; ++i)
    1628       647704 :     if (omp_pragmas_simd[i].id == id)
    1629              :       {
    1630           66 :         *space = "omp";
    1631           66 :         *name = omp_pragmas_simd[i].name;
    1632           66 :         return;
    1633              :       }
    1634              : 
    1635        40447 :   if (id >= PRAGMA_FIRST_EXTERNAL
    1636        80894 :       && (id < PRAGMA_FIRST_EXTERNAL + registered_pragmas.length ()))
    1637              :     {
    1638        40447 :       *space = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].space;
    1639        40447 :       *name = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].name;
    1640        40447 :       return;
    1641              :     }
    1642              : 
    1643            0 :   gcc_unreachable ();
    1644              : }
    1645              : 
    1646              : /* Front-end wrappers for pragma registration to avoid dragging
    1647              :    cpplib.h in almost everywhere.  */
    1648              : 
    1649              : static void
    1650      4007655 : c_register_pragma_1 (const char *space, const char *name,
    1651              :                      internal_pragma_handler ihandler, bool allow_expansion)
    1652              : {
    1653      4007655 :   unsigned id;
    1654              : 
    1655      4007655 :   pragma_data data;
    1656      4007655 :   data.space = space;
    1657      4007655 :   data.name = name;
    1658              : 
    1659      4007655 :   if (flag_preprocess_only
    1660       116592 :       && (cpp_get_options (parse_in)->directives_only
    1661       115024 :         || !(allow_expansion || ihandler.early_handler.handler_1arg)))
    1662        59080 :     return;
    1663              : 
    1664      3948575 :   data.ihandler = ihandler;
    1665      3948575 :   registered_pragmas.safe_push (data);
    1666      3948575 :   id = registered_pragmas.length ();
    1667      7897150 :   id += PRAGMA_FIRST_EXTERNAL - 1;
    1668              : 
    1669              :   /* The C front end allocates 8 bits in c_token.  The C++ front end
    1670              :      keeps the pragma kind in the form of INTEGER_CST, so no small
    1671              :      limit applies.  At present this is sufficient.  */
    1672      3948575 :   gcc_assert (id < 256);
    1673              : 
    1674      3948575 :   cpp_register_deferred_pragma (parse_in, space, name, id,
    1675              :                                 allow_expansion, false);
    1676              : }
    1677              : 
    1678              : /* Register a C pragma handler, using a space and a name.  It disallows pragma
    1679              :    expansion (if you want it, use c_register_pragma_with_expansion instead).  */
    1680              : void
    1681      2301599 : c_register_pragma (const char *space, const char *name,
    1682              :                    pragma_handler_1arg handler)
    1683              : {
    1684      2301599 :   c_register_pragma_with_early_handler (space, name, handler, nullptr);
    1685      2301599 : }
    1686      3581141 : void c_register_pragma_with_early_handler (const char *space, const char *name,
    1687              :                                            pragma_handler_1arg handler,
    1688              :                                            pragma_handler_1arg early_handler)
    1689              : {
    1690      3581141 :   internal_pragma_handler ihandler;
    1691              : 
    1692      3581141 :   ihandler.handler.handler_1arg = handler;
    1693      3581141 :   ihandler.early_handler.handler_1arg = early_handler;
    1694      3581141 :   ihandler.extra_data = false;
    1695      3581141 :   ihandler.data = NULL;
    1696      3581141 :   c_register_pragma_1 (space, name, ihandler, false);
    1697      3581141 : }
    1698              : 
    1699              : /* Register a C pragma handler, using a space and a name, it also carries an
    1700              :    extra data field which can be used by the handler.  It disallows pragma
    1701              :    expansion (if you want it, use c_register_pragma_with_expansion_and_data
    1702              :    instead).  */
    1703              : void
    1704            0 : c_register_pragma_with_data (const char *space, const char *name,
    1705              :                              pragma_handler_2arg handler, void * data)
    1706              : {
    1707            0 :   internal_pragma_handler ihandler;
    1708              : 
    1709            0 :   ihandler.handler.handler_2arg = handler;
    1710            0 :   ihandler.early_handler.handler_2arg = nullptr;
    1711            0 :   ihandler.extra_data = true;
    1712            0 :   ihandler.data = data;
    1713            0 :   c_register_pragma_1 (space, name, ihandler, false);
    1714            0 : }
    1715              : 
    1716              : /* Register a C pragma handler, using a space and a name.  It allows pragma
    1717              :    expansion as in the following example:
    1718              : 
    1719              :    #define NUMBER 10
    1720              :    #pragma count (NUMBER)
    1721              : 
    1722              :    Name expansion is still disallowed.  */
    1723              : void
    1724       426514 : c_register_pragma_with_expansion (const char *space, const char *name,
    1725              :                                   pragma_handler_1arg handler)
    1726              : {
    1727       426514 :   internal_pragma_handler ihandler;
    1728              : 
    1729       426514 :   ihandler.handler.handler_1arg = handler;
    1730       426514 :   ihandler.early_handler.handler_1arg = nullptr;
    1731       426514 :   ihandler.extra_data = false;
    1732       426514 :   ihandler.data = NULL;
    1733       426514 :   c_register_pragma_1 (space, name, ihandler, true);
    1734       426514 : }
    1735              : 
    1736              : /* Register a C pragma handler, using a space and a name, it also carries an
    1737              :    extra data field which can be used by the handler.  It allows pragma
    1738              :    expansion as in the following example:
    1739              : 
    1740              :    #define NUMBER 10
    1741              :    #pragma count (NUMBER)
    1742              : 
    1743              :    Name expansion is still disallowed.  */
    1744              : void
    1745            0 : c_register_pragma_with_expansion_and_data (const char *space, const char *name,
    1746              :                                            pragma_handler_2arg handler,
    1747              :                                            void *data)
    1748              : {
    1749            0 :   internal_pragma_handler ihandler;
    1750              : 
    1751            0 :   ihandler.handler.handler_2arg = handler;
    1752            0 :   ihandler.early_handler.handler_2arg = nullptr;
    1753            0 :   ihandler.extra_data = true;
    1754            0 :   ihandler.data = data;
    1755            0 :   c_register_pragma_1 (space, name, ihandler, true);
    1756            0 : }
    1757              : 
    1758              : void
    1759      9706854 : c_invoke_pragma_handler (unsigned int id)
    1760              : {
    1761      9706854 :   internal_pragma_handler *ihandler;
    1762      9706854 :   pragma_handler_1arg handler_1arg;
    1763      9706854 :   pragma_handler_2arg handler_2arg;
    1764              : 
    1765      9706854 :   id -= PRAGMA_FIRST_EXTERNAL;
    1766      9706854 :   ihandler = &registered_pragmas[id].ihandler;
    1767      9706854 :   if (ihandler->extra_data)
    1768              :     {
    1769            0 :       handler_2arg = ihandler->handler.handler_2arg;
    1770            0 :       handler_2arg (parse_in, ihandler->data);
    1771              :     }
    1772              :   else
    1773              :     {
    1774      9706854 :       handler_1arg = ihandler->handler.handler_1arg;
    1775      9706854 :       handler_1arg (parse_in);
    1776              :     }
    1777      9706854 : }
    1778              : 
    1779              : /* In contrast to the normal handler, the early handler is optional.  */
    1780              : void
    1781      7801485 : c_invoke_early_pragma_handler (unsigned int id)
    1782              : {
    1783      7801485 :   internal_pragma_handler *ihandler;
    1784      7801485 :   pragma_handler_1arg handler_1arg;
    1785      7801485 :   pragma_handler_2arg handler_2arg;
    1786              : 
    1787      7801485 :   id -= PRAGMA_FIRST_EXTERNAL;
    1788      7801485 :   ihandler = &registered_pragmas[id].ihandler;
    1789      7801485 :   if (ihandler->extra_data)
    1790              :     {
    1791            0 :       handler_2arg = ihandler->early_handler.handler_2arg;
    1792            0 :       if (handler_2arg)
    1793            0 :         handler_2arg (parse_in, ihandler->data);
    1794              :     }
    1795              :   else
    1796              :     {
    1797      7801485 :       handler_1arg = ihandler->early_handler.handler_1arg;
    1798      7801485 :       if (handler_1arg)
    1799      7546574 :         handler_1arg (parse_in);
    1800              :     }
    1801      7801485 : }
    1802              : 
    1803              : void
    1804        40447 : c_pp_invoke_early_pragma_handler (unsigned int id)
    1805              : {
    1806        40447 :   const auto data = &registered_pragmas[id - PRAGMA_FIRST_EXTERNAL];
    1807        40447 :   pragma_handler_1arg handler = data->ihandler.early_handler.handler_1arg;
    1808        40447 :   if (handler)
    1809              :     {
    1810        40429 :       handler (parse_in);
    1811        40429 :       pragma_lex_discard_to_eol ();
    1812              :     }
    1813        40447 : }
    1814              : 
    1815              : /* Set up front-end pragmas.  */
    1816              : void
    1817       213257 : init_pragma (void)
    1818              : {
    1819              : 
    1820       213257 :   if (!cpp_get_options (parse_in)->directives_only)
    1821              :     {
    1822       213126 :       if (flag_openacc)
    1823              :         {
    1824              :           const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
    1825              :           int i;
    1826              : 
    1827        25125 :           for (i = 0; i < n_oacc_pragmas; ++i)
    1828        23450 :             cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
    1829        23450 :                                           oacc_pragmas[i].id, true, true);
    1830              :         }
    1831              : 
    1832       213126 :       if (flag_openmp)
    1833              :         {
    1834              :           const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
    1835              :           int i;
    1836              : 
    1837       182504 :           for (i = 0; i < n_omp_pragmas; ++i)
    1838       175986 :             cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
    1839       175986 :                                           omp_pragmas[i].id, true, true);
    1840              :         }
    1841       213126 :       if (flag_openmp || flag_openmp_simd)
    1842              :         {
    1843              :           const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
    1844              :           int i;
    1845              : 
    1846       118014 :           for (i = 0; i < n_omp_pragmas_simd; ++i)
    1847       111072 :             cpp_register_deferred_pragma (parse_in, "omp",
    1848       111072 :                                           omp_pragmas_simd[i].name,
    1849       111072 :                                           omp_pragmas_simd[i].id, true, true);
    1850              :         }
    1851              :     }
    1852              : 
    1853       213257 :   if (!flag_preprocess_only)
    1854       205970 :     cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
    1855              :                                   PRAGMA_GCC_PCH_PREPROCESS, false, false);
    1856              : 
    1857       213257 :   if (!flag_preprocess_only)
    1858       205970 :     cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
    1859              :                                   false);
    1860              : 
    1861       213257 :   if (!flag_preprocess_only)
    1862       205970 :     cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
    1863              :                                   false, false);
    1864              : 
    1865       213257 :   if (!flag_preprocess_only)
    1866       205970 :     cpp_register_deferred_pragma (parse_in, "GCC", "novector", PRAGMA_NOVECTOR,
    1867              :                                   false, false);
    1868              : 
    1869              : #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
    1870              :   c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
    1871              : #else
    1872       213257 :   c_register_pragma (0, "pack", handle_pragma_pack);
    1873              : #endif
    1874       213257 :   c_register_pragma (0, "weak", handle_pragma_weak);
    1875              : 
    1876       213257 :   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
    1877       213257 :   c_register_pragma ("GCC", "suppress_coverage",
    1878              :                      handle_pragma_suppress_coverage);
    1879              : 
    1880       213257 :   if (flag_preprocess_only)
    1881         7287 :     c_register_pragma_with_early_handler ("GCC", "diagnostic",
    1882              :                                           nullptr,
    1883              :                                           handle_pragma_diagnostic_early_pp);
    1884              :   else
    1885       205970 :     c_register_pragma_with_early_handler ("GCC", "diagnostic",
    1886              :                                           handle_pragma_diagnostic,
    1887              :                                           handle_pragma_diagnostic_early);
    1888       213257 :   c_register_pragma_with_early_handler ("GCC", "target",
    1889              :                                         handle_pragma_target,
    1890              :                                         handle_pragma_target);
    1891       213257 :   c_register_pragma_with_early_handler ("GCC", "optimize",
    1892              :                                         handle_pragma_optimize,
    1893              :                                         handle_pragma_optimize);
    1894       213257 :   c_register_pragma_with_early_handler ("GCC", "push_options",
    1895              :                                         handle_pragma_push_options,
    1896              :                                         handle_pragma_push_options);
    1897       213257 :   c_register_pragma_with_early_handler ("GCC", "pop_options",
    1898              :                                         handle_pragma_pop_options,
    1899              :                                         handle_pragma_pop_options);
    1900       213257 :   c_register_pragma_with_early_handler ("GCC", "reset_options",
    1901              :                                         handle_pragma_reset_options,
    1902              :                                         handle_pragma_reset_options);
    1903              : 
    1904       213257 :   c_register_pragma (0, "region", handle_pragma_ignore);
    1905       213257 :   c_register_pragma (0, "endregion", handle_pragma_ignore);
    1906              : 
    1907       213257 :   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
    1908              :                      handle_pragma_float_const_decimal64);
    1909              : 
    1910       213257 :   c_register_pragma_with_expansion (0, "redefine_extname",
    1911              :                                     handle_pragma_redefine_extname);
    1912              : 
    1913       213257 :   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
    1914              : 
    1915              : #ifdef REGISTER_TARGET_PRAGMAS
    1916       213257 :   REGISTER_TARGET_PRAGMAS ();
    1917              : #endif
    1918              : 
    1919       213257 :   global_sso = default_sso;
    1920       213257 :   c_register_pragma (0, "scalar_storage_order",
    1921              :                      handle_pragma_scalar_storage_order);
    1922              : 
    1923              :   /* Allow plugins to register their own pragmas. */
    1924       213257 :   invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
    1925       213257 : }
    1926              : 
    1927              : #include "gt-c-family-c-pragma.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.