/* 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"
-#ifdef HANDLE_GENERIC_PRAGMAS
-
-#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, reset, push, pop } action;
+ enum { set, push, pop } action;
if (c_lex (&x) != CPP_OPEN_PAREN)
BAD ("missing '(' after '#pragma pack' - ignored");
token = c_lex (&x);
if (token == CPP_CLOSE_PAREN)
- action = reset;
+ {
+ action = set;
+ align = 0;
+ }
else if (token == CPP_NUMBER)
{
align = TREE_INT_CST_LOW (x);
action = set;
+ if (c_lex (&x) != CPP_CLOSE_PAREN)
+ BAD ("malformed '#pragma pack' - ignored");
}
else if (token == CPP_NAME)
{
- if (!strcmp (IDENTIFIER_POINTER (x), "push"))
+#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 if (!strcmp (IDENTIFIER_POINTER (x), "pop"))
+ else if (!strcmp (op, "pop"))
action = pop;
else
- BAD2 ("unknown action '%s' for '#pragma pack' - ignored",
- IDENTIFIER_POINTER (x));
- }
- else
- BAD ("malformed '#pragma pack' - ignored");
-
- token = c_lex (&x);
- if ((action == set || action == reset) && token != CPP_CLOSE_PAREN)
- BAD ("malformed '#pragma pack' - ignored");
- if ((action == push || action == pop) && token != CPP_COMMA)
- BAD2 ("malformed '#pragma pack(%s[, id], <n>)' - ignored",
- action == push ? "push" : "pop");
+ BAD2 ("unknown action '%s' for '#pragma pack' - ignored", op);
- if (action == push || action == pop)
- {
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",
- action == push ? "push" : "pop");
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 (action == push)
+ {
+ if (token == CPP_NUMBER)
+ {
+ align = TREE_INT_CST_LOW (x);
+ token = c_lex (&x);
+ }
+ else
+ BAD_ACTION;
+ }
}
- if (token == CPP_NUMBER)
- align = TREE_INT_CST_LOW (x);
- else
- BAD2 ("malformed '#pragma pack(%s[, id], <n>)' - ignored",
- action == push ? "push" : "pop");
- 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)
{
case set: SET_GLOBAL_ALIGNMENT (align); break;
- case reset: SET_GLOBAL_ALIGNMENT (0); break;
case push: push_alignment (align, id); break;
case pop: pop_alignment (id); break;
}
}
#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 ()
{
-#if !USE_CPPLIB
- cpp_reader *pfile = 0;
-#else
- cpp_reader *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
mark_align_stack);
#endif
}
-
-#endif /* HANDLE_GENERIC_PRAGMAS */