Commit 858a0ff1 by Mark Mitchell Committed by Mark Mitchell

method.c (PARM_CAN_BE_ARRAY_TYPE): Remove.

	* method.c (PARM_CAN_BE_ARRAY_TYPE): Remove.
	(mangling_flags): New type.
	(build_overload_int): Change prototype.
	(build_overload_value): Likewise.
	(numeric_output_need_bar): Improve comment.
	(mangle_expression): New function, broken out from ...
	(build_overload_int): Here.
	(build_overload_value): Adjust for use of mangling flags.  Don't
	warn about real-valued template parameters here.  Do handle
	complex expressions involving real-valued template parameters.
	(build_template_parm_names): Encase non-type template parameters
	in underscores, if necessary.
	(process_overload_item): Remove conditional on
	PARM_CAN_BE_ARRAY_TYPE.

From-SVN: r30090
parent 9ce71c6f
1999-10-19 Mark Mitchell <mark@codesourcery.com>
* method.c (PARM_CAN_BE_ARRAY_TYPE): Remove.
(mangling_flags): New type.
(build_overload_int): Change prototype.
(build_overload_value): Likewise.
(numeric_output_need_bar): Improve comment.
(mangle_expression): New function, broken out from ...
(build_overload_int): Here.
(build_overload_value): Adjust for use of mangling flags. Don't
warn about real-valued template parameters here. Do handle
complex expressions involving real-valued template parameters.
(build_template_parm_names): Encase non-type template parameters
in underscores, if necessary.
(process_overload_item): Remove conditional on
PARM_CAN_BE_ARRAY_TYPE.
1999-10-17 Mark Mitchell <mark@codesourcery.com> 1999-10-17 Mark Mitchell <mark@codesourcery.com>
* dump.c (dequeue_and_dump): Handle CLEANUP_POINT_EXPR. * dump.c (dequeue_and_dump): Handle CLEANUP_POINT_EXPR.
......
*** Changes in GCC 3.0: *** Changes in GCC 3.0:
* In some obscure cases, functions with the same type could have the
same mangled name. This bug caused compiler crashes, link-time clashes,
and debugger crahses. Fixing this bug required breaking ABI
compatibility for the functions involved. The functions in questions
are those whose types involve non-type template arguments whose
mangled representations require more than one digit.
* Support for assignment to `this' has been removed. This idiom * Support for assignment to `this' has been removed. This idiom
was used in the very early days of C++, before users were allowed was used in the very early days of C++, before users were allowed
to overload `operator new'; it is no longer allowed by the C++ to overload `operator new'; it is no longer allowed by the C++
......
...@@ -25,10 +25,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -25,10 +25,6 @@ Boston, MA 02111-1307, USA. */
#define __inline #define __inline
#endif #endif
#ifndef PARM_CAN_BE_ARRAY_TYPE
#define PARM_CAN_BE_ARRAY_TYPE 1
#endif
/* Handle method declarations. */ /* Handle method declarations. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
...@@ -44,6 +40,24 @@ Boston, MA 02111-1307, USA. */ ...@@ -44,6 +40,24 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h" #include "ggc.h"
#include "tm_p.h" #include "tm_p.h"
/* Various flags to control the mangling process. */
enum mangling_flags
{
/* No flags. */
mf_none = 0,
/* The thing we are presently mangling is part of a template type,
rather than a fully instantiated type. Therefore, we may see
complex expressions where we would normally expect to see a
simple integer constant. */
mf_maybe_uninstantiated = 1,
/* When mangling a numeric value, use the form `_XX_' (instead of
just `XX') if the value has more than one digit. */
mf_use_underscores_around_value = 2,
};
typedef enum mangling_flags mangling_flags;
/* TREE_LIST of the current inline functions that need to be /* TREE_LIST of the current inline functions that need to be
processed. */ processed. */
struct pending_inline *pending_inlines; struct pending_inline *pending_inlines;
...@@ -61,10 +75,11 @@ static int old_backref_index PROTO((tree)); ...@@ -61,10 +75,11 @@ static int old_backref_index PROTO((tree));
static int flush_repeats PROTO((int, tree)); static int flush_repeats PROTO((int, tree));
static void build_overload_identifier PROTO((tree)); static void build_overload_identifier PROTO((tree));
static void build_overload_nested_name PROTO((tree)); static void build_overload_nested_name PROTO((tree));
static void build_overload_int PROTO((tree, int)); static void mangle_expression PROTO((tree));
static void build_overload_int PROTO((tree, mangling_flags));
static void build_overload_identifier PROTO((tree)); static void build_overload_identifier PROTO((tree));
static void build_qualified_name PROTO((tree)); static void build_qualified_name PROTO((tree));
static void build_overload_value PROTO((tree, tree, int)); static void build_overload_value PROTO((tree, tree, mangling_flags));
static void issue_nrepeats PROTO((int, tree)); static void issue_nrepeats PROTO((int, tree));
static char *build_mangled_name PROTO((tree,int,int)); static char *build_mangled_name PROTO((tree,int,int));
static void process_modifiers PROTO((tree)); static void process_modifiers PROTO((tree));
...@@ -197,8 +212,8 @@ do_inline_function_hair (type, friend_list) ...@@ -197,8 +212,8 @@ do_inline_function_hair (type, friend_list)
/* Nonzero if we should not try folding parameter types. */ /* Nonzero if we should not try folding parameter types. */
static int nofold; static int nofold;
/* This appears to be set to true if an underscore is required to be /* Nonzero if an underscore is required before adding a digit to the
comcatenated before another number can be outputed. */ mangled name currently being built. */
static int numeric_output_need_bar; static int numeric_output_need_bar;
static __inline void static __inline void
...@@ -546,15 +561,15 @@ build_overload_scope_ref (value) ...@@ -546,15 +561,15 @@ build_overload_scope_ref (value)
build_overload_identifier (TREE_OPERAND (value, 1)); build_overload_identifier (TREE_OPERAND (value, 1));
} }
/* Encoding for an INTEGER_CST value. */ /* VALUE is a complex expression. Produce an appropriate mangling.
(We are forced to mangle complex expressions when dealing with
templates, and an expression involving template parameters appears
in the type of a function parameter.) */
static void static void
build_overload_int (value, in_template) mangle_expression (value)
tree value; tree value;
int in_template;
{ {
if (in_template && TREE_CODE (value) != INTEGER_CST)
{
if (TREE_CODE (value) == SCOPE_REF) if (TREE_CODE (value) == SCOPE_REF)
{ {
build_overload_scope_ref (value); build_overload_scope_ref (value);
...@@ -603,12 +618,10 @@ build_overload_int (value, in_template) ...@@ -603,12 +618,10 @@ build_overload_int (value, in_template)
template <class T> void f(A<sizeof(T)>); */ template <class T> void f(A<sizeof(T)>); */
build_mangled_name_for_type (operand); build_mangled_name_for_type (operand);
else if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc)))
build_overload_int (operand, in_template);
else else
build_overload_value (TREE_TYPE (operand), build_overload_value (TREE_TYPE (operand),
operand, operand,
in_template); mf_maybe_uninstantiated);
} }
} }
else else
...@@ -625,24 +638,63 @@ build_overload_int (value, in_template) ...@@ -625,24 +638,63 @@ build_overload_int (value, in_template)
OB_PUTC ('W'); OB_PUTC ('W');
numeric_output_need_bar = 0; numeric_output_need_bar = 0;
}
/* Encoding for an INTEGER_CST value. */
static void
build_overload_int (value, flags)
tree value;
mangling_flags flags;
{
int multiple_words_p = 0;
int multiple_digits_p = 0;
if ((flags & mf_maybe_uninstantiated) && TREE_CODE (value) != INTEGER_CST)
{
mangle_expression (value);
return; return;
} }
/* Unless we were looking at an uninstantiated template, integers
should always be represented by constants. */
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
{ /* If the high-order word is not merely a sign-extension of the
low-order word, we must use a special output routine that can
deal with this. */
if (TREE_INT_CST_HIGH (value) if (TREE_INT_CST_HIGH (value)
!= (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
{ {
/* need to print a DImode value in decimal */ multiple_words_p = 1;
dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value)); /* And there is certainly going to be more than one digit. */
numeric_output_need_bar = 1; multiple_digits_p = 1;
return;
}
/* else fall through to print in smaller mode */
} }
/* Wordsize or smaller */ else
multiple_digits_p = (TREE_INT_CST_LOW (value) > 9
|| TREE_INT_CST_LOW (value) < -9);
/* If necessary, add a leading underscore. */
if (multiple_digits_p && (flags & mf_use_underscores_around_value))
OB_PUTC ('_');
/* Output the number itself. */
if (multiple_words_p)
dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value));
else
icat (TREE_INT_CST_LOW (value)); icat (TREE_INT_CST_LOW (value));
if (flags & mf_use_underscores_around_value)
{
if (multiple_digits_p)
OB_PUTC ('_');
/* Whether or not there were multiple digits, we don't need an
underscore. We've either terminated the number with an
underscore, or else it only had one digit. */
numeric_output_need_bar = 0;
}
else
/* We just output a numeric value. */
numeric_output_need_bar = 1; numeric_output_need_bar = 1;
} }
...@@ -701,9 +753,9 @@ build_mangled_C9x_name (bits) ...@@ -701,9 +753,9 @@ build_mangled_C9x_name (bits)
#endif #endif
static void static void
build_overload_value (type, value, in_template) build_overload_value (type, value, flags)
tree type, value; tree type, value;
int in_template; mangling_flags flags;
{ {
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0);
...@@ -738,24 +790,31 @@ build_overload_value (type, value, in_template) ...@@ -738,24 +790,31 @@ build_overload_value (type, value, in_template)
build_overload_identifier (DECL_NAME (value)); build_overload_identifier (DECL_NAME (value));
return; return;
} }
else if (INTEGRAL_TYPE_P (type))
switch (TREE_CODE (type))
{ {
case INTEGER_TYPE: build_overload_int (value, flags);
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
{
build_overload_int (value, in_template);
return; return;
} }
/* The only case where we use the extra underscores here is when
forming the mangling for an integral non-type template argument.
If that didn't happen, stop now. */
flags &= ~mf_use_underscores_around_value;
switch (TREE_CODE (type))
{
case REAL_TYPE: case REAL_TYPE:
{ {
REAL_VALUE_TYPE val; REAL_VALUE_TYPE val;
char *bufp = digit_buffer; char *bufp = digit_buffer;
pedwarn ("ANSI C++ forbids floating-point template arguments"); /* We must handle non-constants in templates. */
if (TREE_CODE (value) != REAL_CST)
{
mangle_expression (value);
break;
}
my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
val = TREE_REAL_CST (value); val = TREE_REAL_CST (value);
if (REAL_VALUE_ISNAN (val)) if (REAL_VALUE_ISNAN (val))
{ {
...@@ -817,7 +876,7 @@ build_overload_value (type, value, in_template) ...@@ -817,7 +876,7 @@ build_overload_value (type, value, in_template)
case POINTER_TYPE: case POINTER_TYPE:
if (TREE_CODE (value) == INTEGER_CST) if (TREE_CODE (value) == INTEGER_CST)
{ {
build_overload_int (value, in_template); build_overload_int (value, flags);
return; return;
} }
else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX)
...@@ -877,9 +936,9 @@ build_overload_value (type, value, in_template) ...@@ -877,9 +936,9 @@ build_overload_value (type, value, in_template)
my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0); my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0);
expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2); expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2);
build_overload_int (delta, in_template); build_overload_int (delta, flags);
OB_PUTC ('_'); OB_PUTC ('_');
build_overload_int (idx, in_template); build_overload_int (idx, flags);
OB_PUTC ('_'); OB_PUTC ('_');
if (pfn) if (pfn)
{ {
...@@ -890,7 +949,7 @@ build_overload_value (type, value, in_template) ...@@ -890,7 +949,7 @@ build_overload_value (type, value, in_template)
else else
{ {
OB_PUTC ('i'); OB_PUTC ('i');
build_overload_int (delta2, in_template); build_overload_int (delta2, flags);
} }
} }
break; break;
...@@ -983,7 +1042,9 @@ build_template_parm_names (parmlist, arglist) ...@@ -983,7 +1042,9 @@ build_template_parm_names (parmlist, arglist)
/* It's a PARM_DECL. */ /* It's a PARM_DECL. */
build_mangled_name_for_type (TREE_TYPE (parm)); build_mangled_name_for_type (TREE_TYPE (parm));
build_overload_value (TREE_TYPE (parm), arg, build_overload_value (TREE_TYPE (parm), arg,
uses_template_parms (arglist)); ((mf_maybe_uninstantiated
* uses_template_parms (arglist))
| mf_use_underscores_around_value));
} }
} }
} }
...@@ -1317,7 +1378,6 @@ process_overload_item (parmtype, extra_Gcode) ...@@ -1317,7 +1378,6 @@ process_overload_item (parmtype, extra_Gcode)
goto more; goto more;
case ARRAY_TYPE: case ARRAY_TYPE:
#if PARM_CAN_BE_ARRAY_TYPE
{ {
OB_PUTC ('A'); OB_PUTC ('A');
if (TYPE_DOMAIN (parmtype) == NULL_TREE) if (TYPE_DOMAIN (parmtype) == NULL_TREE)
...@@ -1337,10 +1397,6 @@ process_overload_item (parmtype, extra_Gcode) ...@@ -1337,10 +1397,6 @@ process_overload_item (parmtype, extra_Gcode)
OB_PUTC ('_'); OB_PUTC ('_');
goto more; goto more;
} }
#else
OB_PUTC ('P');
goto more;
#endif
case POINTER_TYPE: case POINTER_TYPE:
OB_PUTC ('P'); OB_PUTC ('P');
......
// Build don't link:
// Special g++ Options:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <double d>
struct S;
template <double d, double e>
void f (S<d>*, S<e>*, S<d + e>*);
void g ()
{
S<2.0>* s1;
S<3.7>* s2;
S<5.7>* s3;
f (s1, s2, s3);
}
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
typedef enum {} i;
template <int II>
class Bar {};
void f (Bar<21>, int) {}
void f (Bar<2>, i) {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment