Add source location to TRAIT_EXPR.

Since TRAIT_EXPR is exceptional, maybe_wrap_with_location won't wrap it, so
we need to put its location in the TRAIT_EXPR node itself.

	* cp-tree.h (TRAIT_EXPR_LOCATION): New.
	(struct tree_trait_expr): Add locus field.
	* parser.c (cp_parser_trait_expr): Pass trait_loc down.
	* pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise.
	* semantics.c (finish_trait_expr): Add location parm.
	* tree.c (cp_expr_location): Handle TRAIT_EXPR.

From-SVN: r275260
This commit is contained in:
Jason Merrill 2019-08-31 18:09:47 -04:00 committed by Jason Merrill
parent bd486c8cdf
commit ad527d8018
7 changed files with 27 additions and 6 deletions

View File

@ -1,3 +1,13 @@
2019-08-30 Jason Merrill <jason@redhat.com>
Add source location to TRAIT_EXPR.
* cp-tree.h (TRAIT_EXPR_LOCATION): New.
(struct tree_trait_expr): Add locus field.
* parser.c (cp_parser_trait_expr): Pass trait_loc down.
* pt.c (tsubst_copy_and_build) [TRAIT_EXPR]: Likewise.
* semantics.c (finish_trait_expr): Add location parm.
* tree.c (cp_expr_location): Handle TRAIT_EXPR.
2019-08-29 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (check_var_type): Add location_t parameter and use it.

View File

@ -1295,10 +1295,14 @@ enum cp_trait_kind
#define TRAIT_EXPR_KIND(NODE) \
(((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind)
#define TRAIT_EXPR_LOCATION(NODE) \
(((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->locus)
struct GTY (()) tree_trait_expr {
struct tree_common common;
tree type1;
tree type2;
location_t locus;
enum cp_trait_kind kind;
};
@ -7174,7 +7178,7 @@ extern tree baselink_for_fns (tree);
extern void finish_static_assert (tree, tree, location_t,
bool);
extern tree finish_decltype_type (tree, bool, tsubst_flags_t);
extern tree finish_trait_expr (enum cp_trait_kind, tree, tree);
extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree);
extern tree build_lambda_expr (void);
extern tree build_lambda_object (tree);
extern tree begin_lambda_type (tree);

View File

@ -10396,7 +10396,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
case CPTK_DIRECT_BASES:
return cp_expr (finish_bases (type1, true), trait_loc);
default:
return cp_expr (finish_trait_expr (kind, type1, type2), trait_loc);
return finish_trait_expr (trait_loc, kind, type1, type2);
}
}

View File

@ -19536,7 +19536,8 @@ tsubst_copy_and_build (tree t,
else if (type2)
type2 = tsubst (type2, args, complain, in_decl);
RETURN (finish_trait_expr (TRAIT_EXPR_KIND (t), type1, type2));
RETURN (finish_trait_expr (TRAIT_EXPR_LOCATION (t),
TRAIT_EXPR_KIND (t), type1, type2));
}
case STMT_EXPR:

View File

@ -9921,7 +9921,7 @@ check_trait_type (tree type)
/* Process a trait expression. */
tree
finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
{
if (type1 == error_mark_node
|| type2 == error_mark_node)
@ -9934,6 +9934,7 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
TRAIT_EXPR_TYPE1 (trait_expr) = type1;
TRAIT_EXPR_TYPE2 (trait_expr) = type2;
TRAIT_EXPR_KIND (trait_expr) = kind;
TRAIT_EXPR_LOCATION (trait_expr) = loc;
return trait_expr;
}
@ -9991,8 +9992,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
gcc_unreachable ();
}
return (trait_expr_value (kind, type1, type2)
? boolean_true_node : boolean_false_node);
tree val = (trait_expr_value (kind, type1, type2)
? boolean_true_node : boolean_false_node);
return maybe_wrap_with_location (val, loc);
}
/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,

View File

@ -5500,6 +5500,8 @@ cp_expr_location (const_tree t_)
return LAMBDA_EXPR_LOCATION (t);
case STATIC_ASSERT:
return STATIC_ASSERT_SOURCE_LOCATION (t);
case TRAIT_EXPR:
return TRAIT_EXPR_LOCATION (t);
default:
return EXPR_LOCATION (t);
}

View File

@ -0,0 +1,2 @@
struct A {};
void *p = __is_class (A); // { dg-error "11:cannot convert" }