semantics.c (describable_type): New function.
gcc/cp: * semantics.c (describable_type): New function. (finish_decltype_type): Use it for dependent exprs. * cp-tree.h: Declare it. * mangle.c (write_type) [DECLTYPE_TYPE]: Set skip_evaluation. (write_expression): If skip_evaluation, use type stubs. * tree.c (cp_tree_equal): Handle PARM_DECLs from different declarations of a function. * init.c (build_new): Do auto deduction if type is describable. * decl.c (cp_finish_decl): Likewise. * parser.c (cp_parser_omp_for_loop): Likewise. gcc/testsuite: * g++.dg/cpp0x/auto6.C: Test more stuff. * g++.dg/cpp0x/auto12.C: New test. libiberty: * cp-demangle.c (d_expression): Handle rvalue stubs too. [DEMANGLE_COMPONENT_CAST]: Update mangling. (d_print_comp): Avoid extra ", " with empty template argument packs. Remove handling for obsolete T() mangling. From-SVN: r142799
This commit is contained in:
parent
3aea2d1ce2
commit
a77f94e240
@ -1,3 +1,16 @@
|
||||
2008-12-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* semantics.c (describable_type): New function.
|
||||
(finish_decltype_type): Use it for dependent exprs.
|
||||
* cp-tree.h: Declare it.
|
||||
* mangle.c (write_type) [DECLTYPE_TYPE]: Set skip_evaluation.
|
||||
(write_expression): If skip_evaluation, use type stubs.
|
||||
* tree.c (cp_tree_equal): Handle PARM_DECLs from different
|
||||
declarations of a function.
|
||||
* init.c (build_new): Do auto deduction if type is describable.
|
||||
* decl.c (cp_finish_decl): Likewise.
|
||||
* parser.c (cp_parser_omp_for_loop): Likewise.
|
||||
|
||||
2008-12-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/35319
|
||||
|
@ -4814,6 +4814,7 @@ extern bool cxx_omp_create_clause_info (tree, tree, bool, bool, bool);
|
||||
extern tree baselink_for_fns (tree);
|
||||
extern void finish_static_assert (tree, tree, location_t,
|
||||
bool);
|
||||
extern tree describable_type (tree);
|
||||
extern tree finish_decltype_type (tree, bool);
|
||||
extern tree finish_trait_expr (enum cp_trait_kind, tree, tree);
|
||||
|
||||
|
@ -5496,7 +5496,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
return;
|
||||
}
|
||||
else if (!type_dependent_expression_p (init))
|
||||
else if (describable_type (init))
|
||||
{
|
||||
type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node);
|
||||
if (type == error_mark_node)
|
||||
|
@ -2329,7 +2329,7 @@ build_new (tree placement, tree type, tree nelts, tree init,
|
||||
orig_init = init;
|
||||
|
||||
if (nelts == NULL_TREE && init != void_zero_node && list_length (init) == 1
|
||||
&& !any_type_dependent_arguments_p (init))
|
||||
&& describable_type (TREE_VALUE (init)))
|
||||
{
|
||||
tree auto_node = type_uses_auto (type);
|
||||
if (auto_node)
|
||||
|
@ -1680,7 +1680,9 @@ write_type (tree type)
|
||||
write_char ('t');
|
||||
else
|
||||
write_char ('T');
|
||||
++skip_evaluation;
|
||||
write_expression (DECLTYPE_TYPE_EXPR (type));
|
||||
--skip_evaluation;
|
||||
write_char ('E');
|
||||
break;
|
||||
|
||||
@ -2139,9 +2141,28 @@ write_member_name (tree member)
|
||||
static void
|
||||
write_expression (tree expr)
|
||||
{
|
||||
enum tree_code code;
|
||||
enum tree_code code = TREE_CODE (expr);
|
||||
|
||||
code = TREE_CODE (expr);
|
||||
/* Inside decltype we can simplify some expressions, since we're only
|
||||
interested in the type. */
|
||||
if (skip_evaluation)
|
||||
{
|
||||
tree type = describable_type (expr);
|
||||
if (type == NULL_TREE)
|
||||
;
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
write_string ("sT");
|
||||
write_type (TREE_TYPE (type));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_string ("sR");
|
||||
write_type (type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip NOP_EXPRs. They can occur when (say) a pointer argument
|
||||
is converted (via qualification conversions) to another
|
||||
|
@ -21159,7 +21159,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
|
||||
&is_direct_init,
|
||||
&is_non_constant_init);
|
||||
|
||||
if (auto_node && !type_dependent_expression_p (init))
|
||||
if (auto_node && describable_type (init))
|
||||
{
|
||||
TREE_TYPE (decl)
|
||||
= do_auto_deduction (TREE_TYPE (decl), init,
|
||||
|
@ -4438,12 +4438,79 @@ finish_static_assert (tree condition, tree message, location_t location,
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns decltype((EXPR)) for cases where we can drop the decltype and
|
||||
just return the type even though EXPR is a type-dependent expression.
|
||||
The ABI specifies which cases this applies to, which is a subset of the
|
||||
possible cases. */
|
||||
|
||||
tree
|
||||
describable_type (tree expr)
|
||||
{
|
||||
tree type = NULL_TREE;
|
||||
|
||||
/* processing_template_decl isn't set when we're called from the mangling
|
||||
code, so bump it now. */
|
||||
++processing_template_decl;
|
||||
if (! type_dependent_expression_p (expr)
|
||||
&& ! type_unknown_p (expr))
|
||||
{
|
||||
type = TREE_TYPE (expr);
|
||||
if (real_lvalue_p (expr))
|
||||
type = build_reference_type (type);
|
||||
}
|
||||
--processing_template_decl;
|
||||
|
||||
if (type)
|
||||
return type;
|
||||
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
case FUNCTION_DECL:
|
||||
/* Named rvalue reference becomes lvalue. */
|
||||
type = build_reference_type (non_reference (TREE_TYPE (expr)));
|
||||
break;
|
||||
|
||||
case NEW_EXPR:
|
||||
case CONST_DECL:
|
||||
case TEMPLATE_PARM_INDEX:
|
||||
case CAST_EXPR:
|
||||
case STATIC_CAST_EXPR:
|
||||
case REINTERPRET_CAST_EXPR:
|
||||
case CONST_CAST_EXPR:
|
||||
case DYNAMIC_CAST_EXPR:
|
||||
type = TREE_TYPE (expr);
|
||||
break;
|
||||
|
||||
case INDIRECT_REF:
|
||||
{
|
||||
tree ptrtype = describable_type (TREE_OPERAND (expr, 0));
|
||||
if (ptrtype && POINTER_TYPE_P (ptrtype))
|
||||
type = build_reference_type (TREE_TYPE (ptrtype));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_constant)
|
||||
type = TREE_TYPE (expr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (type && type_uses_auto (type))
|
||||
return NULL_TREE;
|
||||
else
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Implements the C++0x decltype keyword. Returns the type of EXPR,
|
||||
suitable for use as a type-specifier.
|
||||
|
||||
ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
|
||||
id-expression or a class member access, FALSE when it was parsed as
|
||||
a full expression. */
|
||||
|
||||
tree
|
||||
finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
|
||||
{
|
||||
@ -4464,6 +4531,29 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
|
||||
|
||||
if (type_dependent_expression_p (expr))
|
||||
{
|
||||
if (id_expression_or_member_access_p)
|
||||
{
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
case FUNCTION_DECL:
|
||||
case CONST_DECL:
|
||||
case TEMPLATE_PARM_INDEX:
|
||||
type = TREE_TYPE (expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
type = describable_type (expr);
|
||||
|
||||
if (type && !type_uses_auto (type))
|
||||
return type;
|
||||
|
||||
type = cxx_make_type (DECLTYPE_TYPE);
|
||||
DECLTYPE_TYPE_EXPR (type) = expr;
|
||||
DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
|
||||
|
@ -1857,8 +1857,17 @@ cp_tree_equal (tree t1, tree t2)
|
||||
return false;
|
||||
return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
|
||||
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
/* For comparing uses of parameters in late-specified return types
|
||||
with an out-of-class definition of the function. */
|
||||
if ((!DECL_CONTEXT (t1) || !DECL_CONTEXT (t2))
|
||||
&& same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
|
||||
&& DECL_NAME (t1) == DECL_NAME (t2))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
case VAR_DECL:
|
||||
case CONST_DECL:
|
||||
case FUNCTION_DECL:
|
||||
case TEMPLATE_DECL:
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-12-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/auto6.C: Test more stuff.
|
||||
* g++.dg/cpp0x/auto12.C: New test.
|
||||
|
||||
2008-12-17 Daniel Kraft <d@domob.eu>
|
||||
|
||||
PR fortran/38137
|
||||
|
52
gcc/testsuite/g++.dg/cpp0x/auto12.C
Normal file
52
gcc/testsuite/g++.dg/cpp0x/auto12.C
Normal file
@ -0,0 +1,52 @@
|
||||
// More auto/decltype mangling tests.
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
template <class T>
|
||||
struct B
|
||||
{
|
||||
static int i;
|
||||
};
|
||||
|
||||
int&& x();
|
||||
|
||||
template <class T>
|
||||
struct A
|
||||
{
|
||||
static int i;
|
||||
static int &ir;
|
||||
static int &&irr;
|
||||
template <class U>
|
||||
auto f(U u) -> decltype (u + i);
|
||||
template <class U>
|
||||
auto fr(U u) -> decltype (u + ir);
|
||||
template <class U>
|
||||
auto frr(U u) -> decltype (u + irr);
|
||||
template <class U>
|
||||
auto g(U u) -> decltype (u + sizeof (i));
|
||||
template <class U>
|
||||
auto h(U u) -> decltype (u + B<U>::i);
|
||||
template <class U>
|
||||
auto j(U u) -> decltype (u + x());
|
||||
};
|
||||
|
||||
template<class T> template<class U>
|
||||
auto A<T>::f(U u) -> decltype (u + i)
|
||||
{
|
||||
return u + i;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplsTT_sTiES2_" } }
|
||||
A<int>().f(1);
|
||||
// { dg-final { scan-assembler "_ZN1AIiE2frIiEEDTplsTT_sTiES2_" } }
|
||||
A<int>().fr(1);
|
||||
// { dg-final { scan-assembler "_ZN1AIiE3frrIiEEDTplsTT_sTiES2_" } }
|
||||
A<int>().frr(1);
|
||||
// { dg-final { scan-assembler "_ZN1AIiE1gIiEEDTplsTT_sRjES2_" } }
|
||||
A<int>().g(1);
|
||||
// { dg-final { scan-assembler "_ZN1AIiE1hIiEEDTplsTT_sr1BIS2_E1iES2_" } }
|
||||
A<int>().h(1);
|
||||
// { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplsTT_sRiES2_" } }
|
||||
A<int>().j(1);
|
||||
}
|
@ -30,6 +30,12 @@ auto add3(T t, U u) -> decltype (ag(t,u))
|
||||
return ag(t,u);
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
decltype(*(T*)0+*(U*)0) add4(T t, U u)
|
||||
{
|
||||
return t+u;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct A
|
||||
{
|
||||
@ -72,13 +78,28 @@ auto k(T t, U u, V v) -> decltype (t.U::template B<V>::MEM)
|
||||
return t.U::template B<V>::MEM;
|
||||
}
|
||||
|
||||
// For these two examples we can elide the 'decltype' and just mangle the type.
|
||||
template <class T>
|
||||
auto l(T t) -> decltype (t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template <class T, T u>
|
||||
auto m(T t) -> decltype (u)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
A<int> a, *p;
|
||||
|
||||
int main()
|
||||
{
|
||||
// { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
|
||||
// { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
|
||||
auto i = add(1, 2.0);
|
||||
// { dg-final { scan-assembler "_Z4add2IidEDTplcvT_vcvT0_vES0_S1_" } }
|
||||
// { dg-final { scan-assembler "_Z4add4IidEDTplsTT_sTT0_ES0_S1_" } }
|
||||
auto i4 = add4(1, 2.0);
|
||||
// { dg-final { scan-assembler "_Z4add2IidEDTplsRT_sRT0_ES0_S1_" } }
|
||||
auto i2 = add2(1, 2.0);
|
||||
// { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } }
|
||||
auto i3 = add3(1, 2.0);
|
||||
@ -90,4 +111,8 @@ int main()
|
||||
h(a,1.0);
|
||||
// { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } }
|
||||
k( C(), A<int>(), D() );
|
||||
// { dg-final { scan-assembler "_Z1lIiET_S0_" } }
|
||||
l(1);
|
||||
// { dg-final { scan-assembler "_Z1mIiLi1EET_S0_" } }
|
||||
m<int,1>(1);
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
2008-12-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-demangle.c (d_expression): Handle rvalue stubs too.
|
||||
[DEMANGLE_COMPONENT_CAST]: Update mangling.
|
||||
(d_print_comp): Avoid extra ", " with empty template argument packs.
|
||||
Remove handling for obsolete T() mangling.
|
||||
|
||||
2008-12-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-demangle.c (cplus_demangle_type): Support fixed-point types.
|
||||
|
@ -2561,7 +2561,8 @@ d_expression (struct d_info *di)
|
||||
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
|
||||
d_template_args (di)));
|
||||
}
|
||||
else if (peek == 's' && d_peek_next_char (di) == 'T')
|
||||
else if (peek == 's'
|
||||
&& (d_peek_next_char (di) == 'T' || d_peek_next_char (di) == 'R'))
|
||||
{
|
||||
/* Just demangle a parameter placeholder as its type. */
|
||||
d_advance (di, 2);
|
||||
@ -2608,20 +2609,22 @@ d_expression (struct d_info *di)
|
||||
args = op->u.s_extended_operator.args;
|
||||
break;
|
||||
case DEMANGLE_COMPONENT_CAST:
|
||||
if (d_peek_char (di) == 'v')
|
||||
/* T() encoded as an operand of void. */
|
||||
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
||||
cplus_demangle_type (di));
|
||||
else
|
||||
args = 1;
|
||||
args = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (args)
|
||||
{
|
||||
case 1:
|
||||
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
||||
d_expression (di));
|
||||
{
|
||||
struct demangle_component *operand;
|
||||
if (op->type == DEMANGLE_COMPONENT_CAST)
|
||||
operand = d_exprlist (di);
|
||||
else
|
||||
operand = d_expression (di);
|
||||
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
||||
operand);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
struct demangle_component *left;
|
||||
@ -3763,8 +3766,14 @@ d_print_comp (struct d_print_info *dpi,
|
||||
d_print_comp (dpi, d_left (dc));
|
||||
if (d_right (dc) != NULL)
|
||||
{
|
||||
size_t len;
|
||||
d_append_string (dpi, ", ");
|
||||
len = dpi->len;
|
||||
d_print_comp (dpi, d_right (dc));
|
||||
/* If that didn't print anything (which can happen with empty
|
||||
template argument packs), remove the comma and space. */
|
||||
if (dpi->len == len)
|
||||
dpi->len -= 2;
|
||||
}
|
||||
return;
|
||||
|
||||
@ -3800,12 +3809,7 @@ d_print_comp (struct d_print_info *dpi,
|
||||
d_print_cast (dpi, d_left (dc));
|
||||
d_append_char (dpi, ')');
|
||||
}
|
||||
if (d_left (dc)->type == DEMANGLE_COMPONENT_CAST
|
||||
&& d_right (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
|
||||
/* type() -- FIXME what about type(multiple,args) */
|
||||
d_append_string (dpi, "()");
|
||||
else
|
||||
d_print_subexpr (dpi, d_right (dc));
|
||||
d_print_subexpr (dpi, d_right (dc));
|
||||
return;
|
||||
|
||||
case DEMANGLE_COMPONENT_BINARY:
|
||||
|
Loading…
Reference in New Issue
Block a user