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.c344
1 files changed, 194 insertions, 150 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2bd6ff335bc..92f3a75975c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -140,7 +140,7 @@ tree error_mark_list;
tree ptm_desc_type_node;
tree base_desc_type_node;
- tree class_type_node, record_type_node, union_type_node, enum_type_node;
+ tree class_type_node;
tree unknown_type_node;
Array type `vtable_entry_type[]'
@@ -228,10 +228,6 @@ struct named_label_list GTY(())
#define named_labels cp_function_chain->x_named_labels
-/* The name of the anonymous namespace, throughout this translation
- unit. */
-tree anonymous_namespace_name;
-
/* The number of function bodies which we are currently processing.
(Zero if we are at namespace scope, one inside the body of a
function, two inside the body of a function in a local class, etc.) */
@@ -429,7 +425,7 @@ pop_labels (tree block)
tree
poplevel (int keep, int reverse, int functionbody)
{
- register tree link;
+ tree link;
/* The chain of decls was accumulated in reverse order.
Put it into forward order, just for cleanliness. */
tree decls;
@@ -1137,14 +1133,14 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
cp_pedwarn_at ("previous declaration of `%D'", olddecl);
}
-/* Handle when a new declaration NEWDECL has the same name as an old
- one OLDDECL in the same binding contour. Prints an error message
- if appropriate.
+/* If NEWDECL is a redeclaration of OLDDECL, merge the declarations.
+ If the redeclaration is invalid, a diagnostic is issued, and the
+ error_mark_node is returned. Otherwise, OLDDECL is returned.
- If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
- Otherwise, return 0. */
+ If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
+ returned. */
-int
+tree
duplicate_decls (tree newdecl, tree olddecl)
{
unsigned olddecl_uid = DECL_UID (olddecl);
@@ -1152,7 +1148,7 @@ duplicate_decls (tree newdecl, tree olddecl)
int new_defines_function = 0;
if (newdecl == olddecl)
- return 1;
+ return olddecl;
types_match = decls_match (newdecl, olddecl);
@@ -1205,7 +1201,7 @@ duplicate_decls (tree newdecl, tree olddecl)
{
/* Avoid warnings redeclaring anticipated built-ins. */
if (DECL_ANTICIPATED (olddecl))
- return 0;
+ return NULL_TREE;
/* If you declare a built-in or predefined function name as static,
the old definition is overridden, but optionally warn this was a
@@ -1217,7 +1213,7 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
olddecl);
/* Discard the old built-in function. */
- return 0;
+ return NULL_TREE;
}
/* If the built-in is not ansi, then programs can override
it even globally without an error. */
@@ -1230,7 +1226,7 @@ duplicate_decls (tree newdecl, tree olddecl)
error ("conflicts with built-in declaration `%#D'",
olddecl);
}
- return 0;
+ return NULL_TREE;
}
else if (!types_match)
{
@@ -1257,7 +1253,7 @@ duplicate_decls (tree newdecl, tree olddecl)
}
else
/* Discard the old built-in function. */
- return 0;
+ return NULL_TREE;
/* Replace the old RTL to avoid problems with inlining. */
SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
@@ -1265,7 +1261,14 @@ duplicate_decls (tree newdecl, tree olddecl)
/* Even if the types match, prefer the new declarations type
for anticipated built-ins, for exception lists, etc... */
else if (DECL_ANTICIPATED (olddecl))
- TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+ {
+ tree type = TREE_TYPE (newdecl);
+ tree attribs = (*targetm.merge_type_attributes)
+ (TREE_TYPE (olddecl), type);
+
+ type = build_type_attribute_variant (type, attribs);
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
+ }
/* Whether or not the builtin can throw exceptions has no
bearing on this declarator. */
@@ -1302,14 +1305,14 @@ duplicate_decls (tree newdecl, tree olddecl)
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
- return 0;
+ return NULL_TREE;
}
if ((TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (olddecl))
|| (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (newdecl)))
- return 0;
+ return NULL_TREE;
error ("`%#D' redeclared as different kind of symbol", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST)
@@ -1319,14 +1322,14 @@ duplicate_decls (tree newdecl, tree olddecl)
/* New decl is completely inconsistent with the old one =>
tell caller to replace the old one. */
- return 0;
+ return NULL_TREE;
}
else if (!types_match)
{
if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
/* These are certainly not duplicate declarations; they're
from different scopes. */
- return 0;
+ return NULL_TREE;
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
@@ -1354,7 +1357,7 @@ duplicate_decls (tree newdecl, tree olddecl)
error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
- return 0;
+ return NULL_TREE;
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@@ -1371,7 +1374,7 @@ duplicate_decls (tree newdecl, tree olddecl)
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
else
- return 0;
+ return NULL_TREE;
}
/* Already complained about this, so don't do so again. */
@@ -1381,7 +1384,7 @@ duplicate_decls (tree newdecl, tree olddecl)
error ("conflicting declaration '%#D'", newdecl);
cp_error_at ("'%D' has a previous declaration as `%#D'",
olddecl, olddecl);
- return false;
+ return NULL_TREE;
}
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL
@@ -1401,7 +1404,7 @@ duplicate_decls (tree newdecl, tree olddecl)
can occur if we instantiate a template class, and then
specialize one of its methods. This situation is valid, but
the declarations must be merged in the usual way. */
- return 0;
+ return NULL_TREE;
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& ((DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_USE_TEMPLATE (newdecl))
@@ -1409,12 +1412,20 @@ duplicate_decls (tree newdecl, tree olddecl)
&& !DECL_USE_TEMPLATE (olddecl))))
/* One of the declarations is a template instantiation, and the
other is not a template at all. That's OK. */
- return 0;
+ return NULL_TREE;
else if (TREE_CODE (newdecl) == NAMESPACE_DECL
&& DECL_NAMESPACE_ALIAS (newdecl)
&& DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
- /* Redeclaration of namespace alias, ignore it. */
- return 1;
+ /* In [namespace.alias] we have:
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers.
+
+ Therefore, if we encounter a second alias directive for the same
+ alias, we can just ignore the second directive. */
+ return olddecl;
else
{
const char *errmsg = redeclaration_error_message (newdecl, olddecl);
@@ -1426,7 +1437,7 @@ duplicate_decls (tree newdecl, tree olddecl)
&& namespace_bindings_p ())
? "`%#D' previously defined here"
: "`%#D' previously declared here", olddecl);
- return 0;
+ return error_mark_node;
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_INITIAL (olddecl) != NULL_TREE
@@ -1506,7 +1517,7 @@ duplicate_decls (tree newdecl, tree olddecl)
if (TREE_CODE (olddecl) == TYPE_DECL
&& (DECL_IMPLICIT_TYPEDEF_P (olddecl)
|| DECL_IMPLICIT_TYPEDEF_P (newdecl)))
- return 0;
+ return NULL_TREE;
/* If new decl is `static' and an `extern' was seen previously,
warn about it. */
@@ -1552,8 +1563,8 @@ duplicate_decls (tree newdecl, tree olddecl)
/* Deal with C++: must preserve virtual function table size. */
if (TREE_CODE (olddecl) == TYPE_DECL)
{
- register tree newtype = TREE_TYPE (newdecl);
- register tree oldtype = TREE_TYPE (olddecl);
+ tree newtype = TREE_TYPE (newdecl);
+ tree oldtype = TREE_TYPE (olddecl);
if (newtype != error_mark_node && oldtype != error_mark_node
&& TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype))
@@ -1585,7 +1596,15 @@ duplicate_decls (tree newdecl, tree olddecl)
= DECL_SOURCE_LOCATION (newdecl);
}
- return 1;
+ if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+ {
+ DECL_INLINE (DECL_TEMPLATE_RESULT (olddecl))
+ |= DECL_INLINE (DECL_TEMPLATE_RESULT (newdecl));
+ DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (olddecl))
+ |= DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (newdecl));
+ }
+
+ return olddecl;
}
if (types_match)
@@ -1852,6 +1871,19 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+ /* If either declaration has a nondefault visibility, use it. */
+ if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
+ {
+ if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
+ && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
+ {
+ warning ("%J'%D': visibility attribute ignored because it",
+ newdecl, newdecl);
+ warning ("%Jconflicts with previous declaration here", olddecl);
+ }
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+ }
+
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
@@ -1913,7 +1945,7 @@ duplicate_decls (tree newdecl, tree olddecl)
&& TREE_STATIC (olddecl))))
make_decl_rtl (olddecl, NULL);
- return 1;
+ return olddecl;
}
/* Generate an implicit declaration for identifier FUNCTIONID
@@ -1922,7 +1954,7 @@ duplicate_decls (tree newdecl, tree olddecl)
tree
implicitly_declare (tree functionid)
{
- register tree decl;
+ tree decl;
/* We used to reuse an old implicit decl here,
but this loses with inline functions because it can clobber
@@ -2331,7 +2363,7 @@ define_label (location_t location, tree name)
{
tree decl = lookup_label (name);
struct named_label_list *ent;
- register struct cp_binding_level *p;
+ struct cp_binding_level *p;
timevar_push (TV_NAME_LOOKUP);
for (ent = named_labels; ent; ent = ent->next)
@@ -2422,19 +2454,7 @@ tree
finish_case_label (tree low_value, tree high_value)
{
tree cond, r;
- register struct cp_binding_level *p;
-
- if (! switch_stack)
- {
- if (high_value)
- error ("case label not within a switch statement");
- else if (low_value)
- error ("case label `%E' not within a switch statement",
- low_value);
- else
- error ("`default' label not within a switch statement");
- return NULL_TREE;
- }
+ struct cp_binding_level *p;
if (processing_template_decl)
{
@@ -3098,7 +3118,7 @@ cxx_init_decl_processing (void)
/* Generate an initializer for a function naming variable from
NAME. NAME may be NULL, to indicate a dependent name. TYPE_P is
- filled in with the type of the init. */
+ filled in with the type of the init. */
tree
cp_fname_init (const char* name, tree *type_p)
@@ -3160,9 +3180,10 @@ cp_make_fname_decl (tree id, int type_dep)
while (b->level_chain->kind != sk_function_parms)
b = b->level_chain;
pushdecl_with_scope (decl, b);
+ cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
}
-
- cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+ else
+ pushdecl_top_level_and_finish (decl, init);
return decl;
}
@@ -3371,7 +3392,7 @@ fixup_anonymous_aggr (tree t)
{
tree *q;
- /* Wipe out memory of synthesized methods */
+ /* Wipe out memory of synthesized methods. */
TYPE_HAS_CONSTRUCTOR (t) = 0;
TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
TYPE_HAS_INIT_REF (t) = 0;
@@ -3435,7 +3456,7 @@ check_tag_decl (tree declspecs)
int saw_friend = 0;
int saw_typedef = 0;
tree ob_modifier = NULL_TREE;
- register tree link;
+ tree link;
/* If a class, struct, or enum type is declared by the DECLSPECS
(i.e, if a class-specifier, enum-specifier, or non-typename
elaborated-type-specifier appears in the DECLSPECS),
@@ -3632,7 +3653,7 @@ start_decl (tree declarator,
tree prefix_attributes)
{
tree decl;
- register tree type, tem;
+ tree type, tem;
tree context;
/* This should only be done once on the top most decl. */
@@ -3758,7 +3779,9 @@ start_decl (tree declarator,
}
else
{
- tree field = check_classfn (context, decl);
+ tree field = check_classfn (context, decl,
+ processing_template_decl
+ > template_class_depth (context));
if (field && duplicate_decls (decl, field))
decl = field;
}
@@ -4263,8 +4286,11 @@ reshape_init (tree type, tree *initp)
empty class shall have the form of an empty
initializer-list {}. */
if (!brace_enclosed_p)
- error ("initializer for `%T' must be brace-enclosed",
- type);
+ {
+ error ("initializer for `%T' must be brace-enclosed",
+ type);
+ return error_mark_node;
+ }
}
else
{
@@ -4289,6 +4315,8 @@ reshape_init (tree type, tree *initp)
break;
field_init = reshape_init (TREE_TYPE (field), initp);
+ if (field_init == error_mark_node)
+ return error_mark_node;
TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init);
CONSTRUCTOR_ELTS (new_init) = field_init;
/* [dcl.init.aggr]
@@ -4319,10 +4347,22 @@ reshape_init (tree type, tree *initp)
tree element_init;
element_init = reshape_init (TREE_TYPE (type), initp);
+ if (element_init == error_mark_node)
+ return error_mark_node;
TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
CONSTRUCTOR_ELTS (new_init) = element_init;
if (TREE_PURPOSE (element_init))
- index = TREE_PURPOSE (element_init);
+ {
+ tree next_index = TREE_PURPOSE (element_init);
+ if (TREE_CODE (next_index) == IDENTIFIER_NODE)
+ {
+ error ("name `%D' used in a GNU-style designated "
+ "initializer for an array", next_index);
+ TREE_PURPOSE (element_init) = NULL_TREE;
+ }
+ else
+ index = next_index;
+ }
}
}
else
@@ -4528,7 +4568,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
/* Set the DECL_ASSEMBLER_NAME for the variable. */
if (asmspec)
{
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ change_decl_assembler_name (decl, get_identifier (asmspec));
/* The `register' keyword, when used together with an
asm-specification, indicates that the variable should be
placed in a particular register. */
@@ -4910,7 +4950,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
mark_referenced (DECL_ASSEMBLER_NAME (decl));
}
-/* This is here for a midend callback from c-common.c */
+/* This is here for a midend callback from c-common.c. */
void
finish_decl (tree decl, tree init, tree asmspec_tree)
@@ -5271,7 +5311,7 @@ start_handler_parms (tree declspecs, tree declarator)
int
complete_array_type (tree type, tree initial_value, int do_default)
{
- register tree maxindex = NULL_TREE;
+ tree maxindex = NULL_TREE;
int value = 0;
if (initial_value)
@@ -5663,7 +5703,9 @@ grokfndecl (tree ctype,
{
tree old_decl;
- old_decl = check_classfn (ctype, decl);
+ old_decl = check_classfn (ctype, decl,
+ processing_template_decl
+ > template_class_depth (ctype));
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
@@ -5685,7 +5727,7 @@ grokfndecl (tree ctype,
if (old_decl)
{
- bool ok;
+ tree ok;
/* Since we've smashed OLD_DECL to its
DECL_TEMPLATE_RESULT, we must do the same to DECL. */
@@ -5972,48 +6014,35 @@ check_static_variable_definition (tree decl, tree type)
tree
compute_array_index_type (tree name, tree size)
{
+ tree type = TREE_TYPE (size);
tree itype;
- /* If this involves a template parameter, it will be a constant at
- instantiation time, but we don't know what the value is yet.
- Even if no template parameters are involved, we may an expression
- that is not a constant; we don't even simplify `1 + 2' when
- processing a template. */
- if (processing_template_decl)
+ /* The array bound must be an integer type. */
+ if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
{
- /* Resolve a qualified reference to an enumerator or static
- const data member of ours. */
- if (TREE_CODE (size) == SCOPE_REF
- && TREE_OPERAND (size, 0) == current_class_type)
- {
- tree t = lookup_field (current_class_type,
- TREE_OPERAND (size, 1), 0, false);
- if (t)
- size = t;
- }
-
- return build_index_type (build_min (MINUS_EXPR, sizetype,
- size, integer_one_node));
+ if (name)
+ error ("size of array `%D' has non-integral type `%T'", name, type);
+ else
+ error ("size of array has non-integral type `%T'", type);
+ size = integer_one_node;
+ type = TREE_TYPE (size);
}
+ if (abi_version_at_least (2)
+ /* We should only handle value dependent expressions specially. */
+ ? value_dependent_expression_p (size)
+ /* But for abi-1, we handled all instances in templates. This
+ effects the manglings produced. */
+ : processing_template_decl)
+ return build_index_type (build_min (MINUS_EXPR, sizetype,
+ size, integer_one_node));
+
/* The size might be the result of a cast. */
STRIP_TYPE_NOPS (size);
/* It might be a const variable or enumeration constant. */
size = decl_constant_value (size);
- /* The array bound must be an integer type. */
- if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE
- && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE)
- {
- if (name)
- error ("size of array `%D' has non-integer type", name);
- else
- error ("size of array has non-integer type");
- size = integer_one_node;
- }
-
/* Normally, the array-bound will be a constant. */
if (TREE_CODE (size) == INTEGER_CST)
{
@@ -6055,38 +6084,36 @@ compute_array_index_type (tree name, tree size)
else
error ("size of array is not an integral constant-expression");
}
+ else if (pedantic)
+ {
+ if (name)
+ pedwarn ("ISO C++ forbids variable-size array `%D'", name);
+ else
+ pedwarn ("ISO C++ forbids variable-size array");
+ }
- /* Compute the index of the largest element in the array. It is
- one less than the number of elements in the array. */
- itype
- = fold (cp_build_binary_op (MINUS_EXPR,
- cp_convert (ssizetype, size),
- cp_convert (ssizetype,
- integer_one_node)));
-
- /* Check for variable-sized arrays. We allow such things as an
- extension, even though they are not allowed in ANSI/ISO C++. */
- if (!TREE_CONSTANT (itype))
+ if (processing_template_decl && !TREE_CONSTANT (size))
+ /* A variable sized array. */
+ itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
+ else
{
- if (pedantic)
+ /* Compute the index of the largest element in the array. It is
+ one less than the number of elements in the array. */
+ itype
+ = fold (cp_build_binary_op (MINUS_EXPR,
+ cp_convert (ssizetype, size),
+ cp_convert (ssizetype, integer_one_node)));
+ if (!TREE_CONSTANT (itype))
+ /* A variable sized array. */
+ itype = variable_size (itype);
+ /* Make sure that there was no overflow when creating to a signed
+ index type. (For example, on a 32-bit machine, an array with
+ size 2^32 - 1 is too big.) */
+ else if (TREE_OVERFLOW (itype))
{
- if (name)
- pedwarn ("ISO C++ forbids variable-size array `%D'",
- name);
- else
- pedwarn ("ISO C++ forbids variable-size array");
+ error ("overflow in array dimension");
+ TREE_OVERFLOW (itype) = 0;
}
-
- /* Create a variable-sized array index type. */
- itype = variable_size (itype);
- }
- /* Make sure that there was no overflow when creating to a signed
- index type. (For example, on a 32-bit machine, an array with
- size 2^32 - 1 is too big.) */
- else if (TREE_OVERFLOW (itype))
- {
- error ("overflow in array dimension");
- TREE_OVERFLOW (itype) = 0;
}
/* Create and return the appropriate index type. */
@@ -6348,7 +6375,7 @@ grokdeclarator (tree declarator,
and get it as a string, for an error message. */
{
tree *next = &declarator;
- register tree decl;
+ tree decl;
name = NULL;
while (next && *next)
@@ -6672,8 +6699,8 @@ grokdeclarator (tree declarator,
for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
{
- register int i;
- register tree id;
+ int i;
+ tree id;
/* Certain parse errors slip through. For example,
`int class;' is not caught by the parser. Try
@@ -6777,7 +6804,7 @@ grokdeclarator (tree declarator,
error ("two or more data types in declaration of `%s'", name);
else if (TREE_CODE (id) == IDENTIFIER_NODE)
{
- register tree t = lookup_name (id, 1);
+ tree t = lookup_name (id, 1);
if (!t || TREE_CODE (t) != TYPE_DECL)
error ("`%s' fails to be a typedef or built in type",
IDENTIFIER_POINTER (id));
@@ -7086,7 +7113,7 @@ grokdeclarator (tree declarator,
else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
;
else if (decl_context == FIELD
- /* C++ allows static class elements */
+ /* C++ allows static class elements. */
&& RIDBIT_SETP (RID_STATIC, specbits))
/* C++ also allows inlines and signed and unsigned elements,
but in those cases we don't come in here. */
@@ -7096,7 +7123,7 @@ grokdeclarator (tree declarator,
if (decl_context == FIELD)
{
tree tmp = NULL_TREE;
- register int op = 0;
+ int op = 0;
if (declarator)
{
@@ -7472,7 +7499,7 @@ grokdeclarator (tree declarator,
if (TREE_TYPE (declarator))
{
- register tree typemodlist;
+ tree typemodlist;
int erred = 0;
int constp = 0;
int volatilep = 0;
@@ -7991,7 +8018,7 @@ grokdeclarator (tree declarator,
}
{
- register tree decl;
+ tree decl;
if (decl_context == PARM)
{
@@ -8194,7 +8221,7 @@ grokdeclarator (tree declarator,
return void_type_node;
}
- /* Structure field. It may not be a function, except for C++ */
+ /* Structure field. It may not be a function, except for C++. */
if (decl == NULL_TREE)
{
@@ -8419,7 +8446,7 @@ require_complete_types_for_parms (tree parms)
for (; parms; parms = TREE_CHAIN (parms))
{
if (VOID_TYPE_P (TREE_TYPE (parms)))
- /* grokparms will have already issued an error */
+ /* grokparms will have already issued an error. */
TREE_TYPE (parms) = error_mark_node;
else if (complete_type_or_else (TREE_TYPE (parms), parms))
{
@@ -9283,7 +9310,7 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
bool globalize, bool template_header_p)
{
enum tree_code code;
- register tree t;
+ tree t;
struct cp_binding_level *b = current_binding_level;
tree context = NULL_TREE;
@@ -9615,7 +9642,15 @@ xref_basetypes (tree ref, tree base_list)
inheritance order chain. */
copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));
-
+
+ if (TYPE_FOR_JAVA (ref))
+ {
+ if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
+ error ("Java class '%T' cannot have multiple bases", ref);
+ if (CLASSTYPE_VBASECLASSES (ref))
+ error ("Java class '%T' cannot have virtual bases", ref);
+ }
+
/* Unmark all the types. */
while (i--)
{
@@ -9641,7 +9676,7 @@ xref_basetypes (tree ref, tree base_list)
tree
start_enum (tree name)
{
- register tree enumtype = NULL_TREE;
+ tree enumtype = NULL_TREE;
struct cp_binding_level *b = current_binding_level;
/* If this is the real definition for a previous forward reference,
@@ -10217,7 +10252,19 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
/* A specialization is not used to guide overload resolution. */
if (!DECL_TEMPLATE_SPECIALIZATION (decl1)
&& ! DECL_FUNCTION_MEMBER_P (decl1))
- decl1 = pushdecl (decl1);
+ {
+ tree olddecl = pushdecl (decl1);
+
+ if (olddecl == error_mark_node)
+ /* If something went wrong when registering the declaration,
+ use DECL1; we have to have a FUNCTION_DECL to use when
+ parsing the body of the function. */
+ ;
+ else
+ /* Otherwise, OLDDECL is either a previous declaration of
+ the same function or DECL1 itself. */
+ decl1 = olddecl;
+ }
else
{
/* We need to set the DECL_CONTEXT. */
@@ -10288,8 +10335,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
If it belongs to someone else's interface, it is also external.
This only affects inlines and template instantiations. */
else if (interface_unknown == 0
- && (! DECL_TEMPLATE_INSTANTIATION (decl1)
- || flag_alt_external_templates))
+ && ! DECL_TEMPLATE_INSTANTIATION (decl1))
{
if (DECL_DECLARED_INLINE_P (decl1)
|| DECL_TEMPLATE_INSTANTIATION (decl1)
@@ -10310,8 +10356,7 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
DECL_INTERFACE_KNOWN (decl1) = 1;
}
else if (interface_unknown && interface_only
- && (! DECL_TEMPLATE_INSTANTIATION (decl1)
- || flag_alt_external_templates))
+ && ! DECL_TEMPLATE_INSTANTIATION (decl1))
{
/* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
interface, we will have interface_only set but not
@@ -10365,8 +10410,8 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
static void
store_parm_decls (tree current_function_parms)
{
- register tree fndecl = current_function_decl;
- register tree parm;
+ tree fndecl = current_function_decl;
+ tree parm;
/* This is a chain of any other decls that came in among the parm
declarations. If a parm is declared with enum {foo, bar} x;
@@ -10642,7 +10687,7 @@ finish_function_body (tree compstmt)
tree
finish_function (int flags)
{
- register tree fndecl = current_function_decl;
+ tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
int inclass_inline = (flags & 2) != 0;
int nested;
@@ -10797,6 +10842,7 @@ finish_function (int flags)
/* Complain if there's just no return statement. */
if (warn_return_type
&& TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
+ && !dependent_type_p (TREE_TYPE (fntype))
&& !current_function_returns_value && !current_function_returns_null
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
@@ -10915,7 +10961,7 @@ start_method (tree declspecs, tree declarator, tree attrlist)
cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
- /* Make a place for the parms */
+ /* Make a place for the parms. */
begin_scope (sk_function_parms, fndecl);
DECL_IN_AGGR_P (fndecl) = 1;
@@ -10937,10 +10983,10 @@ start_method (tree declspecs, tree declarator, tree attrlist)
tree
finish_method (tree decl)
{
- register tree fndecl = decl;
+ tree fndecl = decl;
tree old_initial;
- register tree link;
+ tree link;
if (decl == void_type_node)
return decl;
@@ -11128,8 +11174,6 @@ cxx_push_function_context (struct function * f)
{
tree fn = f->decl;
- current_function_is_thunk = DECL_THUNK_P (fn);
-
if (DECL_SAVED_FUNCTION_DATA (fn))
{
/* If we already parsed this function, and we're just expanding it