aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c326
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);