diff options
author | obrien <obrien@FreeBSD.org> | 1999-10-16 06:09:09 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 1999-10-16 06:09:09 +0000 |
commit | cae8fa8120c70195f34a2456f18c4c848a2d3e0c (patch) | |
tree | f7d3a3ab9c32694206552e767626366f016f2062 /contrib/gcc/cp/method.c | |
parent | 84656b55b6e25e30322dc903a05de53706361d3d (diff) | |
download | FreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.zip FreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.tar.gz |
Virgin import of the GCC 2.95.1 compilers
Diffstat (limited to 'contrib/gcc/cp/method.c')
-rw-r--r-- | contrib/gcc/cp/method.c | 604 |
1 files changed, 321 insertions, 283 deletions
diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index 29b31c4..d4a667b 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -1,6 +1,6 @@ /* Handle the hair of processing (but not expanding) inline functions. Also manage function and variable name overloading. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -57,7 +57,8 @@ static char *scratch_firstobj; static void icat PROTO((HOST_WIDE_INT)); static void dicat PROTO((HOST_WIDE_INT, HOST_WIDE_INT)); -static void flush_repeats PROTO((int, tree)); +static int old_backref_index PROTO((tree)); +static int flush_repeats PROTO((int, tree)); static void build_overload_identifier PROTO((tree)); static void build_overload_nested_name PROTO((tree)); static void build_overload_int PROTO((tree, int)); @@ -71,8 +72,6 @@ static void process_overload_item PROTO((tree,int)); static void do_build_assign_ref PROTO((tree)); static void do_build_copy_constructor PROTO((tree)); static tree largest_union_member PROTO((tree)); -static tree build_decl_overload_real PROTO((tree, tree, tree, tree, - tree, int)); static void build_template_template_parm_names PROTO((tree)); static void build_template_parm_names PROTO((tree, tree)); static void build_underscore_int PROTO((int)); @@ -82,6 +81,9 @@ static int check_ktype PROTO((tree, int)); static int issue_ktype PROTO((tree)); static void build_overload_scope_ref PROTO((tree)); static void build_mangled_template_parm_index PROTO((char *, tree)); +#if HOST_BITS_PER_WIDE_INT >= 64 +static void build_mangled_C9x_name PROTO((int)); +#endif static int is_back_referenceable_type PROTO((tree)); static int check_btype PROTO((tree)); static void build_mangled_name_for_type PROTO((tree)); @@ -298,15 +300,48 @@ dicat (lo, hi) OB_PUTC ('0' + ulo); } -static __inline void +/* Returns the index of TYPE in the typevec, or -1 if it's not there. */ + +static __inline int +old_backref_index (type) + tree type; +{ + int tindex = 0; + + if (! is_back_referenceable_type (type)) + return -1; + + /* The entry for this parm is at maxtype-1, so don't look there for + something to repeat. */ + for (tindex = 0; tindex < maxtype - 1; ++tindex) + if (same_type_p (typevec[tindex], type)) + break; + + if (tindex == maxtype - 1) + return -1; + + return tindex; +} + +/* Old mangling style: If TYPE has already been used in the parameter list, + emit a backward reference and return non-zero; otherwise, return 0. + + NREPEATS is the number of repeats we've recorded of this type, or 0 if + this is the first time we've seen it and we're just looking to see if + it had been used before. */ + +static __inline int flush_repeats (nrepeats, type) int nrepeats; tree type; { - int tindex = 0; + int tindex = old_backref_index (type); - while (typevec[tindex] != type) - tindex++; + if (tindex == -1) + { + my_friendly_assert (nrepeats == 0, 990316); + return 0; + } if (nrepeats > 1) { @@ -320,25 +355,33 @@ flush_repeats (nrepeats, type) icat (tindex); if (tindex > 9) OB_PUTC ('_'); + + return 1; } /* Returns nonzero iff this is a type to which we will want to make back-references (using the `B' code). */ -int +static int is_back_referenceable_type (type) tree type; { - if (btypelist == NULL) - /* We're not generating any back-references. */ + /* For some reason, the Java folks don't want back refs on these. */ + if (TYPE_FOR_JAVA (type)) return 0; switch (TREE_CODE (type)) { + case BOOLEAN_TYPE: + if (!flag_do_squangling) + /* Even though the mangling of this is just `b', we did + historically generate back-references for it. */ + return 1; + /* Fall through. */ + case INTEGER_TYPE: case REAL_TYPE: case VOID_TYPE: - case BOOLEAN_TYPE: /* These types have single-character manglings, so there's no point in generating back-references. */ return 0; @@ -376,8 +419,10 @@ issue_nrepeats (nrepeats, type) } } -/* Check to see if a tree node has been entered into the Kcode typelist */ -/* if not, add it. Return -1 if it isn't found, otherwise return the index */ +/* Check to see if a tree node has been entered into the Kcode typelist. + If not, add it. Returns -1 if it isn't found, otherwise returns the + index. */ + static int check_ktype (node, add) tree node; @@ -394,10 +439,10 @@ check_ktype (node, add) for (x=0; x < maxktype; x++) { - if (localnode == ktypelist[x]) - return x ; + if (same_type_p (localnode, ktypelist[x])) + return x; } - /* Didn't find it, so add it here */ + /* Didn't find it, so add it here. */ if (add) { if (maxksize <= maxktype) @@ -625,20 +670,53 @@ build_mangled_template_parm_index (s, index) } +/* Mangling for C9X integer types (and Cygnus extensions for 128-bit + and other types) is based on the letter "I" followed by the hex + representations of the bitsize for the type in question. For + encodings that result in larger than two digits, a leading and + trailing underscore is added. + + Thus: + int1_t = 001 = I01 + int8_t = 008 = I08 + int16_t = 010 = I10 + int24_t = 018 = I18 + int32_t = 020 = I20 + int64_t = 040 = I40 + int80_t = 050 = I50 + int128_t = 080 = I80 + int256_t = 100 = I_100_ + int512_t = 200 = I_200_ + + Given an integer in decimal format, mangle according to this scheme. */ + +#if HOST_BITS_PER_WIDE_INT >= 64 +static void +build_mangled_C9x_name (bits) + int bits; +{ + char mangled[10] = ""; + + if (bits > 255) + sprintf (mangled, "I_%x_", bits); + else + sprintf (mangled, "I%.2x", bits); + + OB_PUTCP (mangled); +} +#endif + static void build_overload_value (type, value, in_template) tree type, value; int in_template; { + my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); + while (TREE_CODE (value) == NON_LVALUE_EXPR || TREE_CODE (value) == NOP_EXPR) value = TREE_OPERAND (value, 0); - if (TREE_CODE (type) == PARM_DECL) - type = TREE_TYPE (type); - - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); - if (numeric_output_need_bar) { OB_PUTC ('_'); @@ -651,21 +729,21 @@ build_overload_value (type, value, in_template) return; } - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (type)) { - /* Handle a pointer to data member as a template instantiation - parameter, boy, what fun! */ - type = integer_type_node; - if (TREE_CODE (value) != INTEGER_CST) - { - sorry ("unknown pointer to member constant"); - return; - } - } + if (TREE_CODE (value) != PTRMEM_CST) + /* We should have already rejected this pointer to member, + since it is not a constant. */ + my_friendly_abort (0); - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); + /* Get the actual FIELD_DECL. */ + value = PTRMEM_CST_MEMBER (value); + my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0); + + /* Output the name of the field. */ + build_overload_identifier (DECL_NAME (value)); + return; + } switch (TREE_CODE (type)) { @@ -743,46 +821,6 @@ build_overload_value (type, value, in_template) return; } case POINTER_TYPE: - if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE - && TREE_CODE (value) != ADDR_EXPR) - { - if (TREE_CODE (value) == CONSTRUCTOR) - { - /* This is dangerous code, crack built up pointer to members. */ - tree args = CONSTRUCTOR_ELTS (value); - tree a1 = TREE_VALUE (args); - tree a2 = TREE_VALUE (TREE_CHAIN (args)); - tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)))); - a3 = TREE_VALUE (a3); - STRIP_NOPS (a3); - if (TREE_CODE (a1) == INTEGER_CST - && TREE_CODE (a2) == INTEGER_CST) - { - build_overload_int (a1, in_template); - OB_PUTC ('_'); - build_overload_int (a2, in_template); - OB_PUTC ('_'); - if (TREE_CODE (a3) == ADDR_EXPR) - { - a3 = TREE_OPERAND (a3, 0); - if (TREE_CODE (a3) == FUNCTION_DECL) - { - numeric_output_need_bar = 0; - build_overload_identifier (DECL_ASSEMBLER_NAME (a3)); - return; - } - } - else if (TREE_CODE (a3) == INTEGER_CST) - { - OB_PUTC ('i'); - build_overload_int (a3, in_template); - return; - } - } - } - sorry ("template instantiation with pointer to method that is too complex"); - return; - } if (TREE_CODE (value) == INTEGER_CST) { build_overload_int (value, in_template); @@ -796,6 +834,10 @@ build_overload_value (type, value, in_template) } value = TREE_OPERAND (value, 0); + + /* Fall through. */ + + case REFERENCE_TYPE: if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); @@ -814,6 +856,51 @@ build_overload_value (type, value, in_template) my_friendly_abort (71); break; /* not really needed */ + case RECORD_TYPE: + { + tree delta; + tree idx; + tree pfn; + tree delta2; + + my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0); + + /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're + mangling, an instantiation of something like: + + template <class T, void (T::*fp)()> class C {}; + template <class T> C<T, &T::f> x(); + + We mangle the return type of the function, and that + contains template parameters. */ + if (TREE_CODE (value) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF) + { + build_overload_scope_ref (TREE_OPERAND (value, 0)); + break; + } + + my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0); + + expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2); + build_overload_int (delta, in_template); + OB_PUTC ('_'); + build_overload_int (idx, in_template); + OB_PUTC ('_'); + if (pfn) + { + numeric_output_need_bar = 0; + build_overload_identifier (DECL_ASSEMBLER_NAME + (PTRMEM_CST_MEMBER (value))); + } + else + { + OB_PUTC ('i'); + build_overload_int (delta2, in_template); + } + } + break; + default: sorry ("conversion of %s as template parameter", tree_code_name [(int) TREE_CODE (type)]); @@ -823,7 +910,7 @@ build_overload_value (type, value, in_template) /* Add encodings for the declaration of template template parameters. - PARMLIST must be a TREE_VEC */ + PARMLIST must be a TREE_VEC. */ static void build_template_template_parm_names (parmlist) @@ -864,13 +951,14 @@ build_template_parm_names (parmlist, arglist) tree arglist; { int i, nparms; - + tree inner_args = innermost_args (arglist); + nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); - tree arg = TREE_VEC_ELT (arglist, i); + tree arg = TREE_VEC_ELT (inner_args, i); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ @@ -879,9 +967,9 @@ build_template_parm_names (parmlist, arglist) } else if (TREE_CODE (parm) == TEMPLATE_DECL) { - /* This parameter is a template. */ + /* This parameter is a template. */ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - /* Output parameter declaration, argument index and level */ + /* Output parameter declaration, argument index and level. */ build_mangled_name_for_type (arg); else { @@ -889,17 +977,19 @@ build_template_parm_names (parmlist, arglist) and template name */ OB_PUTC ('z'); - build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); + build_template_template_parm_names + (DECL_INNERMOST_TEMPLATE_PARMS (parm)); icat (IDENTIFIER_LENGTH (DECL_NAME (arg))); OB_PUTID (DECL_NAME (arg)); } } else { - parm = tsubst (parm, arglist, NULL_TREE); + parm = tsubst (parm, arglist, /*complain=*/1, NULL_TREE); /* It's a PARM_DECL. */ build_mangled_name_for_type (TREE_TYPE (parm)); - build_overload_value (parm, arg, uses_template_parms (arglist)); + build_overload_value (TREE_TYPE (parm), arg, + uses_template_parms (arglist)); } } } @@ -912,7 +1002,7 @@ build_overload_identifier (name) tree name; { if (TREE_CODE (name) == TYPE_DECL - && IS_AGGR_TYPE (TREE_TYPE (name)) + && CLASS_TYPE_P (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE @@ -921,9 +1011,8 @@ build_overload_identifier (name) { /* NAME is the TYPE_DECL for a template specialization. */ tree template, parmlist, arglist, tname; - template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)); - arglist = innermost_args (TREE_VALUE (template), 0); - template = TREE_PURPOSE (template); + template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)); + arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name)); tname = DECL_NAME (template); parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); OB_PUTC ('t'); @@ -970,15 +1059,18 @@ build_qualified_name (decl) } context = decl; - /* if we can't find a Ktype, do it the hard way */ + /* If we can't find a Ktype, do it the hard way. */ if (check_ktype (context, FALSE) == -1) { - /* count type and namespace scopes */ - while (DECL_CONTEXT (context) && DECL_CONTEXT (context) != global_namespace) + /* Count type and namespace scopes. */ + while (1) { + context = CP_DECL_CONTEXT (context); + if (context == global_namespace) + break; i += 1; - context = DECL_CONTEXT (context); - if (check_ktype (context, FALSE) != -1) /* found it! */ + if (check_ktype (context, FALSE) != -1) + /* Found one! */ break; if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); @@ -998,14 +1090,13 @@ build_qualified_name (decl) non-zero, mangled names for structure/union types are intentionally mangled differently from the method described in the ARM. */ -void +static void build_mangled_name_for_type_with_Gcode (type, extra_Gcode) tree type; int extra_Gcode; { if (TYPE_PTRMEMFUNC_P (type)) type = TYPE_PTRMEMFUNC_FN_TYPE (type); - type = canonical_type_variant (type); process_modifiers (type); process_overload_item (type, extra_Gcode); } @@ -1013,7 +1104,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode) /* Like build_mangled_name_for_type_with_Gcode, but never outputs the `G'. */ -void +static void build_mangled_name_for_type (type) tree type; { @@ -1069,7 +1160,11 @@ build_mangled_name (parmtypes, begin, end) for (; parmtypes && parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { - tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes)); + /* We used to call canonical_type_variant here, but that isn't + good enough; it doesn't handle pointers to typedef types. So + we can't just set TREE_USED to say we've seen a type already; + we have to check each of the earlier types with same_type_p. */ + tree parmtype = TREE_VALUE (parmtypes); if (old_style_repeats) { @@ -1078,11 +1173,11 @@ build_mangled_name (parmtypes, begin, end) typevec[maxtype++] = parmtype; } - if (parmtype == last_type) + if (last_type && same_type_p (parmtype, last_type)) { if (flag_do_squangling - || (old_style_repeats && TREE_USED (parmtype) - && !TYPE_FOR_JAVA (parmtype))) + || (old_style_repeats + && is_back_referenceable_type (parmtype))) { /* The next type is the same as this one. Keep track of the repetition, and output the repeat @@ -1104,35 +1199,11 @@ build_mangled_name (parmtypes, begin, end) last_type = parmtype; - if (old_style_repeats) - { - if (nrepeats) - { - flush_repeats (nrepeats, last_type); - nrepeats = 0; - } - - if (TREE_USED (parmtype)) - { -#if 0 - /* We can turn this on at some point when we want - improved symbol mangling. */ - nrepeats++; -#else - /* This is bug compatible with 2.7.x */ - flush_repeats (nrepeats, parmtype); -#endif - nrepeats = 0; - continue; - } - - /* Only cache types which take more than one character. */ - if ((parmtype != TYPE_MAIN_VARIANT (parmtype) - || (TREE_CODE (parmtype) != INTEGER_TYPE - && TREE_CODE (parmtype) != REAL_TYPE)) - && ! TYPE_FOR_JAVA (parmtype)) - TREE_USED (parmtype) = 1; - } + /* Note that for bug-compatibility with 2.7.2, we can't build up + repeats of types other than the most recent one. So we call + flush_repeats every round, if we get this far. */ + if (old_style_repeats && flush_repeats (0, parmtype)) + continue; /* Output the PARMTYPE. */ build_mangled_name_for_type_with_Gcode (parmtype, 1); @@ -1159,27 +1230,37 @@ build_mangled_name (parmtypes, begin, end) return (char *)obstack_base (&scratch_obstack); } -/* handles emitting modifiers such as Constant, read-only, and volatile */ -void +/* Emit modifiers such as constant, read-only, and volatile. */ + +static void process_modifiers (parmtype) tree parmtype; { - if (TREE_READONLY (parmtype)) + /* Note that here we do not use CP_TYPE_CONST_P and friends because + we describe types recursively; we will get the `const' in + `const int ()[10]' when processing the `const int' part. */ + if (TYPE_READONLY (parmtype)) OB_PUTC ('C'); if (TREE_CODE (parmtype) == INTEGER_TYPE + && parmtype != char_type_node + && parmtype != wchar_type_node && (TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) && ! TYPE_FOR_JAVA (parmtype)) OB_PUTC ('U'); if (TYPE_VOLATILE (parmtype)) OB_PUTC ('V'); + /* It would be better to use `R' for `restrict', but that's already + used for reference types. And `r' is used for `long double'. */ + if (TYPE_RESTRICT (parmtype)) + OB_PUTC ('u'); } /* Check to see if TYPE has been entered into the Bcode typelist. If so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE to the list of back-referenceable types and return 0. */ -int +static int check_btype (type) tree type; { @@ -1191,12 +1272,8 @@ check_btype (type) if (!is_back_referenceable_type (type)) return 0; - /* We assume that our caller has put out any necessary - qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - for (x = 0; x < maxbtype; x++) - if (type == btypelist[x]) + if (same_type_p (type, btypelist[x])) { OB_PUTC ('B'); icat (x); @@ -1218,7 +1295,8 @@ check_btype (type) return 0; } -/* handle emitting the correct code for various node types */ +/* Emit the correct code for various node types. */ + static void process_overload_item (parmtype, extra_Gcode) tree parmtype; @@ -1226,9 +1304,17 @@ process_overload_item (parmtype, extra_Gcode) { numeric_output_need_bar = 0; - /* These tree types are considered modifiers for B code squangling , */ - /* and therefore should not get entries in the Btypelist */ - /* they are, however, repeatable types */ + /* Our caller should have already handed any qualifiers, so pull out the + TYPE_MAIN_VARIANT to avoid typedef confusion. Except we can't do that + for arrays, because they are transparent to qualifiers. Sigh. */ + if (TREE_CODE (parmtype) == ARRAY_TYPE) + parmtype = canonical_type_variant (parmtype); + else + parmtype = TYPE_MAIN_VARIANT (parmtype); + + /* These tree types are considered modifiers for B code squangling, + and therefore should not get entries in the Btypelist. They are, + however, repeatable types. */ switch (TREE_CODE (parmtype)) { @@ -1239,11 +1325,9 @@ process_overload_item (parmtype, extra_Gcode) case ARRAY_TYPE: #if PARM_CAN_BE_ARRAY_TYPE { - tree length; - OB_PUTC ('A'); if (TYPE_DOMAIN (parmtype) == NULL_TREE) - error("pointer/reference to array of unknown bound in parm type"); + OB_PUTC ('_'); else { tree length = array_type_nelts (parmtype); @@ -1331,7 +1415,6 @@ process_overload_item (parmtype, extra_Gcode) } case INTEGER_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == integer_type_node || parmtype == unsigned_type_node || parmtype == java_int_type_node) @@ -1359,15 +1442,18 @@ process_overload_item (parmtype, extra_Gcode) || parmtype == long_long_unsigned_type_node || parmtype == java_long_type_node) OB_PUTC ('x'); -#if 0 - /* it would seem there is no way to enter these in source code, - yet. (mrs) */ - else if (parmtype == long_long_long_integer_type_node - || parmtype == long_long_long_unsigned_type_node) - OB_PUTC ('q'); -#endif else if (parmtype == java_boolean_type_node) OB_PUTC ('b'); +#if HOST_BITS_PER_WIDE_INT >= 64 + else if (parmtype == intTI_type_node + || parmtype == unsigned_intTI_type_node) + { + /* Should just check a flag here instead of specific + *_type_nodes, because all C9x types could use this. */ + int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype)); + build_mangled_C9x_name (bits); + } +#endif else my_friendly_abort (73); break; @@ -1377,7 +1463,6 @@ process_overload_item (parmtype, extra_Gcode) break; case REAL_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == long_double_type_node) OB_PUTC ('r'); else if (parmtype == double_type_node @@ -1413,11 +1498,6 @@ process_overload_item (parmtype, extra_Gcode) { tree name = TYPE_NAME (parmtype); - if (TREE_CODE (name) == IDENTIFIER_NODE) - { - build_overload_identifier (TYPE_NAME (parmtype)); - break; - } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248); build_qualified_name (name); @@ -1432,14 +1512,14 @@ process_overload_item (parmtype, extra_Gcode) case TEMPLATE_TEMPLATE_PARM: /* Find and output the original template parameter declaration. */ - if (CLASSTYPE_TEMPLATE_INFO (parmtype)) + if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype)) { build_mangled_template_parm_index ("tzX", TEMPLATE_TYPE_PARM_INDEX (parmtype)); build_template_parm_names - (DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (parmtype)), - CLASSTYPE_TI_ARGS (parmtype)); + (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)), + TYPE_TI_ARGS (parmtype)); } else { @@ -1499,7 +1579,10 @@ build_static_name (context, name) return get_identifier ((char *)obstack_base (&scratch_obstack)); } -static tree +/* FOR_METHOD should be 1 if the declaration in question is for a member + of a class (including a static member) and 2 if the declaration is + for a constructor. */ +tree build_decl_overload_real (dname, parms, ret_type, tparms, targs, for_method) tree dname; @@ -1557,12 +1640,13 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, OB_PUTC ('v'); else { - if (!flag_do_squangling) /* Allocate typevec array. */ + if (!flag_do_squangling) { + /* Allocate typevec array. */ maxtype = 0; typevec_size = list_length (parms); if (!for_method && current_namespace != global_namespace) - /* the namespace of a global function needs one slot */ + /* The namespace of a global function needs one slot. */ typevec_size++; typevec = (tree *)alloca (typevec_size * sizeof (tree)); } @@ -1583,12 +1667,6 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, { my_friendly_assert (maxtype < typevec_size, 387); typevec[maxtype++] = this_type; - TREE_USED (this_type) = 1; - - /* By setting up PARMS in this way, the loop below will - automatically clear TREE_USED on THIS_TYPE. */ - parms = temp_tree_cons (NULL_TREE, this_type, - TREE_CHAIN (parms)); } if (TREE_CHAIN (parms)) @@ -1609,20 +1687,9 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, build_mangled_name (parms, 0, 0); } - if (!flag_do_squangling) /* Deallocate typevec array */ - { - tree t = parms; - typevec = NULL; - while (t) - { - tree temp = TREE_VALUE (t); - TREE_USED (temp) = 0; - /* clear out the type variant in case we used it */ - temp = canonical_type_variant (temp); - TREE_USED (temp) = 0; - t = TREE_CHAIN (t); - } - } + if (!flag_do_squangling) + /* Deallocate typevec array. */ + typevec = NULL; } if (ret_type != NULL_TREE && for_method != 2) @@ -1661,38 +1728,38 @@ build_decl_overload (dname, parms, for_method) NULL_TREE, for_method); } +/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */ -/* Like build_decl_overload, but for template functions. */ - -tree -build_template_decl_overload (decl, parms, ret_type, tparms, targs, - for_method) +void +set_mangled_name_for_decl (decl) tree decl; - tree parms; - tree ret_type; - tree tparms; - tree targs; - int for_method; { - tree res, saved_ctx; - - /* If the template is in a namespace, we need to put that into the - mangled name. Unfortunately, build_decl_overload_real does not - get the decl to mangle, so it relies on the current - namespace. Therefore, we set that here temporarily. */ + tree parm_types; - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 980702); - saved_ctx = current_namespace; - current_namespace = CP_DECL_CONTEXT (decl); + if (processing_template_decl) + /* There's no need to mangle the name of a template function. */ + return; - res = build_decl_overload_real (DECL_NAME (decl), parms, ret_type, - tparms, targs, for_method); + parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - current_namespace = saved_ctx; - return res; + if (DECL_STATIC_FUNCTION_P (decl)) + parm_types = + hash_tree_chain (build_pointer_type (DECL_CLASS_CONTEXT (decl)), + parm_types); + else + /* The only member functions whose type is a FUNCTION_TYPE, rather + than a METHOD_TYPE, should be static members. */ + my_friendly_assert (!DECL_CONTEXT (decl) + || !IS_AGGR_TYPE_CODE (TREE_CODE (DECL_CONTEXT (decl))) + || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE, + 0); + + DECL_ASSEMBLER_NAME (decl) + = build_decl_overload (DECL_NAME (decl), parm_types, + DECL_FUNCTION_MEMBER_P (decl) + + DECL_CONSTRUCTOR_P (decl)); } - /* Build an overload name for the type expression TYPE. */ tree @@ -1851,8 +1918,16 @@ hack_identifier (value, name) { if (current_class_ptr == NULL_TREE) { - error ("request for member `%s' in static member function", - IDENTIFIER_POINTER (DECL_NAME (value))); + if (current_function_decl + && DECL_STATIC_FUNCTION_P (current_function_decl)) + cp_error ("invalid use of member `%D' in static member function", + value); + else + /* We can get here when processing a bad default + argument, like: + struct S { int a; void f(int i = a); } */ + cp_error ("invalid use of member `%D'", value); + return error_mark_node; } TREE_USED (current_class_ptr) = 1; @@ -1863,24 +1938,24 @@ hack_identifier (value, name) TREE_USED (value) = 1; value = build_component_ref (current_class_ref, name, NULL_TREE, 1); } - else if (TREE_CODE (value) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (value)) - /* This is a placeholder; don't mark it used. */ - return value; - else if (really_overloaded_fn (value)) + else if ((TREE_CODE (value) == FUNCTION_DECL + && DECL_FUNCTION_MEMBER_P (value)) + || (TREE_CODE (value) == OVERLOAD + && DECL_FUNCTION_MEMBER_P (OVL_CURRENT (value)))) { -#if 0 - tree t = get_first_fn (value); - for (; t; t = DECL_CHAIN (t)) - { - if (TREE_CODE (t) == TEMPLATE_DECL) - continue; + tree decl; - assemble_external (t); - TREE_USED (t) = 1; - } -#endif + if (TREE_CODE (value) == OVERLOAD) + value = OVL_CURRENT (value); + + if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value))) + return value; + + decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0); + value = build_component_ref (decl, name, NULL_TREE, 1); } + else if (really_overloaded_fn (value)) + ; else if (TREE_CODE (value) == OVERLOAD) /* not really overloaded function */ mark_used (OVL_FUNCTION (value)); @@ -1907,7 +1982,8 @@ hack_identifier (value, name) else mark_used (value); - if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL) + if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL + || TREE_CODE (value) == RESULT_DECL) { tree context = decl_function_context (value); if (context != NULL_TREE && context != current_function_decl @@ -1926,44 +2002,27 @@ hack_identifier (value, name) if (DECL_LANG_SPECIFIC (value) && DECL_CLASS_CONTEXT (value) != current_class_type) { - tree path, access; + tree path; register tree context = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) ? DECL_CLASS_CONTEXT (value) : DECL_CONTEXT (value); get_base_distance (context, current_class_type, 0, &path); - if (path) - { - access = compute_access (path, value); - if (access != access_public_node) - { - if (TREE_CODE (value) == VAR_DECL) - error ("static member `%s' is %s", - IDENTIFIER_POINTER (name), - TREE_PRIVATE (value) ? "private" - : "from a private base class"); - else - error ("enum `%s' is from private base class", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - } + if (path && !enforce_access (current_class_type, value)) + return error_mark_node; } } - else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) + else if (TREE_CODE (value) == TREE_LIST + && TREE_TYPE (value) == error_mark_node) { - if (type == 0) - { - error ("request for member `%s' is ambiguous in multiple inheritance lattice", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - - return value; + error ("request for member `%s' is ambiguous in multiple inheritance lattice", + IDENTIFIER_POINTER (name)); + print_candidates (value); + return error_mark_node; } - if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl) + if (! processing_template_decl) value = convert_from_reference (value); return value; } @@ -2172,42 +2231,21 @@ do_build_copy_constructor (fndecl) tree binfos = TYPE_BINFO_BASETYPES (current_class_type); int i; + /* Initialize all the base-classes. */ for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; t = TREE_CHAIN (t)) - { - tree basetype = BINFO_TYPE (t); - tree p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - p = convert_from_reference (p); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } - + current_base_init_list + = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); for (i = 0; i < n_bases; ++i) { - tree p, basetype = TREE_VEC_ELT (binfos, i); - if (TREE_VIA_VIRTUAL (basetype)) + t = TREE_VEC_ELT (binfos, i); + if (TREE_VIA_VIRTUAL (t)) continue; - basetype = BINFO_TYPE (basetype); - p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - { - p = convert_from_reference (p); - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } + current_base_init_list + = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); } + for (; fields; fields = TREE_CHAIN (fields)) { tree init, t; @@ -2305,7 +2343,7 @@ do_build_assign_ref (fndecl) if (TREE_CODE (field) != FIELD_DECL) continue; - if (TREE_READONLY (field)) + if (CP_TYPE_CONST_P (TREE_TYPE (field))) { if (DECL_NAME (field)) cp_error ("non-static const member `%#D', can't use default assignment operator", field); |