92th Cygnus<->FSF quick merge

From-SVN: r14524
This commit is contained in:
Brendan Kehoe 1997-07-24 17:09:25 -04:00
parent 067aea74e2
commit 42976354a6
19 changed files with 945 additions and 167 deletions

View File

@ -1,3 +1,126 @@
Wed Jul 23 13:36:25 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (struct cp_function): Add static_labelno.
(push_cp_function_context): Save it.
(pop_cp_function_context): Restore it.
Tue Jul 22 14:43:29 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_component_ref_1): Convert from reference.
Tue Jul 22 11:06:23 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* parse.y (current_declspecs, prefix_attributes): Initialize to
NULL_TREE.
* parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil
before we try to force it to be a TREE_LIST.
(decl): Make sure $1.t is non-nil.
Sun Jul 20 11:53:07 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (uses_template_parms): Handle template first-parse codes.
* decl.c (cp_finish_decl): Only warn about user-defined statics.
Fri Jul 18 17:56:08 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (unify): Handle BOOLEAN_TYPE.
* cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE.
* pt.c (tsubst): Don't set it.
* call.c (build_over_call): Use uses_template_parms.
Thu Jul 17 18:06:30 1997 Jason Merrill <jason@yorick.cygnus.com>
* method.c (build_overload_nested_name): Use static_labelno
instead of var_labelno.
(build_qualified_name): New fn.
(build_overload_name): Split out from here.
(build_static_name): Use build_qualified_name.
* decl.c (cp_finish_decl): Statics in extern inline functions
have comdat linkage.
(start_function): Initialize static_labelno.
Thu Jul 17 11:20:17 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
* class.c (finish_struct_methods): add check of warn_ctor_dtor_privacy
before "all member functions in class [] are private"
Wed Jul 16 23:47:08 1997 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (do_scoped_id): convert_from_reference.
* init.c (build_offset_ref): Likewise.
Wed Jul 16 15:57:42 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com>
* parse.y (empty_parms): Only use VOID_LIST_NODE for the PARMS if
we're in a C++ struct/class, not if we're doing `extern "C"'.
Wed Jul 16 12:34:29 1997 Benjamin Kosnik <bkoz@lisa.cygnus.com>
* error.c (dump_expr): Check TREE_OPERAND before dump_expr_list.
Mon Jul 14 03:23:46 1997 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (get_member_function_from_ptrfunc): Promote index
before saving it.
Sun Jul 13 00:11:52 1997 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (layout_basetypes): Move non-virtual destructor warning.
* decl.c (xref_basetypes): Remove non-virtual destructor warning.
Sat Jul 12 12:47:12 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (grokdeclarator): Call add_defarg_fn for the function
type, too.
* lex.c (add_defarg_fn): Adjust.
(do_pending_defargs): Adjust. Don't skip the first parm.
Fri Jul 11 01:39:50 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (build_enumerator): Global enumerators are also readonly.
* rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast.
(build_dynamic_cast): Call it and convert_from_reference.
* lex.c (add_defarg_fn): New fn.
(snarf_defarg): Don't add to defarg_types.
(do_pending_defargs): Lose defarg_types. All fns we process now
have defargs.
* decl.c (grokfndecl): Call add_defarg_fn.
* Makefile.in (CONFLICTS): Expect 18 s/r conflicts.
* cp-tree.def: Add DEFAULT_ARG.
* spew.c (yylex): Call snarf_defarg as appropriate.
* parse.y: New tokens DEFARG and DEFARG_MARKER.
(defarg_again, pending_defargs, defarg, defarg1): New rules.
(structsp): Use pending_defargs.
(parms, full_parm): Use defarg.
* lex.c (init_lex): Initialize inline_text_firstobj.
(do_pending_inlines): Never pass the obstack to feed_input.
(process_next_inline): Call end_input instead of restore_pending_input.
(clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs,
finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns.
* input.c (end_input): New fn.
(sub_getch): At the end of some fed input, just keep returning EOF
until someone calls end_input.
Remove 'obstack' field from struct input_source.
* decl.c (grokparms): Handle DEFAULT_ARG.
(replace_defarg): New fn.
* cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros.
Wed Jul 9 13:44:12 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (implicit_conversion): If nothing else works, try binding
an rvalue to a reference.
Wed Jul 9 13:04:38 1997 Geoffrey Noer <noer@cygnus.com>
* decl.c (init_decl_processing): fix Jun 30 patch -- move
ifndef for Cygwin32 to include SIGSEGV.
Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com>
* class.c (finish_struct_1): Only complain about pointers without
@ -16,10 +139,11 @@ Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com>
Mon Jun 30 17:53:21 1997 Geoffrey Noer <noer@cygnus.com>
* decl.c: Stop trying to catch signals other than SIGABRT
since the Cygwin32 library doesn't support them correctly
yet. This fixes a situation in which g++ causes a hang on
SIGSEGVs and other such signals in our Win32-hosted tools.
* decl.c (init_decl_processing): Stop trying to catch signals
other than SIGABRT since the Cygwin32 library doesn't support
them correctly yet. This fixes a situation in which g++ causes
a hang on SIGSEGVs and other such signals in our Win32-hosted
tools.
Mon Jun 30 14:50:01 1997 Jason Merrill <jason@yorick.cygnus.com>

View File

@ -195,7 +195,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
CONFLICTS = expect 16 shift/reduce conflicts and 39 reduce/reduce conflicts.
CONFLICTS = expect 18 shift/reduce conflicts and 39 reduce/reduce conflicts.
$(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y
@echo $(CONFLICTS)

View File

@ -3281,14 +3281,19 @@ implicit_conversion (to, from, expr, flags)
conv = cand->second_conv;
if ((! conv || ICS_BAD_FLAG (conv))
&& TREE_CODE (to) == REFERENCE_TYPE
&& TYPE_READONLY (TREE_TYPE (to))
&& ! TYPE_VOLATILE (TREE_TYPE (to))
&& (flags & LOOKUP_NO_TEMP_BIND) == 0)
{
cand = build_user_type_conversion_1
(TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
if (cand)
conv = build_conv (REF_BIND, to, cand->second_conv);
{
if (! TYPE_READONLY (TREE_TYPE (to))
|| TYPE_VOLATILE (TREE_TYPE (to)))
ICS_BAD_FLAG (cand->second_conv) = 1;
if (!conv || (ICS_BAD_FLAG (conv)
> ICS_BAD_FLAG (cand->second_conv)))
conv = build_conv (REF_BIND, to, cand->second_conv);
}
}
}
@ -5108,10 +5113,11 @@ build_over_call (fn, convs, args, flags)
{
tree arg = TREE_PURPOSE (parm);
if (PARM_DEFAULT_FROM_TEMPLATE (parm))
if (DECL_TEMPLATE_INFO (fn) && uses_template_parms (arg))
/* This came from a template. Instantiate the default arg here,
not in tsubst. */
arg = tsubst_expr (arg, &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
arg = tsubst_expr (arg,
&TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
TREE_VEC_LENGTH (DECL_TI_ARGS (fn)), NULL_TREE);
converted_args = tree_cons
(NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),

View File

@ -2011,7 +2011,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
nonprivate_method = 1;
break;
}
if (nonprivate_method == 0)
if (nonprivate_method == 0
&& warn_ctor_dtor_privacy)
cp_warning ("all member functions in class `%T' are private", t);
}

View File

@ -110,6 +110,11 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
This is not an alias, but is later expanded into multiple aliases. */
DEFTREECODE (USING_DECL, "using_decl", "d", 0)
/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */
DEFTREECODE (DEFAULT_ARG, "default_arg", "c", 2)
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)

View File

@ -1094,10 +1094,6 @@ struct lang_decl
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
/* For a TREE_LIST node representing a function parm type and its default arg,
did the default arg come from a template? */
#define PARM_DEFAULT_FROM_TEMPLATE(NODE) TREE_LANG_FLAG_0 (NODE)
/* Nonzero in INT_CST means that this int is negative by dint of
using a twos-complement negated operand. */
#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
@ -1418,6 +1414,10 @@ extern int flag_new_for_scope;
#define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE))
#define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE))
/* An un-parsed default argument looks like an identifier. */
#define DEFARG_LENGTH(NODE) IDENTIFIER_LENGTH(NODE)
#define DEFARG_POINTER(NODE) IDENTIFIER_POINTER(NODE)
#define builtin_function(NAME, TYPE, CODE, LIBNAME) \
define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME)

View File

@ -51,6 +51,8 @@ extern int current_class_depth;
extern tree static_ctors, static_dtors;
extern int static_labelno;
/* Stack of places to restore the search obstack back to. */
/* Obstack used for remembering local class declarations (like
@ -4672,12 +4674,12 @@ init_decl_processing ()
current_binding_level = NULL_BINDING_LEVEL;
free_binding_level = NULL_BINDING_LEVEL;
#ifndef __CYGWIN32__
/* Because most segmentation signals can be traced back into user
code, catch them and at least give the user a chance of working
around compiler bugs. */
signal (SIGSEGV, signal_catch);
#ifndef __CYGWIN32__
/* We will also catch aborts in the back-end through signal_catch and
give the user a chance to see where the error might be, and to defeat
aborts in the back-end when there have been errors previously in their
@ -6532,6 +6534,32 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (was_temp)
end_temporary_allocation ();
/* Extern inline function static data has external linkage. */
if (TREE_CODE (decl) == VAR_DECL
&& TREE_STATIC (decl)
&& current_function_decl
&& DECL_CONTEXT (decl) == current_function_decl
&& DECL_THIS_INLINE (current_function_decl)
&& DECL_PUBLIC (current_function_decl))
{
/* We can only do this if we can use common or weak, and we
can't if it has been initialized and we don't support weak. */
if (DECL_INITIAL (decl) == NULL_TREE
|| DECL_INITIAL (decl) == error_mark_node)
{
TREE_PUBLIC (decl) = 1;
DECL_COMMON (decl) = 1;
}
else if (flag_weak)
make_decl_one_only (decl);
if (TREE_PUBLIC (decl))
DECL_ASSEMBLER_NAME (decl)
= build_static_name (current_function_decl, DECL_NAME (decl));
else if (! DECL_ARTIFICIAL (decl))
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
}
if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
make_decl_rtl (decl, NULL_PTR, toplev);
else if (TREE_CODE (decl) == VAR_DECL
@ -7067,6 +7095,7 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
{
tree cname, decl;
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
tree t;
if (ctype)
cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL
@ -7128,6 +7157,14 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
if (ctype && hack_decl_function_context (decl))
DECL_NO_STATIC_CHAIN (decl) = 1;
for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t)
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
{
add_defarg_fn (decl);
break;
}
/* Caller will do the rest of this. */
if (check < 0)
return decl;
@ -8672,6 +8709,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* ANSI says that `const int foo ();'
does not make the function foo const. */
type = build_function_type (type, arg_types);
{
tree t;
for (t = arg_types; t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t)
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
{
add_defarg_fn (type);
break;
}
}
}
break;
@ -9858,6 +9906,9 @@ grokparms (first_parm, funcdef_flag)
PARM_DECL_EXPR (init) = 1;
else if (processing_template_decl)
;
/* Unparsed default arg from in-class decl. */
else if (TREE_CODE (init) == DEFAULT_ARG)
;
else if (TREE_CODE (init) == VAR_DECL
|| TREE_CODE (init) == PARM_DECL)
{
@ -9877,6 +9928,7 @@ grokparms (first_parm, funcdef_flag)
else
init = require_instantiated_type (type, init, integer_zero_node);
if (! processing_template_decl
&& TREE_CODE (init) != DEFAULT_ARG
&& ! can_convert_arg (type, TREE_TYPE (init), init))
cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
TREE_TYPE (init), decl);
@ -9931,6 +9983,21 @@ grokparms (first_parm, funcdef_flag)
return result;
}
/* Called from the parser to update an element of TYPE_ARG_TYPES for some
FUNCTION_TYPE with the newly parsed version of its default argument, which
was previously digested as text. See snarf_defarg et al in lex.c. */
void
replace_defarg (arg, init)
tree arg, init;
{
if (! processing_template_decl
&& ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
cp_pedwarn ("invalid type `%T' for default argument to `%T'",
TREE_TYPE (init), TREE_VALUE (arg));
TREE_PURPOSE (arg) = init;
}
int
copy_args_p (d)
@ -10595,13 +10662,6 @@ xref_basetypes (code_type_node, name, ref, binfo)
continue;
}
/* Effective C++ rule 14. The case of virtual functions but
non-virtual dtor is handled in finish_struct_1. */
if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
&& TYPE_HAS_DESTRUCTOR (basetype))
cp_warning ("base class `%#T' has a non-virtual destructor",
basetype);
/* Note that the BINFO records which describe individual
inheritances are *not* shared in the lattice! They
cannot be shared because a given baseclass may be
@ -10891,6 +10951,7 @@ build_enumerator (name, value)
a function could mean local to a class method. */
decl = build_decl (CONST_DECL, name, integer_type_node);
DECL_INITIAL (decl) = value;
TREE_READONLY (decl) = 1;
pushdecl (decl);
GNU_xref_decl (current_function_decl, decl);
@ -10988,6 +11049,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
current_base_init_list = NULL_TREE;
current_member_init_list = NULL_TREE;
ctor_label = dtor_label = NULL_TREE;
static_labelno = 0;
clear_temp_name ();
@ -12606,6 +12668,7 @@ struct cp_function
rtx result_rtx;
struct cp_function *next;
struct binding_level *binding_level;
int static_labelno;
};
static struct cp_function *cp_function_chain;
@ -12647,6 +12710,7 @@ push_cp_function_context (context)
p->member_init_list = current_member_init_list;
p->current_class_ptr = current_class_ptr;
p->current_class_ref = current_class_ref;
p->static_labelno = static_labelno;
}
/* Restore the variables used during compilation of a C++ function. */
@ -12688,6 +12752,7 @@ pop_cp_function_context (context)
current_member_init_list = p->member_init_list;
current_class_ptr = p->current_class_ptr;
current_class_ref = p->current_class_ref;
static_labelno = p->static_labelno;
free (p);
}

View File

@ -1081,7 +1081,8 @@ dump_expr (t, nop)
case NEW_EXPR:
OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
OB_PUTC ('(');
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
if (TREE_OPERAND (t, 1))
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
OB_PUTC (')');
break;

View File

@ -26,6 +26,7 @@ Questions and comments to Mike Stump @code{<mrs@@cygnus.com>}.
* Copying Objects::
* Exception Handling::
* Free Store::
* Mangling:: Function name mangling for C++ and Java
* Concept Index::
@end menu
@ -1472,7 +1473,7 @@ would do the hard work of fixing up the registers, adjusting the stack
pointer, frame pointer, arg pointer and so on.
@node Free Store, Concept Index, Exception Handling, Top
@node Free Store, Mangling, Exception Handling, Top
@section Free Store
@code{operator new []} adds a magic cookie to the beginning of arrays
@ -1518,8 +1519,246 @@ The linkage code in g++ is horribly twisted in order to meet two design goals:
To meet the first goal, we defer emission of inlines and vtables until
the end of the translation unit, where we can decide whether or not they
are needed, and how to emit them if they are.
@node Mangling, Concept Index, Free Store, Top
@section Function name mangling for C++ and Java
Both C++ and Jave provide overloaded function and methods,
which are methods with the same types but different parameter lists.
Selecting the correct version is done at compile time.
Though the overloaded functions have the same name in the source code,
they need to be translated into different assembler-level names,
since typical assemblers and linkers cannot handle overloading.
This process of encoding the parameter types with the method name
into a unique name is called @dfn{name mangling}. The inverse
process is called @dfn{demangling}.
It is convenient that C++ and Java use compatible mangling schemes,
since the makes life easier for tools such as gdb, and it eases
integration between C++ and Java.
Note there is also a standard "Jave Native Interface" (JNI) which
implements a different calling convention, and uses a different
mangling scheme. The JNI is a rather abstract ABI so Java can call methods
written in C or C++;
we are concerned here about a lower-level interface primarily
intended for methods written in Java, but that can also be used for C++
(and less easily C).
@subsection Method name mangling
C++ mangles a method by emitting the function name, followed by @code{__},
followed by encodings of any method qualifiers (such as @code{const}),
followed by the mangling of the method's class,
followed by the mangling of the parameters, in order.
For example @code{Foo::bar(int, long) const} is mangled
as @samp{bar__C3Fooil}.
For a constructor, the method name is left out.
That is @code{Foo::Foo(int, long) const} is mangled
as @samp{__C3Fooil}.
GNU Java does the same.
@subsection Primitive types
The C++ types @code{int}, @code{long}, @code{short}, @code{char},
and @code{long long} are mangled as @samp{i}, @samp{l},
@samp{s}, @samp{c}, and @samp{x}, respectively.
The corresponding unsigned types have @samp{U} prefixed
to the mangling. The type @code{signed char} is mangled @samp{Sc}.
The C++ and Java floating-point types @code{float} and @code{double}
are mangled as @samp{f} and @samp{d} respectively.
The C++ @code{bool} type and the Java @code{boolean} type are
mangled as @samp{b}.
The C++ @code{wchar_t} and the Java @code{char} types are
mangled as @samp{w}.
The Java integral types @code{byte}, @code{short}, @code{int}
and @code{long} are mangled as @samp{c}, @samp{s}, @samp{i},
and @samp{x}, respectively.
C++ code that has included @code{javatypes.h} will mangle
the typedefs @code{jbyte}, @code{jshort}, @code{jint}
and @code{jlong} as respectively @samp{c}, @samp{s}, @samp{i},
and @samp{x}. (This has not been implemented yet.)
@subsection Mangling of simple names
A simple class, package, template, or namespace name is
encoded as the number of characters in the name, followed by
the actual characters. Thus the class @code{Foo}
is encoded as @samp{3Foo}.
If any of the characters in the name are not alphanumeric
(i.e not one of the standard ASCII letters, digits, or '_'),
or the initial character is a digit, then the name is
mangled as a sequence of encoded Unicode letters.
A Unicode encoding starts with a @samp{U} to indicate
that Unicode escapes are used, followed by the number of
bytes used by the Unicode encoding, followed by the bytes
representing the encoding. ASSCI letters and
non-initial digits are encoded without change. However, all
other characters (including underscore and initial digits) are
translated into a sequence starting with an underscore,
followed by the big-endian 4-hex-digit lower-case encoding of the character.
If a method name contains Unicode-escaped characters, the
entire mangled method name is followed by a @samp{U}.
For example, the method @code{X\u0319::M\u002B(int)} is encoded as
@samp{M_002b__U6X_0319iU}.
@subsection Pointer and reference types
A C++ pointer type is mangled as @samp{P} followed by the
mangling of the type pointed to.
A C++ reference type as mangled as @samp{R} followed by the
mangling of the type referenced.
A Java object reference type is equivalent
to a C++ pointer parameter, so we mangle such an parameter type
as @samp{P} followed by the mangling of the class name.
@subsection Qualified names
Both C++ and Java allow a class to be lexically nested inside another
class. C++ also supports namespaces (not yet implemented by G++).
Java also supports packages.
These are all mangled the same way: First the letter @samp{Q}
indicates that we are emitting a qualified name.
That is followed by the number of parts in the qualified name.
If that number is 9 or less, it is emitted with no delimiters.
Otherwise, an underscore is written before and after the count.
Then follows each part of the qualified name, as described above.
For example @code{Foo::\u0319::Bar} is encoded as
@samp{Q33FooU5_03193Bar}.
@subsection Templates
A template instantiation is encoded as the letter @samp{t},
followed by the encoding of the template name, followed
the number of template parameters, followed by encoding of the template
parameters. If a template parameter is a type, it is written
as a @samp{Z} followed by the encoding of the type.
@subsection Arrays
C++ array types are mangled by emitting @samp{A}, followed by
the length of the array, followed by an @samp{_}, followed by
the mangling of the element type. Of course, normally
array parameter types decay into a pointer types, so you
don't see this.
Java arrays are objects. A Java type @code{T[]} is mangled
as if it were the C++ type @code{JArray<T>}.
For example @code{java.lang.String[]} is encoded as
@samp{Pt6JArray1ZPQ34java4lang6String}.
@subsection Table of demangling code characters
The following special characters are used in mangling:
@table @samp
@item A
Indicates a C++ array type.
@item b
Encodes the C++ @code{bool} type,
and the Java @code{boolean} type.
@item c
Encodes the C++ @code{char} type, and the Java @code{byte} type.
@item C
A modifier to indicate a @code{const} type.
Also used to indicate a @code{const} member function
(in which cases it precedes the encoding of the method's class).
@item d
Encodes the C++ and Java @code{double} types.
@item e
Indicates extra unknown arguments @code{...}.
@item f
Encodes the C++ and Java @code{float} types.
@item F
Used to indicate a function type.
@item i
Encodes the C++ and Java @code{int} types.
@item J
Indicates a complex type.
@item l
Encodes the C++ @code{long} type.
@item P
Indicates a pointer type. Followed by the type pointed to.
@item Q
Used to mangle qualified names, which arise from nested classes.
Should also be used for namespaces (?).
In Java used to mangle package-qualified names, and inner classes.
@item r
Encodes the GNU C++ @code{long double} type.
@item R
Indicates a reference type. Followed by the referenced type.
@item s
Encodes the C++ and java @code{short} types.
@item S
A modifier that indicates that the following integer type is signed.
Only used with @code{char}.
Also used as a modifier to indicate a static member function.
@item t
Indicates a template instantiation.
@item T
A back reference to a previously seen type.
@item U
A modifier that indicates that the following integer type is unsigned.
Also used to indicate that the following class or namespace name
is encoded using Unicode-mangling.
@item v
Encodes the C++ and Java @code{void} types.
@item V
A modified for a @code{const} type or method.
@item w
Encodes the C++ @code{wchar_t} type, and the Java @code{char} types.
@item x
Encodes the GNU C++ @code{long long} type, and the Java @code{long} type.
@item Z
Used for template type parameters.
@end table
The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p}
also seem to be used for obscure purposes ...
@node Concept Index, , Mangling, Top
@node Concept Index, , Free Store, Top
@section Concept Index
@printindex cp

View File

@ -1963,7 +1963,7 @@ build_offset_ref (type, name)
if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
{
mark_used (t);
return t;
return convert_from_reference (t);
}
if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))

View File

@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */
inlining). */
#include <stdio.h>
#include "obstack.h"
extern FILE *finput;
@ -43,8 +42,6 @@ struct input_source {
int length;
/* current position, when reading as input */
int offset;
/* obstack to free this input string from when finished, if any */
struct obstack *obstack;
/* linked list maintenance */
struct input_source *next;
/* values to restore after reading all of current string */
@ -78,7 +75,6 @@ allocate_input ()
}
inp = (struct input_source *) xmalloc (sizeof (struct input_source));
inp->next = 0;
inp->obstack = 0;
return inp;
}
@ -86,9 +82,6 @@ static inline void
free_input (inp)
struct input_source *inp;
{
if (inp->obstack)
obstack_free (inp->obstack, inp->str);
inp->obstack = 0;
inp->str = 0;
inp->length = 0;
inp->next = free_inputs;
@ -102,10 +95,9 @@ static int putback_char = -1;
inline
void
feed_input (str, len, delete)
feed_input (str, len)
char *str;
int len;
struct obstack *delete;
{
struct input_source *inp = allocate_input ();
@ -115,7 +107,6 @@ feed_input (str, len, delete)
inp->str = str;
inp->length = len;
inp->obstack = delete;
inp->offset = 0;
inp->next = input;
inp->filename = input_filename;
@ -129,6 +120,22 @@ feed_input (str, len, delete)
struct pending_input *to_be_restored; /* XXX */
extern int end_of_file;
static inline void
end_input ()
{
struct input_source *inp = input;
end_of_file = 0;
input = inp->next;
input_filename = inp->filename;
lineno = inp->lineno;
/* Get interface/implementation back in sync. */
extract_interface_info ();
putback_char = inp->putback_char;
restore_pending_input (inp->input);
free_input (inp);
}
static inline int
sub_getch ()
{
@ -140,30 +147,12 @@ sub_getch ()
}
if (input)
{
if (input->offset == input->length)
if (input->offset >= input->length)
{
struct input_source *inp = input;
my_friendly_assert (putback_char == -1, 223);
to_be_restored = inp->input;
input->offset++;
return EOF;
}
else if (input->offset > input->length)
{
struct input_source *inp = input;
end_of_file = 0;
input = inp->next;
input_filename = inp->filename;
lineno = inp->lineno;
/* Get interface/implementation back in sync. */
extract_interface_info ();
putback_char = inp->putback_char;
free_input (inp);
return getch ();
}
if (input)
return (unsigned char)input->str[input->offset++];
return (unsigned char)input->str[input->offset++];
}
return getc (finput);
}

View File

@ -72,6 +72,7 @@ void yyerror ();
/* This obstack is needed to hold text. It is not safe to use
TOKEN_BUFFER because `check_newline' calls `yylex'. */
struct obstack inline_text_obstack;
char *inline_text_firstobj;
int end_of_file;
@ -91,7 +92,7 @@ extern struct obstack token_obstack;
#else
extern void put_back (/* int */);
extern int input_redirected ();
extern void feed_input (/* char *, int, struct obstack * */);
extern void feed_input (/* char *, int */);
#endif
/* Holds translations from TREE_CODEs to operator name strings,
@ -575,6 +576,7 @@ init_lex ()
init_method ();
init_error ();
gcc_obstack_init (&inline_text_obstack);
inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
/* Start it at 0, because check_newline is called at the very beginning
and will increment it to 1. */
@ -1170,7 +1172,7 @@ do_pending_inlines ()
push_cp_function_context (context);
if (t->len > 0)
{
feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
feed_input (t->buf, t->len);
lineno = t->lineno;
#if 0
if (input_filename != t->filename)
@ -1192,7 +1194,6 @@ do_pending_inlines ()
DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
}
extern struct pending_input *to_be_restored;
static int nextchar = -1;
/* Called from the fndecl rule in the parser when the function just parsed
@ -1222,16 +1223,13 @@ process_next_inline (t)
nextchar = -1;
}
yychar = YYEMPTY;
if (to_be_restored == 0)
my_friendly_abort (123);
restore_pending_input (to_be_restored);
to_be_restored = 0;
end_input ();
if (i && i->fndecl != NULL_TREE)
{
context = hack_decl_function_context (i->fndecl);
if (context)
push_cp_function_context (context);
feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
feed_input (i->buf, i->len);
lineno = i->lineno;
input_filename = i->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
@ -1392,6 +1390,12 @@ yyungetc (ch, rescan)
}
}
void
clear_inline_text_obstack ()
{
obstack_free (&inline_text_obstack, inline_text_firstobj);
}
/* This function stores away the text for an inline function that should
be processed later. It decides how much later, and may need to move
the info between obstacks; therefore, the caller should not refer to
@ -1448,7 +1452,6 @@ reinit_parse_for_method (yychar, decl)
t->token_value = 0;
t->buf = buf;
t->len = len;
t->can_free = 1;
t->deja_vu = 0;
#if 0
if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
@ -1625,6 +1628,259 @@ reinit_parse_for_block (pyychar, obstackp)
obstack_1grow (obstackp, '\0');
}
/* Consume a no-commas expression -- actually, a default argument -- and
save it away on the specified obstack. */
static void
reinit_parse_for_expr (obstackp)
struct obstack *obstackp;
{
register int c = 0;
int starting_lineno = lineno;
char *starting_filename = input_filename;
int len;
int look_for_semicolon = 0;
int look_for_lbrac = 0;
int plev = 0;
if (nextchar != EOF)
{
c = nextchar;
nextchar = EOF;
}
else
c = getch ();
while (c != EOF)
{
int this_lineno = lineno;
c = skip_white_space (c);
/* Don't lose our cool if there are lots of comments. */
if (lineno == this_lineno + 1)
obstack_1grow (obstackp, '\n');
else if (lineno == this_lineno)
;
else if (lineno - this_lineno < 10)
{
int i;
for (i = lineno - this_lineno; i > 0; --i)
obstack_1grow (obstackp, '\n');
}
else
{
char buf[16];
sprintf (buf, "\n# %d \"", lineno);
len = strlen (buf);
obstack_grow (obstackp, buf, len);
len = strlen (input_filename);
obstack_grow (obstackp, input_filename, len);
obstack_1grow (obstackp, '\"');
obstack_1grow (obstackp, '\n');
}
while (c > ' ') /* ASCII dependent... */
{
if (plev <= 0 && (c == ')' || c == ','))
{
put_back (c);
goto done;
}
obstack_1grow (obstackp, c);
if (c == '(' || c == '[')
++plev;
else if (c == ']' || c == ')')
--plev;
else if (c == '\\')
{
/* Don't act on the next character...e.g, doing an escaped
double-quote. */
c = getch ();
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
obstack_1grow (obstackp, c);
}
else if (c == '\"')
consume_string (obstackp, c);
else if (c == '\'')
consume_string (obstackp, c);
c = getch ();
}
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
else if (c != '\n')
{
obstack_1grow (obstackp, c);
c = getch ();
}
}
done:
obstack_1grow (obstackp, '\0');
}
int do_snarf_defarg;
/* Decide whether the default argument we are about to see should be
gobbled up as text for later parsing. */
void
maybe_snarf_defarg ()
{
if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
do_snarf_defarg = 1;
}
/* When we see a default argument in a method declaration, we snarf it as
text using snarf_defarg. When we get up to namespace scope, we then go
through and parse all of them using do_pending_defargs. Since yacc
parsers are not reentrant, we retain defargs state in these two
variables so that subsequent calls to do_pending_defargs can resume
where the previous call left off. */
tree defarg_fns;
tree defarg_parm;
tree
snarf_defarg ()
{
int len;
char *buf;
tree arg;
struct pending_inline *t;
reinit_parse_for_expr (&inline_text_obstack);
len = obstack_object_size (&inline_text_obstack);
buf = obstack_finish (&inline_text_obstack);
push_obstacks (&inline_text_obstack, &inline_text_obstack);
arg = make_node (DEFAULT_ARG);
DEFARG_LENGTH (arg) = len - 1;
DEFARG_POINTER (arg) = buf;
pop_obstacks ();
return arg;
}
/* Called from grokfndecl to note a function decl with unparsed default
arguments for later processing. Also called from grokdeclarator
for function types with unparsed defargs; the call from grokfndecl
will always come second, so we can overwrite the entry from the type. */
void
add_defarg_fn (decl)
tree decl;
{
if (TREE_CODE (decl) == FUNCTION_DECL)
TREE_VALUE (defarg_fns) = decl;
else
{
push_obstacks (&inline_text_obstack, &inline_text_obstack);
defarg_fns = tree_cons (current_class_type, decl, defarg_fns);
pop_obstacks ();
}
}
/* Helper for do_pending_defargs. Starts the parsing of a default arg. */
static void
feed_defarg (f, p)
tree f, p;
{
tree d = TREE_PURPOSE (p);
feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
if (TREE_CODE (f) == FUNCTION_DECL)
{
lineno = DECL_SOURCE_LINE (f);
input_filename = DECL_SOURCE_FILE (f);
}
yychar = DEFARG_MARKER;
yylval.ttype = p;
}
/* Helper for do_pending_defargs. Ends the parsing of a default arg. */
static void
finish_defarg ()
{
if (yychar == YYEMPTY)
yychar = yylex ();
if (yychar != END_OF_SAVED_INPUT)
{
error ("parse error at end of saved function text");
/* restore_pending_input will abort unless yychar is either
END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
hosed, feed back YYEMPTY. We also need to discard nextchar,
since that may have gotten set as well. */
nextchar = -1;
}
yychar = YYEMPTY;
end_input ();
}
/* Main function for deferred parsing of default arguments. Called from
the parser. */
void
do_pending_defargs ()
{
if (defarg_parm)
finish_defarg ();
for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
{
tree defarg_fn = TREE_VALUE (defarg_fns);
if (defarg_parm == NULL_TREE)
{
tree p;
push_nested_class (TREE_PURPOSE (defarg_fns), 1);
pushlevel (0);
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
{
#if 0
for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
pushdecl (copy_node (p));
#endif
defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
}
else
defarg_parm = TYPE_ARG_TYPES (defarg_fn);
}
else
defarg_parm = TREE_CHAIN (defarg_parm);
for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
if (TREE_PURPOSE (defarg_parm))
{
my_friendly_assert (TREE_CODE (TREE_PURPOSE (defarg_parm))
== DEFAULT_ARG, 2349);
feed_defarg (defarg_fn, defarg_parm);
/* Return to the parser, which will process this defarg
and call us again. */
return;
}
poplevel (0, 0, 0);
pop_nested_class (1);
}
}
/* Build a default function named NAME for type TYPE.
KIND says what to build.
@ -2716,7 +2972,7 @@ do_scoped_id (token, parsing)
}
/* else just use the decl */
}
return id;
return convert_from_reference (id);
}
tree

View File

@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA. */
processed. */
struct pending_inline *pending_inlines;
int static_labelno;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
@ -371,18 +373,15 @@ build_overload_nested_name (decl)
{
tree name = DECL_ASSEMBLER_NAME (decl);
char *label;
extern int var_labelno;
ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
var_labelno++;
ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno);
static_labelno++;
if (numeric_output_need_bar)
{
OB_PUTC ('_');
numeric_output_need_bar = 0;
}
OB_PUTC ('_');
icat (strlen (label));
OB_PUTCP (label);
numeric_output_need_bar = 1;
}
else /* TYPE_DECL */
build_overload_identifier (decl);
@ -669,6 +668,49 @@ build_overload_identifier (name)
}
}
/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce
the mangling for it. Used by build_overload_name and build_static_name. */
static void
build_qualified_name (decl)
tree decl;
{
tree context;
int i = 1;
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
decl = TYPE_NAME (decl);
/* If DECL_ASSEMBLER_NAME has been set properly, use it. */
if (TREE_CODE (decl) == TYPE_DECL
&& DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
{
OB_PUTID (DECL_ASSEMBLER_NAME (decl));
return;
}
context = decl;
while (DECL_CONTEXT (context))
{
i += 1;
context = DECL_CONTEXT (context);
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
context = TYPE_NAME (context);
}
if (i > 1)
{
OB_PUTC ('Q');
if (i > 9)
OB_PUTC ('_');
icat (i);
if (i > 9)
OB_PUTC ('_');
numeric_output_need_bar = 0;
}
build_overload_nested_name (decl);
}
/* Given a list of parameters in PARMTYPES, create an unambiguous
overload string. Should distinguish any type that C (or C++) can
distinguish. I.e., pointers to functions are treated correctly.
@ -931,41 +973,15 @@ build_overload_name (parmtypes, begin, end)
common:
{
tree name = TYPE_NAME (parmtype);
int i = 1;
if (TREE_CODE (name) == TYPE_DECL)
if (TREE_CODE (name) == IDENTIFIER_NODE)
{
tree context = name;
build_overload_identifier (TYPE_NAME (parmtype));
break;
}
my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248);
/* If DECL_ASSEMBLER_NAME has been set properly, use it. */
if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
{
OB_PUTID (DECL_ASSEMBLER_NAME (context));
break;
}
while (DECL_CONTEXT (context))
{
i += 1;
context = DECL_CONTEXT (context);
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
context = TYPE_NAME (context);
}
name = DECL_NAME (name);
}
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
if (i > 1)
{
OB_PUTC ('Q');
if (i > 9)
OB_PUTC ('_');
icat (i);
if (i > 9)
OB_PUTC ('_');
numeric_output_need_bar = 0;
build_overload_nested_name (TYPE_NAME (parmtype));
}
else
build_overload_identifier (TYPE_NAME (parmtype));
build_qualified_name (name);
break;
}
@ -1015,17 +1031,29 @@ build_overload_name (parmtypes, begin, end)
return (char *)obstack_base (&scratch_obstack);
}
/* Produce the mangling for a variable named NAME in CONTEXT, which can
be either a class TYPE or a FUNCTION_DECL. */
tree
build_static_name (basetype, name)
tree basetype, name;
build_static_name (context, name)
tree context, name;
{
char *basename = build_overload_name (basetype, 1, 1);
char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
+ sizeof (STATIC_NAME_FORMAT)
+ strlen (basename));
sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
return get_identifier (buf);
}
OB_INIT ();
numeric_output_need_bar = 0;
#ifdef JOINER
OB_PUTC ('_');
build_qualified_name (context);
OB_PUTC (JOINER);
#else
OB_PUTS ("__static_");
build_qualified_name (context);
OB_PUTC (' ');
#endif
OB_PUTID (name);
OB_FINISH ();
return get_identifier ((char *)obstack_base (&scratch_obstack));
}
/* Change the name of a function definition so that it may be
overloaded. NAME is the name of the function to overload,

View File

@ -89,7 +89,10 @@ empty_parms ()
tree parms;
if (strict_prototype
|| current_class_type != NULL)
/* Only go ahead with using the void list node if we're actually
parsing a class in C++, not a struct in extern "C" mode. */
|| (current_class_type != NULL
&& current_lang_name == lang_name_cplusplus))
parms = void_list_node;
else
parms = NULL_TREE;
@ -201,7 +204,7 @@ empty_parms ()
%type <ttype> declmods
%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
%type <itype> initdecls notype_initdecls initdcl /* C++ modification */
%type <ttype> init initlist maybeasm maybe_init
%type <ttype> init initlist maybeasm maybe_init defarg defarg1
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word
@ -236,7 +239,7 @@ empty_parms ()
/* C++ extensions */
%token <ttype> TYPENAME_ELLIPSIS PTYPENAME
%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
%type <ttype> fn.def1 /* Not really! */ component_constructor_declarator
%type <ttype> fn.def2 return_id fn.defpen constructor_declarator
%type <itype> ctor_initializer_opt
@ -284,13 +287,13 @@ empty_parms ()
%{
/* List of types and structure classes of the current declaration. */
static tree current_declspecs;
static tree current_declspecs = NULL_TREE;
/* List of prefix attributes in effect.
Prefix attributes are parsed by the reserved_declspecs and declmods
rules. They create a list that contains *both* declspecs and attrs. */
/* ??? It is not clear yet that all cases where an attribute can now appear in
a declspec list have been updated. */
static tree prefix_attributes;
static tree prefix_attributes = NULL_TREE;
/* When defining an aggregate, this is the most recent one being defined. */
static tree current_aggr;
@ -1661,7 +1664,7 @@ decl:
typespec initdecls ';'
{
resume_momentary ($2);
if (IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
note_got_semicolon ($1.t);
}
| typed_declspecs initdecls ';'
@ -1907,7 +1910,8 @@ initdcl0:
declarator maybeasm maybe_attribute '='
{ split_specs_attrs ($<ttype>0, &current_declspecs,
&prefix_attributes);
if (TREE_CODE (current_declspecs) != TREE_LIST)
if (current_declspecs
&& TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = get_decl_list (current_declspecs);
if (have_extern_spec && !used_extern_spec)
{
@ -1927,7 +1931,8 @@ initdcl0:
{ tree d;
split_specs_attrs ($<ttype>0, &current_declspecs,
&prefix_attributes);
if (TREE_CODE (current_declspecs) != TREE_LIST)
if (current_declspecs
&& TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = get_decl_list (current_declspecs);
if (have_extern_spec && !used_extern_spec)
{
@ -2119,6 +2124,20 @@ pending_inlines:
eat_saved_input
;
/* A regurgitated default argument. The value of DEFARG_MARKER will be
the TREE_LIST node for the parameter in question. */
defarg_again:
DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT
{ replace_defarg ($1, $2); }
pending_defargs:
/* empty */ %prec EMPTY
| pending_defargs defarg_again
{ do_pending_defargs (); }
| pending_defargs error
{ do_pending_defargs (); }
;
structsp:
ENUM identifier '{'
{ $<itype>3 = suspend_momentary ();
@ -2188,13 +2207,22 @@ structsp:
if (! semi)
check_for_missing_semicolon ($1);
if (current_scope () == current_function_decl)
do_pending_defargs ($1);
}
pending_defargs
{
if (pending_inlines
&& current_scope () == current_function_decl)
do_pending_inlines ();
}
pending_inlines
{ $$.t = $<ttype>6;
$$.new_type_flag = 1; }
{
$$.t = $<ttype>6;
$$.new_type_flag = 1;
if (current_scope () == current_function_decl)
clear_inline_text_obstack ();
}
| class_head %prec EMPTY
{
$$.t = $1;
@ -3951,14 +3979,27 @@ complex_parmlist:
}
;
/* A default argument to a */
defarg:
'='
{ maybe_snarf_defarg (); }
defarg1
{ $$ = $3; }
;
defarg1:
DEFARG
| init
;
/* A nonempty list of parameter declarations or type names. */
parms:
named_parm
{ check_for_new_type ("in a parameter list", $1);
$$ = build_tree_list (NULL_TREE, $1.t); }
| parm '=' init
| parm defarg
{ check_for_new_type ("in a parameter list", $1);
$$ = build_tree_list ($3, $1.t); }
$$ = build_tree_list ($2, $1.t); }
| parms_comma full_parm
{ check_for_new_type ("in a parameter list", $2);
$$ = chainon ($$, $2.t); }
@ -4005,7 +4046,10 @@ named_parm:
;
full_parm:
parm maybe_init
parm
{ $$.t = build_tree_list (NULL_TREE, $1.t);
$$.new_type_flag = $1.new_type_flag; }
| parm defarg
{ $$.t = build_tree_list ($2, $1.t);
$$.new_type_flag = $1.new_type_flag; }
;

View File

@ -962,6 +962,18 @@ uses_template_parms (t)
return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
return uses_template_parms (TREE_OPERAND (t, 1));
case MODOP_EXPR:
case CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
case SIZEOF_EXPR:
case ARROW_EXPR:
case DOTSTAR_EXPR:
case TYPEID_EXPR:
return 1;
default:
switch (TREE_CODE_CLASS (TREE_CODE (t)))
{
@ -1849,9 +1861,6 @@ tsubst (t, args, nargs, in_decl)
tree purpose = TREE_PURPOSE (values);
tree x = build_tree_list (purpose, value);
if (purpose)
PARM_DEFAULT_FROM_TEMPLATE (x) = 1;
if (first)
TREE_CHAIN (last) = x;
else
@ -2828,6 +2837,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
case REAL_TYPE:
case COMPLEX_TYPE:
case INTEGER_TYPE:
case BOOLEAN_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;

View File

@ -405,8 +405,8 @@ ifnonnull (test, result)
/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
paper. */
tree
build_dynamic_cast (type, expr)
static tree
build_dynamic_cast_1 (type, expr)
tree type, expr;
{
enum tree_code tc = TREE_CODE (type);
@ -628,6 +628,13 @@ build_dynamic_cast (type, expr)
expr, exprtype, type);
return error_mark_node;
}
tree
build_dynamic_cast (type, expr)
tree type, expr;
{
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
/* Build and initialize various sorts of descriptors. Every descriptor
node has a name associated with it (the name created by mangling).

View File

@ -215,6 +215,7 @@ probe_obstack (h, obj, nlevels)
Value is 0 if we treat this name in a default fashion. */
extern int looking_for_typename;
int looking_for_template;
extern int do_snarf_defarg;
extern struct obstack *current_obstack, *saveable_obstack;
tree got_scope;
@ -227,6 +228,8 @@ peekyylex ()
return nth_token (0)->yychar;
}
extern tree snarf_defarg ();
int
yylex ()
{
@ -242,8 +245,18 @@ yylex ()
}
#endif
if (do_snarf_defarg)
{
my_friendly_assert (num_tokens () == 0, 2837);
tmp_token.yychar = DEFARG;
tmp_token.yylval.ttype = snarf_defarg ();
tmp_token.end_of_file = 0;
do_snarf_defarg = 0;
add_token (&tmp_token);
}
/* if we've got tokens, send them */
if (num_tokens ())
else if (num_tokens ())
{
tmp_token= *nth_token (0);

View File

@ -832,20 +832,18 @@ layout_basetypes (rec, binfos)
BINFO_VPTR_FIELD (base_binfo) = decl;
vbase_decls = decl;
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s: virtual %s'",
TYPE_NAME_STRING (rec),
TYPE_NAME_STRING (basetype));
}
got_it:
/* The space this decl occupies has already been accounted for. */
continue;
}
/* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P
here because the case of virtual functions but non-virtual
dtor is handled in finish_struct_1. */
if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
&& TYPE_HAS_DESTRUCTOR (basetype))
cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
if (const_size == 0)
offset = integer_zero_node;
else
@ -854,22 +852,6 @@ layout_basetypes (rec, binfos)
const_size = CEIL (const_size, TYPE_ALIGN (basetype))
* TYPE_ALIGN (basetype);
offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
#if 0
/* bpk: Disabled this check until someone is willing to
claim it as theirs and explain exactly what circumstances
warrant the warning. */
if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
&& DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
{
warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
"destructor `%s' non-virtual");
warning ("in inheritance relationship `%s:%s %s'",
TYPE_NAME_STRING (rec),
TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",
TYPE_NAME_STRING (basetype));
}
#endif
}
BINFO_OFFSET (base_binfo) = offset;
if (CLASSTYPE_VSIZE (basetype))

View File

@ -1652,15 +1652,17 @@ build_object_ref (datum, basetype, field)
return error_mark_node;
}
/* Like `build_component_ref, but uses an already found field.
Must compute access for current_class_ref. Otherwise, ok. */
/* Like `build_component_ref, but uses an already found field, and converts
from a reference. Must compute access for current_class_ref.
Otherwise, ok. */
tree
build_component_ref_1 (datum, field, protect)
tree datum, field;
int protect;
{
return build_component_ref (datum, field, NULL_TREE, protect);
return convert_from_reference
(build_component_ref (datum, field, NULL_TREE, protect));
}
/* Given a COND_EXPR in T, return it in a form that we can, for
@ -2484,11 +2486,17 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
function = save_expr (function);
fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
idx = save_expr (build_component_ref (function,
index_identifier,
NULL_TREE, 0));
e1 = fold (build (GT_EXPR, boolean_type_node, idx,
cp_convert (delta_type_node, integer_zero_node)));
/* Promoting idx before saving it improves performance on RISC
targets. Without promoting, the first compare used
load-with-sign-extend, while the second used normal load then
shift to sign-extend. An optimizer flaw, perhaps, but it's easier
to make this change. */
idx = save_expr (default_conversion
(build_component_ref (function,
index_identifier,
NULL_TREE, 0)));
e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier, NULL_TREE, 0));
delta2 = DELTA2_FROM_PTRMEMFUNC (function);