diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 22 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 23 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 75 | ||||
-rw-r--r-- | gcc/cp/operators.def | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 30 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto12.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto6.C | 16 |
12 files changed, 136 insertions, 71 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a925c5d..1f5dd9d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2009-03-17 Jason Merrill <jason@redhat.com> + + * decl.c (grokfndecl): Set DECL_CONTEXT on parms. + (duplicate_decls): Adjust DECL_CONTEXT of newdecl's parms. + * pt.c (check_explicit_specialization): Likewise. + (tsubst_copy) [PARM_DECL]: Return a dummy parm if we don't have a + local specialization. + * tree.c (cp_tree_equal) [PARM_DECL]: Check type and index, not name. + * decl2.c (parm_index): New fn. + * semantics.c (finish_decltype_type): Don't use describable_type. + * mangle.c (write_expression): Likewise. Mangle ALIGNOF_EXPR. + Give a sorry for unsupported codes rather than crash. Mangle + conversions with other than 1 operand. New mangling for PARM_DECL. + * operators.def (ALIGNOF_EXPR): Mangle as "az". + 2009-03-17 Jing Yu <jingyu@google.com> PR middle-end/39378 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0b1d7c6..1745ede 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4436,6 +4436,7 @@ extern bool decl_needed_p (tree); extern void note_vague_linkage_fn (tree); extern tree build_artificial_parm (tree, tree); extern bool possibly_inlined_p (tree); +extern int parm_index (tree); /* in error.c */ extern void init_error (void); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 03e65d0..9a6ab02 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1684,8 +1684,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) = DECL_SOURCE_LOCATION (newdecl); DECL_INITIAL (old_result) = DECL_INITIAL (new_result); if (DECL_FUNCTION_TEMPLATE_P (newdecl)) - DECL_ARGUMENTS (old_result) - = DECL_ARGUMENTS (new_result); + { + tree parm; + DECL_ARGUMENTS (old_result) + = DECL_ARGUMENTS (new_result); + for (parm = DECL_ARGUMENTS (old_result); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = old_result; + } } return olddecl; @@ -1918,6 +1924,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (TREE_CODE (newdecl) == FUNCTION_DECL) { + tree parm; + if (DECL_TEMPLATE_INSTANTIATION (olddecl) && !DECL_TEMPLATE_INSTANTIATION (newdecl)) { @@ -1974,6 +1982,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) /* Preserve abstractness on cloned [cd]tors. */ DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl); + /* Update newdecl's parms to point at olddecl. */ + for (parm = DECL_ARGUMENTS (newdecl); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = olddecl; + if (! types_match) { SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl)); @@ -2006,7 +2019,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) } DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - /* Don't clear out the arguments if we're redefining a function. */ + /* Don't clear out the arguments if we're just redeclaring a + function. */ if (DECL_ARGUMENTS (olddecl)) DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); } @@ -6555,6 +6569,8 @@ grokfndecl (tree ctype, parms = parm; } DECL_ARGUMENTS (decl) = parms; + for (t = parms; t; t = TREE_CHAIN (t)) + DECL_CONTEXT (t) = decl; /* Propagate volatile out from type to decl. */ if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d570150..deba8b4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3907,4 +3907,27 @@ mark_used (tree decl) processing_template_decl = saved_processing_template_decl; } +/* Given function PARM_DECL PARM, return its index in the function's list + of parameters, beginning with 1. */ + +int +parm_index (tree parm) +{ + int index; + tree arg; + + for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm)); + arg; + ++index, arg = TREE_CHAIN (arg)) + { + if (DECL_NAME (parm) == DECL_NAME (arg)) + break; + if (DECL_ARTIFICIAL (arg)) + --index; + } + + gcc_assert (arg); + return index; +} + #include "gt-cp-decl2.h" diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c72747c..eabab7f 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2143,27 +2143,6 @@ write_expression (tree expr) { enum tree_code 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 type. */ @@ -2210,10 +2189,12 @@ write_expression (tree expr) write_template_arg_literal (expr); else if (code == PARM_DECL) { - /* A function parameter used under decltype in a late-specified - return type. Represented with a type placeholder. */ - write_string ("sT"); - write_type (non_reference (TREE_TYPE (expr))); + /* A function parameter used in a late-specified return type. */ + int index = parm_index (expr); + write_string ("fp"); + if (index > 1) + write_unsigned_number (index - 2); + write_char ('_'); } else if (DECL_P (expr)) { @@ -2231,6 +2212,12 @@ write_expression (tree expr) write_string ("st"); write_type (TREE_OPERAND (expr, 0)); } + else if (TREE_CODE (expr) == ALIGNOF_EXPR + && TYPE_P (TREE_OPERAND (expr, 0))) + { + write_string ("at"); + write_type (TREE_OPERAND (expr, 0)); + } else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF) { tree scope = TREE_OPERAND (expr, 0); @@ -2298,9 +2285,16 @@ write_expression (tree expr) write_template_args (template_args); } } + else if (TREE_CODE (expr) == INDIRECT_REF + && TREE_TYPE (TREE_OPERAND (expr, 0)) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE) + { + write_expression (TREE_OPERAND (expr, 0)); + } else { int i; + const char *name; /* When we bind a variable or function to a non-type template argument with reference type, we create an ADDR_EXPR to show @@ -2338,7 +2332,14 @@ write_expression (tree expr) } /* If it wasn't any of those, recursively expand the expression. */ - write_string (operator_name_info[(int) code].mangled_name); + name = operator_name_info[(int) code].mangled_name; + if (name == NULL) + { + sorry ("mangling %C", code); + return; + } + else + write_string (name); switch (code) { @@ -2351,23 +2352,29 @@ write_expression (tree expr) case CAST_EXPR: write_type (TREE_TYPE (expr)); - /* There is no way to mangle a zero-operand cast like - "T()". */ - if (!TREE_OPERAND (expr, 0)) - sorry ("zero-operand casts cannot be mangled due to a defect " - "in the C++ ABI"); - else if (list_length (TREE_OPERAND (expr, 0)) > 1) - sorry ("mangling function-style cast with more than one argument"); - else + if (list_length (TREE_OPERAND (expr, 0)) == 1) write_expression (TREE_VALUE (TREE_OPERAND (expr, 0))); + else + { + tree args = TREE_OPERAND (expr, 0); + write_char ('_'); + for (; args; args = TREE_CHAIN (args)) + write_expression (TREE_VALUE (args)); + write_char ('E'); + } break; + /* FIXME these should have a distinct mangling. */ case STATIC_CAST_EXPR: case CONST_CAST_EXPR: write_type (TREE_TYPE (expr)); write_expression (TREE_OPERAND (expr, 0)); break; + case NEW_EXPR: + sorry ("mangling new-expression"); + break; + /* Handle pointers-to-members specially. */ case SCOPE_REF: write_type (TREE_OPERAND (expr, 0)); diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index 698f0de4..20d811b 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -94,7 +94,7 @@ DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", 1) DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1) DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1) /* These are extensions. */ -DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "v17alignof", 1) +DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", 1) DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1) DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8ae4ed5..62a7b88 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2217,17 +2217,21 @@ check_explicit_specialization (tree declarator, the specialization of it. */ if (tsk == tsk_template) { + tree result = DECL_TEMPLATE_RESULT (tmpl); SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); - DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE; + DECL_INITIAL (result) = NULL_TREE; if (have_def) { + tree parm; DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); - DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl)) + DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (decl); /* We want to use the argument list specified in the definition, not in the original declaration. */ - DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl)) - = DECL_ARGUMENTS (decl); + DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl); + for (parm = DECL_ARGUMENTS (result); parm; + parm = TREE_CHAIN (parm)) + DECL_CONTEXT (parm) = result; } return tmpl; } @@ -9898,16 +9902,14 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (r == NULL) { /* This can happen for a parameter name used later in a function - declaration (such as in a late-specified return type). - Replace it with an arbitrary expression with the same type - (*(T*)0). This should only occur in an unevaluated context - (i.e. decltype). */ - gcc_assert (skip_evaluation); - r = non_reference (TREE_TYPE (t)); - r = tsubst (r, args, complain, in_decl); - r = build_pointer_type (r); - r = build_c_cast (r, null_node); - return cp_build_indirect_ref (r, NULL, tf_warning_or_error); + declaration (such as in a late-specified return type). Just + make a dummy decl, since it's only used for its type. */ + gcc_assert (skip_evaluation); + r = tsubst_decl (t, args, complain); + /* Give it the template pattern as its context; its true context + hasn't been instantiated yet and this is good enough for + mangling. */ + DECL_CONTEXT (r) = DECL_CONTEXT (t); } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 82a6797..c728970 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4585,8 +4585,6 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p) break; } } - else - type = describable_type (expr); if (type && !type_uses_auto (type)) return type; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 82f3b89..2287f11 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1881,9 +1881,8 @@ cp_tree_equal (tree t1, tree t2) 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)) + if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) + && parm_index (t1) == parm_index (t2)) return true; else return false; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2352594..b59350c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-03-17 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/auto6.C, auto12.C: Update mangling. + 2009-03-17 Paolo Carlini <paolo.carlini@oracle.com> PR c++/39475 diff --git a/gcc/testsuite/g++.dg/cpp0x/auto12.C b/gcc/testsuite/g++.dg/cpp0x/auto12.C index 437088d..45ceedf 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto12.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto12.C @@ -37,16 +37,16 @@ auto A<T>::f(U u) -> decltype (u + i) int main() { - // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplsTT_sTiES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } } A<int>().f(1); - // { dg-final { scan-assembler "_ZN1AIiE2frIiEEDTplsTT_sTiES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE2frIiEEDTplfp_L_ZNS0_2irEEET_" } } A<int>().fr(1); - // { dg-final { scan-assembler "_ZN1AIiE3frrIiEEDTplsTT_sTiES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE3frrIiEEDTplfp_L_ZNS0_3irrEEET_" } } A<int>().frr(1); - // { dg-final { scan-assembler "_ZN1AIiE1gIiEEDTplsTT_sR.ES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE1gIiEEDTplfp_szL_ZNS0_1iEEET_" } } A<int>().g(1); - // { dg-final { scan-assembler "_ZN1AIiE1hIiEEDTplsTT_sr1BIS2_E1iES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE1hIiEEDTplfp_sr1BIT_E1iES3_" } } A<int>().h(1); - // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplsTT_sRiES2_" } } + // { dg-final { scan-assembler "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } } A<int>().j(1); } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto6.C b/gcc/testsuite/g++.dg/cpp0x/auto6.C index 7d659c7..dfd6a20 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto6.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto6.C @@ -95,21 +95,21 @@ A<int> a, *p; int main() { - // { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } } + // { dg-final { scan-assembler "_Z3addIidEDTplfp_fp0_ET_T0_" } } auto i = add(1, 2.0); - // { dg-final { scan-assembler "_Z4add4IidEDTplsTT_sTT0_ES0_S1_" } } + // { dg-final { scan-assembler "_Z4add4IidEDTpldecvPT_Li0EdecvPT0_Li0EES0_S2_" } } auto i4 = add4(1, 2.0); - // { dg-final { scan-assembler "_Z4add2IidEDTplsRT_sRT0_ES0_S1_" } } + // { dg-final { scan-assembler "_Z4add2IidEDTplcvT__EcvT0__EES0_S1_" } } auto i2 = add2(1, 2.0); - // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } } + // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEfp_fp0_EET_T0_" } } auto i3 = add3(1, 2.0); - // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptsTPT_1fEES3_" } } + // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptfp_1fEEPT_" } } f(p); - // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtsTT_1fEES2_" } } + // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtfp_1fEET_" } } g(a); - // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_" } } + // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_" } } h(a,1.0); - // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } } + // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtfp_srNT0_1BIT1_EE3MEMET_S4_S6_" } } k( C(), A<int>(), D() ); // { dg-final { scan-assembler "_Z1lIiET_S0_" } } l(1); |