/* If this is declaring a typedef name, return a TYPE_DECL. */
if (typedef_p && decl_context != TYPENAME)
{
+ bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias);
tree decl;
/* This declaration:
if (type_uses_auto (type))
{
- error ("typedef declared %<auto%>");
+ if (alias_p)
+ error_at (declspecs->locations[ds_type_spec],
+ "%<auto%> not allowed in alias declaration");
+ else
+ error_at (declspecs->locations[ds_type_spec],
+ "typedef declared %<auto%>");
type = error_mark_node;
}
inlinep, friendp, raises != NULL_TREE,
declspecs->locations);
- if (decl_spec_seq_has_spec_p (declspecs, ds_alias))
+ if (alias_p)
/* Acknowledge that this was written:
`using analias = atype;'. */
TYPE_DECL_ALIAS_P (decl) = 1;
static tree cp_parser_declarator_id
(cp_parser *, bool);
static tree cp_parser_type_id
- (cp_parser *);
+ (cp_parser *, location_t * = NULL);
static tree cp_parser_template_type_arg
(cp_parser *);
static tree cp_parser_trailing_type_id (cp_parser *);
static tree cp_parser_type_id_1
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, location_t *);
static void cp_parser_type_specifier_seq
(cp_parser *, bool, bool, cp_decl_specifier_seq *);
static tree cp_parser_parameter_declaration_clause
cp_parser_alias_declaration (cp_parser* parser)
{
tree id, type, decl, pushed_scope = NULL_TREE, attributes;
- location_t id_location;
+ location_t id_location, type_location;
cp_declarator *declarator;
cp_decl_specifier_seq decl_specs;
bool member_p;
G_("types may not be defined in alias template declarations");
}
- type = cp_parser_type_id (parser);
+ type = cp_parser_type_id (parser, &type_location);
/* Restore the error message if need be. */
if (parser->num_template_parameter_lists)
set_and_check_decl_spec_loc (&decl_specs,
ds_alias,
using_token);
+ decl_specs.locations[ds_type_spec] = type_location;
if (parser->num_template_parameter_lists
&& !cp_parser_check_template_parameters (parser,
static tree
cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg,
- bool is_trailing_return)
+ bool is_trailing_return, location_t * type_location)
{
cp_decl_specifier_seq type_specifier_seq;
cp_declarator *abstract_declarator;
cp_parser_type_specifier_seq (parser, /*is_declaration=*/false,
is_trailing_return,
&type_specifier_seq);
+ if (type_location)
+ *type_location = type_specifier_seq.locations[ds_type_spec];
+
if (is_template_arg && type_specifier_seq.type
&& TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM
&& CLASS_PLACEHOLDER_TEMPLATE (type_specifier_seq.type))
}
static tree
-cp_parser_type_id (cp_parser *parser)
+cp_parser_type_id (cp_parser *parser, location_t * type_location)
{
- return cp_parser_type_id_1 (parser, false, false);
+ return cp_parser_type_id_1 (parser, false, false, type_location);
}
static tree
const char *saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
= G_("types may not be defined in template arguments");
- r = cp_parser_type_id_1 (parser, true, false);
+ r = cp_parser_type_id_1 (parser, true, false, NULL);
parser->type_definition_forbidden_message = saved_message;
if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r))
{
static tree
cp_parser_trailing_type_id (cp_parser *parser)
{
- return cp_parser_type_id_1 (parser, false, true);
+ return cp_parser_type_id_1 (parser, false, true, NULL);
}
/* Parse a type-specifier-seq.