Return false on error.
* decl.c (xref_tag): Return error_mark_node if
redeclare_class_template returned false.
+
+ PR c++/27667
+ * cp-tree.h (begin_specialization): Return bool
+ instead of void.
+ * pt.c (check_specialization_scope): Likwise.
+ Adjust comment. Return false if a specialization
+ isn't permitted in the current scope.
+ (begin_specialization): Use the return value of
+ check_specialization_scope.
+ * parser.c (cp_parser_explicit_specialization): If
+ begin_specialization returned false, skip the rest
+ of the specialization.
2006-09-21 Mark Mitchell <mark@codesourcery.com>
extern void maybe_end_member_template_processing (void);
extern tree finish_member_template_decl (tree);
extern void begin_template_parm_list (void);
-extern void begin_specialization (void);
+extern bool begin_specialization (void);
extern void reset_specialization (void);
extern void end_specialization (void);
extern void begin_explicit_instantiation (void);
else
need_lang_pop = false;
/* Let the front end know that we are beginning a specialization. */
- begin_specialization ();
+ if (!begin_specialization ())
+ {
+ end_specialization ();
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
+
/* If the next keyword is `template', we need to figure out whether
or not we're looking a template-declaration. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
-static void check_specialization_scope (void);
+static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
}
/* This routine is called when a specialization is declared. If it is
- invalid to declare a specialization here, an error is reported. */
+ invalid to declare a specialization here, an error is reported and
+ false is returned, otherwise this routine will return true. */
-static void
+static bool
check_specialization_scope (void)
{
tree scope = current_scope ();
shall be declared in the namespace of which the class template
is a member. */
if (scope && TREE_CODE (scope) != NAMESPACE_DECL)
- error ("explicit specialization in non-namespace scope %qD", scope);
+ {
+ error ("explicit specialization in non-namespace scope %qD", scope);
+ return false;
+ }
/* [temp.expl.spec]
explicitly specialize a class member template if its enclosing
class templates are not explicitly specialized as well. */
if (current_template_parms)
- error ("enclosing class templates are not explicitly specialized");
+ {
+ error ("enclosing class templates are not explicitly specialized");
+ return false;
+ }
+
+ return true;
}
/* We've just seen template <>. */
-void
+bool
begin_specialization (void)
{
begin_scope (sk_template_spec, NULL);
note_template_header (1);
- check_specialization_scope ();
+ return check_specialization_scope ();
}
/* Called at then end of processing a declaration preceded by