summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-09-30 21:34:04 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-09-30 21:34:04 +0000
commit3cc0b4b927b943873f4aa7dea40aad5c448f14ba (patch)
tree7df90e2fe04ce0e37b684ebb2fa65e27a632aaa8 /gcc/cp
parent5da6226800b028774529c6e5b1b06b0b04c23c54 (diff)
downloadgcc-3cc0b4b927b943873f4aa7dea40aad5c448f14ba.tar.gz
89th Cygnus<->FSF quick merge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12883 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog171
-rw-r--r--gcc/cp/Make-lang.in50
-rw-r--r--gcc/cp/call.c19
-rw-r--r--gcc/cp/class.c5
-rw-r--r--gcc/cp/config-lang.in4
-rw-r--r--gcc/cp/cp-tree.def1
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/decl.c125
-rw-r--r--gcc/cp/decl2.c29
-rw-r--r--gcc/cp/error.c11
-rw-r--r--gcc/cp/except.c2
-rw-r--r--gcc/cp/exception.cc111
-rw-r--r--gcc/cp/expr.c2
-rw-r--r--gcc/cp/gxxint.texi7
-rw-r--r--gcc/cp/inc/exception42
-rw-r--r--gcc/cp/inc/new38
-rw-r--r--gcc/cp/inc/new.h13
-rw-r--r--gcc/cp/inc/typeinfo71
-rw-r--r--gcc/cp/init.c29
-rw-r--r--gcc/cp/input.c2
-rw-r--r--gcc/cp/lex.c40
-rw-r--r--gcc/cp/method.c6
-rw-r--r--gcc/cp/new.cc6
-rw-r--r--gcc/cp/parse.y83
-rw-r--r--gcc/cp/pt.c77
-rw-r--r--gcc/cp/rtti.c235
-rw-r--r--gcc/cp/tinfo.cc125
-rw-r--r--gcc/cp/tinfo2.cc311
-rw-r--r--gcc/cp/tree.c18
-rw-r--r--gcc/cp/typeck.c57
-rw-r--r--gcc/cp/typeck2.c13
31 files changed, 1417 insertions, 289 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1888c1bec00..7a518d14f36 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index c6a227bbebb..f7265c96124 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0b749f68fb3..9ae201c9313 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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. */
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 676b1363326..424c10cb87d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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));
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 7a9a5c558c7..66fe112519e 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -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
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index de30bda436b..ab271ea63fd 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -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)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 12552ec3180..0d5189f2139 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 01af1a56a86..245d521cf64 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 39a25729286..2a26a59a8f5 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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? */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 755b54b8bd5..80eb8e9c33c 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 2863e21645a..fefcd021f6b 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -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;
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
new file mode 100644
index 00000000000..8cf227a719a
--- /dev/null
+++ b/gcc/cp/exception.cc
@@ -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 ();
+}
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 7e8673b50a3..506d64c7284 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -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;
diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi
index be3d89659e3..dbfc2346883 100644
--- a/gcc/cp/gxxint.texi
+++ b/gcc/cp/gxxint.texi
@@ -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
diff --git a/gcc/cp/inc/exception b/gcc/cp/inc/exception
new file mode 100644
index 00000000000..d38806b81c4
--- /dev/null
+++ b/gcc/cp/inc/exception
@@ -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
diff --git a/gcc/cp/inc/new b/gcc/cp/inc/new
new file mode 100644
index 00000000000..4bfb960c851
--- /dev/null
+++ b/gcc/cp/inc/new
@@ -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
diff --git a/gcc/cp/inc/new.h b/gcc/cp/inc/new.h
new file mode 100644
index 00000000000..eed0910b668
--- /dev/null
+++ b/gcc/cp/inc/new.h
@@ -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__
diff --git a/gcc/cp/inc/typeinfo b/gcc/cp/inc/typeinfo
new file mode 100644
index 00000000000..bad3b66a8d1
--- /dev/null
+++ b/gcc/cp/inc/typeinfo
@@ -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
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 8ac11e888d6..af629caf051 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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;
diff --git a/gcc/cp/input.c b/gcc/cp/input.c
index 364b8e21813..e142bf4f99d 100644
--- a/gcc/cp/input.c
+++ b/gcc/cp/input.c
@@ -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);
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index f5701f45450..f91d939b2d9 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -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
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index c7c63d7cdd0..b127002b070 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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;
}
diff --git a/gcc/cp/new.cc b/gcc/cp/new.cc
new file mode 100644
index 00000000000..297b395e1db
--- /dev/null
+++ b/gcc/cp/new.cc
@@ -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"
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index c0a2c453deb..774bb047142 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f8161fae649..5b7caf37fbe 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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 ();
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 69513ac9d7a..f51ea644953 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -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);
diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc
new file mode 100644
index 00000000000..d82aaaf0431
--- /dev/null
+++ b/gcc/cp/tinfo.cc
@@ -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;
+}
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc
new file mode 100644
index 00000000000..10290a8e52b
--- /dev/null
+++ b/gcc/cp/tinfo2.cc
@@ -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);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ceb9acc3aec..0d0dc05318e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 944acc62e46..8d77956c064 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 16b29dc0c5d..786ca79706c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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))