LCOV - code coverage report
Current view: top level - gcc/c-family - c-pragma.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 562 667 84.3 %
Date: 2020-03-28 11:57:23 Functions: 31 34 91.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.