11590Srgrimes/* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
21590Srgrimes   Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
31590Srgrimes   2006 Free Software Foundation, Inc.
41590Srgrimes
51590SrgrimesThis file is part of GCC.
61590Srgrimes
71590SrgrimesGCC is free software; you can redistribute it and/or modify it under
81590Srgrimesthe terms of the GNU General Public License as published by the Free
91590SrgrimesSoftware Foundation; either version 2, or (at your option) any later
101590Srgrimesversion.
111590Srgrimes
121590SrgrimesGCC is distributed in the hope that it will be useful, but WITHOUT ANY
131590SrgrimesWARRANTY; without even the implied warranty of MERCHANTABILITY or
141590SrgrimesFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151590Srgrimesfor more details.
161590Srgrimes
171590SrgrimesYou should have received a copy of the GNU General Public License
181590Srgrimesalong with GCC; see the file COPYING.  If not, write to the Free
191590SrgrimesSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
201590Srgrimes02110-1301, USA.  */
211590Srgrimes
221590Srgrimes#include "config.h"
231590Srgrimes#include "system.h"
241590Srgrimes#include "coretypes.h"
251590Srgrimes#include "tm.h"
261590Srgrimes#include "rtl.h"
271590Srgrimes#include "tree.h"
281590Srgrimes#include "function.h"
291590Srgrimes#include "cpplib.h"
301590Srgrimes#include "c-pragma.h"
3174769Smikeh#include "flags.h"
321590Srgrimes#include "toplev.h"
3374769Smikeh#include "ggc.h"
341590Srgrimes#include "c-common.h"
3599112Sobrien#include "output.h"
3699112Sobrien#include "tm_p.h"
371590Srgrimes#include "vec.h"
381590Srgrimes#include "target.h"
391590Srgrimes#include "diagnostic.h"
401590Srgrimes#include "opts.h"
411590Srgrimes
421590Srgrimes#define GCC_BAD(gmsgid) \
431590Srgrimes  do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
441590Srgrimes#define GCC_BAD2(gmsgid, arg) \
451590Srgrimes  do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
461590Srgrimes
471590Srgrimestypedef struct align_stack GTY(())
481590Srgrimes{
491590Srgrimes  int		       alignment;
501590Srgrimes  tree		       id;
511590Srgrimes  struct align_stack * prev;
521590Srgrimes} align_stack;
531590Srgrimes
541590Srgrimesstatic GTY(()) struct align_stack * alignment_stack;
55216564Scharnier
56216564Scharnier#ifdef HANDLE_PRAGMA_PACK
571590Srgrimesstatic void handle_pragma_pack (cpp_reader *);
581590Srgrimes
5977274Smikeh#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
6077274Smikeh/* If we have a "global" #pragma pack(<n>) in effect when the first
611590Srgrimes   #pragma pack(push,<n>) is encountered, this stores the value of
6277274Smikeh   maximum_field_alignment in effect.  When the final pop_alignment()
631590Srgrimes   happens, we restore the value to this, not to a value of 0 for
641590Srgrimes   maximum_field_alignment.  Value is in bits.  */
651590Srgrimesstatic int default_alignment;
661590Srgrimes#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
6777274Smikeh	? &default_alignment \
681590Srgrimes	: &alignment_stack->alignment) = (ALIGN))
6977274Smikeh
701590Srgrimesstatic void push_alignment (int, tree);
711590Srgrimesstatic void pop_alignment (tree);
7277274Smikeh
731590Srgrimes/* Push an alignment value onto the stack.  */
741590Srgrimesstatic void
751590Srgrimespush_alignment (int alignment, tree id)
761590Srgrimes{
771590Srgrimes  align_stack * entry;
781590Srgrimes
791590Srgrimes  entry = GGC_NEW (align_stack);
801590Srgrimes
811590Srgrimes  entry->alignment  = alignment;
821590Srgrimes  entry->id	    = id;
831590Srgrimes  entry->prev	    = alignment_stack;
8474769Smikeh
851590Srgrimes  /* The current value of maximum_field_alignment is not necessarily
861590Srgrimes     0 since there may be a #pragma pack(<n>) in effect; remember it
871590Srgrimes     so that we can restore it after the final #pragma pop().  */
888874Srgrimes  if (alignment_stack == NULL)
891590Srgrimes    default_alignment = maximum_field_alignment;
901590Srgrimes
911590Srgrimes  alignment_stack = entry;
921590Srgrimes
931590Srgrimes  maximum_field_alignment = alignment;
941590Srgrimes}
951590Srgrimes
961590Srgrimes/* Undo a push of an alignment onto the stack.  */
971590Srgrimesstatic void
981590Srgrimespop_alignment (tree id)
991590Srgrimes{
1001590Srgrimes  align_stack * entry;
1011590Srgrimes
1021590Srgrimes  if (alignment_stack == NULL)
1031590Srgrimes    GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
1041590Srgrimes
1051590Srgrimes  /* If we got an identifier, strip away everything above the target
1061590Srgrimes     entry so that the next step will restore the state just below it.  */
1071590Srgrimes  if (id)
1081590Srgrimes    {
1091590Srgrimes      for (entry = alignment_stack; entry; entry = entry->prev)
1101590Srgrimes	if (entry->id == id)
1111590Srgrimes	  {
1121590Srgrimes	    alignment_stack = entry;
1131590Srgrimes	    break;
1141590Srgrimes	  }
1151590Srgrimes      if (entry == NULL)
1161590Srgrimes	warning (OPT_Wpragmas, "\
1171590Srgrimes#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
11877274Smikeh		 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
11988227Sache    }
1201590Srgrimes
1211590Srgrimes  entry = alignment_stack->prev;
12288227Sache
1231590Srgrimes  maximum_field_alignment = entry ? entry->alignment : default_alignment;
1241590Srgrimes
1251590Srgrimes  alignment_stack = entry;
1261590Srgrimes}
1271590Srgrimes#else  /* not HANDLE_PRAGMA_PACK_PUSH_POP */
1281590Srgrimes#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
1291590Srgrimes#define push_alignment(ID, N) \
1301590Srgrimes    GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target")
1311590Srgrimes#define pop_alignment(ID) \
1321590Srgrimes    GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target")
1331590Srgrimes#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
1341590Srgrimes
1351590Srgrimes/* #pragma pack ()
13677274Smikeh   #pragma pack (N)
1371590Srgrimes
1381590Srgrimes   #pragma pack (push)
1391590Srgrimes   #pragma pack (push, N)
1401590Srgrimes   #pragma pack (push, ID)
1411590Srgrimes   #pragma pack (push, ID, N)
1421590Srgrimes   #pragma pack (pop)
1431590Srgrimes   #pragma pack (pop, ID) */
14477274Smikehstatic void
1451590Srgrimeshandle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
1461590Srgrimes{
1471590Srgrimes  tree x, id = 0;
1481590Srgrimes  int align = -1;
1491590Srgrimes  enum cpp_ttype token;
1501590Srgrimes  enum { set, push, pop } action;
1511590Srgrimes
1521590Srgrimes  if (pragma_lex (&x) != CPP_OPEN_PAREN)
1531590Srgrimes    GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
1541590Srgrimes
1551590Srgrimes  token = pragma_lex (&x);
1561590Srgrimes  if (token == CPP_CLOSE_PAREN)
1571590Srgrimes    {
1581590Srgrimes      action = set;
1591590Srgrimes      align = initial_max_fld_align;
1601590Srgrimes    }
1611590Srgrimes  else if (token == CPP_NUMBER)
1621590Srgrimes    {
1631590Srgrimes      if (TREE_CODE (x) != INTEGER_CST)
1641590Srgrimes	GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
1651590Srgrimes      align = TREE_INT_CST_LOW (x);
1661590Srgrimes      action = set;
1671590Srgrimes      if (pragma_lex (&x) != CPP_CLOSE_PAREN)
1681590Srgrimes	GCC_BAD ("malformed %<#pragma pack%> - ignored");
1691590Srgrimes    }
17077274Smikeh  else if (token == CPP_NAME)
1711590Srgrimes    {
1721590Srgrimes#define GCC_BAD_ACTION do { if (action != pop) \
1731590Srgrimes	  GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
17477274Smikeh	else \
17577274Smikeh	  GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
17674769Smikeh	} while (0)
17777274Smikeh
1781590Srgrimes      const char *op = IDENTIFIER_POINTER (x);
17977274Smikeh      if (!strcmp (op, "push"))
1801590Srgrimes	action = push;
1811590Srgrimes      else if (!strcmp (op, "pop"))
1821590Srgrimes	action = pop;
1831590Srgrimes      else
1841590Srgrimes	GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
1851590Srgrimes
1861590Srgrimes      while ((token = pragma_lex (&x)) == CPP_COMMA)
18777274Smikeh	{
1881590Srgrimes	  token = pragma_lex (&x);
18974769Smikeh	  if (token == CPP_NAME && id == 0)
1901590Srgrimes	    {
1911590Srgrimes	      id = x;
1921590Srgrimes	    }
1931590Srgrimes	  else if (token == CPP_NUMBER && action == push && align == -1)
1941590Srgrimes	    {
1951590Srgrimes	      if (TREE_CODE (x) != INTEGER_CST)
1961590Srgrimes		GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
1971590Srgrimes	      align = TREE_INT_CST_LOW (x);
1981590Srgrimes	      if (align == -1)
1991590Srgrimes		action = set;
2001590Srgrimes	    }
20177274Smikeh	  else
20277274Smikeh	    GCC_BAD_ACTION;
20377274Smikeh	}
2041590Srgrimes
20577274Smikeh      if (token != CPP_CLOSE_PAREN)
2061590Srgrimes	GCC_BAD_ACTION;
2071590Srgrimes#undef GCC_BAD_ACTION
2081590Srgrimes    }
2091590Srgrimes  else
21077274Smikeh    GCC_BAD ("malformed %<#pragma pack%> - ignored");
2111590Srgrimes
2121590Srgrimes  if (pragma_lex (&x) != CPP_EOF)
21377274Smikeh    warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
21477274Smikeh
2151590Srgrimes  if (flag_pack_struct)
2161590Srgrimes    GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
2171590Srgrimes
2181590Srgrimes  if (action != pop)
21977274Smikeh    switch (align)
22077274Smikeh      {
2211590Srgrimes      case 0:
2221590Srgrimes      case 1:
2231590Srgrimes      case 2:
2241590Srgrimes      case 4:
2251590Srgrimes      case 8:
2261590Srgrimes      case 16:
227216564Scharnier	align *= BITS_PER_UNIT;
2281590Srgrimes	break;
2291590Srgrimes      case -1:
23077274Smikeh	if (action == push)
2311590Srgrimes	  {
2321590Srgrimes	    align = maximum_field_alignment;
2331590Srgrimes	    break;
2341590Srgrimes	  }
2351590Srgrimes      default:
23677274Smikeh	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
23777274Smikeh      }
2381590Srgrimes
23977274Smikeh  switch (action)
2401590Srgrimes    {
2411590Srgrimes    case set:   SET_GLOBAL_ALIGNMENT (align);  break;
2421590Srgrimes    case push:  push_alignment (align, id);    break;
2431590Srgrimes    case pop:   pop_alignment (id);	       break;
2441590Srgrimes    }
2451590Srgrimes}
2461590Srgrimes#endif  /* HANDLE_PRAGMA_PACK */
247216564Scharnier
248216564Scharnierstatic GTY(()) tree pending_weaks;
2491590Srgrimes
2501590Srgrimes#ifdef HANDLE_PRAGMA_WEAK
2511590Srgrimesstatic void apply_pragma_weak (tree, tree);
2521590Srgrimesstatic void handle_pragma_weak (cpp_reader *);
2531590Srgrimes
2541590Srgrimesstatic void
2551590Srgrimesapply_pragma_weak (tree decl, tree value)
2561590Srgrimes{
25732189Sjoerg  if (value)
25877274Smikeh    {
2591590Srgrimes      value = build_string (IDENTIFIER_LENGTH (value),
26077274Smikeh			    IDENTIFIER_POINTER (value));
2611590Srgrimes      decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
2621590Srgrimes					       build_tree_list (NULL, value)),
2631590Srgrimes		       0);
2641590Srgrimes    }
2651590Srgrimes
2661590Srgrimes  if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
2671590Srgrimes      && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
2681590Srgrimes      && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
269216564Scharnier    warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
2701590Srgrimes	     "results in unspecified behavior", decl);
2711590Srgrimes
2721590Srgrimes  declare_weak (decl);
2731590Srgrimes}
27477274Smikeh
27577274Smikehvoid
27677274Smikehmaybe_apply_pragma_weak (tree decl)
27777274Smikeh{
27878193Smikeh  tree *p, t, id;
27977274Smikeh
2801590Srgrimes  /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
28177274Smikeh
2821590Srgrimes  /* No weak symbols pending, take the short-cut.  */
2831590Srgrimes  if (!pending_weaks)
2841590Srgrimes    return;
2851590Srgrimes  /* If it's not visible outside this file, it doesn't matter whether
2861590Srgrimes     it's weak.  */
2871590Srgrimes  if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
2881590Srgrimes    return;
289216564Scharnier  /* If it's not a function or a variable, it can't be weak.
2901590Srgrimes     FIXME: what kinds of things are visible outside this file but
2911590Srgrimes     aren't functions or variables?   Should this be an assert instead?  */
292126415Smikeh  if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
2931590Srgrimes    return;
2941590Srgrimes
295126415Smikeh  id = DECL_ASSEMBLER_NAME (decl);
2961590Srgrimes
2971590Srgrimes  for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
2981590Srgrimes    if (id == TREE_PURPOSE (t))
2991590Srgrimes      {
3001590Srgrimes	apply_pragma_weak (decl, TREE_VALUE (t));
3011590Srgrimes	*p = TREE_CHAIN (t);
3021590Srgrimes	break;
3031590Srgrimes      }
30477274Smikeh}
30588150Smikeh
30688150Smikeh/* Process all "#pragma weak A = B" directives where we have not seen
30788150Smikeh   a decl for A.  */
30888150Smikehvoid
30988150Smikehmaybe_apply_pending_pragma_weaks (void)
31088150Smikeh{
3111590Srgrimes  tree *p, t, alias_id, id, decl, *next;
31277274Smikeh
3131590Srgrimes  for (p = &pending_weaks; (t = *p) ; p = next)
31474769Smikeh    {
31574769Smikeh      next = &TREE_CHAIN (t);
31678904Smikeh      alias_id = TREE_PURPOSE (t);
31778904Smikeh      id = TREE_VALUE (t);
31877274Smikeh
3191590Srgrimes      if (TREE_VALUE (t) == NULL)
3201590Srgrimes	continue;
3211590Srgrimes
32274769Smikeh      decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
3231590Srgrimes
3241590Srgrimes      DECL_ARTIFICIAL (decl) = 1;
3251590Srgrimes      TREE_PUBLIC (decl) = 1;
3261590Srgrimes      DECL_EXTERNAL (decl) = 1;
3271590Srgrimes      DECL_WEAK (decl) = 1;
3281590Srgrimes
3291590Srgrimes      assemble_alias (decl, id);
33077274Smikeh    }
3311590Srgrimes}
3321590Srgrimes
3331590Srgrimes/* #pragma weak name [= value] */
3341590Srgrimesstatic void
3351590Srgrimeshandle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
3361590Srgrimes{
3371590Srgrimes  tree name, value, x, decl;
3381590Srgrimes  enum cpp_ttype t;
3391590Srgrimes
3401590Srgrimes  value = 0;
3411590Srgrimes
3421590Srgrimes  if (pragma_lex (&name) != CPP_NAME)
3431590Srgrimes    GCC_BAD ("malformed #pragma weak, ignored");
344126415Smikeh  t = pragma_lex (&x);
345126415Smikeh  if (t == CPP_EQ)
346126415Smikeh    {
347126415Smikeh      if (pragma_lex (&value) != CPP_NAME)
348126415Smikeh	GCC_BAD ("malformed #pragma weak, ignored");
349126415Smikeh      t = pragma_lex (&x);
350126415Smikeh    }
351126415Smikeh  if (t != CPP_EOF)
352126415Smikeh    warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
353126415Smikeh
354126415Smikeh  decl = identifier_global_value (name);
355126415Smikeh  if (decl && DECL_P (decl))
3561590Srgrimes    {
3571590Srgrimes      apply_pragma_weak (decl, value);
3581590Srgrimes      if (value)
3591590Srgrimes	assemble_alias (decl, value);
3601590Srgrimes    }
3611590Srgrimes  else
3621590Srgrimes    pending_weaks = tree_cons (name, value, pending_weaks);
3631590Srgrimes}
3641590Srgrimes#else
3651590Srgrimesvoid
36677274Smikehmaybe_apply_pragma_weak (tree ARG_UNUSED (decl))
3671590Srgrimes{
3681590Srgrimes}
3691590Srgrimes
3701590Srgrimesvoid
371126415Smikehmaybe_apply_pending_pragma_weaks (void)
372126415Smikeh{
373126415Smikeh}
374126415Smikeh#endif /* HANDLE_PRAGMA_WEAK */
375126415Smikeh
376126415Smikeh/* GCC supports two #pragma directives for renaming the external
377126415Smikeh   symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
378126415Smikeh   compatibility with the Solaris and Tru64 system headers.  GCC also
379126415Smikeh   has its own notation for this, __asm__("name") annotations.
380126415Smikeh
381126415Smikeh   Corner cases of these features and their interaction:
382126415Smikeh
38377274Smikeh   1) Both pragmas silently apply only to declarations with external
3841590Srgrimes      linkage (that is, TREE_PUBLIC || DECL_EXTERNAL).  Asm labels
3851590Srgrimes      do not have this restriction.
3861590Srgrimes
3871590Srgrimes   2) In C++, both #pragmas silently apply only to extern "C" declarations.
3881590Srgrimes      Asm labels do not have this restriction.
3891590Srgrimes
3901590Srgrimes   3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
39174769Smikeh      applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
3921590Srgrimes      new name is different, a warning issues and the name does not change.
3931590Srgrimes
3941590Srgrimes   4) The "source name" for #pragma redefine_extname is the DECL_NAME,
3951590Srgrimes      *not* the DECL_ASSEMBLER_NAME.
39688150Smikeh
39788150Smikeh   5) If #pragma extern_prefix is in effect and a declaration occurs
39888150Smikeh      with an __asm__ name, the #pragma extern_prefix is silently
39988150Smikeh      ignored for that declaration.
40088150Smikeh
40188150Smikeh   6) If #pragma extern_prefix and #pragma redefine_extname apply to
40288150Smikeh      the same declaration, whichever triggered first wins, and a warning
40388150Smikeh      is issued.  (We would like to have #pragma redefine_extname always
40488150Smikeh      win, but it can appear either before or after the declaration, and
40577274Smikeh      if it appears afterward, we have no way of knowing whether a modified
4061590Srgrimes      DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.)  */
4071590Srgrimes
4081590Srgrimesstatic GTY(()) tree pending_redefine_extname;
4091590Srgrimes
41074769Smikehstatic void handle_pragma_redefine_extname (cpp_reader *);
4111590Srgrimes
4121590Srgrimes/* #pragma redefine_extname oldname newname */
41377274Smikehstatic void
41477274Smikehhandle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
4151590Srgrimes{
4161590Srgrimes  tree oldname, newname, decl, x;
4171590Srgrimes  enum cpp_ttype t;
41877274Smikeh
4191590Srgrimes  if (pragma_lex (&oldname) != CPP_NAME)
4201590Srgrimes    GCC_BAD ("malformed #pragma redefine_extname, ignored");
4211590Srgrimes  if (pragma_lex (&newname) != CPP_NAME)
4221590Srgrimes    GCC_BAD ("malformed #pragma redefine_extname, ignored");
4231590Srgrimes  t = pragma_lex (&x);
4241590Srgrimes  if (t != CPP_EOF)
4251590Srgrimes    warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
426216564Scharnier
4271590Srgrimes  if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
42877274Smikeh    {
4291590Srgrimes      if (warn_unknown_pragmas > in_system_header)
43077274Smikeh	warning (OPT_Wunknown_pragmas,
43177274Smikeh		 "#pragma redefine_extname not supported on this target");
43277274Smikeh      return;
43388229Sache    }
43488150Smikeh
43588150Smikeh  decl = identifier_global_value (oldname);
43688150Smikeh  if (decl
4371590Srgrimes      && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
4381590Srgrimes      && (TREE_CODE (decl) == FUNCTION_DECL
43977274Smikeh	  || TREE_CODE (decl) == VAR_DECL)
4401590Srgrimes      && has_c_linkage (decl))
4411590Srgrimes    {
44277274Smikeh      if (DECL_ASSEMBLER_NAME_SET_P (decl))
4431590Srgrimes	{
4441590Srgrimes	  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
44577274Smikeh	  name = targetm.strip_name_encoding (name);
44688229Sache
4471590Srgrimes	  if (strcmp (name, IDENTIFIER_POINTER (newname)))
4481590Srgrimes	    warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
4491590Srgrimes		     "conflict with previous rename");
4501590Srgrimes	}
4511590Srgrimes      else
4521590Srgrimes	change_decl_assembler_name (decl, newname);
4531590Srgrimes    }
454216564Scharnier  else
4551590Srgrimes    /* We have to add this to the rename list even if there's already
45677274Smikeh       a global value that doesn't meet the above criteria, because in
45777274Smikeh       C++ "struct foo {...};" puts "foo" in the current namespace but
45874769Smikeh       does *not* conflict with a subsequent declaration of a function
4591590Srgrimes       or variable foo.  See g++.dg/other/pragma-re-2.C.  */
46077274Smikeh    add_to_renaming_pragma_list (oldname, newname);
46177274Smikeh}
46274769Smikeh
46374769Smikeh/* This is called from here and from ia64.c.  */
46474769Smikehvoid
46577274Smikehadd_to_renaming_pragma_list (tree oldname, tree newname)
4661590Srgrimes{
46774769Smikeh  tree previous = purpose_member (oldname, pending_redefine_extname);
46874769Smikeh  if (previous)
46977274Smikeh    {
47077274Smikeh      if (TREE_VALUE (previous) != newname)
47177274Smikeh	warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
4721590Srgrimes		 "conflict with previous #pragma redefine_extname");
47377274Smikeh      return;
47477274Smikeh    }
47577274Smikeh
4761590Srgrimes  pending_redefine_extname
4771590Srgrimes    = tree_cons (oldname, newname, pending_redefine_extname);
47877274Smikeh}
4791590Srgrimes
4801590Srgrimesstatic GTY(()) tree pragma_extern_prefix;
4811590Srgrimes
48274769Smikeh/* #pragma extern_prefix "prefix" */
4831590Srgrimesstatic void
48477274Smikehhandle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
4851590Srgrimes{
48677274Smikeh  tree prefix, x;
4871590Srgrimes  enum cpp_ttype t;
48874769Smikeh
48977274Smikeh  if (pragma_lex (&prefix) != CPP_STRING)
49077274Smikeh    GCC_BAD ("malformed #pragma extern_prefix, ignored");
4911590Srgrimes  t = pragma_lex (&x);
49277274Smikeh  if (t != CPP_EOF)
4931590Srgrimes    warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>");
49477274Smikeh
49577274Smikeh  if (targetm.handle_pragma_extern_prefix)
4961590Srgrimes    /* Note that the length includes the null terminator.  */
49777274Smikeh    pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
4981590Srgrimes  else if (warn_unknown_pragmas > in_system_header)
4991590Srgrimes    warning (OPT_Wunknown_pragmas,
5001590Srgrimes	     "#pragma extern_prefix not supported on this target");
5011590Srgrimes}
5021590Srgrimes
5031590Srgrimes/* Hook from the front ends to apply the results of one of the preceding
5041590Srgrimes   pragmas that rename variables.  */
505216564Scharnier
5061590Srgrimestree
50777274Smikehmaybe_apply_renaming_pragma (tree decl, tree asmname)
5081590Srgrimes{
5091590Srgrimes  tree *p, t;
51077274Smikeh
5111590Srgrimes  /* The renaming pragmas are only applied to declarations with
51277274Smikeh     external linkage.  */
5131590Srgrimes  if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
51477274Smikeh      || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
5151590Srgrimes      || !has_c_linkage (decl))
51677274Smikeh    return asmname;
5171590Srgrimes
51877274Smikeh  /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
51932189Sjoerg     but we may warn about a rename that conflicts.  */
52077274Smikeh  if (DECL_ASSEMBLER_NAME_SET_P (decl))
52132189Sjoerg    {
5221590Srgrimes      const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
52377274Smikeh      oldname = targetm.strip_name_encoding (oldname);
52477274Smikeh
5251590Srgrimes      if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
5261590Srgrimes	  warning (OPT_Wpragmas, "asm declaration ignored due to "
5271590Srgrimes		   "conflict with previous rename");
5281590Srgrimes
5291590Srgrimes      /* Take any pending redefine_extname off the list.  */
5301590Srgrimes      for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
531216564Scharnier	if (DECL_NAME (decl) == TREE_PURPOSE (t))
5321590Srgrimes	  {
53377274Smikeh	    /* Only warn if there is a conflict.  */
5341590Srgrimes	    if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname))
5351590Srgrimes	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
5361590Srgrimes		       "conflict with previous rename");
5371590Srgrimes
5381590Srgrimes	    *p = TREE_CHAIN (t);
53977274Smikeh	    break;
54077274Smikeh	  }
5411590Srgrimes      return 0;
5421590Srgrimes    }
5431590Srgrimes
5441590Srgrimes  /* Find out if we have a pending #pragma redefine_extname.  */
54577274Smikeh  for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
5461590Srgrimes    if (DECL_NAME (decl) == TREE_PURPOSE (t))
5471590Srgrimes      {
54877274Smikeh	tree newname = TREE_VALUE (t);
5491590Srgrimes	*p = TREE_CHAIN (t);
5501590Srgrimes
55177274Smikeh	/* If we already have an asmname, #pragma redefine_extname is
5521590Srgrimes	   ignored (with a warning if it conflicts).  */
5531590Srgrimes	if (asmname)
55477274Smikeh	  {
5551590Srgrimes	    if (strcmp (TREE_STRING_POINTER (asmname),
5561590Srgrimes			IDENTIFIER_POINTER (newname)) != 0)
5571590Srgrimes	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
5581590Srgrimes		       "conflict with __asm__ declaration");
5591590Srgrimes	    return asmname;
5601590Srgrimes	  }
5611590Srgrimes
5621590Srgrimes	/* Otherwise we use what we've got; #pragma extern_prefix is
563216564Scharnier	   silently ignored.  */
5641590Srgrimes	return build_string (IDENTIFIER_LENGTH (newname),
56577274Smikeh			     IDENTIFIER_POINTER (newname));
5661590Srgrimes      }
56777274Smikeh
56877274Smikeh  /* If we've got an asmname, #pragma extern_prefix is silently ignored.  */
5691590Srgrimes  if (asmname)
5701590Srgrimes    return asmname;
57174769Smikeh
5721590Srgrimes  /* If #pragma extern_prefix is in effect, apply it.  */
5731590Srgrimes  if (pragma_extern_prefix)
57477274Smikeh    {
5751590Srgrimes      const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
57677274Smikeh      size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
57777274Smikeh
57877274Smikeh      const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
57977274Smikeh      size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
5801590Srgrimes
58174769Smikeh      char *newname = (char *) alloca (plen + ilen + 1);
58277274Smikeh
5831590Srgrimes      memcpy (newname,        prefix, plen);
5841590Srgrimes      memcpy (newname + plen, id, ilen + 1);
5851590Srgrimes
586      return build_string (plen + ilen, newname);
587    }
588
589  /* Nada.  */
590  return 0;
591}
592
593
594#ifdef HANDLE_PRAGMA_VISIBILITY
595static void handle_pragma_visibility (cpp_reader *);
596
597typedef enum symbol_visibility visibility;
598DEF_VEC_I (visibility);
599DEF_VEC_ALLOC_I (visibility, heap);
600static VEC (visibility, heap) *visstack;
601
602/* Push the visibility indicated by STR onto the top of the #pragma
603   visibility stack.  */
604
605void
606push_visibility (const char *str)
607{
608  VEC_safe_push (visibility, heap, visstack,
609		 default_visibility);
610  if (!strcmp (str, "default"))
611    default_visibility = VISIBILITY_DEFAULT;
612  else if (!strcmp (str, "internal"))
613    default_visibility = VISIBILITY_INTERNAL;
614  else if (!strcmp (str, "hidden"))
615    default_visibility = VISIBILITY_HIDDEN;
616  else if (!strcmp (str, "protected"))
617    default_visibility = VISIBILITY_PROTECTED;
618  else
619    GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
620  visibility_options.inpragma = 1;
621}
622
623/* Pop a level of the #pragma visibility stack.  */
624
625void
626pop_visibility (void)
627{
628  default_visibility = VEC_pop (visibility, visstack);
629  visibility_options.inpragma
630    = VEC_length (visibility, visstack) != 0;
631}
632
633/* Sets the default visibility for symbols to something other than that
634   specified on the command line.  */
635
636static void
637handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
638{
639  /* Form is #pragma GCC visibility push(hidden)|pop */
640  tree x;
641  enum cpp_ttype token;
642  enum { bad, push, pop } action = bad;
643
644  token = pragma_lex (&x);
645  if (token == CPP_NAME)
646    {
647      const char *op = IDENTIFIER_POINTER (x);
648      if (!strcmp (op, "push"))
649	action = push;
650      else if (!strcmp (op, "pop"))
651	action = pop;
652    }
653  if (bad == action)
654    GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
655  else
656    {
657      if (pop == action)
658	{
659	  if (!VEC_length (visibility, visstack))
660	    GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
661	  else
662	    pop_visibility ();
663	}
664      else
665	{
666	  if (pragma_lex (&x) != CPP_OPEN_PAREN)
667	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
668	  token = pragma_lex (&x);
669	  if (token != CPP_NAME)
670	    GCC_BAD ("malformed #pragma GCC visibility push");
671	  else
672	    push_visibility (IDENTIFIER_POINTER (x));
673	  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
674	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
675	}
676    }
677  if (pragma_lex (&x) != CPP_EOF)
678    warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
679}
680
681#endif
682
683static void
684handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
685{
686  const char *kind_string, *option_string;
687  unsigned int option_index;
688  enum cpp_ttype token;
689  diagnostic_t kind;
690  tree x;
691
692  if (cfun)
693    {
694      error ("#pragma GCC diagnostic not allowed inside functions");
695      return;
696    }
697
698  token = pragma_lex (&x);
699  if (token != CPP_NAME)
700    GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
701  kind_string = IDENTIFIER_POINTER (x);
702  if (strcmp (kind_string, "error") == 0)
703    kind = DK_ERROR;
704  else if (strcmp (kind_string, "warning") == 0)
705    kind = DK_WARNING;
706  else if (strcmp (kind_string, "ignored") == 0)
707    kind = DK_IGNORED;
708  else
709    GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
710
711  token = pragma_lex (&x);
712  if (token != CPP_STRING)
713    GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
714  option_string = TREE_STRING_POINTER (x);
715  for (option_index = 0; option_index < cl_options_count; option_index++)
716    if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
717      {
718	/* This overrides -Werror, for example.  */
719	diagnostic_classify_diagnostic (global_dc, option_index, kind);
720	/* This makes sure the option is enabled, like -Wfoo would do.  */
721	if (cl_options[option_index].var_type == CLVC_BOOLEAN
722	    && cl_options[option_index].flag_var
723	    && kind != DK_IGNORED)
724	    *(int *) cl_options[option_index].flag_var = 1;
725	return;
726      }
727  GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
728}
729
730/* A vector of registered pragma callbacks.  */
731
732DEF_VEC_O (pragma_handler);
733DEF_VEC_ALLOC_O (pragma_handler, heap);
734
735static VEC(pragma_handler, heap) *registered_pragmas;
736
737/* Front-end wrappers for pragma registration to avoid dragging
738   cpplib.h in almost everywhere.  */
739
740static void
741c_register_pragma_1 (const char *space, const char *name,
742		     pragma_handler handler, bool allow_expansion)
743{
744  unsigned id;
745
746  VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
747  id = VEC_length (pragma_handler, registered_pragmas);
748  id += PRAGMA_FIRST_EXTERNAL - 1;
749
750  /* The C++ front end allocates 6 bits in cp_token; the C front end
751     allocates 7 bits in c_token.  At present this is sufficient.  */
752  gcc_assert (id < 64);
753
754  cpp_register_deferred_pragma (parse_in, space, name, id,
755				allow_expansion, false);
756}
757
758void
759c_register_pragma (const char *space, const char *name, pragma_handler handler)
760{
761  c_register_pragma_1 (space, name, handler, false);
762}
763
764void
765c_register_pragma_with_expansion (const char *space, const char *name,
766				  pragma_handler handler)
767{
768  c_register_pragma_1 (space, name, handler, true);
769}
770
771void
772c_invoke_pragma_handler (unsigned int id)
773{
774  pragma_handler handler;
775
776  id -= PRAGMA_FIRST_EXTERNAL;
777  handler = *VEC_index (pragma_handler, registered_pragmas, id);
778
779  handler (parse_in);
780}
781
782/* Set up front-end pragmas.  */
783void
784init_pragma (void)
785{
786  if (flag_openmp && !flag_preprocess_only)
787    {
788      struct omp_pragma_def { const char *name; unsigned int id; };
789      static const struct omp_pragma_def omp_pragmas[] = {
790	{ "atomic", PRAGMA_OMP_ATOMIC },
791	{ "barrier", PRAGMA_OMP_BARRIER },
792	{ "critical", PRAGMA_OMP_CRITICAL },
793	{ "flush", PRAGMA_OMP_FLUSH },
794	{ "for", PRAGMA_OMP_FOR },
795	{ "master", PRAGMA_OMP_MASTER },
796	{ "ordered", PRAGMA_OMP_ORDERED },
797	{ "parallel", PRAGMA_OMP_PARALLEL },
798	{ "section", PRAGMA_OMP_SECTION },
799	{ "sections", PRAGMA_OMP_SECTIONS },
800	{ "single", PRAGMA_OMP_SINGLE },
801	{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
802      };
803
804      const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
805      int i;
806
807      for (i = 0; i < n_omp_pragmas; ++i)
808	cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
809				      omp_pragmas[i].id, true, true);
810    }
811
812  cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
813				PRAGMA_GCC_PCH_PREPROCESS, false, false);
814
815#ifdef HANDLE_PRAGMA_PACK
816#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
817  c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
818#else
819  c_register_pragma (0, "pack", handle_pragma_pack);
820#endif
821#endif
822#ifdef HANDLE_PRAGMA_WEAK
823  c_register_pragma (0, "weak", handle_pragma_weak);
824#endif
825#ifdef HANDLE_PRAGMA_VISIBILITY
826  c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
827#endif
828
829  c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
830
831  c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
832  c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
833
834#ifdef REGISTER_TARGET_PRAGMAS
835  REGISTER_TARGET_PRAGMAS ();
836#endif
837}
838
839#include "gt-c-pragma.h"
840