cp-tree.h (DECL_PARM_LEVEL): New.
* cp-tree.h (DECL_PARM_LEVEL): New. (struct lang_decl_parm): Add level field. * name-lookup.c (function_parm_depth): New fn. * name-lookup.h: Declare it. * parser.c (cp_parser_parameter_declaration_list): Use it. * mangle.c (struct globals): Add parm_depth field. (write_bare_function_type): Adjust it. (write_expression): Include the level delta in PARM_DECL mangling for abi >= 6. * semantics.c (finish_decltype_type): Remove shortcut for decltype of id-expression. * mangle.c (write_type) [DECLTYPE_TYPE]: Strip it here for abi < 6. From-SVN: r170459
This commit is contained in:
parent
5a30f819c7
commit
67e18edbc6
15 changed files with 148 additions and 28 deletions
|
@ -1,3 +1,7 @@
|
|||
2011-02-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* common.opt (fabi-version): Document v5 and v6.
|
||||
|
||||
2011-02-23 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/47849
|
||||
|
|
|
@ -741,6 +741,12 @@ Driver Undocumented
|
|||
; 4: The version of the ABI that introduces unambiguous mangling of
|
||||
; vector types.
|
||||
;
|
||||
; 5: The version of the ABI that ignores attribute const/noreturn
|
||||
; in function pointer mangling.
|
||||
;
|
||||
; 6: The version of the ABI that corrects mangling of decltype and
|
||||
; function parameters used in other parameters and the return type.
|
||||
;
|
||||
; Additional positive integers will be assigned as new versions of
|
||||
; the ABI become the default version of the ABI.
|
||||
fabi-version=
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
2011-02-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-tree.h (DECL_PARM_LEVEL): New.
|
||||
(struct lang_decl_parm): Add level field.
|
||||
* name-lookup.c (function_parm_depth): New fn.
|
||||
* name-lookup.h: Declare it.
|
||||
* parser.c (cp_parser_parameter_declaration_list): Use it.
|
||||
* mangle.c (struct globals): Add parm_depth field.
|
||||
(write_bare_function_type): Adjust it.
|
||||
(write_expression): Include the level delta in PARM_DECL mangling
|
||||
for abi >= 6.
|
||||
|
||||
* semantics.c (finish_decltype_type): Remove shortcut for decltype
|
||||
of id-expression.
|
||||
* mangle.c (write_type) [DECLTYPE_TYPE]: Strip it here for abi < 6.
|
||||
|
||||
2011-02-23 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
PR c++/46868
|
||||
|
|
|
@ -1914,6 +1914,7 @@ struct GTY(()) lang_decl_ns {
|
|||
|
||||
struct GTY(()) lang_decl_parm {
|
||||
struct lang_decl_base base;
|
||||
int level;
|
||||
int index;
|
||||
};
|
||||
|
||||
|
@ -2108,6 +2109,13 @@ struct GTY((variable_size)) lang_decl {
|
|||
#define DECL_PARM_INDEX(NODE) \
|
||||
(LANG_DECL_PARM_CHECK (NODE)->index)
|
||||
|
||||
/* The level of a user-declared parameter in its function, starting at 1.
|
||||
A parameter of the function will have level 1; a parameter of the first
|
||||
nested function declarator (i.e. t in void f (void (*p)(T t))) will have
|
||||
level 2. */
|
||||
#define DECL_PARM_LEVEL(NODE) \
|
||||
(LANG_DECL_PARM_CHECK (NODE)->level)
|
||||
|
||||
/* Nonzero if the VTT parm has been added to NODE. */
|
||||
#define DECL_HAS_VTT_PARM_P(NODE) \
|
||||
(LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
|
||||
|
|
|
@ -96,6 +96,9 @@ typedef struct GTY(()) globals {
|
|||
/* The entity that is being mangled. */
|
||||
tree GTY ((skip)) entity;
|
||||
|
||||
/* How many parameter scopes we are inside. */
|
||||
int parm_depth;
|
||||
|
||||
/* True if the mangling will be different in a future version of the
|
||||
ABI. */
|
||||
bool need_abi_warning;
|
||||
|
@ -1931,6 +1934,35 @@ write_type (tree type)
|
|||
gcc_assert (!DECLTYPE_FOR_LAMBDA_CAPTURE (type)
|
||||
&& !DECLTYPE_FOR_LAMBDA_RETURN (type));
|
||||
|
||||
/* In ABI <6, we stripped decltype of a plain decl. */
|
||||
if (!abi_version_at_least (6)
|
||||
&& DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
|
||||
{
|
||||
tree expr = DECLTYPE_TYPE_EXPR (type);
|
||||
tree etype = NULL_TREE;
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case VAR_DECL:
|
||||
case PARM_DECL:
|
||||
case RESULT_DECL:
|
||||
case FUNCTION_DECL:
|
||||
case CONST_DECL:
|
||||
case TEMPLATE_PARM_INDEX:
|
||||
etype = TREE_TYPE (expr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (etype && !type_uses_auto (etype))
|
||||
{
|
||||
G.need_abi_warning = 1;
|
||||
write_type (etype);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
write_char ('D');
|
||||
if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
|
||||
write_char ('t');
|
||||
|
@ -2270,9 +2302,11 @@ write_bare_function_type (const tree type, const int include_return_type_p,
|
|||
write_type (TREE_TYPE (type));
|
||||
|
||||
/* Now mangle the types of the arguments. */
|
||||
++G.parm_depth;
|
||||
write_method_parms (TYPE_ARG_TYPES (type),
|
||||
TREE_CODE (type) == METHOD_TYPE,
|
||||
decl);
|
||||
--G.parm_depth;
|
||||
}
|
||||
|
||||
/* Write the mangled representation of a method parameter list of
|
||||
|
@ -2458,8 +2492,28 @@ write_expression (tree expr)
|
|||
{
|
||||
/* A function parameter used in a late-specified return type. */
|
||||
int index = DECL_PARM_INDEX (expr);
|
||||
int level = DECL_PARM_LEVEL (expr);
|
||||
int delta = G.parm_depth - level + 1;
|
||||
gcc_assert (index >= 1);
|
||||
write_string ("fp");
|
||||
write_char ('f');
|
||||
if (delta != 0)
|
||||
{
|
||||
if (abi_version_at_least (6))
|
||||
{
|
||||
/* Let L be the number of function prototype scopes from the
|
||||
innermost one (in which the parameter reference occurs) up
|
||||
to (and including) the one containing the declaration of
|
||||
the referenced parameter. If the parameter declaration
|
||||
clause of the innermost function prototype scope has been
|
||||
completely seen, it is not counted (in that case -- which
|
||||
is perhaps the most common -- L can be zero). */
|
||||
write_char ('L');
|
||||
write_unsigned_number (delta - 1);
|
||||
}
|
||||
else
|
||||
G.need_abi_warning = true;
|
||||
}
|
||||
write_char ('p');
|
||||
write_compact_number (index - 1);
|
||||
}
|
||||
else if (DECL_P (expr))
|
||||
|
|
|
@ -1635,6 +1635,22 @@ getdecls (void)
|
|||
return current_binding_level->names;
|
||||
}
|
||||
|
||||
/* Return how many function prototypes we are currently nested inside. */
|
||||
|
||||
int
|
||||
function_parm_depth (void)
|
||||
{
|
||||
int level = 0;
|
||||
struct cp_binding_level *b;
|
||||
|
||||
for (b = current_binding_level;
|
||||
b->kind == sk_function_parms;
|
||||
b = b->level_chain)
|
||||
++level;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/* For debugging. */
|
||||
static int no_print_functions = 0;
|
||||
static int no_print_builtins = 0;
|
||||
|
|
|
@ -333,6 +333,7 @@ extern bool pushdecl_class_level (tree);
|
|||
extern tree pushdecl_namespace_level (tree, bool);
|
||||
extern bool push_class_level_binding (tree, tree);
|
||||
extern tree getdecls (void);
|
||||
extern int function_parm_depth (void);
|
||||
extern tree cp_namespace_decls (tree);
|
||||
extern void set_decl_namespace (tree, tree, bool);
|
||||
extern void push_decl_namespace (tree);
|
||||
|
|
|
@ -15942,6 +15942,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
|
|||
{
|
||||
retrofit_lang_decl (decl);
|
||||
DECL_PARM_INDEX (decl) = ++index;
|
||||
DECL_PARM_LEVEL (decl) = function_parm_depth ();
|
||||
}
|
||||
|
||||
/* Add the new parameter to the list. */
|
||||
|
|
|
@ -4772,6 +4772,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* FIXME instantiation-dependent */
|
||||
if (type_dependent_expression_p (expr)
|
||||
/* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
|
||||
if it isn't dependent, so that we can check access control at
|
||||
|
@ -4780,27 +4781,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
|
|||
&& processing_template_decl
|
||||
&& TREE_CODE (expr) == COMPONENT_REF))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (type && !type_uses_auto (type))
|
||||
return type;
|
||||
|
||||
treat_as_dependent:
|
||||
type = cxx_make_type (DECLTYPE_TYPE);
|
||||
DECLTYPE_TYPE_EXPR (type) = expr;
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2011-02-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/abi/mangle39.C: Adjust parm mangling.
|
||||
* g++.dg/abi/mangle45.C: New.
|
||||
|
||||
* g++.dg/cpp0x/trailing1.C: Mangle decltype.
|
||||
* g++.dg/template/canon-type-9.C: Match use of decltype
|
||||
between declaration and definition.
|
||||
* g++.dg/template/canon-type-12.C: Likewise.
|
||||
|
||||
2011-02-23 Mikael Morin <mikael@gcc.gnu.org>
|
||||
|
||||
PR fortran/40850
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// PR c++/42338
|
||||
// { dg-options "-std=c++0x" }
|
||||
// { dg-final { scan-assembler "_Z1fIPiEDTcmppfp_Li0EET_" } }
|
||||
// { dg-final { scan-assembler "_Z1gIiEvRK1AIT_EDTixfp_Li0EE" } }
|
||||
// { dg-final { scan-assembler "_Z1gIiEvRK1AIT_EDTixfL0p_Li0EE" } }
|
||||
|
||||
template<typename T>
|
||||
auto f(T t) -> decltype(++t, 0)
|
||||
|
|
25
gcc/testsuite/g++.dg/abi/mangle45.C
Normal file
25
gcc/testsuite/g++.dg/abi/mangle45.C
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Testcase for mangling of parameters used other than in a trailing return type
|
||||
// { dg-options -std=c++0x }
|
||||
|
||||
template<class T> void f(T p, decltype(p)) { } // L = 1
|
||||
template<class T> void g(T p, decltype(p) (*)()) { } // L = 1
|
||||
// G++ incorrectly rejects these currently.
|
||||
// template<class T> void h(T p, auto (*)()->decltype(p)); // L = 1
|
||||
// template<class T> void i(T p, auto (*)(T q)->decltype(q)); // L = 0
|
||||
// template<class T> void j(T p, auto (*)(decltype(p))->T); // L = 2
|
||||
template<class T> void k(T p, int (*(*)(T* p))[sizeof(p)]) {} // L = 1
|
||||
|
||||
int garg();
|
||||
int (*karg (int*))[sizeof(int)];
|
||||
int main()
|
||||
{
|
||||
// { dg-final { scan-assembler "_Z1fIiEvT_DtfL0p_E" } }
|
||||
f (1,0);
|
||||
// { dg-final { scan-assembler "_Z1gIiEvT_PFDtfL0p_EvE" } }
|
||||
g (1,garg);
|
||||
// h (1,0);
|
||||
// i (1,0);
|
||||
// j (1,0);
|
||||
// { dg-final { scan-assembler "_Z1kIiEvT_PFPAszfL0p__iPS0_E" } }
|
||||
k (1,karg);
|
||||
}
|
|
@ -78,7 +78,6 @@ 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)
|
||||
{
|
||||
|
@ -111,8 +110,8 @@ int main()
|
|||
h(a,1.0);
|
||||
// { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtfp_srNT0_1BIT1_EE3MEMET_S4_S6_" } }
|
||||
k( C(), A<int>(), D() );
|
||||
// { dg-final { scan-assembler "_Z1lIiET_S0_" } }
|
||||
// { dg-final { scan-assembler "_Z1lIiEDtfp_ET_" } }
|
||||
l(1);
|
||||
// { dg-final { scan-assembler "_Z1mIiLi1EET_S0_" } }
|
||||
// { dg-final { scan-assembler "_Z1mIiLi1EEDtT0_ET_" } }
|
||||
m<int,1>(1);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ struct S
|
|||
|
||||
template<class T, T t>
|
||||
void
|
||||
S<T, t>::foo(T)
|
||||
S<T, t>::foo(decltype(t))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ struct S
|
|||
};
|
||||
|
||||
template<class T, T *u>
|
||||
T* S<T, u>::foo(T)
|
||||
decltype(u) S<T, u>::foo(T)
|
||||
{
|
||||
T t;
|
||||
return t;
|
||||
|
|
Loading…
Add table
Reference in a new issue