/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
- Copyright (C) 1992, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU CC.
#include "rtl.h"
#include "tree.h"
#include "function.h"
-#include "defaults.h"
#include "cpplib.h"
#include "c-pragma.h"
#include "flags.h"
#include "c-lex.h"
#include "tm_p.h"
-#if USE_CPPLIB
-extern cpp_reader parse_in;
-#else
-struct pragma_entry;
-static struct pragma_entry *pragmas;
-
-void cpp_register_pragma PARAMS ((cpp_reader *, const char *, const char *,
- void (*) PARAMS ((cpp_reader *)) ));
-void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *));
-#endif
-
#define BAD(msgid) do { warning (msgid); return; } while (0)
#define BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
static struct align_stack * alignment_stack = NULL;
-/* If we have a "global" #pragma pack(<n>) if effect when the first
- #pragma push(pack,<n>) is encountered, this stores the the value of
+/* If we have a "global" #pragma pack(<n>) in effect when the first
+ #pragma pack(push,<n>) is encountered, this stores the value of
maximum_field_alignment in effect. When the final pop_alignment()
happens, we restore the value to this, not to a value of 0 for
maximum_field_alignment. Value is in bits. */
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
tree x, id = 0;
- int align;
+ int align = -1;
enum cpp_ttype token;
enum { set, push, pop } action;
}
else if (token == CPP_NAME)
{
+#define BAD_ACTION do { if (action == push) \
+ BAD ("malformed '#pragma pack(push[, id], <n>)' - ignored"); \
+ else \
+ BAD ("malformed '#pragma pack(pop[, id])' - ignored"); \
+ } while (0)
+
const char *op = IDENTIFIER_POINTER (x);
if (!strcmp (op, "push"))
action = push;
else
BAD2 ("unknown action '%s' for '#pragma pack' - ignored", op);
- if (c_lex (&x) != CPP_COMMA)
- BAD2 ("malformed '#pragma pack(%s[, id], <n>)' - ignored", op);
-
token = c_lex (&x);
- if (token == CPP_NAME)
+ if (token != CPP_COMMA && action == push)
+ BAD_ACTION;
+
+ if (token == CPP_COMMA)
{
- id = x;
- if (c_lex (&x) != CPP_COMMA)
- BAD2 ("malformed '#pragma pack(%s[, id], <n>)' - ignored", op);
token = c_lex (&x);
- }
+ if (token == CPP_NAME)
+ {
+ id = x;
+ if (action == push && c_lex (&x) != CPP_COMMA)
+ BAD_ACTION;
+ token = c_lex (&x);
+ }
- if (token == CPP_NUMBER)
- align = TREE_INT_CST_LOW (x);
- else
- BAD2 ("malformed '#pragma pack(%s[, id], <n>)' - ignored", op);
+ if (action == push)
+ {
+ if (token == CPP_NUMBER)
+ {
+ align = TREE_INT_CST_LOW (x);
+ token = c_lex (&x);
+ }
+ else
+ BAD_ACTION;
+ }
+ }
- if (c_lex (&x) != CPP_CLOSE_PAREN)
- BAD ("malformed '#pragma pack' - ignored");
+ if (token != CPP_CLOSE_PAREN)
+ BAD_ACTION;
+#undef BAD_ACTION
}
else
BAD ("malformed '#pragma pack' - ignored");
if (c_lex (&x) != CPP_EOF)
warning ("junk at end of '#pragma pack'");
- switch (align)
- {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- align *= BITS_PER_UNIT;
- break;
- default:
- BAD2 ("alignment must be a small power of two, not %d", align);
- }
+ if (action != pop)
+ switch (align)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ align *= BITS_PER_UNIT;
+ break;
+ default:
+ BAD2 ("alignment must be a small power of two, not %d", align);
+ }
switch (action)
{
}
#endif
-#if !USE_CPPLIB
-/* Glue version of cpplib's pragma registration and dispatch system. */
-struct pragma_entry
-{
- struct pragma_entry *next;
- const char *name;
- size_t len;
- int isnspace;
- union {
- void (*handler) PARAMS ((cpp_reader *));
- struct pragma_entry *space;
- } u;
-};
-
-void
-cpp_register_pragma_space (pfile, space)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- const char *space;
-{
- struct pragma_entry *new;
- const struct pragma_entry *p = pragmas;
- size_t len = strlen (space);
-
- while (p)
- {
- if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
- return;
- p = p->next;
- }
-
- new = (struct pragma_entry *) xmalloc (sizeof (struct pragma_entry));
- new->name = space;
- new->len = len;
- new->isnspace = 1;
- new->u.space = 0;
-
- new->next = pragmas;
- pragmas = new;
-}
-
-void
-cpp_register_pragma (pfile, space, name, handler)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- const char *space;
- const char *name;
- void (*handler) PARAMS ((cpp_reader *));
-{
- struct pragma_entry **x, *new;
- size_t len;
-
- x = &pragmas;
- if (space)
- {
- struct pragma_entry *p = pragmas;
- len = strlen (space);
- while (p)
- {
- if (p->isnspace && p->len == len && !memcmp (p->name, space, len))
- {
- x = &p->u.space;
- goto found;
- }
- p = p->next;
- }
- abort ();
- }
-
- found:
- new = (struct pragma_entry *) xmalloc (sizeof (struct pragma_entry));
- new->name = name;
- new->len = strlen (name);
- new->isnspace = 0;
- new->u.handler = handler;
-
- new->next = *x;
- *x = new;
-}
-
-/* Called from process_directive() for #pragma lines. */
-void
-dispatch_pragma ()
-{
- enum cpp_ttype t;
- tree x;
- const struct pragma_entry *p;
- const char *name, *space = 0;
- size_t len;
-
- p = pragmas;
-
- new_space:
- t = c_lex (&x);
- if (t == CPP_EOF)
- return;
-
- if (t != CPP_NAME)
- {
- warning ("malformed #pragma directive");
- return;
- }
-
- name = IDENTIFIER_POINTER (x);
- len = IDENTIFIER_LENGTH (x);
- while (p)
- {
- if (strlen (p->name) == len && !memcmp (p->name, name, len))
- {
- if (p->isnspace)
- {
- space = p->name;
- p = p->u.space;
- goto new_space;
- }
- else
- {
- (*p->u.handler) (0);
- return;
- }
- }
- p = p->next;
- }
-
- /* Issue a warning message if we have been asked to do so. Ignore
- unknown pragmas in system headers unless an explicit
- -Wunknown-pragmas has been given. */
- if (warn_unknown_pragmas > in_system_header)
- {
- if (space)
- warning ("ignoring #pragma %s %s", space, name);
- else
- warning ("ignoring #pragma %s", name);
- }
-}
-
-#endif
-
void
init_pragma ()
{
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-#if !USE_CPPLIB
- pfile = 0;
-#else
- pfile = &parse_in;
-#endif
-
#ifdef HANDLE_PRAGMA_PACK
- cpp_register_pragma (pfile, 0, "pack", handle_pragma_pack);
+ cpp_register_pragma (parse_in, 0, "pack", handle_pragma_pack);
#endif
#ifdef HANDLE_PRAGMA_WEAK
- cpp_register_pragma (pfile, 0, "weak", handle_pragma_weak);
+ cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
- REGISTER_TARGET_PRAGMAS (pfile);
+ REGISTER_TARGET_PRAGMAS (parse_in);
#endif
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP