xref: /openbsd/gnu/usr.bin/gcc/gcc/c-pragma.c (revision c87b03e5)
1*c87b03e5Sespie /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
2*c87b03e5Sespie    Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
3*c87b03e5Sespie    Free Software Foundation, Inc.
4*c87b03e5Sespie 
5*c87b03e5Sespie This file is part of GCC.
6*c87b03e5Sespie 
7*c87b03e5Sespie GCC is free software; you can redistribute it and/or modify it under
8*c87b03e5Sespie the terms of the GNU General Public License as published by the Free
9*c87b03e5Sespie Software Foundation; either version 2, or (at your option) any later
10*c87b03e5Sespie version.
11*c87b03e5Sespie 
12*c87b03e5Sespie GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*c87b03e5Sespie WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*c87b03e5Sespie FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*c87b03e5Sespie for more details.
16*c87b03e5Sespie 
17*c87b03e5Sespie You should have received a copy of the GNU General Public License
18*c87b03e5Sespie along with GCC; see the file COPYING.  If not, write to the Free
19*c87b03e5Sespie Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20*c87b03e5Sespie 02111-1307, USA.  */
21*c87b03e5Sespie 
22*c87b03e5Sespie #include "config.h"
23*c87b03e5Sespie #include "system.h"
24*c87b03e5Sespie #include "rtl.h"
25*c87b03e5Sespie #include "tree.h"
26*c87b03e5Sespie #include "function.h"
27*c87b03e5Sespie #include "cpplib.h"
28*c87b03e5Sespie #include "c-pragma.h"
29*c87b03e5Sespie #include "flags.h"
30*c87b03e5Sespie #include "toplev.h"
31*c87b03e5Sespie #include "ggc.h"
32*c87b03e5Sespie #include "c-common.h"
33*c87b03e5Sespie #include "output.h"
34*c87b03e5Sespie #include "tm_p.h"
35*c87b03e5Sespie 
36*c87b03e5Sespie #define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
37*c87b03e5Sespie #define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
38*c87b03e5Sespie 
39*c87b03e5Sespie typedef struct align_stack GTY(())
40*c87b03e5Sespie {
41*c87b03e5Sespie   int                  alignment;
42*c87b03e5Sespie   unsigned int         num_pushes;
43*c87b03e5Sespie   tree                 id;
44*c87b03e5Sespie   struct align_stack * prev;
45*c87b03e5Sespie } align_stack;
46*c87b03e5Sespie 
47*c87b03e5Sespie static GTY(()) struct align_stack * alignment_stack;
48*c87b03e5Sespie 
49*c87b03e5Sespie #ifdef HANDLE_PRAGMA_PACK
50*c87b03e5Sespie static void handle_pragma_pack PARAMS ((cpp_reader *));
51*c87b03e5Sespie 
52*c87b03e5Sespie #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
53*c87b03e5Sespie /* If we have a "global" #pragma pack(<n>) in effect when the first
54*c87b03e5Sespie    #pragma pack(push,<n>) is encountered, this stores the value of
55*c87b03e5Sespie    maximum_field_alignment in effect.  When the final pop_alignment()
56*c87b03e5Sespie    happens, we restore the value to this, not to a value of 0 for
57*c87b03e5Sespie    maximum_field_alignment.  Value is in bits.  */
58*c87b03e5Sespie static int default_alignment;
59*c87b03e5Sespie #define SET_GLOBAL_ALIGNMENT(ALIGN) \
60*c87b03e5Sespie   (default_alignment = maximum_field_alignment = (ALIGN))
61*c87b03e5Sespie 
62*c87b03e5Sespie static void push_alignment PARAMS ((int, tree));
63*c87b03e5Sespie static void pop_alignment  PARAMS ((tree));
64*c87b03e5Sespie 
65*c87b03e5Sespie /* Push an alignment value onto the stack.  */
66*c87b03e5Sespie static void
push_alignment(alignment,id)67*c87b03e5Sespie push_alignment (alignment, id)
68*c87b03e5Sespie      int alignment;
69*c87b03e5Sespie      tree id;
70*c87b03e5Sespie {
71*c87b03e5Sespie   if (alignment_stack == NULL
72*c87b03e5Sespie       || alignment_stack->alignment != alignment
73*c87b03e5Sespie       || id != NULL_TREE)
74*c87b03e5Sespie     {
75*c87b03e5Sespie       align_stack * entry;
76*c87b03e5Sespie 
77*c87b03e5Sespie       entry = (align_stack *) ggc_alloc (sizeof (* entry));
78*c87b03e5Sespie 
79*c87b03e5Sespie       entry->alignment  = alignment;
80*c87b03e5Sespie       entry->num_pushes = 1;
81*c87b03e5Sespie       entry->id         = id;
82*c87b03e5Sespie       entry->prev       = alignment_stack;
83*c87b03e5Sespie 
84*c87b03e5Sespie       /* The current value of maximum_field_alignment is not necessarily
85*c87b03e5Sespie 	 0 since there may be a #pragma pack(<n>) in effect; remember it
86*c87b03e5Sespie 	 so that we can restore it after the final #pragma pop().  */
87*c87b03e5Sespie       if (alignment_stack == NULL)
88*c87b03e5Sespie 	default_alignment = maximum_field_alignment;
89*c87b03e5Sespie 
90*c87b03e5Sespie       alignment_stack = entry;
91*c87b03e5Sespie 
92*c87b03e5Sespie       maximum_field_alignment = alignment;
93*c87b03e5Sespie     }
94*c87b03e5Sespie   else
95*c87b03e5Sespie     alignment_stack->num_pushes ++;
96*c87b03e5Sespie }
97*c87b03e5Sespie 
98*c87b03e5Sespie /* Undo a push of an alignment onto the stack.  */
99*c87b03e5Sespie static void
pop_alignment(id)100*c87b03e5Sespie pop_alignment (id)
101*c87b03e5Sespie      tree id;
102*c87b03e5Sespie {
103*c87b03e5Sespie   align_stack * entry;
104*c87b03e5Sespie 
105*c87b03e5Sespie   if (alignment_stack == NULL)
106*c87b03e5Sespie     {
107*c87b03e5Sespie       warning ("\
108*c87b03e5Sespie #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
109*c87b03e5Sespie 	       );
110*c87b03e5Sespie       return;
111*c87b03e5Sespie     }
112*c87b03e5Sespie 
113*c87b03e5Sespie   /* If we got an identifier, strip away everything above the target
114*c87b03e5Sespie      entry so that the next step will restore the state just below it.  */
115*c87b03e5Sespie   if (id)
116*c87b03e5Sespie     {
117*c87b03e5Sespie       for (entry = alignment_stack; entry; entry = entry->prev)
118*c87b03e5Sespie 	if (entry->id == id)
119*c87b03e5Sespie 	  {
120*c87b03e5Sespie 	    entry->num_pushes = 1;
121*c87b03e5Sespie 	    alignment_stack = entry;
122*c87b03e5Sespie 	    break;
123*c87b03e5Sespie 	  }
124*c87b03e5Sespie       if (entry == NULL)
125*c87b03e5Sespie 	warning ("\
126*c87b03e5Sespie #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
127*c87b03e5Sespie 		 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
128*c87b03e5Sespie     }
129*c87b03e5Sespie 
130*c87b03e5Sespie   if (-- alignment_stack->num_pushes == 0)
131*c87b03e5Sespie     {
132*c87b03e5Sespie       entry = alignment_stack->prev;
133*c87b03e5Sespie 
134*c87b03e5Sespie       if (entry == NULL)
135*c87b03e5Sespie 	maximum_field_alignment = default_alignment;
136*c87b03e5Sespie       else
137*c87b03e5Sespie 	maximum_field_alignment = entry->alignment;
138*c87b03e5Sespie 
139*c87b03e5Sespie       alignment_stack = entry;
140*c87b03e5Sespie     }
141*c87b03e5Sespie }
142*c87b03e5Sespie #else  /* not HANDLE_PRAGMA_PACK_PUSH_POP */
143*c87b03e5Sespie #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
144*c87b03e5Sespie #define push_alignment(ID, N) \
145*c87b03e5Sespie     GCC_BAD("#pragma pack(push[, id], <n>) is not supported on this target")
146*c87b03e5Sespie #define pop_alignment(ID) \
147*c87b03e5Sespie     GCC_BAD("#pragma pack(pop[, id], <n>) is not supported on this target")
148*c87b03e5Sespie #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
149*c87b03e5Sespie 
150*c87b03e5Sespie /* #pragma pack ()
151*c87b03e5Sespie    #pragma pack (N)
152*c87b03e5Sespie 
153*c87b03e5Sespie    #pragma pack (push, N)
154*c87b03e5Sespie    #pragma pack (push, ID, N)
155*c87b03e5Sespie    #pragma pack (pop)
156*c87b03e5Sespie    #pragma pack (pop, ID) */
157*c87b03e5Sespie static void
handle_pragma_pack(dummy)158*c87b03e5Sespie handle_pragma_pack (dummy)
159*c87b03e5Sespie      cpp_reader *dummy ATTRIBUTE_UNUSED;
160*c87b03e5Sespie {
161*c87b03e5Sespie   tree x, id = 0;
162*c87b03e5Sespie   int align = -1;
163*c87b03e5Sespie   enum cpp_ttype token;
164*c87b03e5Sespie   enum { set, push, pop } action;
165*c87b03e5Sespie 
166*c87b03e5Sespie   if (c_lex (&x) != CPP_OPEN_PAREN)
167*c87b03e5Sespie     GCC_BAD ("missing '(' after '#pragma pack' - ignored");
168*c87b03e5Sespie 
169*c87b03e5Sespie   token = c_lex (&x);
170*c87b03e5Sespie   if (token == CPP_CLOSE_PAREN)
171*c87b03e5Sespie     {
172*c87b03e5Sespie       action = set;
173*c87b03e5Sespie       align = 0;
174*c87b03e5Sespie     }
175*c87b03e5Sespie   else if (token == CPP_NUMBER)
176*c87b03e5Sespie     {
177*c87b03e5Sespie       align = TREE_INT_CST_LOW (x);
178*c87b03e5Sespie       action = set;
179*c87b03e5Sespie       if (c_lex (&x) != CPP_CLOSE_PAREN)
180*c87b03e5Sespie 	GCC_BAD ("malformed '#pragma pack' - ignored");
181*c87b03e5Sespie     }
182*c87b03e5Sespie   else if (token == CPP_NAME)
183*c87b03e5Sespie     {
184*c87b03e5Sespie #define GCC_BAD_ACTION do { if (action == push) \
185*c87b03e5Sespie 	  GCC_BAD ("malformed '#pragma pack(push[, id], <n>)' - ignored"); \
186*c87b03e5Sespie 	else \
187*c87b03e5Sespie 	  GCC_BAD ("malformed '#pragma pack(pop[, id])' - ignored"); \
188*c87b03e5Sespie 	} while (0)
189*c87b03e5Sespie 
190*c87b03e5Sespie       const char *op = IDENTIFIER_POINTER (x);
191*c87b03e5Sespie       if (!strcmp (op, "push"))
192*c87b03e5Sespie 	action = push;
193*c87b03e5Sespie       else if (!strcmp (op, "pop"))
194*c87b03e5Sespie 	action = pop;
195*c87b03e5Sespie       else
196*c87b03e5Sespie 	GCC_BAD2 ("unknown action '%s' for '#pragma pack' - ignored", op);
197*c87b03e5Sespie 
198*c87b03e5Sespie       token = c_lex (&x);
199*c87b03e5Sespie       if (token != CPP_COMMA && action == push)
200*c87b03e5Sespie 	GCC_BAD_ACTION;
201*c87b03e5Sespie 
202*c87b03e5Sespie       if (token == CPP_COMMA)
203*c87b03e5Sespie 	{
204*c87b03e5Sespie 	  token = c_lex (&x);
205*c87b03e5Sespie 	  if (token == CPP_NAME)
206*c87b03e5Sespie 	    {
207*c87b03e5Sespie 	      id = x;
208*c87b03e5Sespie 	      if (action == push && c_lex (&x) != CPP_COMMA)
209*c87b03e5Sespie 		GCC_BAD_ACTION;
210*c87b03e5Sespie 	      token = c_lex (&x);
211*c87b03e5Sespie 	    }
212*c87b03e5Sespie 
213*c87b03e5Sespie 	  if (action == push)
214*c87b03e5Sespie 	    {
215*c87b03e5Sespie 	      if (token == CPP_NUMBER)
216*c87b03e5Sespie 		{
217*c87b03e5Sespie 		  align = TREE_INT_CST_LOW (x);
218*c87b03e5Sespie 		  token = c_lex (&x);
219*c87b03e5Sespie 		}
220*c87b03e5Sespie 	      else
221*c87b03e5Sespie 		GCC_BAD_ACTION;
222*c87b03e5Sespie 	    }
223*c87b03e5Sespie 	}
224*c87b03e5Sespie 
225*c87b03e5Sespie       if (token != CPP_CLOSE_PAREN)
226*c87b03e5Sespie 	GCC_BAD_ACTION;
227*c87b03e5Sespie #undef GCC_BAD_ACTION
228*c87b03e5Sespie     }
229*c87b03e5Sespie   else
230*c87b03e5Sespie     GCC_BAD ("malformed '#pragma pack' - ignored");
231*c87b03e5Sespie 
232*c87b03e5Sespie   if (c_lex (&x) != CPP_EOF)
233*c87b03e5Sespie     warning ("junk at end of '#pragma pack'");
234*c87b03e5Sespie 
235*c87b03e5Sespie   if (action != pop)
236*c87b03e5Sespie     switch (align)
237*c87b03e5Sespie       {
238*c87b03e5Sespie       case 0:
239*c87b03e5Sespie       case 1:
240*c87b03e5Sespie       case 2:
241*c87b03e5Sespie       case 4:
242*c87b03e5Sespie       case 8:
243*c87b03e5Sespie       case 16:
244*c87b03e5Sespie 	align *= BITS_PER_UNIT;
245*c87b03e5Sespie 	break;
246*c87b03e5Sespie       default:
247*c87b03e5Sespie 	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
248*c87b03e5Sespie       }
249*c87b03e5Sespie 
250*c87b03e5Sespie   switch (action)
251*c87b03e5Sespie     {
252*c87b03e5Sespie     case set:   SET_GLOBAL_ALIGNMENT (align);  break;
253*c87b03e5Sespie     case push:  push_alignment (align, id);    break;
254*c87b03e5Sespie     case pop:   pop_alignment (id);            break;
255*c87b03e5Sespie     }
256*c87b03e5Sespie }
257*c87b03e5Sespie #endif  /* HANDLE_PRAGMA_PACK */
258*c87b03e5Sespie 
259*c87b03e5Sespie static GTY(()) tree pending_weaks;
260*c87b03e5Sespie 
261*c87b03e5Sespie #ifdef HANDLE_PRAGMA_WEAK
262*c87b03e5Sespie static void apply_pragma_weak PARAMS ((tree, tree));
263*c87b03e5Sespie static void handle_pragma_weak PARAMS ((cpp_reader *));
264*c87b03e5Sespie 
265*c87b03e5Sespie static void
apply_pragma_weak(decl,value)266*c87b03e5Sespie apply_pragma_weak (decl, value)
267*c87b03e5Sespie      tree decl, value;
268*c87b03e5Sespie {
269*c87b03e5Sespie   if (value)
270*c87b03e5Sespie     {
271*c87b03e5Sespie       value = build_string (IDENTIFIER_LENGTH (value),
272*c87b03e5Sespie 			    IDENTIFIER_POINTER (value));
273*c87b03e5Sespie       decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
274*c87b03e5Sespie 					       build_tree_list (NULL, value)),
275*c87b03e5Sespie 		       0);
276*c87b03e5Sespie     }
277*c87b03e5Sespie 
278*c87b03e5Sespie   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
279*c87b03e5Sespie       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
280*c87b03e5Sespie     warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
281*c87b03e5Sespie 
282*c87b03e5Sespie   declare_weak (decl);
283*c87b03e5Sespie }
284*c87b03e5Sespie 
285*c87b03e5Sespie void
maybe_apply_pragma_weak(decl)286*c87b03e5Sespie maybe_apply_pragma_weak (decl)
287*c87b03e5Sespie      tree decl;
288*c87b03e5Sespie {
289*c87b03e5Sespie   tree *p, t, id;
290*c87b03e5Sespie 
291*c87b03e5Sespie   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
292*c87b03e5Sespie 
293*c87b03e5Sespie   /* No weak symbols pending, take the short-cut.  */
294*c87b03e5Sespie   if (!pending_weaks)
295*c87b03e5Sespie     return;
296*c87b03e5Sespie   /* If it's not visible outside this file, it doesn't matter whether
297*c87b03e5Sespie      it's weak.  */
298*c87b03e5Sespie   if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
299*c87b03e5Sespie     return;
300*c87b03e5Sespie   /* If it's not a function or a variable, it can't be weak.
301*c87b03e5Sespie      FIXME: what kinds of things are visible outside this file but
302*c87b03e5Sespie      aren't functions or variables?   Should this be an abort() instead?  */
303*c87b03e5Sespie   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
304*c87b03e5Sespie     return;
305*c87b03e5Sespie 
306*c87b03e5Sespie   id = DECL_ASSEMBLER_NAME (decl);
307*c87b03e5Sespie 
308*c87b03e5Sespie   for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
309*c87b03e5Sespie     if (id == TREE_PURPOSE (t))
310*c87b03e5Sespie       {
311*c87b03e5Sespie 	apply_pragma_weak (decl, TREE_VALUE (t));
312*c87b03e5Sespie 	*p = TREE_CHAIN (t);
313*c87b03e5Sespie 	break;
314*c87b03e5Sespie       }
315*c87b03e5Sespie }
316*c87b03e5Sespie 
317*c87b03e5Sespie /* #pragma weak name [= value] */
318*c87b03e5Sespie static void
handle_pragma_weak(dummy)319*c87b03e5Sespie handle_pragma_weak (dummy)
320*c87b03e5Sespie      cpp_reader *dummy ATTRIBUTE_UNUSED;
321*c87b03e5Sespie {
322*c87b03e5Sespie   tree name, value, x, decl;
323*c87b03e5Sespie   enum cpp_ttype t;
324*c87b03e5Sespie 
325*c87b03e5Sespie   value = 0;
326*c87b03e5Sespie 
327*c87b03e5Sespie   if (c_lex (&name) != CPP_NAME)
328*c87b03e5Sespie     GCC_BAD ("malformed #pragma weak, ignored");
329*c87b03e5Sespie   t = c_lex (&x);
330*c87b03e5Sespie   if (t == CPP_EQ)
331*c87b03e5Sespie     {
332*c87b03e5Sespie       if (c_lex (&value) != CPP_NAME)
333*c87b03e5Sespie 	GCC_BAD ("malformed #pragma weak, ignored");
334*c87b03e5Sespie       t = c_lex (&x);
335*c87b03e5Sespie     }
336*c87b03e5Sespie   if (t != CPP_EOF)
337*c87b03e5Sespie     warning ("junk at end of #pragma weak");
338*c87b03e5Sespie 
339*c87b03e5Sespie   decl = identifier_global_value (name);
340*c87b03e5Sespie   if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
341*c87b03e5Sespie     {
342*c87b03e5Sespie       apply_pragma_weak (decl, value);
343*c87b03e5Sespie       if (value)
344*c87b03e5Sespie 	assemble_alias (decl, value);
345*c87b03e5Sespie     }
346*c87b03e5Sespie   else
347*c87b03e5Sespie     pending_weaks = tree_cons (name, value, pending_weaks);
348*c87b03e5Sespie }
349*c87b03e5Sespie #else
350*c87b03e5Sespie void
maybe_apply_pragma_weak(decl)351*c87b03e5Sespie maybe_apply_pragma_weak (decl)
352*c87b03e5Sespie      tree decl ATTRIBUTE_UNUSED;
353*c87b03e5Sespie {
354*c87b03e5Sespie }
355*c87b03e5Sespie #endif /* HANDLE_PRAGMA_WEAK */
356*c87b03e5Sespie 
357*c87b03e5Sespie static GTY(()) tree pending_redefine_extname;
358*c87b03e5Sespie 
359*c87b03e5Sespie #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
360*c87b03e5Sespie static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
361*c87b03e5Sespie 
362*c87b03e5Sespie /* #pragma redefined_extname oldname newname */
363*c87b03e5Sespie static void
handle_pragma_redefine_extname(dummy)364*c87b03e5Sespie handle_pragma_redefine_extname (dummy)
365*c87b03e5Sespie      cpp_reader *dummy ATTRIBUTE_UNUSED;
366*c87b03e5Sespie {
367*c87b03e5Sespie   tree oldname, newname, decl, x;
368*c87b03e5Sespie   enum cpp_ttype t;
369*c87b03e5Sespie 
370*c87b03e5Sespie   if (c_lex (&oldname) != CPP_NAME)
371*c87b03e5Sespie     {
372*c87b03e5Sespie       warning ("malformed #pragma redefine_extname, ignored");
373*c87b03e5Sespie       return;
374*c87b03e5Sespie     }
375*c87b03e5Sespie   if (c_lex (&newname) != CPP_NAME)
376*c87b03e5Sespie     {
377*c87b03e5Sespie       warning ("malformed #pragma redefine_extname, ignored");
378*c87b03e5Sespie       return;
379*c87b03e5Sespie     }
380*c87b03e5Sespie   t = c_lex (&x);
381*c87b03e5Sespie   if (t != CPP_EOF)
382*c87b03e5Sespie     warning ("junk at end of #pragma redefine_extname");
383*c87b03e5Sespie 
384*c87b03e5Sespie   decl = identifier_global_value (oldname);
385*c87b03e5Sespie   if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
386*c87b03e5Sespie     {
387*c87b03e5Sespie       if (DECL_ASSEMBLER_NAME_SET_P (decl)
388*c87b03e5Sespie 	  && DECL_ASSEMBLER_NAME (decl) != newname)
389*c87b03e5Sespie         warning ("#pragma redefine_extname conflicts with declaration");
390*c87b03e5Sespie       SET_DECL_ASSEMBLER_NAME (decl, newname);
391*c87b03e5Sespie     }
392*c87b03e5Sespie   else
393*c87b03e5Sespie     add_to_renaming_pragma_list(oldname, newname);
394*c87b03e5Sespie }
395*c87b03e5Sespie #endif
396*c87b03e5Sespie 
397*c87b03e5Sespie void
add_to_renaming_pragma_list(oldname,newname)398*c87b03e5Sespie add_to_renaming_pragma_list (oldname, newname)
399*c87b03e5Sespie 	tree oldname, newname;
400*c87b03e5Sespie {
401*c87b03e5Sespie   pending_redefine_extname
402*c87b03e5Sespie     = tree_cons (oldname, newname, pending_redefine_extname);
403*c87b03e5Sespie }
404*c87b03e5Sespie 
405*c87b03e5Sespie static GTY(()) tree pragma_extern_prefix;
406*c87b03e5Sespie 
407*c87b03e5Sespie #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
408*c87b03e5Sespie static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
409*c87b03e5Sespie 
410*c87b03e5Sespie /* #pragma extern_prefix "prefix" */
411*c87b03e5Sespie static void
handle_pragma_extern_prefix(dummy)412*c87b03e5Sespie handle_pragma_extern_prefix (dummy)
413*c87b03e5Sespie      cpp_reader *dummy ATTRIBUTE_UNUSED;
414*c87b03e5Sespie {
415*c87b03e5Sespie   tree prefix, x;
416*c87b03e5Sespie   enum cpp_ttype t;
417*c87b03e5Sespie 
418*c87b03e5Sespie   if (c_lex (&prefix) != CPP_STRING)
419*c87b03e5Sespie     {
420*c87b03e5Sespie       warning ("malformed #pragma extern_prefix, ignored");
421*c87b03e5Sespie       return;
422*c87b03e5Sespie     }
423*c87b03e5Sespie   t = c_lex (&x);
424*c87b03e5Sespie   if (t != CPP_EOF)
425*c87b03e5Sespie     warning ("junk at end of #pragma extern_prefix");
426*c87b03e5Sespie 
427*c87b03e5Sespie   /* Note that the length includes the null terminator.  */
428*c87b03e5Sespie   pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
429*c87b03e5Sespie }
430*c87b03e5Sespie #endif
431*c87b03e5Sespie 
432*c87b03e5Sespie /* Hook from the front ends to apply the results of one of the preceeding
433*c87b03e5Sespie    pragmas that rename variables.  */
434*c87b03e5Sespie 
435*c87b03e5Sespie tree
maybe_apply_renaming_pragma(decl,asmname)436*c87b03e5Sespie maybe_apply_renaming_pragma (decl, asmname)
437*c87b03e5Sespie      tree decl, asmname;
438*c87b03e5Sespie {
439*c87b03e5Sespie   tree oldname;
440*c87b03e5Sespie 
441*c87b03e5Sespie   /* Copied from the check in set_decl_assembler_name.  */
442*c87b03e5Sespie   if (TREE_CODE (decl) == FUNCTION_DECL
443*c87b03e5Sespie       || (TREE_CODE (decl) == VAR_DECL
444*c87b03e5Sespie           && (TREE_STATIC (decl)
445*c87b03e5Sespie               || DECL_EXTERNAL (decl)
446*c87b03e5Sespie               || TREE_PUBLIC (decl))))
447*c87b03e5Sespie     oldname = DECL_ASSEMBLER_NAME (decl);
448*c87b03e5Sespie   else
449*c87b03e5Sespie     return asmname;
450*c87b03e5Sespie 
451*c87b03e5Sespie   /* If the name begins with a *, that's a sign of an asmname attached to
452*c87b03e5Sespie      a previous declaration.  */
453*c87b03e5Sespie   if (IDENTIFIER_POINTER (oldname)[0] == '*')
454*c87b03e5Sespie     {
455*c87b03e5Sespie       const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
456*c87b03e5Sespie       if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
457*c87b03e5Sespie 	warning ("asm declaration conflicts with previous rename");
458*c87b03e5Sespie       asmname = build_string (strlen (oldasmname), oldasmname);
459*c87b03e5Sespie     }
460*c87b03e5Sespie 
461*c87b03e5Sespie   {
462*c87b03e5Sespie     tree *p, t;
463*c87b03e5Sespie 
464*c87b03e5Sespie     for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
465*c87b03e5Sespie       if (oldname == TREE_PURPOSE (t))
466*c87b03e5Sespie 	{
467*c87b03e5Sespie 	  const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
468*c87b03e5Sespie 
469*c87b03e5Sespie 	  if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
470*c87b03e5Sespie             warning ("#pragma redefine_extname conflicts with declaration");
471*c87b03e5Sespie 	  *p = TREE_CHAIN (t);
472*c87b03e5Sespie 
473*c87b03e5Sespie 	  return build_string (strlen (newname), newname);
474*c87b03e5Sespie 	}
475*c87b03e5Sespie   }
476*c87b03e5Sespie 
477*c87b03e5Sespie #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
478*c87b03e5Sespie   if (pragma_extern_prefix && !asmname)
479*c87b03e5Sespie     {
480*c87b03e5Sespie       char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
481*c87b03e5Sespie 			IDENTIFIER_POINTER (oldname), NULL);
482*c87b03e5Sespie       asmname = build_string (strlen (x), x);
483*c87b03e5Sespie       free (x);
484*c87b03e5Sespie       return asmname;
485*c87b03e5Sespie     }
486*c87b03e5Sespie #endif
487*c87b03e5Sespie 
488*c87b03e5Sespie   return asmname;
489*c87b03e5Sespie }
490*c87b03e5Sespie 
491*c87b03e5Sespie void
init_pragma()492*c87b03e5Sespie init_pragma ()
493*c87b03e5Sespie {
494*c87b03e5Sespie #ifdef HANDLE_PRAGMA_PACK
495*c87b03e5Sespie   cpp_register_pragma (parse_in, 0, "pack", handle_pragma_pack);
496*c87b03e5Sespie #endif
497*c87b03e5Sespie #ifdef HANDLE_PRAGMA_WEAK
498*c87b03e5Sespie   cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
499*c87b03e5Sespie #endif
500*c87b03e5Sespie #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
501*c87b03e5Sespie   cpp_register_pragma (parse_in, 0, "redefine_extname",
502*c87b03e5Sespie 		       handle_pragma_redefine_extname);
503*c87b03e5Sespie #endif
504*c87b03e5Sespie #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
505*c87b03e5Sespie   cpp_register_pragma (parse_in, 0, "extern_prefix",
506*c87b03e5Sespie 		       handle_pragma_extern_prefix);
507*c87b03e5Sespie #endif
508*c87b03e5Sespie 
509*c87b03e5Sespie #ifdef REGISTER_TARGET_PRAGMAS
510*c87b03e5Sespie   REGISTER_TARGET_PRAGMAS (parse_in);
511*c87b03e5Sespie #endif
512*c87b03e5Sespie }
513*c87b03e5Sespie 
514*c87b03e5Sespie #include "gt-c-pragma.h"
515