diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2011-05-14 21:13:23 +0300 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-05-14 14:13:23 -0400 |
commit | 486d481b392fae54d39413f3d1fc6851383fce47 (patch) | |
tree | 6e71c4f8224656772ee33335e93d1fb8eb7d983e /gcc/cp/parser.c | |
parent | ade2e40389bd3c76031c486991005ffffa1493bf (diff) | |
download | gcc-486d481b392fae54d39413f3d1fc6851383fce47.zip gcc-486d481b392fae54d39413f3d1fc6851383fce47.tar.gz gcc-486d481b392fae54d39413f3d1fc6851383fce47.tar.bz2 |
Implement final on class.
* class.c (check_bases): Diagnose derivation from a final class.
* cp-tree.h (lang_type_class): Add is_final and adjust dummy.
(CLASSTYPE_FINAL): New.
* parser.c (cp_parser_class_head): Parse class-virt-specifier, set
CLASSTYPE_FINAL.
* pt.c (instantiate_class_template_1): Copy CLASSTYPE_FINAL.
From-SVN: r173761
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index fa6cd83..a77d4ff 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -17082,10 +17082,13 @@ cp_parser_class_specifier (cp_parser* parser) class-head: class-key identifier [opt] base-clause [opt] - class-key nested-name-specifier identifier base-clause [opt] + class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt] class-key nested-name-specifier [opt] template-id base-clause [opt] + class-virt-specifier: + final + GNU Extensions: class-key attributes identifier [opt] base-clause [opt] class-key attributes nested-name-specifier identifier base-clause [opt] @@ -17117,6 +17120,7 @@ cp_parser_class_head (cp_parser* parser, tree id = NULL_TREE; tree type = NULL_TREE; tree attributes; + cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED; bool template_id_p = false; bool qualified_p = false; bool invalid_nested_name_p = false; @@ -17260,8 +17264,11 @@ cp_parser_class_head (cp_parser* parser, pop_deferring_access_checks (); if (id) - cp_parser_check_for_invalid_template_id (parser, id, - type_start_token->location); + { + cp_parser_check_for_invalid_template_id (parser, id, + type_start_token->location); + virt_specifiers = cp_parser_virt_specifier_seq_opt (parser); + } /* If it's not a `:' or a `{' then we can't really be looking at a class-head, since a class-head only appears as part of a @@ -17277,6 +17284,13 @@ cp_parser_class_head (cp_parser* parser, /* At this point, we're going ahead with the class-specifier, even if some other problem occurs. */ cp_parser_commit_to_tentative_parse (parser); + if (virt_specifiers & VIRT_SPEC_OVERRIDE) + { + cp_parser_error (parser, + "cannot specify %<override%> for a class"); + type = error_mark_node; + goto out; + } /* Issue the error about the overly-qualified name now. */ if (qualified_p) { @@ -17493,6 +17507,8 @@ cp_parser_class_head (cp_parser* parser, if (type) DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location; *attributes_p = attributes; + if (type && (virt_specifiers & VIRT_SPEC_FINAL)) + CLASSTYPE_FINAL (type) = 1; out: parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; return type; |