diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 326 |
1 files changed, 164 insertions, 162 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 07f0375..0314bb3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13371,181 +13371,183 @@ cp_parser_direct_declarator (cp_parser* parser, } else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) { - tree qualifying_scope; - tree unqualified_name; - special_function_kind sfk; - bool abstract_ok; - bool pack_expansion_p = false; - cp_token *declarator_id_start_token; - - /* Parse a declarator-id */ - abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); - if (abstract_ok) - { - cp_parser_parse_tentatively (parser); + { + tree qualifying_scope; + tree unqualified_name; + special_function_kind sfk; + bool abstract_ok; + bool pack_expansion_p = false; + cp_token *declarator_id_start_token; + + /* Parse a declarator-id */ + abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER); + if (abstract_ok) + { + cp_parser_parse_tentatively (parser); - /* If we see an ellipsis, we should be looking at a - parameter pack. */ - if (token->type == CPP_ELLIPSIS) - { - /* Consume the `...' */ - cp_lexer_consume_token (parser->lexer); + /* If we see an ellipsis, we should be looking at a + parameter pack. */ + if (token->type == CPP_ELLIPSIS) + { + /* Consume the `...' */ + cp_lexer_consume_token (parser->lexer); - pack_expansion_p = true; - } - } + pack_expansion_p = true; + } + } - declarator_id_start_token = cp_lexer_peek_token (parser->lexer); - unqualified_name - = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); - qualifying_scope = parser->scope; - if (abstract_ok) - { - bool okay = false; - - if (!unqualified_name && pack_expansion_p) - { - /* Check whether an error occurred. */ - okay = !cp_parser_error_occurred (parser); - - /* We already consumed the ellipsis to mark a - parameter pack, but we have no way to report it, - so abort the tentative parse. We will be exiting - immediately anyway. */ - cp_parser_abort_tentative_parse (parser); - } - else - okay = cp_parser_parse_definitely (parser); - - if (!okay) - unqualified_name = error_mark_node; - else if (unqualified_name - && (qualifying_scope - || (TREE_CODE (unqualified_name) - != IDENTIFIER_NODE))) - { - cp_parser_error (parser, "expected unqualified-id"); - unqualified_name = error_mark_node; - } - } + declarator_id_start_token = cp_lexer_peek_token (parser->lexer); + unqualified_name + = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok); + qualifying_scope = parser->scope; + if (abstract_ok) + { + bool okay = false; - if (!unqualified_name) - return NULL; - if (unqualified_name == error_mark_node) - { - declarator = cp_error_declarator; - pack_expansion_p = false; - declarator->parameter_pack_p = false; - break; - } + if (!unqualified_name && pack_expansion_p) + { + /* Check whether an error occurred. */ + okay = !cp_parser_error_occurred (parser); + + /* We already consumed the ellipsis to mark a + parameter pack, but we have no way to report it, + so abort the tentative parse. We will be exiting + immediately anyway. */ + cp_parser_abort_tentative_parse (parser); + } + else + okay = cp_parser_parse_definitely (parser); - if (qualifying_scope && at_namespace_scope_p () - && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) - { - /* In the declaration of a member of a template class - outside of the class itself, the SCOPE will sometimes - be a TYPENAME_TYPE. For example, given: - - template <typename T> - int S<T>::R::i = 3; - - the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In - this context, we must resolve S<T>::R to an ordinary - type, rather than a typename type. - - The reason we normally avoid resolving TYPENAME_TYPEs - is that a specialization of `S' might render - `S<T>::R' not a type. However, if `S' is - specialized, then this `i' will not be used, so there - is no harm in resolving the types here. */ - tree type; + if (!okay) + unqualified_name = error_mark_node; + else if (unqualified_name + && (qualifying_scope + || (TREE_CODE (unqualified_name) + != IDENTIFIER_NODE))) + { + cp_parser_error (parser, "expected unqualified-id"); + unqualified_name = error_mark_node; + } + } - /* Resolve the TYPENAME_TYPE. */ - type = resolve_typename_type (qualifying_scope, - /*only_current_p=*/false); - /* If that failed, the declarator is invalid. */ - if (TREE_CODE (type) == TYPENAME_TYPE) - error ("%H%<%T::%E%> is not a type", - &declarator_id_start_token->location, - TYPE_CONTEXT (qualifying_scope), - TYPE_IDENTIFIER (qualifying_scope)); - qualifying_scope = type; - } + if (!unqualified_name) + return NULL; + if (unqualified_name == error_mark_node) + { + declarator = cp_error_declarator; + pack_expansion_p = false; + declarator->parameter_pack_p = false; + break; + } - sfk = sfk_none; + if (qualifying_scope && at_namespace_scope_p () + && TREE_CODE (qualifying_scope) == TYPENAME_TYPE) + { + /* In the declaration of a member of a template class + outside of the class itself, the SCOPE will sometimes + be a TYPENAME_TYPE. For example, given: + + template <typename T> + int S<T>::R::i = 3; + + the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In + this context, we must resolve S<T>::R to an ordinary + type, rather than a typename type. + + The reason we normally avoid resolving TYPENAME_TYPEs + is that a specialization of `S' might render + `S<T>::R' not a type. However, if `S' is + specialized, then this `i' will not be used, so there + is no harm in resolving the types here. */ + tree type; + + /* Resolve the TYPENAME_TYPE. */ + type = resolve_typename_type (qualifying_scope, + /*only_current_p=*/false); + /* If that failed, the declarator is invalid. */ + if (TREE_CODE (type) == TYPENAME_TYPE) + error ("%H%<%T::%E%> is not a type", + &declarator_id_start_token->location, + TYPE_CONTEXT (qualifying_scope), + TYPE_IDENTIFIER (qualifying_scope)); + qualifying_scope = type; + } - if (unqualified_name) - { - tree class_type; + sfk = sfk_none; - if (qualifying_scope - && CLASS_TYPE_P (qualifying_scope)) - class_type = qualifying_scope; - else - class_type = current_class_type; + if (unqualified_name) + { + tree class_type; - if (TREE_CODE (unqualified_name) == TYPE_DECL) - { - tree name_type = TREE_TYPE (unqualified_name); - if (class_type && same_type_p (name_type, class_type)) - { - if (qualifying_scope - && CLASSTYPE_USE_TEMPLATE (name_type)) - { - error ("%Hinvalid use of constructor as a template", - &declarator_id_start_token->location); - inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to " - "name the constructor in a qualified name", - class_type, - DECL_NAME (TYPE_TI_TEMPLATE (class_type)), - class_type, name_type); - declarator = cp_error_declarator; - break; - } - else - unqualified_name = constructor_name (class_type); - } - else - { - /* We do not attempt to print the declarator - here because we do not have enough - information about its original syntactic - form. */ - cp_parser_error (parser, "invalid declarator"); - declarator = cp_error_declarator; - break; - } - } + if (qualifying_scope + && CLASS_TYPE_P (qualifying_scope)) + class_type = qualifying_scope; + else + class_type = current_class_type; - if (class_type) - { - if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) - sfk = sfk_destructor; - else if (IDENTIFIER_TYPENAME_P (unqualified_name)) - sfk = sfk_conversion; - else if (/* There's no way to declare a constructor - for an anonymous type, even if the type - got a name for linkage purposes. */ - !TYPE_WAS_ANONYMOUS (class_type) - && constructor_name_p (unqualified_name, - class_type)) - { - unqualified_name = constructor_name (class_type); - sfk = sfk_constructor; - } + if (TREE_CODE (unqualified_name) == TYPE_DECL) + { + tree name_type = TREE_TYPE (unqualified_name); + if (class_type && same_type_p (name_type, class_type)) + { + if (qualifying_scope + && CLASSTYPE_USE_TEMPLATE (name_type)) + { + error ("%Hinvalid use of constructor as a template", + &declarator_id_start_token->location); + inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to " + "name the constructor in a qualified name", + class_type, + DECL_NAME (TYPE_TI_TEMPLATE (class_type)), + class_type, name_type); + declarator = cp_error_declarator; + break; + } + else + unqualified_name = constructor_name (class_type); + } + else + { + /* We do not attempt to print the declarator + here because we do not have enough + information about its original syntactic + form. */ + cp_parser_error (parser, "invalid declarator"); + declarator = cp_error_declarator; + break; + } + } - if (ctor_dtor_or_conv_p && sfk != sfk_none) - *ctor_dtor_or_conv_p = -1; - } - } - declarator = make_id_declarator (qualifying_scope, - unqualified_name, - sfk); - declarator->id_loc = token->location; - declarator->parameter_pack_p = pack_expansion_p; + if (class_type) + { + if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR) + sfk = sfk_destructor; + else if (IDENTIFIER_TYPENAME_P (unqualified_name)) + sfk = sfk_conversion; + else if (/* There's no way to declare a constructor + for an anonymous type, even if the type + got a name for linkage purposes. */ + !TYPE_WAS_ANONYMOUS (class_type) + && constructor_name_p (unqualified_name, + class_type)) + { + unqualified_name = constructor_name (class_type); + sfk = sfk_constructor; + } - if (pack_expansion_p) - maybe_warn_variadic_templates (); + if (ctor_dtor_or_conv_p && sfk != sfk_none) + *ctor_dtor_or_conv_p = -1; + } + } + declarator = make_id_declarator (qualifying_scope, + unqualified_name, + sfk); + declarator->id_loc = token->location; + declarator->parameter_pack_p = pack_expansion_p; + + if (pack_expansion_p) + maybe_warn_variadic_templates (); + } handle_declarator:; scope = get_scope_of_declarator (declarator); |