aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c100
1 files changed, 66 insertions, 34 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 05a0340b0d4..c60acc7b80d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -63,8 +63,6 @@ extern tree global_namespace;
extern void (*print_error_function) PROTO((char *));
extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree));
-/* Stack of places to restore the search obstack back to. */
-
/* Obstack used for remembering local class declarations (like
enums and static (const) members. */
#include "stack.h"
@@ -2420,6 +2418,7 @@ struct saved_scope {
tree previous_class_type, previous_class_values;
int processing_specialization;
int processing_explicit_instantiation;
+ char *class_cache_firstobj;
};
static struct saved_scope *current_saved_scope;
@@ -2537,6 +2536,7 @@ maybe_push_to_top_level (pseudo)
s->processing_template_decl = processing_template_decl;
s->previous_class_type = previous_class_type;
s->previous_class_values = previous_class_values;
+ s->class_cache_firstobj = class_cache_firstobj;
s->processing_specialization = processing_specialization;
s->processing_explicit_instantiation = processing_explicit_instantiation;
@@ -2552,6 +2552,7 @@ maybe_push_to_top_level (pseudo)
shadowed_labels = NULL_TREE;
minimal_parse_mode = 0;
previous_class_type = previous_class_values = NULL_TREE;
+ class_cache_firstobj = 0;
processing_specialization = 0;
processing_explicit_instantiation = 0;
current_template_parms = NULL_TREE;
@@ -2623,6 +2624,7 @@ pop_from_top_level ()
previous_class_values = s->previous_class_values;
processing_specialization = s->processing_specialization;
processing_explicit_instantiation = s->processing_explicit_instantiation;
+ class_cache_firstobj = s->class_cache_firstobj;
free (s);
@@ -3514,7 +3516,8 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE (olddecl) = build_exception_variant (newtype,
TYPE_RAISES_EXCEPTIONS (oldtype));
- if ((pedantic || ! DECL_IN_SYSTEM_HEADER (olddecl))
+ if ((pedantic || (! DECL_IN_SYSTEM_HEADER (olddecl)
+ && ! DECL_IN_SYSTEM_HEADER (newdecl)))
&& DECL_SOURCE_LINE (olddecl) != 0
&& flag_exceptions
&& ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
@@ -4151,8 +4154,10 @@ pushdecl (x)
/* Warn if shadowing an argument at the top level of the body. */
else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
- && TREE_CODE (oldlocal) == PARM_DECL
- && TREE_CODE (x) != PARM_DECL)
+ && TREE_CODE (oldlocal) == PARM_DECL
+ /* Don't complain if it's from an enclosing function. */
+ && DECL_CONTEXT (oldlocal) == current_function_decl
+ && TREE_CODE (x) != PARM_DECL)
{
/* Go to where the parms should be and see if we
find them there. */
@@ -4443,7 +4448,7 @@ push_class_level_binding (name, x)
IDENTIFIER_CLASS_VALUE. */
if (push_class_binding (name, x))
{
- maybe_push_cache_obstack ();
+ push_cache_obstack ();
class_binding_level->class_shadowed
= tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
class_binding_level->class_shadowed);
@@ -5812,6 +5817,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
{
struct tree_binding b;
val = binding_init (&b);
+ flags |= LOOKUP_COMPLAIN;
if (!qualified_lookup_using_namespace (name, type, val, flags))
return NULL_TREE;
val = select_decl (val, flags);
@@ -7336,6 +7342,13 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
DECL_INITIAL (decl) = error_mark_node;
}
+#ifdef SET_DEFAULT_DECL_ATTRIBUTES
+ SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
+#endif
+
+ /* Set attributes here so if duplicate decl, will have proper attributes. */
+ cplus_decl_attributes (decl, attributes, prefix_attributes);
+
if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE)
{
push_nested_class (context, 2);
@@ -7393,13 +7406,6 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
decl);
}
-#ifdef SET_DEFAULT_DECL_ATTRIBUTES
- SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
-#endif
-
- /* Set attributes here so if duplicate decl, will have proper attributes. */
- cplus_decl_attributes (decl, attributes, prefix_attributes);
-
/* Add this decl to the current binding level, but not if it
comes from another scope, e.g. a static member variable.
TEM may equal DECL or it may be a previous decl of the same name. */
@@ -8128,7 +8134,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
else if (! DECL_ARTIFICIAL (decl))
{
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
- cp_warning_at (" you can work around this by removing the initializer"), decl;
+ cp_warning_at (" you can work around this by removing the initializer", decl);
}
}
}
@@ -8504,6 +8510,8 @@ expand_static_init (decl, init)
{
tree cleanup, fcall;
static tree Atexit = 0;
+ int saved_flag_access_control;
+
if (Atexit == 0)
{
tree atexit_fndecl, PFV, pfvlist;
@@ -8530,13 +8538,31 @@ expand_static_init (decl, init)
so that any access checks will be done relative to the
current scope, rather than the scope of the anonymous
function. */
- fcall = build_cleanup (decl);
+ build_cleanup (decl);
+
+ /* Now start the function. */
cleanup = start_anon_func ();
+
+ /* Now, recompute the cleanup. It may contain SAVE_EXPRs
+ that refer to the original function, rather than the
+ anonymous one. That will make the back-end think that
+ nested functions are in use, which causes confusion. */
+ saved_flag_access_control = flag_access_control;
+ flag_access_control = 0;
+ fcall = build_cleanup (decl);
+ flag_access_control = saved_flag_access_control;
+
+ /* Finish off the function. */
expand_expr_stmt (fcall);
end_anon_func ();
+
+ /* Call atexit with the cleanup function. */
mark_addressable (cleanup);
cleanup = build_unary_op (ADDR_EXPR, cleanup, 0);
- fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE));
+ fcall = build_function_call (Atexit,
+ expr_tree_cons (NULL_TREE,
+ cleanup,
+ NULL_TREE));
expand_expr_stmt (fcall);
}
@@ -8558,7 +8584,7 @@ expand_static_init (decl, init)
/* Make TYPE a complete type based on INITIAL_VALUE.
Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
- 2 if there was no information (in which case assume 1 if DO_DEFAULT). */
+ 2 if there was no information (in which case assume 0 if DO_DEFAULT). */
int
complete_array_type (type, initial_value, do_default)
@@ -8567,7 +8593,10 @@ complete_array_type (type, initial_value, do_default)
{
register tree maxindex = NULL_TREE;
int value = 0;
-
+
+ /* Allocate on the same obstack as TYPE. */
+ push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
+
if (initial_value)
{
/* Note MAXINDEX is really the maximum index,
@@ -8615,23 +8644,28 @@ complete_array_type (type, initial_value, do_default)
if (maxindex)
{
tree itype;
+ tree domain;
+
+ domain = build_index_type (maxindex);
+ TYPE_DOMAIN (type) = domain;
- TYPE_DOMAIN (type) = build_index_type (maxindex);
if (! TREE_TYPE (maxindex))
- TREE_TYPE (maxindex) = TYPE_DOMAIN (type);
+ TREE_TYPE (maxindex) = domain;
if (initial_value)
itype = TREE_TYPE (initial_value);
else
itype = NULL;
if (itype && !TYPE_DOMAIN (itype))
- TYPE_DOMAIN (itype) = TYPE_DOMAIN (type);
+ TYPE_DOMAIN (itype) = domain;
/* The type of the main variant should never be used for arrays
of different sizes. It should only ever be completed with the
size of the array. */
if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
- TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = TYPE_DOMAIN (type);
+ TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
}
+ pop_obstacks();
+
/* Lay out the type now that we can get the real answer. */
layout_type (type);
@@ -10319,7 +10353,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
continue;
/* VC++ spells a zero-sized array with []. */
- if (size == NULL_TREE && decl_context == FIELD && ! staticp)
+ if (size == NULL_TREE && decl_context == FIELD && ! staticp
+ && ! RIDBIT_SETP (RID_TYPEDEF, specbits))
size = integer_zero_node;
if (size)
@@ -10355,10 +10390,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
size = t;
}
- itype = make_node (INTEGER_TYPE);
- TYPE_MIN_VALUE (itype) = size_zero_node;
- TYPE_MAX_VALUE (itype) = build_min
- (MINUS_EXPR, sizetype, size, integer_one_node);
+ itype = build_index_type (build_min
+ (MINUS_EXPR, sizetype, size, integer_one_node));
goto dont_grok_size;
}
@@ -11017,18 +11050,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
{
+ tree oldname = TYPE_NAME (type);
+ tree t;
+
/* FIXME: This is bogus; we should not be doing this for
cv-qualified types. */
- /* For anonymous structs that are cv-qualified, need to use
- TYPE_MAIN_VARIANT so that name will mangle correctly. As
- type not referenced after this block, don't bother
- resetting type to original type, ie. TREE_TYPE (decl). */
- type = TYPE_MAIN_VARIANT (type);
-
/* Replace the anonymous name with the real name everywhere. */
lookup_tag_reverse (type, declarator);
- TYPE_NAME (type) = decl;
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ if (TYPE_NAME (t) == oldname)
+ TYPE_NAME (t) = decl;
if (TYPE_LANG_SPECIFIC (type))
TYPE_WAS_ANONYMOUS (type) = 1;