89th Cygnus<->FSF quick merge

From-SVN: r12883
This commit is contained in:
Mike Stump 1996-09-30 21:34:04 +00:00
parent bf6103db43
commit 5156628f9f
31 changed files with 1417 additions and 289 deletions

View File

@ -1,3 +1,174 @@
Mon Sep 30 12:58:40 1996 Mike Stump <mrs@cygnus.com>
* input.c (sub_getch): Handle 8-bit characters in string literals.
Sun Sep 29 03:12:01 1996 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (mapcar): Handle CONSTRUCTORs.
(copy_to_permanent): Handle expression_obstack properly.
* Make-lang.in (cplib2.txt): Also depend on the headers.
* rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE ==
INT_TYPE_SIZE.
(expand_class_desc): Use USItype for offset field.
* tinfo.h (struct __class_type_info): Likewise.
* method.c (build_overload_int): TYPE_PRECISION should be applied
to types.
Sat Sep 28 14:44:50 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_new_op): A COND_EXPR involving void must be a
builtin.
Fri Sep 27 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_x_component_ref): New fn.
(build_object_ref): Use it.
* parse.y (primary): Use it.
* decl2.c (build_expr_from_tree): Use it.
* cp-tree.h: Declare it.
* decl.c (start_decl): variable-sized arrays cannot be initialized.
* error.c (dump_type_suffix): Handle variable arrays.
Fri Sep 27 13:14:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* Make-lang.in (exception.o): Put back compiling it with -fPIC.
Fri Sep 27 03:00:09 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (lookup_name_real): Don't try to look up anything in a
TYPENAME_TYPE.
* tinfo2.cc (__throw_type_match_rtti): Oops.
Thu Sep 26 22:11:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* Make-lang.in (exception.o): Use -fno-PIC for now.
Thu Sep 26 10:59:00 1996 Jason Merrill <jason@yorick.cygnus.com>
* rtti.c (build_dynamic_cast): Pass tinfo fns rather than
calling them.
(get_tinfo_fn_dynamic): Extracted from build_typeid.
* tinfo2.cc (__dynamic_cast): Adjust.
* rtti.c (build_typeid): Use resolves_to_fixed_type_p.
(build_x_typeid): Likewise.
* parse.y: Call build_x_typeid instead of build_typeid.
* cp-tree.def: Add TYPEID_EXPR.
* pt.c (tsubst_copy): Handle typeid.
* decl2.c (build_expr_from_tree): Likewise.
* rtti.c (build_x_typeid): Throw bad_typeid from here.
(build_typeid): Not here.
* cp-tree.h: Declare build_x_typeid.
Wed Sep 25 17:26:16 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c (convert_like): Pull out constant values.
* tree.c (mapcar): Use build_cplus_array_type, not build_array_type.
Wed Sep 25 17:28:53 1996 Michael Meissner <meissner@tiktok.cygnus.com>
* decl.c (init_decl_processing): Create short int types before
creating size_t in case a machine description needs to use
unsigned short for size_t.
Tue Sep 24 18:18:44 1996 Jason Merrill <jason@yorick.cygnus.com>
* Make-lang.in (exception.o): Turn off pic.
* tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same
type, multi-level ptr conversions.
* rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast.
(throw_bad_cast): Use it.
(throw_bad_typeid): New fn.
(build_typeid): Throw bad_typeid as needed.
Use build_call.
(synthesize_tinfo_fn): Handle functions and arrays before checking
for cv-quals.
* Remove .h from standard C++ headers, add new.h, move into inc
subdirectory.
* exception*: Remove pointer from object, constructors. Add
default exception::what that uses type_info::name. Add
__throw_bad_typeid.
* init.c (build_new): Don't add a cookie to new (void *) T[2].
Mon Sep 23 15:21:53 1996 Jason Merrill <jason@yorick.cygnus.com>
* Make-lang.in: Building C++ code depends on cc1plus.
Mon Sep 23 12:38:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as
a HOST_WIDE_INT, not a tree.
Mon Sep 23 12:36:02 1996 Jason Merrill <jason@yorick.cygnus.com>
* exception.cc: Don't include <stdlib.h>.
* Make-lang.in (c++.clean): Remove cplib2.*.
Mon Sep 23 09:42:19 1996 Doug Evans <dje@canuck.cygnus.com>
* parse.y (component_decl_1, component_costructor_declarator case):
Pass attributes/prefix_attributes in tree list.
Mon Sep 23 01:18:50 1996 Jason Merrill <jason@yorick.cygnus.com>
* tinfo{,2}.cc: #include <stddef.h> instead of <stdlib.h>.
Sun Sep 22 05:31:22 1996 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (do_identifier): Don't do deferred lookup in a template
header.
* typeck2.c (store_init_value): Oops.
* new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}:
New files for C++ lang-support library.
* Make-lang.in (CXX_EXTRA_HEADERS): Define.
(CXX_LIB2FUNCS): Define.
And rules for building the C++ lang-support code.
* config-lang.in (headers): Define.
(lib2funcs): Define.
Sat Sep 21 19:17:28 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call
digest_init.
* pt.c (tsubst_copy): Compute type for CONSTRUCTOR.
* typeck2.c (store_init_value): Check for initializing pmf with { }
here.
(process_init_constructor): Not here.
Thu Sep 19 16:41:07 1996 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (begin_template_parm_list): Increment
processing_template_decl here.
(end_template_parm_list): Not here.
(process_template_parm): No need to add 1 to it now.
* *.c: Use processing_template_decl instead of current_template_parms
to check for being in a template.
* pt.c (uses_template_parms): Handle SCOPE_REF. Fix CONSTRUCTOR.
(tsubst_copy): Handle CONSTRUCTOR.
(instantiate_decl): Set up context properly for variables.
* decl2.c (build_expr_from_tree): Handle CONSTRUCTOR.
* class.c (finish_struct): Reverse CLASSTYPE_TAGS.
Wed Sep 18 13:30:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back.
Wed Sep 18 04:24:07 1996 Jason Merrill <jason@yorick.cygnus.com>
* method.c (make_thunk): Call comdat_linkage before setting the

View File

@ -52,6 +52,15 @@ GXX_CROSS_NAME = `t='$(program_transform_cross_name)'; echo g++ | sed $$t`
# The name to use for the demangler program.
DEMANGLER_PROG = c++filt
# Extra headers to install.
CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
$(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
# Extra code to include in libgcc2.
CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o exception.o
CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/exception.cc \
$(srcdir)/cp/tinfo.cc $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
# Define the names for selecting c++ in LANGUAGES.
# Note that it would be nice to move the dependency on g++
@ -105,6 +114,46 @@ c++.rest.encap: $(DEMANGLER_PROG)
c++.info:
c++.dvi:
# C++ language-support library pieces for libgcc.
tinfo.o: cc1plus $(srcdir)/cp/tinfo.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/tinfo.cc
tinfo2.o: cc1plus $(srcdir)/cp/tinfo2.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/tinfo2.cc
exception.o: cc1plus $(srcdir)/cp/exception.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c -O0 -fexceptions $(srcdir)/cp/exception.cc
new.o: cc1plus $(srcdir)/cp/new.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/new.cc
# We want to update cplib2.txt if any of the source files change...
cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
if [ -f cc1plus ]; then \
echo $(CXX_LIB2FUNCS) > cplib2.new; \
else \
echo "" > cplib2.new; \
fi
mv -f cplib2.new cplib2.txt
# Or if it would be different.
cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs
@if [ -r cplib2.txt ]; then \
if [ -f cc1plus ]; then \
echo $(CXX_LIB2FUNCS) > cplib2.new; \
else \
echo "" > cplib2.new; \
fi; \
if cmp -s cplib2.new cplib2.txt; then \
touch cplib2.ready; \
fi; \
rm -f cplib2.new; \
fi
@if [ -f cplib2.ready ]; then true; else \
touch cplib2.ready; \
fi
# Install hooks:
# cc1plus is installed elsewhere as part of $(COMPILERS).
@ -165,6 +214,7 @@ c++.uninstall:
c++.mostlyclean:
-rm -f cp/*$(objext) $(DEMANGLER_PROG)
c++.clean:
-rm -f cplib2.txt cplib2.ready
c++.distclean:
-rm -f cp/config.status cp/Makefile
-rm -f cp/parse.output

View File

@ -1410,7 +1410,7 @@ build_scoped_method_call (exp, basetype, name, parms)
|| basetype == error_mark_node)
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
@ -1681,7 +1681,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|| (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
@ -4545,9 +4545,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (arg3 && TREE_CODE (arg3) == OFFSET_REF)
arg3 = resolve_offset_ref (arg3);
if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
&& (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)))
&& (! arg3 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
if (code == COND_EXPR)
{
if (TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
|| TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
|| (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
&& ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
goto builtin;
}
else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
&& (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
goto builtin;
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
@ -4871,6 +4878,8 @@ convert_like (convs, expr)
case IDENTITY_CONV:
if (type_unknown_p (expr))
expr = instantiate_type (TREE_TYPE (convs), expr, 1);
if (TREE_READONLY_DECL_P (expr))
expr = decl_constant_value (expr);
return expr;
case AMBIG_CONV:
/* Call build_user_type_conversion again for the error. */

View File

@ -4341,7 +4341,10 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
defined for this type. */
if (CLASSTYPE_TAGS (t) || dummy)
{
x = CLASSTYPE_TAGS (t);
/* The list of tags was built up in pushtag in reverse order; we need
to fix that so that enumerators will be processed in forward order
in template instantiation. */
CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t));
while (x)
{
tree tag = TYPE_NAME (TREE_VALUE (x));

View File

@ -33,3 +33,7 @@ compilers="cc1plus\$(exeext)"
stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
diff_excludes="-x cp/parse.c -x cp/parse.h"
headers='$(CXX_EXTRA_HEADERS)'
lib2funcs=cplib2.txt

View File

@ -120,6 +120,7 @@ DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", "1", 1)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
DEFTREECODE (TYPEID_EXPR, "typeid_expr", "e", 1)
DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)

View File

@ -2169,7 +2169,9 @@ extern void finish_repo PROTO((void));
/* in rtti.c */
extern tree get_tinfo_fn PROTO((tree));
extern tree get_tinfo_fn_dynamic PROTO((tree));
extern tree build_typeid PROTO((tree));
extern tree build_x_typeid PROTO((tree));
extern tree get_typeid PROTO((tree));
extern tree build_dynamic_cast PROTO((tree, tree));
@ -2454,6 +2456,7 @@ extern tree default_conversion PROTO((tree));
extern tree build_object_ref PROTO((tree, tree, tree));
extern tree build_component_ref_1 PROTO((tree, tree, int));
extern tree build_component_ref PROTO((tree, tree, tree, int));
extern tree build_x_component_ref PROTO((tree, tree, tree, int));
extern tree build_x_indirect_ref PROTO((tree, char *));
extern tree build_indirect_ref PROTO((tree, char *));
extern tree build_x_array_ref PROTO((tree, tree));

View File

@ -1773,6 +1773,7 @@ struct saved_scope {
int minimal_parse_mode;
tree last_function_parms;
tree template_parms;
HOST_WIDE_INT processing_template_decl;
tree previous_class_type, previous_class_values;
};
static struct saved_scope *current_saved_scope;
@ -1869,6 +1870,7 @@ maybe_push_to_top_level (pseudo)
s->minimal_parse_mode = minimal_parse_mode;
s->last_function_parms = last_function_parms;
s->template_parms = current_template_parms;
s->processing_template_decl = processing_template_decl;
s->previous_class_type = previous_class_type;
s->previous_class_values = previous_class_values;
@ -1884,7 +1886,10 @@ maybe_push_to_top_level (pseudo)
minimal_parse_mode = 0;
previous_class_type = previous_class_values = NULL_TREE;
if (!pseudo)
current_template_parms = NULL_TREE;
{
current_template_parms = NULL_TREE;
processing_template_decl = 0;
}
s->prev = current_saved_scope;
s->old_bindings = old_bindings;
@ -1943,6 +1948,7 @@ pop_from_top_level ()
minimal_parse_mode = s->minimal_parse_mode;
last_function_parms = s->last_function_parms;
current_template_parms = s->template_parms;
processing_template_decl = s->processing_template_decl;
previous_class_type = s->previous_class_type;
previous_class_values = s->previous_class_values;
@ -2078,7 +2084,7 @@ pushtag (name, type, globalize)
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
push_template_decl (d);
/* If it is anonymous, then we are called from pushdecl,
@ -2110,7 +2116,7 @@ pushtag (name, type, globalize)
TYPE_MAIN_DECL (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
push_template_decl (d);
d = pushdecl_class_level (d);
@ -2723,7 +2729,7 @@ duplicate_decls (newdecl, olddecl)
/* Lay the type out, unless already done. */
if (oldtype != TREE_TYPE (newdecl)
&& TREE_TYPE (newdecl) != error_mark_node
&& !(current_template_parms && uses_template_parms (newdecl)))
&& !(processing_template_decl && uses_template_parms (newdecl)))
layout_type (TREE_TYPE (newdecl));
if ((TREE_CODE (newdecl) == VAR_DECL
@ -2731,7 +2737,7 @@ duplicate_decls (newdecl, olddecl)
|| TREE_CODE (newdecl) == RESULT_DECL
|| TREE_CODE (newdecl) == FIELD_DECL
|| TREE_CODE (newdecl) == TYPE_DECL)
&& !(current_template_parms && uses_template_parms (newdecl)))
&& !(processing_template_decl && uses_template_parms (newdecl)))
layout_decl (newdecl, 0);
/* Merge the type qualifiers. */
@ -4312,7 +4318,7 @@ make_typename_type (context, name)
else if (TREE_CODE (name) != IDENTIFIER_NODE)
my_friendly_abort (2000);
if (! current_template_parms
if (! processing_template_decl
|| ! uses_template_parms (context)
|| context == current_class_type)
{
@ -4325,11 +4331,11 @@ make_typename_type (context, name)
return TREE_TYPE (t);
}
if (current_template_parms)
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
t = make_lang_type (TYPENAME_TYPE);
d = build_decl (TYPE_DECL, name, t);
if (current_template_parms)
if (processing_template_decl)
pop_obstacks ();
TYPE_CONTEXT (t) = context;
@ -4389,7 +4395,8 @@ lookup_name_real (name, prefer_type, nonclass)
val = lookup_namespace_name (type, name);
}
else if (! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TYPENAME_TYPE)
/* Someone else will give an error about this if needed. */
val = NULL_TREE;
else if (TYPE_BEING_DEFINED (type))
@ -4421,7 +4428,7 @@ lookup_name_real (name, prefer_type, nonclass)
val = NULL_TREE;
#if 1
if (got_scope && current_template_parms
if (got_scope && processing_template_decl
&& got_scope != current_class_type
&& uses_template_parms (got_scope)
&& val && TREE_CODE (val) == TYPE_DECL
@ -4805,6 +4812,12 @@ init_decl_processing ()
record_builtin_type (RID_MAX, "long long unsigned",
long_long_unsigned_type_node);
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
/* `unsigned long' is the standard type for sizeof.
Traditionally, use a signed type.
Note that stddef.h uses `unsigned long',
@ -4824,12 +4837,8 @@ init_decl_processing ()
TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
/* Define both `signed char' and `unsigned char'. */
signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
@ -5646,7 +5655,7 @@ shadow_tag (declspecs)
&& TYPE_SIZE (value) == NULL_TREE)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value);
if (current_template_parms)
if (processing_template_decl)
push_template_decl (TYPE_MAIN_DECL (value));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value))
@ -5782,7 +5791,7 @@ start_decl (declarator, declspecs, initialized)
type = TREE_TYPE (decl);
/* Don't lose if destructors must be executed at file-level. */
if (! current_template_parms && TREE_STATIC (decl)
if (! processing_template_decl && TREE_STATIC (decl)
&& TYPE_NEEDS_DESTRUCTOR (complete_type (type))
&& !TREE_PERMANENT (decl))
{
@ -5829,11 +5838,23 @@ start_decl (declarator, declspecs, initialized)
break;
default:
if (TREE_CODE (type) == ARRAY_TYPE && ! current_template_parms
&& TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
if (! processing_template_decl)
{
cp_error ("elements of array `%#D' have incomplete type", decl);
initialized = 0;
if (TYPE_SIZE (type) != NULL_TREE
&& ! TREE_CONSTANT (TYPE_SIZE (type)))
{
cp_error
("variable-sized object `%D' may not be initialized", decl);
initialized = 0;
}
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
{
cp_error
("elements of array `%#D' have incomplete type", decl);
initialized = 0;
}
}
}
@ -5901,7 +5922,7 @@ start_decl (declarator, declspecs, initialized)
else
tem = pushdecl (decl);
if (current_template_parms)
if (processing_template_decl)
{
if (! current_function_decl)
push_template_decl (tem);
@ -5922,7 +5943,7 @@ start_decl (declarator, declspecs, initialized)
DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
#endif
if (! current_template_parms)
if (! processing_template_decl)
start_decl_1 (tem);
/* Corresponding pop_obstacks is done in `cp_finish_decl'. */
@ -5942,7 +5963,7 @@ start_decl (declarator, declspecs, initialized)
use temporary storage. Do this even if we will ignore the value. */
if (toplevel_bindings_p () && debug_temp_inits)
{
if (current_template_parms
if (processing_template_decl
|| TYPE_NEEDS_CONSTRUCTING (type)
|| TREE_CODE (type) == REFERENCE_TYPE)
/* In this case, the initializer must lay down in permanent
@ -6002,7 +6023,7 @@ start_decl_1 (decl)
&& TREE_CODE (decl) != TEMPLATE_DECL
&& IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl))
{
if ((! current_template_parms || ! uses_template_parms (type))
if ((! processing_template_decl || ! uses_template_parms (type))
&& TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
cp_error ("aggregate `%#D' has incomplete type and cannot be initialized",
@ -6228,7 +6249,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
return;
}
if (current_template_parms)
if (processing_template_decl)
{
if (init && DECL_INITIAL (decl))
DECL_INITIAL (decl) = init;
@ -6796,7 +6817,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
/* If requested, warn about definitions of large data objects. */
if (warn_larger_than
&& ! current_template_parms
&& ! processing_template_decl
&& (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
&& !DECL_EXTERNAL (decl))
{
@ -8393,7 +8414,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* If this involves a template parameter, it'll be
constant, but we don't know what the value is yet. */
if (current_template_parms)
if (processing_template_decl)
{
itype = make_node (INTEGER_TYPE);
TYPE_MIN_VALUE (itype) = size_zero_node;
@ -9481,7 +9502,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
if (current_lang_name == lang_name_cplusplus
&& ! current_template_parms
&& ! processing_template_decl
&& ! (IDENTIFIER_LENGTH (original_name) == 4
&& IDENTIFIER_POINTER (original_name)[0] == 'm'
&& strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
@ -9873,7 +9894,7 @@ grokparms (first_parm, funcdef_flag)
any_init++;
if (TREE_CODE (init) == SAVE_EXPR)
PARM_DECL_EXPR (init) = 1;
else if (current_template_parms)
else if (processing_template_decl)
;
else if (TREE_CODE (init) == VAR_DECL
|| TREE_CODE (init) == PARM_DECL)
@ -9893,7 +9914,7 @@ grokparms (first_parm, funcdef_flag)
}
else
init = require_instantiated_type (type, init, integer_zero_node);
if (! current_template_parms
if (! processing_template_decl
&& ! can_convert_arg (type, TREE_TYPE (init), init))
cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
TREE_TYPE (init), decl);
@ -10229,7 +10250,7 @@ grok_op_properties (decl, virtualp, friendp)
{
if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
&& ! current_template_parms
&& ! processing_template_decl
&& TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
{
if (methodp)
@ -10688,7 +10709,7 @@ finish_enum (enumtype, values)
register tree pair;
register tree value = DECL_INITIAL (TREE_VALUE (values));
if (! current_template_parms)
if (! processing_template_decl)
{
/* Speed up the main loop by performing some precalculations */
TREE_TYPE (TREE_VALUE (values)) = enumtype;
@ -10700,7 +10721,7 @@ finish_enum (enumtype, values)
for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
{
value = DECL_INITIAL (TREE_VALUE (pair));
if (! current_template_parms)
if (! processing_template_decl)
{
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
TREE_TYPE (value) = enumtype;
@ -10717,7 +10738,7 @@ finish_enum (enumtype, values)
TYPE_VALUES (enumtype) = values;
if (current_template_parms)
if (processing_template_decl)
return enumtype;
{
@ -10786,7 +10807,7 @@ build_enumerator (name, value)
if (value)
STRIP_TYPE_NOPS (value);
if (! current_template_parms)
if (! processing_template_decl)
{
/* Validate and default VALUE. */
if (value != NULL_TREE)
@ -10807,7 +10828,7 @@ build_enumerator (name, value)
}
/* Default based on previous value. */
if (value == NULL_TREE && ! current_template_parms)
if (value == NULL_TREE && ! processing_template_decl)
{
value = enum_next_value;
if (enum_overflow)
@ -10849,7 +10870,7 @@ build_enumerator (name, value)
GNU_xref_decl (current_function_decl, decl);
}
if (! current_template_parms)
if (! processing_template_decl)
{
/* Set basis for default for next value. */
enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value,
@ -11059,7 +11080,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
announce_function (decl1);
if (! current_template_parms)
if (! processing_template_decl)
{
if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
{
@ -11105,7 +11126,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
If we already have a decl for this name, and it is a FUNCTION_DECL,
use the old decl. */
if (current_template_parms)
if (processing_template_decl)
push_template_decl (decl1);
else if (pre_parsed_p == 0)
{
@ -11129,7 +11150,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
|| flag_alt_external_templates))
{
if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)
|| current_template_parms)
|| processing_template_decl)
DECL_EXTERNAL (decl1)
= (interface_only
|| (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
@ -11246,7 +11267,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
of this function only. Tiemann moved up here from bottom of fn. */
temporary_allocation ();
if (current_template_parms)
if (processing_template_decl)
{
extern tree last_tree;
++minimal_parse_mode;
@ -11395,7 +11416,7 @@ store_parm_decls ()
pushdecl (parm);
}
if (! current_template_parms
if (! processing_template_decl
&& (cleanup = maybe_build_cleanup (parm), cleanup))
{
expand_decl (parm);
@ -11433,7 +11454,7 @@ store_parm_decls ()
/* Initialize the RTL code for the function. */
DECL_SAVED_INSNS (fndecl) = NULL_RTX;
if (! current_template_parms)
if (! processing_template_decl)
expand_function_start (fndecl, parms_have_cleanups);
/* Create a binding contour which can be used to catch
@ -11458,7 +11479,7 @@ store_parm_decls ()
}
/* Take care of exception handling things. */
if (! current_template_parms && flag_exceptions)
if (! processing_template_decl && flag_exceptions)
{
rtx insns;
start_sequence ();
@ -11589,7 +11610,7 @@ finish_function (lineno, call_poplevel, nested)
store_parm_decls ();
}
if (current_template_parms)
if (processing_template_decl)
{
if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel)
{
@ -12017,7 +12038,7 @@ finish_function (lineno, call_poplevel, nested)
to the FUNCTION_DECL node itself. */
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
if (! current_template_parms)
if (! processing_template_decl)
{
/* So we can tell if jump_optimize sets it to 1. */
can_reach_end = 0;
@ -12070,7 +12091,7 @@ finish_function (lineno, call_poplevel, nested)
/* Free all the tree nodes making up this function. */
/* Switch back to allocating nodes permanently
until we start another function. */
if (current_template_parms)
if (processing_template_decl)
{
--minimal_parse_mode;
DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
@ -12086,7 +12107,7 @@ finish_function (lineno, call_poplevel, nested)
was an actual function definition. */
DECL_INITIAL (fndecl) = error_mark_node;
/* And we need the arguments for template instantiation. */
if (! current_template_parms)
if (! processing_template_decl)
{
if (! DECL_CONSTRUCTOR_P (fndecl)
|| !(TYPE_USES_VIRTUAL_BASECLASSES
@ -12178,7 +12199,7 @@ start_method (declspecs, declarator)
if (flag_default_inline)
DECL_INLINE (fndecl) = 1;
if (current_template_parms && ! current_function_decl)
if (processing_template_decl && ! current_function_decl)
push_template_decl (fndecl);
/* We read in the parameters on the maybepermanent_obstack,
@ -12437,7 +12458,7 @@ cplus_expand_expr_stmt (exp)
push_temp_slots ();
target_temp_slot_level = temp_slot_level;
if (current_template_parms)
if (processing_template_decl)
{
add_tree (build_min_nt (EXPR_STMT, exp));
return;

View File

@ -1053,7 +1053,7 @@ grok_array_decl (array_expr, index_exp)
if (type == error_mark_node || index_exp == error_mark_node)
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
array_expr, index_exp);
@ -1133,7 +1133,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
if (exp == error_mark_node)
return exp;
if (current_template_parms)
if (processing_template_decl)
{
t = build_min (DELETE_EXPR, void_type_node, exp, size);
DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
@ -1455,7 +1455,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
because `decl_const_value' would mis-interpret it
as only meaning that this VAR_DECL is defined. */
init = build1 (NOP_EXPR, TREE_TYPE (value), init);
else if (current_template_parms)
else if (processing_template_decl)
;
else if (! TREE_CONSTANT (init))
{
@ -1476,7 +1476,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
/* The corresponding pop_obstacks is in cp_finish_decl. */
push_obstacks_nochange ();
if (current_template_parms && ! current_function_decl
if (processing_template_decl && ! current_function_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
push_template_decl (value);
@ -1500,7 +1500,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
DECL_ASSEMBLER_NAME (value)
= build_static_name (current_class_type, DECL_NAME (value));
}
if (! current_template_parms)
if (! processing_template_decl)
pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
/* Static consts need not be initialized in the class definition. */
@ -1839,7 +1839,7 @@ setup_vtbl_ptr ()
if (base_init_expr == 0
&& DECL_CONSTRUCTOR_P (current_function_decl))
{
if (current_template_parms)
if (processing_template_decl)
add_tree (build_min_nt
(CTOR_INITIALIZER,
current_member_init_list, current_base_init_list));
@ -3412,13 +3412,26 @@ build_expr_from_tree (t)
}
case COMPONENT_REF:
return build_component_ref
return build_x_component_ref
(build_expr_from_tree (TREE_OPERAND (t, 0)),
TREE_OPERAND (t, 1), NULL_TREE, 1);
case THROW_EXPR:
return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
case CONSTRUCTOR:
{
tree r = build_nt (CONSTRUCTOR, NULL_TREE,
build_expr_from_tree (CONSTRUCTOR_ELTS (t)));
if (TREE_TYPE (t))
return digest_init (TREE_TYPE (t), r, 0);
return r;
}
case TYPEID_EXPR:
return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
default:
return t;
}
@ -3629,7 +3642,7 @@ mark_used (decl)
tree decl;
{
TREE_USED (decl) = 1;
if (current_template_parms)
if (processing_template_decl)
return;
assemble_external (decl);
/* Is it a synthesized method that needs to be synthesized? */

View File

@ -487,7 +487,16 @@ dump_type_suffix (t, v)
case ARRAY_TYPE:
OB_PUTC ('[');
if (TYPE_DOMAIN (t))
OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
{
if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0);
else
dump_expr (fold (build_binary_op
(PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
integer_one_node, 1)), 0);
}
OB_PUTC (']');
dump_type_suffix (TREE_TYPE (t), v);
break;

View File

@ -1132,7 +1132,7 @@ build_throw (e)
{
if (e != error_mark_node)
{
if (current_template_parms)
if (processing_template_decl)
return build_min (THROW_EXPR, void_type_node, e);
e = build1 (THROW_EXPR, void_type_node, e);
TREE_SIDE_EFFECTS (e) = 1;

111
gcc/cp/exception.cc Normal file
View File

@ -0,0 +1,111 @@
// Functions for Exception Support for -*- C++ -*-
// Copyright (C) 1994, 1995, 1996 Free Software Foundation
// This file is part of GNU CC.
// GNU CC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// GNU CC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with GNU CC; see the file COPYING. If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// As a special exception, if you link this library with other files,
// some of which are compiled with GCC, to produce an executable,
// this library does not by itself cause the resulting executable
// to be covered by the GNU General Public License.
// This exception does not however invalidate any other reasons why
// the executable file might be covered by the GNU General Public License.
#pragma implementation "exception"
#include "typeinfo"
#include "exception"
/* terminate (), unexpected (), set_terminate (), set_unexpected () as
well as the default terminate func and default unexpected func */
void
__default_terminate ()
{
abort ();
}
void
__default_unexpected ()
{
__default_terminate ();
}
static terminate_handler __terminate_func = __default_terminate;
static unexpected_handler __unexpected_func = __default_unexpected;
terminate_handler
set_terminate (terminate_handler func)
{
terminate_handler old = __terminate_func;
__terminate_func = func;
return old;
}
unexpected_handler
set_unexpected (unexpected_handler func)
{
unexpected_handler old = __unexpected_func;
__unexpected_func = func;
return old;
}
void
terminate ()
{
__terminate_func ();
}
void
unexpected ()
{
__unexpected_func ();
}
extern "C" void
__throw_bad_cast (void)
{
throw bad_cast ();
}
extern "C" void
__throw_bad_typeid (void)
{
throw bad_typeid ();
}
extern "C" void
__throw_bad_exception (void)
{
throw bad_exception ();
}
bool
uncaught_exception ()
{
extern void *__eh_type;
extern bool __eh_in_catch;
return __eh_type && ! __eh_in_catch;
}
const char * exception::
what () const
{
return typeid (*this).name ();
}

View File

@ -373,7 +373,7 @@ do_case (start, end)
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (current_template_parms)
if (processing_template_decl)
{
add_tree (build_min_nt (CASE_LABEL, start, end));
return;

View File

@ -1176,10 +1176,9 @@ thrown is used instead. All code that originates exceptions, even code
that throws exceptions as a side effect, like dynamic casting, and all
code that catches exceptions must be compiled with either -frtti, or
-fno-rtti. It is not possible to mix rtti base exception handling
objects with code that doesn't use rtti. Also, -frtti can alter the
binary layout of classes, so mixing -frtti code and -fno-rtti code can
be dangerous. The exceptions to this, are code that doesn't catch or
throw exceptions, catch (...), and code that just rethrows an exception.
objects with code that doesn't use rtti. The exceptions to this, are
code that doesn't catch or throw exceptions, catch (...), and code that
just rethrows an exception.
Currently we use the normal mangling used in building functions names
(int's are "i", const char * is PCc) to build the non-rtti base type

42
gcc/cp/inc/exception Normal file
View File

@ -0,0 +1,42 @@
// Exception Handling support header for -*- C++ -*-
// Copyright (C) 1995, 1996 Free Software Foundation
#ifndef __EXCEPTION__
#define __EXCEPTION__
#pragma interface "exception"
extern "C++" {
#if 0
namespace std {
#endif
class exception {
public:
exception () { }
virtual ~exception () { }
virtual const char* what () const;
};
class bad_exception : public exception {
public:
bad_exception () { }
virtual ~bad_exception () { }
};
typedef void (*terminate_handler) ();
typedef void (*unexpected_handler) ();
terminate_handler set_terminate (terminate_handler);
void terminate (void);
unexpected_handler set_unexpected (unexpected_handler);
void unexpected (void);
bool uncaught_exception ();
} // extern "C++"
#if 0
} // namespace std
#endif
#endif

38
gcc/cp/inc/new Normal file
View File

@ -0,0 +1,38 @@
// The -*- C++ -*- dynamic memory management header.
// Copyright (C) 1994, 1996 Free Software Foundation
#ifndef __NEW__
#define __NEW__
#pragma interface "new"
#include <stddef.h>
extern "C++" {
#if 0
namespace std {
#endif
typedef void (*new_handler)();
extern "C" new_handler set_new_handler (new_handler);
#if 0
} // namespace std
#endif
// G++ implementation internals
extern new_handler __new_handler;
extern "C" void __default_new_handler (void);
// replaceable signatures
void *operator new (size_t);
void *operator new[] (size_t);
void operator delete (void *);
void operator delete[] (void *);
// default placement versions of operator new
inline void *operator new(size_t, void *place) { return place; }
inline void *operator new[](size_t, void *place) { return place; }
} // extern "C++"
#endif

13
gcc/cp/inc/new.h Normal file
View File

@ -0,0 +1,13 @@
// -*- C++ -*- forwarding header.
#ifndef __NEW_H__
#define __NEW_H__
#include <new>
#if 0
using std::new_handler;
using std::set_new_handler;
#endif
#endif // __NEW_H__

71
gcc/cp/inc/typeinfo Normal file
View File

@ -0,0 +1,71 @@
// RTTI support for -*- C++ -*-
// Copyright (C) 1994, 1995, 1996 Free Software Foundation
#ifndef __TYPEINFO__
#define __TYPEINFO__
#include <exception>
extern "C++" {
#if 0
namespace std {
#endif
class type_info {
private:
// assigning type_info is not supported. made private.
type_info& operator= (const type_info&);
type_info (const type_info&);
protected:
type_info (const char *n): _name (n) { }
const char *_name;
public:
// destructor
virtual ~type_info ();
bool before (const type_info& arg);
const char* name () const
{ return _name; }
bool operator== (const type_info& arg) const;
bool operator!= (const type_info& arg) const;
};
// We can't rely on common symbols being shared between translation units
// under Windows. Sigh.
#ifndef _WIN32
inline bool type_info::
operator== (const type_info& arg) const
{
return &arg == this;
}
inline bool type_info::
operator!= (const type_info& arg) const
{
return &arg != this;
}
#endif
class bad_cast : public exception {
public:
bad_cast() { }
virtual ~bad_cast() { }
};
class bad_typeid : public exception {
public:
bad_typeid () { }
virtual ~bad_typeid () { }
};
#if 0
} // namespace std
#endif
} // extern "C++"
#endif

View File

@ -1803,7 +1803,7 @@ build_offset_ref (type, name)
tree basebinfo = NULL_TREE;
int dtor = 0;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (SCOPE_REF, type, name);
/* Handle namespace names fully here. */
@ -2601,6 +2601,7 @@ build_new (placement, decl, init, use_global_new)
tree alloc_expr, alloc_temp;
int has_array = 0;
enum tree_code code = NEW_EXPR;
int use_cookie;
tree pending_sizes = NULL_TREE;
@ -2648,7 +2649,7 @@ build_new (placement, decl, init, use_global_new)
{
if (this_nelts == NULL_TREE)
error ("new of array type fails to specify size");
else if (current_template_parms)
else if (processing_template_decl)
{
nelts = this_nelts;
absdcl = TREE_OPERAND (absdcl, 0);
@ -2718,7 +2719,7 @@ build_new (placement, decl, init, use_global_new)
decl = TYPE_NAME (type);
}
if (current_template_parms)
if (processing_template_decl)
{
tree t;
if (has_array)
@ -2801,9 +2802,25 @@ build_new (placement, decl, init, use_global_new)
return error_mark_node;
}
#if 1
/* Get a little extra space to store a couple of things before the new'ed
array. */
if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
array, if this isn't the default placement new. */
use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
&& ! (placement && ! TREE_CHAIN (placement)
&& TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node));
#else
/* Get a little extra space to store a couple of things before the new'ed
array, if this is either non-placement new or new (nothrow). */
use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
&& (! placement
|| (IS_AGGR_TYPE (TREE_TYPE (placement))
&& (TYPE_IDENTIFIER (TREE_TYPE (placement))
== get_identifier ("nothrow_t")))));
#endif
if (use_cookie)
{
tree extra = BI_header_size;
@ -2857,7 +2874,7 @@ build_new (placement, decl, init, use_global_new)
sure we have some extra bytes in that case for the BI_header_size
cookies? And how does that interact with the code below? (mrs) */
/* Finish up some magic for new'ed arrays */
if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE)
if (use_cookie && rval != NULL_TREE)
{
tree extra = BI_header_size;
tree cookie, exp1;

View File

@ -163,7 +163,7 @@ sub_getch ()
return getch ();
}
if (input)
return input->str[input->offset++];
return (unsigned char)input->str[input->offset++];
}
return getc (finput);
}

View File

@ -2654,7 +2654,7 @@ do_identifier (token, parsing)
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
if (! current_template_parms
if (! processing_template_decl
|| (DECL_INITIAL (id)
&& TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
id = DECL_INITIAL (id);
@ -2691,7 +2691,7 @@ do_scoped_id (token, parsing)
yychar = yylex ();
if (! id)
{
if (current_template_parms)
if (processing_template_decl)
{
id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
LOOKUP_EXPR_GLOBAL (id) = 1;
@ -2716,7 +2716,7 @@ do_scoped_id (token, parsing)
else if (TREE_CODE (id) != TREE_LIST)
mark_used (id);
}
if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
{
/* XXX CHS - should we set TREE_USED of the constant? */
id = DECL_INITIAL (id);
@ -2726,7 +2726,7 @@ do_scoped_id (token, parsing)
TREE_CONSTANT (id) = 1;
}
if (current_template_parms)
if (processing_template_decl)
{
if (is_overloaded_fn (id))
{
@ -3796,19 +3796,19 @@ real_yylex ()
len = p - token_buffer - 1;
}
#endif
if (current_template_parms)
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
if (current_template_parms)
if (processing_template_decl)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
}
else
{
if (current_template_parms)
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
if (current_template_parms)
if (processing_template_decl)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = char_array_type_node;
}
@ -4027,6 +4027,30 @@ is_rid (t)
}
#ifdef GATHER_STATISTICS
/* The original for tree_node_kind is in the toplevel tree.c; changes there
need to be brought into here, unless this were actually put into a header
instead. */
/* Statistics-gathering stuff. */
typedef enum
{
d_kind,
t_kind,
b_kind,
s_kind,
r_kind,
e_kind,
c_kind,
id_kind,
op_id_kind,
perm_list_kind,
temp_list_kind,
vec_kind,
x_kind,
lang_decl,
lang_type,
all_kinds
} tree_node_kind;
extern int tree_node_counts[];
extern int tree_node_sizes[];
#endif

View File

@ -369,7 +369,7 @@ build_overload_int (value)
OB_PUTC ('_');
return;
}
else if (current_template_parms
else if (processing_template_decl
&& TREE_CODE (value) != INTEGER_CST)
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
@ -382,7 +382,7 @@ build_overload_int (value)
}
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
{
if (tree_int_cst_lt (value, integer_zero_node))
{
@ -1656,7 +1656,7 @@ hack_identifier (value, name)
return value;
}
if (TREE_CODE (type) == REFERENCE_TYPE && ! current_template_parms)
if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
value = convert_from_reference (value);
return value;
}

6
gcc/cp/new.cc Normal file
View File

@ -0,0 +1,6 @@
// Implementation file for the -*- C++ -*- dynamic memory management header.
// Copyright (C) 1996 Free Software Foundation
// This file is part of GNU CC.
#pragma implementation "new"
#include "new"

View File

@ -990,7 +990,7 @@ compstmtend:
already_scoped_stmt:
'{'
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
COMPOUND_STMT_NO_SCOPE ($<ttype>$) = 1;
@ -999,7 +999,7 @@ already_scoped_stmt:
}
compstmtend
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -1287,10 +1287,10 @@ primary:
| boolean.literal
| string
{
if (current_template_parms)
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
$$ = combine_strings ($$);
if (current_template_parms)
if (processing_template_decl)
pop_obstacks ();
}
| '(' expr ')'
@ -1455,7 +1455,7 @@ primary:
check_for_new_type ("const_cast", $3);
$$ = build_const_cast (type, $6); }
| TYPEID '(' expr ')'
{ $$ = build_typeid ($3); }
{ $$ = build_x_typeid ($3); }
| TYPEID '(' type_id ')'
{ tree type = groktypename ($3.t);
check_for_new_type ("typeid", $3);
@ -1473,20 +1473,20 @@ primary:
| overqualified_id %prec HYPERUNARY
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
| overqualified_id '(' nonnull_exprlist ')'
{ if (current_template_parms)
{ if (processing_template_decl)
$$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), $3, NULL_TREE);
else
$$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
| overqualified_id LEFT_RIGHT
{ if (current_template_parms)
{ if (processing_template_decl)
$$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1),
NULL_TREE, NULL_TREE);
else
$$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
| object unqualified_id %prec UNARY
{ $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
{ $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); }
| object overqualified_id %prec UNARY
{ if (current_template_parms)
{ if (processing_template_decl)
$$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2));
else
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
@ -2294,7 +2294,7 @@ named_class_head:
&& TYPE_SIZE ($$) == NULL_TREE)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
if (current_template_parms)
if (processing_template_decl)
push_template_decl (TYPE_MAIN_DECL ($$));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
@ -2496,7 +2496,7 @@ left_curly:
pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
$<ttype>0 = t;
}
if (current_template_parms && TYPE_CONTEXT (t)
if (processing_template_decl && TYPE_CONTEXT (t)
&& ! current_class_type)
push_template_decl (TYPE_STUB_DECL (t));
pushclass (t, 0);
@ -2507,7 +2507,7 @@ left_curly:
&& TYPE_SIZE (t) == NULL_TREE)
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
if (current_template_parms)
if (processing_template_decl)
push_template_decl (TYPE_MAIN_DECL (t));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
@ -2672,7 +2672,8 @@ component_decl_1:
$$ = grokfield ($2, specs, $5, $3,
build_tree_list ($4, attrs)); }
| component_constructor_declarator maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, NULL_TREE, $4, $2, $3); }
{ $$ = grokfield ($$, NULL_TREE, $4, $2,
build_tree_list ($3, NULL_TREE)); }
| using_decl
{ $$ = do_class_using_decl ($1); }
;
@ -3242,7 +3243,7 @@ compstmt_or_error:
compstmt:
'{'
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
add_tree ($<ttype>$);
@ -3250,7 +3251,7 @@ compstmt:
}
.pushlevel compstmtend .poplevel
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3263,7 +3264,7 @@ compstmt:
simple_if:
IF
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (IF_STMT, NULL_TREE, NULL_TREE,
NULL_TREE);
@ -3273,7 +3274,7 @@ simple_if:
}
.pushlevel paren_cond_or_null
{
if (current_template_parms)
if (processing_template_decl)
{
if (last_tree != $<ttype>2)
{
@ -3292,7 +3293,7 @@ simple_if:
}
implicitly_scoped_stmt
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3306,7 +3307,7 @@ implicitly_scoped_stmt:
{ finish_stmt (); }
| .pushlevel
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
add_tree ($<ttype>$);
@ -3314,7 +3315,7 @@ implicitly_scoped_stmt:
}
simple_stmt .poplevel
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3336,7 +3337,7 @@ simple_stmt:
| expr ';'
{
tree expr = $1;
if (! current_template_parms)
if (! processing_template_decl)
{
emit_line_note (input_filename, lineno);
/* Do default conversion if safe and possibly important,
@ -3350,10 +3351,10 @@ simple_stmt:
clear_momentary ();
finish_stmt (); }
| simple_if ELSE
{ if (! current_template_parms) expand_start_else (); }
{ if (! processing_template_decl) expand_start_else (); }
implicitly_scoped_stmt
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>1, 2) = TREE_CHAIN ($<ttype>1);
TREE_CHAIN ($<ttype>1) = NULL_TREE;
@ -3365,12 +3366,12 @@ simple_stmt:
.poplevel
{ finish_stmt (); }
| simple_if %prec IF
{ if (! current_template_parms) expand_end_cond ();
{ if (! processing_template_decl) expand_end_cond ();
do_poplevel ();
finish_stmt (); }
| WHILE
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (WHILE_STMT, NULL_TREE, NULL_TREE);
add_tree ($<ttype>$);
@ -3385,7 +3386,7 @@ simple_stmt:
}
.pushlevel paren_cond_or_null
{
if (current_template_parms)
if (processing_template_decl)
{
if (last_tree != $<ttype>2)
{
@ -3404,7 +3405,7 @@ simple_stmt:
}
already_scoped_stmt .poplevel
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3416,7 +3417,7 @@ simple_stmt:
}
| DO
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (DO_STMT, NULL_TREE, NULL_TREE);
add_tree ($<ttype>$);
@ -3430,7 +3431,7 @@ simple_stmt:
}
implicitly_scoped_stmt WHILE
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3444,7 +3445,7 @@ simple_stmt:
}
paren_expr_or_null ';'
{
if (current_template_parms)
if (processing_template_decl)
TREE_OPERAND ($<ttype>2, 1) = $6;
else
{
@ -3456,7 +3457,7 @@ simple_stmt:
finish_stmt ();
}
| FOR
{ if (current_template_parms)
{ if (processing_template_decl)
{
$<ttype>$ = build_min_nt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
@ -3476,7 +3477,7 @@ simple_stmt:
}
'(' for.init.statement
{
if (current_template_parms)
if (processing_template_decl)
{
if (last_tree != $<ttype>2)
{
@ -3494,7 +3495,7 @@ simple_stmt:
}
.pushlevel xcond ';'
{
if (current_template_parms)
if (processing_template_decl)
{
if (last_tree != $<ttype>2)
{
@ -3515,13 +3516,13 @@ simple_stmt:
/* Don't let the tree nodes for $10 be discarded
by clear_momentary during the parsing of the next stmt. */
{
if (current_template_parms)
if (processing_template_decl)
TREE_OPERAND ($<ttype>2, 2) = $10;
push_momentary ();
}
already_scoped_stmt .poplevel
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>2, 3) = TREE_CHAIN ($<ttype>2);
TREE_CHAIN ($<ttype>2) = NULL_TREE;
@ -3542,7 +3543,7 @@ simple_stmt:
finish_stmt (); }
| SWITCH .pushlevel '(' condition ')'
{
if (current_template_parms)
if (processing_template_decl)
{
$<ttype>$ = build_min_nt (SWITCH_STMT, $4, NULL_TREE);
add_tree ($<ttype>$);
@ -3559,7 +3560,7 @@ simple_stmt:
}
implicitly_scoped_stmt
{
if (current_template_parms)
if (processing_template_decl)
{
TREE_OPERAND ($<ttype>6, 1) = TREE_CHAIN ($<ttype>6);
TREE_CHAIN ($<ttype>6) = NULL_TREE;
@ -3583,13 +3584,13 @@ simple_stmt:
stmt
| BREAK ';'
{ emit_line_note (input_filename, lineno);
if (current_template_parms)
if (processing_template_decl)
add_tree (build_min_nt (BREAK_STMT));
else if ( ! expand_exit_something ())
error ("break statement not within loop or switch"); }
| CONTINUE ';'
{ emit_line_note (input_filename, lineno);
if (current_template_parms)
if (processing_template_decl)
add_tree (build_min_nt (CONTINUE_STMT));
else if (! expand_continue_loop (0))
error ("continue statement not within a loop"); }
@ -3637,7 +3638,7 @@ simple_stmt:
}
| GOTO '*' expr ';'
{
if (current_template_parms)
if (processing_template_decl)
add_tree (build_min_nt (GOTO_STMT, $3));
else
{ emit_line_note (input_filename, lineno);
@ -3645,7 +3646,7 @@ simple_stmt:
}
| GOTO identifier ';'
{
if (current_template_parms)
if (processing_template_decl)
add_tree (build_min_nt (GOTO_STMT, $2));
else
{

View File

@ -80,6 +80,7 @@ begin_template_parm_list ()
{
pushlevel (0);
declare_pseudo_global_level ();
++processing_template_decl;
}
/* Process information from new template parameter NEXT and append it to the
@ -141,7 +142,7 @@ process_template_parm (list, next)
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
DECL_INITIAL (decl) = tinfo;
DECL_INITIAL (parm) = tinfo;
TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl + 1);
TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl);
}
else
{
@ -150,7 +151,7 @@ process_template_parm (list, next)
decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
TYPE_MAIN_DECL (t) = decl;
parm = decl;
TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl + 1);
TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl);
}
SET_DECL_ARTIFICIAL (decl);
pushdecl (decl);
@ -171,7 +172,6 @@ end_template_parm_list (parms)
tree parm;
tree saved_parmlist = make_tree_vec (list_length (parms));
++processing_template_decl;
current_template_parms
= tree_cons (build_int_2 (0, processing_template_decl),
saved_parmlist, current_template_parms);
@ -187,7 +187,7 @@ end_template_parm_list (parms)
void
end_template_decl ()
{
if (! current_template_parms)
if (! processing_template_decl)
return;
/* This matches the pushlevel in begin_template_parm_list. */
@ -404,7 +404,7 @@ coerce_template_parms (parms, arglist, in_decl)
if (is_type)
{
val = groktypename (arg);
if (! current_template_parms)
if (! processing_template_decl)
{
tree t = target_type (val);
if (IS_AGGR_TYPE (t)
@ -419,12 +419,12 @@ coerce_template_parms (parms, arglist, in_decl)
{
tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
TREE_VEC_LENGTH (vec), in_decl);
if (current_template_parms)
if (processing_template_decl)
val = arg;
else
val = digest_init (t, arg, (tree *) 0);
if (val == error_mark_node || current_template_parms)
if (val == error_mark_node || processing_template_decl)
;
/* 14.2: Other template-arguments must be constant-expressions,
@ -743,10 +743,10 @@ lookup_template_class (d1, arglist, in_decl)
if (TYPE_BEING_DEFINED (ctx) && ctx == current_class_type)
{
tree save_parms = current_template_parms;
current_template_parms = NULL_TREE;
int save_temp = processing_template_decl;
processing_template_decl = 0;
t = xref_tag_from_type (TREE_TYPE (template), id, 0);
current_template_parms = save_parms;
processing_template_decl = save_temp;
}
else
{
@ -910,10 +910,13 @@ uses_template_parms (t)
case TYPENAME_TYPE:
return 1;
case SCOPE_REF:
return uses_template_parms (TREE_OPERAND (t, 0));
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
/* else fall through */
return uses_template_parms (TREE_OPERAND (t, 1));
default:
switch (TREE_CODE_CLASS (TREE_CODE (t)))
@ -1384,7 +1387,7 @@ tsubst (t, args, nargs, in_decl)
{
tree max = tsubst_expr (TYPE_MAX_VALUE (t), args, nargs, in_decl);
if (current_template_parms)
if (processing_template_decl)
{
tree itype = make_node (INTEGER_TYPE);
TYPE_MIN_VALUE (itype) = size_zero_node;
@ -1986,6 +1989,7 @@ tsubst_copy (t, args, nargs, in_decl)
case SIZEOF_EXPR:
case ARROW_EXPR:
case THROW_EXPR:
case TYPEID_EXPR:
return build1
(code, NULL_TREE,
tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
@ -2139,6 +2143,11 @@ tsubst_copy (t, args, nargs, in_decl)
else
return t;
case CONSTRUCTOR:
return build
(CONSTRUCTOR, tsubst (TREE_TYPE (t), args, nargs, in_decl), NULL_TREE,
tsubst_copy (CONSTRUCTOR_ELTS (t), args, nargs, in_decl));
default:
return t;
}
@ -2153,7 +2162,7 @@ tsubst_expr (t, args, nargs, in_decl)
if (t == NULL_TREE || t == error_mark_node)
return t;
if (current_template_parms)
if (processing_template_decl)
return tsubst_copy (t, args, nargs, in_decl);
switch (TREE_CODE (t))
@ -3255,6 +3264,8 @@ instantiate_decl (d)
int nested = in_function_p ();
int d_defined;
int pattern_defined;
int line = lineno;
char *file = input_filename;
if (TREE_CODE (d) == FUNCTION_DECL)
{
@ -3297,9 +3308,19 @@ instantiate_decl (d)
variable is a static const initialized in the class body. */
if (TREE_CODE (d) == VAR_DECL
&& ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
DECL_INITIAL (d) = tsubst_expr
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), tmpl);
{
lineno = DECL_SOURCE_LINE (d);
input_filename = DECL_SOURCE_FILE (d);
pushclass (DECL_CONTEXT (d), 2);
DECL_INITIAL (d) = tsubst_expr
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), tmpl);
popclass (1);
lineno = line;
input_filename = file;
}
if (! pattern_defined
|| (TREE_CODE (d) == FUNCTION_DECL && ! DECL_INLINE (d)
@ -3320,6 +3341,9 @@ instantiate_decl (d)
push_to_top_level ();
lineno = DECL_SOURCE_LINE (d);
input_filename = DECL_SOURCE_FILE (d);
/* Trick tsubst into giving us a new decl in case the template changed. */
save_ti = DECL_TEMPLATE_INFO (pattern);
DECL_TEMPLATE_INFO (pattern) = NULL_TREE;
@ -3328,9 +3352,13 @@ instantiate_decl (d)
/* And set up DECL_INITIAL, since tsubst doesn't. */
if (TREE_CODE (td) == VAR_DECL)
DECL_INITIAL (td) = tsubst_expr
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), tmpl);
{
pushclass (DECL_CONTEXT (d), 2);
DECL_INITIAL (td) = tsubst_expr
(DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args), tmpl);
popclass (1);
}
/* Convince duplicate_decls to use the DECL_ARGUMENTS from the new decl. */
if (TREE_CODE (d) == FUNCTION_DECL)
@ -3354,11 +3382,6 @@ instantiate_decl (d)
else if (TREE_CODE (d) == FUNCTION_DECL)
{
tree t = DECL_SAVED_TREE (pattern);
int line = lineno;
char *file = input_filename;
lineno = DECL_SOURCE_LINE (d);
input_filename = DECL_SOURCE_FILE (d);
start_function (NULL_TREE, d, NULL_TREE, 1);
store_parm_decls ();
@ -3392,11 +3415,11 @@ instantiate_decl (d)
TREE_VEC_LENGTH (args), tmpl);
finish_function (lineno, 0, nested);
lineno = line;
input_filename = file;
}
lineno = line;
input_filename = file;
pop_from_top_level ();
pop_tinst_level ();

View File

@ -30,6 +30,10 @@ Boston, MA 02111-1307, USA. */
#undef NULL
#define NULL 0
#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif
extern tree define_function ();
extern tree build_t_desc_overload ();
extern struct obstack *permanent_obstack;
@ -111,13 +115,59 @@ build_headof (exp)
return build (PLUS_EXPR, type, exp,
convert (ptrdiff_type_node, offset));
}
/* Build a call to a generic entry point taking and returning void. */
static tree
call_void_fn (name)
char *name;
{
tree d = get_identifier (name);
tree type;
if (IDENTIFIER_GLOBAL_VALUE (d))
d = IDENTIFIER_GLOBAL_VALUE (d);
else
{
push_obstacks (&permanent_obstack, &permanent_obstack);
type = build_function_type (void_type_node, void_list_node);
d = build_lang_decl (FUNCTION_DECL, d, type);
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1;
pushdecl_top_level (d);
make_function_rtl (d);
assemble_external (d);
pop_obstacks ();
}
return build_call (d, void_type_node, NULL_TREE);
}
/* Get a bad_cast node for the program to throw...
See libstdc++/exception.cc for __throw_bad_cast */
static tree
throw_bad_cast ()
{
return call_void_fn ("__throw_bad_cast");
}
static tree
throw_bad_typeid ()
{
return call_void_fn ("__throw_bad_typeid");
}
/* Return the type_info node associated with the expression EXP. If EXP is
a reference to a polymorphic class, return the dynamic type; otherwise
return the static type of the expression. */
/* Return the type_info function associated with the expression EXP. If
EXP is a reference to a polymorphic class, return the dynamic type;
otherwise return the static type of the expression. */
tree
build_typeid (exp)
get_tinfo_fn_dynamic (exp)
tree exp;
{
tree type;
@ -127,14 +177,6 @@ build_typeid (exp)
type = TREE_TYPE (exp);
/* Strip top-level cv-qualifiers. */
type = TYPE_MAIN_VARIANT (type);
/* if b is an instance of B, typeid(b) == typeid(B). Do this before
reference trickiness. */
if (TREE_CODE (exp) == VAR_DECL && TREE_CODE (type) == RECORD_TYPE)
return get_typeid (type);
/* peel back references, so they match. */
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
@ -142,12 +184,8 @@ build_typeid (exp)
/* Peel off cv qualifiers. */
type = TYPE_MAIN_VARIANT (type);
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
if (TREE_CODE (type) == RECORD_TYPE)
type = build_reference_type (type);
/* If exp is a reference to polymorphic type, get the real type_info. */
if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_VIRTUAL_P (TREE_TYPE (type)))
if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0))
{
/* build reference to type_info from vtable. */
tree t;
@ -156,7 +194,7 @@ build_typeid (exp)
warning ("taking dynamic typeid of object without -frtti");
/* If we don't have rtti stuff, get to a sub-object that does. */
if (!CLASSTYPE_VFIELDS (TREE_TYPE (type)))
if (! CLASSTYPE_VFIELDS (type))
{
exp = build_unary_op (ADDR_EXPR, exp, 0);
exp = build_headof_sub (exp);
@ -168,14 +206,57 @@ build_typeid (exp)
else
t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
TREE_TYPE (t) = build_pointer_type (tinfo_fn_type);
t = build (CALL_EXPR, TREE_TYPE (tinfo_fn_type), t, NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (t) = 1;
return convert_from_reference (t);
return t;
}
/* otherwise return the type_info for the static type of the expr. */
return get_typeid (type);
return get_tinfo_fn (TYPE_MAIN_VARIANT (type));
}
tree
build_typeid (exp)
tree exp;
{
exp = get_tinfo_fn_dynamic (exp);
exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE);
return convert_from_reference (exp);
}
tree
build_x_typeid (exp)
tree exp;
{
tree cond = NULL_TREE;
tree type = TREE_TYPE (tinfo_fn_type);
int nonnull;
if (processing_template_decl)
return build_min_nt (TYPEID_EXPR, exp);
if (TREE_CODE (exp) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
&& TYPE_VIRTUAL_P (TREE_TYPE (exp))
&& ! resolves_to_fixed_type_p (exp, &nonnull)
&& ! nonnull)
{
exp = stabilize_reference (exp);
cond = convert (boolean_type_node, TREE_OPERAND (exp, 0));
}
exp = get_tinfo_fn_dynamic (exp);
exp = build_call (exp, type, NULL_TREE);
if (cond)
{
tree bad = throw_bad_typeid ();
bad = build_compound_expr
(tree_cons (NULL_TREE, bad, build_tree_list
(NULL_TREE, convert (type, integer_zero_node))));
exp = build (COND_EXPR, type, cond, exp, bad);
}
return convert_from_reference (exp);
}
tree
@ -193,7 +274,7 @@ get_tinfo_var (type)
If our struct layout or the type_info classes are changed, this will
need to be modified. */
if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
size = 4 * POINTER_SIZE;
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
else if (TREE_CODE (type) == POINTER_TYPE
&& ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
|| TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
@ -207,7 +288,7 @@ get_tinfo_var (type)
(TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
size = 3 * POINTER_SIZE;
else
size = 4 * POINTER_SIZE;
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
}
else
size = 2 * POINTER_SIZE;
@ -266,9 +347,8 @@ tree
get_typeid_1 (type)
tree type;
{
tree t = build (CALL_EXPR, TREE_TYPE (tinfo_fn_type),
default_conversion (get_tinfo_fn (type)), NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (t) = 1;
tree t = build_call
(get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE);
return convert_from_reference (t);
}
@ -296,37 +376,6 @@ get_typeid (type)
return get_typeid_1 (type);
}
/* Get a bad_cast node for the program to throw...
See libstdc++/exception.cc for __throw_bad_cast */
static tree
throw_bad_cast ()
{
tree d = get_identifier ("__throw_bad_cast");
tree type;
if (IDENTIFIER_GLOBAL_VALUE (d))
return IDENTIFIER_GLOBAL_VALUE (d);
push_obstacks (&permanent_obstack, &permanent_obstack);
type = build_function_type (void_type_node, void_list_node);
d = build_lang_decl (FUNCTION_DECL, d, type);
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1;
pushdecl_top_level (d);
make_function_rtl (d);
assemble_external (d);
pop_obstacks ();
d = build (CALL_EXPR, void_type_node, default_conversion (d), NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (d) = 1;
return d;
}
/* Check whether TEST is null before returning RESULT. If TEST is used in
RESULT, it must have previously had a save_expr applied to it. */
@ -355,7 +404,7 @@ build_dynamic_cast (type, expr)
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
{
tree t = build_min (DYNAMIC_CAST_EXPR, type, expr);
return t;
@ -497,19 +546,22 @@ build_dynamic_cast (type, expr)
expr2 = build_headof (expr1);
if (ec == POINTER_TYPE)
td1 = build_typeid (build_indirect_ref (expr, NULL_PTR));
td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR));
else
td1 = build_typeid (expr);
td1 = get_tinfo_fn_dynamic (expr);
td1 = decay_conversion (td1);
td2 = get_typeid (TREE_TYPE (type));
td3 = get_typeid (TREE_TYPE (exprtype));
td2 = decay_conversion
(get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
td3 = decay_conversion
(get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
elems = tree_cons
(NULL_TREE, TREE_OPERAND (td1, 0), tree_cons
(NULL_TREE, TREE_OPERAND (td2, 0), tree_cons
(NULL_TREE, td1, tree_cons
(NULL_TREE, td2, tree_cons
(NULL_TREE, build_int_2 (1, 0), tree_cons
(NULL_TREE, expr2, tree_cons
(NULL_TREE, TREE_OPERAND (td3, 0), tree_cons
(NULL_TREE, td3, tree_cons
(NULL_TREE, expr1, NULL_TREE))))));
dcast_fn = get_identifier ("__dynamic_cast");
@ -520,14 +572,12 @@ build_dynamic_cast (type, expr)
tree tmp;
push_obstacks (&permanent_obstack, &permanent_obstack);
tmp = build_reference_type
(build_type_variant (type_info_type_node, 1, 0));
tmp = tree_cons
(NULL_TREE, tmp, tree_cons
(NULL_TREE, tmp, tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
(NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, tmp, tree_cons
(NULL_TREE, TREE_TYPE (td1), tree_cons
(NULL_TREE, ptr_type_node, void_list_node))))));
tmp = build_function_type (ptr_type_node, tmp);
dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp);
@ -540,15 +590,16 @@ build_dynamic_cast (type, expr)
pop_obstacks ();
}
result = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (dcast_fn)),
decay_conversion (dcast_fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (result) = 1;
result = build_call
(dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
if (tc == REFERENCE_TYPE)
{
expr1 = throw_bad_cast ();
expr1 = build_compound_expr (tree_cons (NULL_TREE, expr1,
build_tree_list (NULL_TREE, convert (type, integer_zero_node))));
expr1 = build_compound_expr
(tree_cons (NULL_TREE, expr1,
build_tree_list (NULL_TREE, convert
(type, integer_zero_node))));
TREE_TYPE (expr1) = type;
result = save_expr (result);
return build (COND_EXPR, type, result, result, expr1);
@ -625,9 +676,7 @@ expand_si_desc (tdecl, type)
pop_obstacks ();
}
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
decay_conversion (fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (fn) = 1;
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@ -668,7 +717,7 @@ expand_class_desc (tdecl, type)
(FIELD_DECL, NULL_TREE,
build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
fields [1] = build_lang_field_decl
(FIELD_DECL, NULL_TREE, sizetype);
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
DECL_FIELD_SIZE (fields[1]) = 29;
@ -805,9 +854,7 @@ expand_class_desc (tdecl, type)
pop_obstacks ();
}
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
decay_conversion (fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (fn) = 1;
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@ -854,9 +901,7 @@ expand_ptr_desc (tdecl, type)
pop_obstacks ();
}
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
decay_conversion (fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (fn) = 1;
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@ -905,9 +950,7 @@ expand_attr_desc (tdecl, type)
pop_obstacks ();
}
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
decay_conversion (fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (fn) = 1;
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@ -947,9 +990,7 @@ expand_generic_desc (tdecl, type, fnname)
pop_obstacks ();
}
fn = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
decay_conversion (fn), elems, NULL_TREE);
TREE_SIDE_EFFECTS (fn) = 1;
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
expand_expr_stmt (fn);
}
@ -994,10 +1035,12 @@ synthesize_tinfo_fn (fndecl)
tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
expand_start_cond (tmp, 0);
if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
expand_attr_desc (tdecl, type);
if (TREE_CODE (type) == FUNCTION_TYPE)
expand_generic_desc (tdecl, type, "__rtti_func");
else if (TREE_CODE (type) == ARRAY_TYPE)
expand_generic_desc (tdecl, type, "__rtti_array");
else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
expand_attr_desc (tdecl, type);
else if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
@ -1022,8 +1065,6 @@ synthesize_tinfo_fn (fndecl)
}
else if (TREE_CODE (type) == ENUMERAL_TYPE)
expand_generic_desc (tdecl, type, "__rtti_user");
else if (TREE_CODE (type) == FUNCTION_TYPE)
expand_generic_desc (tdecl, type, "__rtti_func");
else
my_friendly_abort (252);

125
gcc/cp/tinfo.cc Normal file
View File

@ -0,0 +1,125 @@
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
// Copyright (C) 1994, 1996 Free Software Foundation
// This file is part of GNU CC.
// GNU CC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// GNU CC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with GNU CC; see the file COPYING. If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// As a special exception, if you link this library with other files,
// some of which are compiled with GCC, to produce an executable,
// this library does not by itself cause the resulting executable
// to be covered by the GNU General Public License.
// This exception does not however invalidate any other reasons why
// the executable file might be covered by the GNU General Public License.
#include <stddef.h>
#include "tinfo.h"
#include "new" // for placement new
// This file contains the minimal working set necessary to link with code
// that uses virtual functions and -frtti but does not actually use RTTI
// functionality.
type_info::
~type_info ()
{ }
extern "C" void
__rtti_class (void *addr, const char *name,
const __class_type_info::base_info *bl, size_t bn)
{ new (addr) __class_type_info (name, bl, bn); }
extern "C" void
__rtti_si (void *addr, const char *n, const type_info *ti)
{
new (addr) __si_type_info
(n, static_cast <const __user_type_info &> (*ti));
}
extern "C" void
__rtti_user (void *addr, const char *name)
{ new (addr) __user_type_info (name); }
// dynamic_cast helper methods.
// Returns a pointer to the desired sub-object or 0.
void * __user_type_info::
dcast (const type_info& to, int, void *addr, const type_info *, void *) const
{ return (*this == to) ? addr : 0; }
void * __si_type_info::
dcast (const type_info& to, int require_public, void *addr,
const type_info *sub, void *subptr) const
{
if (*this == to)
return addr;
return base.dcast (to, require_public, addr, sub, subptr);
}
void* __class_type_info::
dcast (const type_info& desired, int is_public, void *objptr,
const type_info *sub, void *subptr) const
{
if (*this == desired)
return objptr;
void *match_found = 0;
for (int i = 0; i < n_bases; i++)
{
if (is_public && base_list[i].access != PUBLIC)
continue;
void *p = (char *)objptr + base_list[i].offset;
if (base_list[i].is_virtual)
p = *(void **)p;
p = base_list[i].base->dcast (desired, is_public, p, sub, subptr);
if (p)
{
if (match_found == 0)
match_found = p;
else if (match_found != p)
{
if (sub)
{
// Perhaps we're downcasting from *sub to desired; see if
// subptr is a subobject of exactly one of {match_found,p}.
const __user_type_info &d =
static_cast <const __user_type_info &> (desired);
void *os = d.dcast (*sub, 1, match_found);
void *ns = d.dcast (*sub, 1, p);
if (os == ns)
/* ambiguous -- subptr is a virtual base */;
else if (os == subptr)
continue;
else if (ns == subptr)
{
match_found = p;
continue;
}
}
// base found at two different pointers,
// conversion is not unique
return 0;
}
}
}
return match_found;
}

311
gcc/cp/tinfo2.cc Normal file
View File

@ -0,0 +1,311 @@
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
// Copyright (C) 1994, 1996 Free Software Foundation
// This file is part of GNU CC.
// GNU CC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// GNU CC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with GNU CC; see the file COPYING. If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
// As a special exception, if you link this library with other files,
// some of which are compiled with GCC, to produce an executable,
// this library does not by itself cause the resulting executable
// to be covered by the GNU General Public License.
// This exception does not however invalidate any other reasons why
// the executable file might be covered by the GNU General Public License.
#include <stddef.h>
#include "tinfo.h"
#include "new" // for placement new
// service function for comparing types by name.
static inline int
fast_compare (const char *n1, const char *n2) {
int c;
if (n1 == n2) return 0;
if (n1 == 0) return *n2;
else if (n2 == 0) return *n1;
c = (int)*n1++ - (int)*n2++;
return c == 0 ? strcmp (n1, n2) : c;
};
bool
type_info::before (const type_info &arg)
{
return fast_compare (name (), arg.name ()) < 0;
}
#ifdef _WIN32
bool type_info::
operator== (const type_info& arg) const
{
return fast_compare (name (), arg.name ()) == 0;
}
bool type_info::
operator!= (const type_info& arg) const
{
return fast_compare (name (), arg.name ()) != 0;
}
#endif
// type info for pointer type.
struct __pointer_type_info : public type_info {
const type_info& type;
__pointer_type_info (const char *n, const type_info& ti)
: type_info (n), type (ti) {}
};
// type info for attributes
struct __attr_type_info : public type_info {
enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 };
const type_info& type;
cv attr;
__attr_type_info (const char *n, cv a, const type_info& t)
: type_info (n), type (t), attr (a) {}
};
// type_info for builtin type
struct __builtin_type_info : public type_info {
__builtin_type_info (const char *n): type_info (n) {}
};
// type info for function.
struct __func_type_info : public type_info {
__func_type_info (const char *n) : type_info (n) {}
};
// type info for pointer to member function.
struct __ptmf_type_info : public type_info {
__ptmf_type_info (const char *n) : type_info (n) {}
};
// type info for pointer to data member.
struct __ptmd_type_info : public type_info {
__ptmd_type_info (const char *n): type_info (n) {}
};
// type info for array.
struct __array_type_info : public type_info {
__array_type_info (const char *n): type_info (n) {}
};
// Entry points for the compiler.
/* Low level match routine used by compiler to match types of catch
variables and thrown objects. */
extern "C" void*
__throw_type_match_rtti (void *catch_type_r, void *throw_type_r, void *objptr)
{
const type_info &catch_type = *(const type_info *)catch_type_r;
const type_info &throw_type = *(const type_info *)throw_type_r;
if (catch_type == throw_type)
return objptr;
#if 0
printf ("We want to match a %s against a %s!\n",
throw_type.name (), catch_type.name ());
#endif
void *new_objptr = 0;
if (const __user_type_info *p
= dynamic_cast <const __user_type_info *> (&throw_type))
{
/* The 1 skips conversions to private bases. */
new_objptr = p->dcast (catch_type, 1, objptr);
}
else if (const __pointer_type_info *fr =
dynamic_cast <const __pointer_type_info *> (&throw_type))
{
const __pointer_type_info *to =
dynamic_cast <const __pointer_type_info *> (&catch_type);
if (! to)
goto fail;
const type_info *subfr = &fr->type, *subto = &to->type;
__attr_type_info::cv cvfrom, cvto;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subfr))
{
cvfrom = at->attr;
subfr = &at->type;
}
else
cvfrom = __attr_type_info::NONE;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subto))
{
cvto = at->attr;
subto = &at->type;
}
else
cvto = __attr_type_info::NONE;
if (((cvfrom & __attr_type_info::CONST)
> (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
> (cvto & __attr_type_info::VOLATILE)))
goto fail;
if (*subto == *subfr)
new_objptr = objptr;
else if (*subto == typeid (void)
&& dynamic_cast <const __func_type_info *> (subfr) == 0)
new_objptr = objptr;
else if (const __user_type_info *p
= dynamic_cast <const __user_type_info *> (subfr))
{
/* The 1 skips conversions to private bases. */
new_objptr = p->dcast (*subto, 1, objptr);
}
else if (const __pointer_type_info *pfr
= dynamic_cast <const __pointer_type_info *> (subfr))
{
// Multi-level pointer conversion.
const __pointer_type_info *pto
= dynamic_cast <const __pointer_type_info *> (subto);
if (! pto)
goto fail;
bool constp = (cvto & __attr_type_info::CONST);
for (subto = &pto->type, subfr = &pfr->type; ;
subto = &pto->type, subfr = &pfr->type)
{
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subfr))
{
cvfrom = at->attr;
subfr = &at->type;
}
else
cvfrom = __attr_type_info::NONE;
if (const __attr_type_info *at
= dynamic_cast <const __attr_type_info *> (subto))
{
cvto = at->attr;
subto = &at->type;
}
else
cvto = __attr_type_info::NONE;
if (((cvfrom & __attr_type_info::CONST)
> (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
> (cvto & __attr_type_info::VOLATILE)))
goto fail;
if (! constp
&& (((cvfrom & __attr_type_info::CONST)
< (cvto & __attr_type_info::CONST))
|| ((cvfrom & __attr_type_info::VOLATILE)
< (cvto & __attr_type_info::VOLATILE))))
goto fail;
if (*subto == *subfr)
{
new_objptr = objptr;
break;
}
pto = dynamic_cast <const __pointer_type_info *> (subto);
pfr = dynamic_cast <const __pointer_type_info *> (subfr);
if (! pto || ! pfr)
goto fail;
if (! (cvto & __attr_type_info::CONST))
constp = false;
}
}
}
fail:
#if 0
if (new_objptr)
printf ("It converts, delta is %d\n", new_objptr-objptr);
#endif
return new_objptr;
}
extern "C" void
__rtti_ptr (void *addr, const char *n, const type_info *ti)
{ new (addr) __pointer_type_info (n, *ti); }
extern "C" void
__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti)
{
new (addr) __attr_type_info
(n, static_cast <__attr_type_info::cv> (attrval), *ti);
}
extern "C" void
__rtti_func (void *addr, const char *name)
{ new (addr) __func_type_info (name); }
extern "C" void
__rtti_ptmf (void *addr, const char *name)
{ new (addr) __ptmf_type_info (name); }
extern "C" void
__rtti_ptmd (void *addr, const char *name)
{ new (addr) __ptmd_type_info (name); }
extern "C" void
__rtti_array (void *addr, const char *name)
{ new (addr) __array_type_info (name); }
extern "C" void *
__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void),
int require_public, void *address,
const type_info & (*sub)(void), void *subptr)
{
return static_cast <const __user_type_info &> (from ()).dcast
(to (), require_public, address, &(sub ()), subptr);
}
// type_info nodes and functions for the builtin types. The mangling here
// must match the mangling in gcc/cp/rtti.c.
#define BUILTIN(mangled) \
unsigned char __ti##mangled [sizeof (__builtin_type_info)] \
__attribute__ ((aligned (__alignof__ (void *)))); \
extern "C" const type_info &__tf##mangled (void) { \
if ((*(void **) __ti##mangled) == 0) \
new (__ti##mangled) __builtin_type_info (#mangled); \
return *(type_info *)__ti##mangled; \
}
BUILTIN (v); BUILTIN (x); BUILTIN (l); BUILTIN (i); BUILTIN (s); BUILTIN (b);
BUILTIN (c); BUILTIN (w); BUILTIN (r); BUILTIN (d); BUILTIN (f);
BUILTIN (Ui); BUILTIN (Ul); BUILTIN (Ux); BUILTIN (Us); BUILTIN (Uc);

View File

@ -356,6 +356,7 @@ break_out_calls (exp)
extern struct obstack *current_obstack;
extern struct obstack permanent_obstack, class_obstack;
extern struct obstack *saveable_obstack;
extern struct obstack *expression_obstack;
/* Here is how primitive or already-canonicalized types' hash
codes are made. MUST BE CONSISTENT WITH tree.c !!! */
@ -421,7 +422,7 @@ build_cplus_array_type_1 (elt_type, index_type)
saveable_obstack = &permanent_obstack;
}
if (current_template_parms)
if (processing_template_decl)
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
@ -1615,8 +1616,8 @@ mapcar (t, func)
mapcar (TYPE_ARG_TYPES (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
case ARRAY_TYPE:
tmp = build_array_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_DOMAIN (t), func));
tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_DOMAIN (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
case INTEGER_TYPE:
tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
@ -1632,6 +1633,11 @@ mapcar (t, func)
mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
case CONSTRUCTOR:
t = copy_node (t);
CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
return t;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
return build_ptrmemfunc_type
@ -1673,20 +1679,20 @@ copy_to_permanent (t)
{
register struct obstack *ambient_obstack = current_obstack;
register struct obstack *ambient_saveable_obstack = saveable_obstack;
int resume;
register struct obstack *ambient_expression_obstack = expression_obstack;
if (t == NULL_TREE || TREE_PERMANENT (t))
return t;
saveable_obstack = &permanent_obstack;
current_obstack = saveable_obstack;
resume = suspend_momentary ();
expression_obstack = saveable_obstack;
t = mapcar (t, perm_manip);
resume_momentary (resume);
current_obstack = ambient_obstack;
saveable_obstack = ambient_saveable_obstack;
expression_obstack = ambient_expression_obstack;
return t;
}

View File

@ -83,7 +83,7 @@ require_complete_type (value)
{
tree type;
if (current_template_parms)
if (processing_template_decl)
return value;
type = TREE_TYPE (value);
@ -132,8 +132,7 @@ complete_type (type)
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
{
tree t = complete_type (TREE_TYPE (type));
if (TYPE_SIZE (t) != NULL_TREE
&& current_template_parms == NULL_TREE)
if (TYPE_SIZE (t) != NULL_TREE && ! processing_template_decl)
layout_type (type);
TYPE_NEEDS_CONSTRUCTING (type)
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
@ -1275,7 +1274,7 @@ c_sizeof (type)
enum tree_code code = TREE_CODE (type);
tree t;
if (current_template_parms)
if (processing_template_decl)
return build_min (SIZEOF_EXPR, sizetype, type);
if (code == FUNCTION_TYPE)
@ -1341,7 +1340,7 @@ tree
expr_sizeof (e)
tree e;
{
if (current_template_parms)
if (processing_template_decl)
return build_min (SIZEOF_EXPR, sizetype, e);
if (TREE_CODE (e) == COMPONENT_REF
@ -1623,8 +1622,8 @@ build_object_ref (datum, basetype, field)
{
tree binfo = binfo_or_else (basetype, dtype);
if (binfo)
return build_component_ref (build_scoped_ref (datum, basetype),
field, binfo, 1);
return build_x_component_ref (build_scoped_ref (datum, basetype),
field, binfo, 1);
}
return error_mark_node;
}
@ -1709,7 +1708,7 @@ build_component_ref (datum, component, basetype_path, protect)
register tree field = NULL;
register tree ref;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (COMPONENT_REF, datum, component);
/* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference
@ -1937,6 +1936,22 @@ build_component_ref (datum, component, basetype_path, protect)
return ref;
}
/* Variant of build_component_ref for use in expressions, which should
never have REFERENCE_TYPE. */
tree
build_x_component_ref (datum, component, basetype_path, protect)
tree datum, component, basetype_path;
int protect;
{
tree t = build_component_ref (datum, component, basetype_path, protect);
if (! processing_template_decl)
t = convert_from_reference (t);
return t;
}
/* Given an expression PTR for a pointer, return an expression
for the value pointed to.
@ -1952,7 +1967,7 @@ build_x_indirect_ref (ptr, errorstring)
{
tree rval;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (INDIRECT_REF, ptr);
rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, NULL_TREE);
@ -2213,7 +2228,7 @@ build_x_function_call (function, params, decl)
if (function == error_mark_node)
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (CALL_EXPR, function, params, NULL_TREE);
type = TREE_TYPE (function);
@ -2908,7 +2923,7 @@ build_x_binary_op (code, arg1, arg2)
{
tree rval;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (code, arg1, arg2);
if (flag_ansi_overloading)
@ -3958,7 +3973,7 @@ build_x_unary_op (code, xarg)
enum tree_code code;
tree xarg;
{
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (code, xarg, NULL_TREE);
/* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
@ -4005,7 +4020,7 @@ condition_conversion (expr)
tree expr;
{
tree t;
if (current_template_parms)
if (processing_template_decl)
return expr;
t = convert (boolean_type_node, expr);
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
@ -4653,7 +4668,7 @@ build_x_conditional_expr (ifexp, op1, op2)
{
tree rval = NULL_TREE;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (COND_EXPR, ifexp, op1, op2);
if (flag_ansi_overloading)
@ -4988,7 +5003,7 @@ build_x_compound_expr (list)
tree rest = TREE_CHAIN (list);
tree result;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (COMPOUND_EXPR, list, NULL_TREE);
if (rest == NULL_TREE)
@ -5068,7 +5083,7 @@ build_static_cast (type, expr)
if (TREE_CODE (expr) == OFFSET_REF)
expr = resolve_offset_ref (expr);
if (current_template_parms)
if (processing_template_decl)
{
tree t = build_min (STATIC_CAST_EXPR, type, expr);
return t;
@ -5160,7 +5175,7 @@ build_reinterpret_cast (type, expr)
if (TREE_CODE (expr) == OFFSET_REF)
expr = resolve_offset_ref (expr);
if (current_template_parms)
if (processing_template_decl)
{
tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
return t;
@ -5252,7 +5267,7 @@ build_const_cast (type, expr)
if (TREE_CODE (expr) == OFFSET_REF)
expr = resolve_offset_ref (expr);
if (current_template_parms)
if (processing_template_decl)
{
tree t = build_min (CONST_CAST_EXPR, type, expr);
return t;
@ -5361,7 +5376,7 @@ build_c_cast (type, expr, allow_nonconverting)
return error_mark_node;
}
if (current_template_parms)
if (processing_template_decl)
{
tree t = build_min (CAST_EXPR, type,
min_tree_cons (NULL_TREE, value, NULL_TREE));
@ -5993,7 +6008,7 @@ build_x_modify_expr (lhs, modifycode, rhs)
enum tree_code modifycode;
tree rhs;
{
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (MODOP_EXPR, lhs,
build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs);
@ -7022,7 +7037,7 @@ c_expand_return (retval)
return;
}
if (current_template_parms)
if (processing_template_decl)
{
add_tree (build_min_nt (RETURN_STMT, retval));
return;

View File

@ -607,6 +607,10 @@ store_init_value (decl, init)
}
}
if (TYPE_PTRMEMFUNC_P (type) && TREE_CODE (init) == CONSTRUCTOR
&& TREE_TYPE (init) == NULL_TREE)
cp_pedwarn ("initializer list for `%T'", type);
/* End of special C++ code. */
/* Digest the specified initializer into an expression. */
@ -1011,9 +1015,6 @@ process_init_constructor (type, init, elts)
sorry ("initializer list for object using virtual functions");
return error_mark_node;
}
if (TYPE_PTRMEMFUNC_P (type))
cp_pedwarn ("initializer list for `%T'", type);
}
for (field = TYPE_FIELDS (type); field && tail;
@ -1262,7 +1263,7 @@ build_x_arrow (datum)
if (type == error_mark_node)
return error_mark_node;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (ARROW_EXPR, rval);
if (TREE_CODE (rval) == OFFSET_REF)
@ -1338,7 +1339,7 @@ build_m_component_ref (datum, component)
tree rettype;
tree binfo;
if (current_template_parms)
if (processing_template_decl)
return build_min_nt (DOTSTAR_EXPR, datum, component);
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
@ -1423,7 +1424,7 @@ build_functional_cast (exp, parms)
else
type = exp;
if (current_template_parms)
if (processing_template_decl)
return build_min (CAST_EXPR, type, parms);
if (IS_SIGNATURE (type))