+1998-09-22 Mark Mitchell <mark@markmitchell.com>
+
+ * decl.c (grokfndecl): Improve error-recovery.
+ * decl2.c (grokfield): Likewise.
+ * pt.c (finish_member_template_decl): Likewise.
+
1998-09-20 Martin von Löwis <loewis@informatik.hu-berlin.de>
* method.c (hack_identifier): Finding multiple members is always
or `volatile'.
RAISES is a list of exceptions that this function can raise.
CHECK is 1 if we must find this method in CTYPE, 0 if we should
- not look, and -1 if we should not call `grokclassfn' at all. */
+ not look, and -1 if we should not call `grokclassfn' at all.
+
+ Returns `error_mark_node' if something goes wrong, after issuing
+ applicable error messages. */
static tree
grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
return tmp;
}
if (! grok_ctor_properties (ctype, decl))
- return NULL_TREE;
+ return error_mark_node;
if (check == 0 && ! current_function_decl)
{
virtualp, flags, quals, raises, attrlist,
friendp ? -1 : 0, friendp, publicp, inlinep,
funcdef_flag, template_count, in_namespace);
- if (decl == NULL_TREE)
- return NULL_TREE;
+ if (decl == NULL_TREE || decl == error_mark_node)
+ return decl;
#if 0
/* This clobbers the attrs stored in `decl' from `attrlist'. */
/* The decl and setting of decl_machine_attr is also turned off. */
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE);
if (! value || value == error_mark_node)
- return NULL_TREE; /* friend or constructor went bad. */
+ /* friend or constructor went bad. */
+ return value;
/* Pass friendly classes back. */
if (TREE_CODE (value) == VOID_TYPE)
if (decl == NULL_TREE || decl == void_type_node)
return NULL_TREE;
+ else if (decl == error_mark_node)
+ /* By returning NULL_TREE, the parser will just ignore this
+ declaration. We have already issued the error. */
+ return NULL_TREE;
else if (TREE_CODE (decl) == TREE_LIST)
{
/* Assume that the class is the only declspec. */
}
else
cp_error ("invalid member template declaration `%D'", decl);
-
return error_mark_node;
}
check_specialization_scope ()
{
tree scope = current_scope ();
+
/* [temp.expl.spec]
An explicit specialization shall be declared in the namespace of
if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
cp_error ("explicit specialization in non-namespace scope `%D'",
scope);
+
/* [temp.expl.spec]
In an explicit specialization declaration for a member of a class
template <class A, class B> void foo();
template <class C> class bar {
int i;
- template <class B> friend void foo<C,B>();
+ template <class B> friend void foo<C,B>(); // ERROR - bogus declaration
};
template <class A, class B> void foo() {
- bar<A> baz; baz.i = 1;
- bar<int> buz; buz.i = 1; // ERROR - foo<void,void> cannot access bar<int>::i - XFAIL *-*-*
+ bar<A> baz; baz.i = 1; // ERROR - foo cannot access bar<int>::i
+ bar<int> buz; buz.i = 1; // ERROR - foo cannot access bar<int>::i
}
int main() {
foo<void,void>();