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