[llvm-commits] [llvm-gcc-4.0] r41867 - in /llvm-gcc-4.0/trunk/gcc: c-pragma.c config/darwin.h
Anton Korobeynikov
asl at math.spbu.ru
Tue Sep 11 15:03:28 PDT 2007
Author: asl
Date: Tue Sep 11 17:03:27 2007
New Revision: 41867
URL: http://llvm.org/viewvc/llvm-project?rev=41867&view=rev
Log:
Unbreak #pragma pack on non-darwin
Modified:
llvm-gcc-4.0/trunk/gcc/c-pragma.c
llvm-gcc-4.0/trunk/gcc/config/darwin.h
Modified: llvm-gcc-4.0/trunk/gcc/c-pragma.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-pragma.c?rev=41867&r1=41866&r2=41867&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/c-pragma.c (original)
+++ llvm-gcc-4.0/trunk/gcc/c-pragma.c Tue Sep 11 17:03:27 2007
@@ -49,8 +49,197 @@
static GTY(()) struct align_stack * alignment_stack;
-/* APPLE LOCAL Macintosh alignment */
-/* Lots of stuff deleted here. */
+/* LLVM LOCAL begin */
+#ifndef TARGET_OVERRIDE_PRAGMA_PACK_HANDLER
+#ifdef HANDLE_PRAGMA_PACK
+static void handle_pragma_pack (cpp_reader *);
+
+#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
+/* 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. */
+static int default_alignment;
+#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
+ ? &default_alignment \
+ : &alignment_stack->alignment) = (ALIGN))
+
+static void push_alignment (int, tree);
+static void pop_alignment (tree);
+
+/* Push an alignment value onto the stack. */
+static void
+push_alignment (int alignment, tree id)
+{
+ align_stack * entry;
+
+ entry = ggc_alloc (sizeof (* entry));
+
+ entry->alignment = alignment;
+ entry->id = id;
+ entry->prev = alignment_stack;
+
+ /* The current value of maximum_field_alignment is not necessarily
+ 0 since there may be a #pragma pack(<n>) in effect; remember it
+ so that we can restore it after the final #pragma pop(). */
+ if (alignment_stack == NULL)
+ default_alignment = maximum_field_alignment;
+
+ alignment_stack = entry;
+
+ maximum_field_alignment = alignment;
+}
+
+/* Undo a push of an alignment onto the stack. */
+static void
+pop_alignment (tree id)
+{
+ align_stack * entry;
+
+ if (alignment_stack == NULL)
+ GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
+
+ /* If we got an identifier, strip away everything above the target
+ entry so that the next step will restore the state just below it. */
+ if (id)
+ {
+ for (entry = alignment_stack; entry; entry = entry->prev)
+ if (entry->id == id)
+ {
+ alignment_stack = entry;
+ break;
+ }
+ if (entry == NULL)
+ warning ("\
+#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
+ , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
+ }
+
+ entry = alignment_stack->prev;
+
+ maximum_field_alignment = entry ? entry->alignment : default_alignment;
+
+ alignment_stack = entry;
+}
+#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */
+#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
+#define push_alignment(ID, N) \
+ GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target")
+#define pop_alignment(ID) \
+ GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target")
+#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
+
+/* #pragma pack ()
+ #pragma pack (N)
+
+ #pragma pack (push)
+ #pragma pack (push, N)
+ #pragma pack (push, ID)
+ #pragma pack (push, ID, N)
+ #pragma pack (pop)
+ #pragma pack (pop, ID) */
+static void
+handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
+{
+ tree x, id = 0;
+ int align = -1;
+ enum cpp_ttype token;
+ enum { set, push, pop } action;
+
+ if (c_lex (&x) != CPP_OPEN_PAREN)
+ GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
+
+ token = c_lex (&x);
+ if (token == CPP_CLOSE_PAREN)
+ {
+ action = set;
+ align = initial_max_fld_align;
+ }
+ else if (token == CPP_NUMBER)
+ {
+ align = TREE_INT_CST_LOW (x);
+ action = set;
+ if (c_lex (&x) != CPP_CLOSE_PAREN)
+ GCC_BAD ("malformed %<#pragma pack%> - ignored");
+ }
+ else if (token == CPP_NAME)
+ {
+#define GCC_BAD_ACTION do { if (action != pop) \
+ GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
+ else \
+ GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
+ } while (0)
+
+ const char *op = IDENTIFIER_POINTER (x);
+ if (!strcmp (op, "push"))
+ action = push;
+ else if (!strcmp (op, "pop"))
+ action = pop;
+ else
+ GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
+
+ while ((token = c_lex (&x)) == CPP_COMMA)
+ {
+ token = c_lex (&x);
+ if (token == CPP_NAME && id == 0)
+ {
+ id = x;
+ }
+ else if (token == CPP_NUMBER && action == push && align == -1)
+ {
+ align = TREE_INT_CST_LOW (x);
+ if (align == -1)
+ action = set;
+ }
+ else
+ GCC_BAD_ACTION;
+ }
+
+ if (token != CPP_CLOSE_PAREN)
+ GCC_BAD_ACTION;
+#undef GCC_BAD_ACTION
+ }
+ else
+ GCC_BAD ("malformed %<#pragma pack%> - ignored");
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of %<#pragma pack%>");
+
+ if (flag_pack_struct)
+ GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
+
+ if (action != pop)
+ switch (align)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ align *= BITS_PER_UNIT;
+ break;
+ case -1:
+ if (action == push)
+ {
+ align = maximum_field_alignment;
+ break;
+ }
+ default:
+ GCC_BAD2 ("alignment must be a small power of two, not %d", align);
+ }
+
+ switch (action)
+ {
+ case set: SET_GLOBAL_ALIGNMENT (align); break;
+ case push: push_alignment (align, id); break;
+ case pop: pop_alignment (id); break;
+ }
+}
+#endif /* HANDLE_PRAGMA_PACK */
+#endif /* TARGET_OVERRIDE_PRAGMA_PACK_HANDLER */
+/* LLVM LOCAL end */
static GTY(()) tree pending_weaks;
@@ -495,10 +684,17 @@
void
init_pragma (void)
{
-/* APPLE LOCAL begin Macintosh alignment 2002-1-22 --ff
- Remove the handling of pragma pack here because it is handled
- in config/darwin-c.c.
- APPLE LOCAL end Macintosh alignment 2002-1-22 --ff */
+/* LLVM LOCAL begin */
+#ifndef TARGET_OVERRIDE_PRAGMA_PACK_HANDLER
+#ifdef HANDLE_PRAGMA_PACK
+#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
+ c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
+#else
+ c_register_pragma (0, "pack", handle_pragma_pack);
+#endif
+#endif
+#endif
+/* LLVM LOCAL end */
#ifdef HANDLE_PRAGMA_WEAK
c_register_pragma (0, "weak", handle_pragma_weak);
#endif
Modified: llvm-gcc-4.0/trunk/gcc/config/darwin.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/darwin.h?rev=41867&r1=41866&r2=41867&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/config/darwin.h (original)
+++ llvm-gcc-4.0/trunk/gcc/config/darwin.h Tue Sep 11 17:03:27 2007
@@ -1563,6 +1563,11 @@
} while (0)
/* APPLE LOCAL end OS pragma hook */
+/* LLVM LOCAL begin */
+/* Handle pragma pack separately */
+#define TARGET_OVERRIDE_PRAGMA_PACK_HANDLER 1
+/* LLVM LOCAL end */
+
#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
#undef TARGET_ASM_NAMED_SECTION
More information about the llvm-commits
mailing list