+2009-11-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/41774
+ * c-pragma.c (visstack): Change into vector of ints rather than
+ enum symbol_visibility.
+ (push_visibility): Add kind argument, push default_visibility together
+ with kind.
+ (pop_visibility): Add kind argument, return true if successful, fail
+ if visibility stack is empty or if stack top is of different kind.
+ (handle_pragma_visibility): Don't check length of visstack, instead
+ call pop_visibility and issue diagnostics if it failed. Pass 0
+ as last argument to push_visibility and pop_visibility.
+ * c-pragma.h (push_visibility): Add kind argument.
+ (pop_visibility): Likewise. Return bool instead of void.
+
2009-11-01 Eric Botcazou <ebotcazou@adacore.com>
* tree.def (TARGET_MEM_REF): Update comment.
#ifdef HANDLE_PRAGMA_VISIBILITY
static void handle_pragma_visibility (cpp_reader *);
-typedef enum symbol_visibility visibility;
-DEF_VEC_I (visibility);
-DEF_VEC_ALLOC_I (visibility, heap);
-static VEC (visibility, heap) *visstack;
+static VEC (int, heap) *visstack;
/* Push the visibility indicated by STR onto the top of the #pragma
- visibility stack. */
+ visibility stack. KIND is 0 for #pragma GCC visibility, 1 for
+ C++ namespace with visibility attribute and 2 for C++ builtin
+ ABI namespace. push_visibility/pop_visibility calls must have
+ matching KIND, it is not allowed to push visibility using one
+ KIND and pop using a different one. */
void
-push_visibility (const char *str)
+push_visibility (const char *str, int kind)
{
- VEC_safe_push (visibility, heap, visstack,
- default_visibility);
+ VEC_safe_push (int, heap, visstack,
+ ((int) default_visibility) | (kind << 8));
if (!strcmp (str, "default"))
default_visibility = VISIBILITY_DEFAULT;
else if (!strcmp (str, "internal"))
visibility_options.inpragma = 1;
}
-/* Pop a level of the #pragma visibility stack. */
+/* Pop a level of the #pragma visibility stack. Return true if
+ successful. */
-void
-pop_visibility (void)
+bool
+pop_visibility (int kind)
{
- default_visibility = VEC_pop (visibility, visstack);
+ if (!VEC_length (int, visstack))
+ return false;
+ if ((VEC_last (int, visstack) >> 8) != kind)
+ return false;
+ default_visibility
+ = (enum symbol_visibility) (VEC_pop (int, visstack) & 0xff);
visibility_options.inpragma
- = VEC_length (visibility, visstack) != 0;
+ = VEC_length (int, visstack) != 0;
+ return true;
}
/* Sets the default visibility for symbols to something other than that
{
if (pop == action)
{
- if (!VEC_length (visibility, visstack))
+ if (! pop_visibility (0))
GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
- else
- pop_visibility ();
}
else
{
if (token != CPP_NAME)
GCC_BAD ("malformed #pragma GCC visibility push");
else
- push_visibility (IDENTIFIER_POINTER (x));
+ push_visibility (IDENTIFIER_POINTER (x), 0);
if (pragma_lex (&x) != CPP_CLOSE_PAREN)
GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
}