OSDN Git Service

89th Cygnus<->FSF quick merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 Sep 1996 21:34:04 +0000 (21:34 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 Sep 1996 21:34:04 +0000 (21:34 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12883 138bc75d-0d04-0410-961f-82ee72b054a4

31 files changed:
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/config-lang.in
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/except.c
gcc/cp/exception.cc [new file with mode: 0644]
gcc/cp/expr.c
gcc/cp/gxxint.texi
gcc/cp/inc/exception [new file with mode: 0644]
gcc/cp/inc/new [new file with mode: 0644]
gcc/cp/inc/new.h [new file with mode: 0644]
gcc/cp/inc/typeinfo [new file with mode: 0644]
gcc/cp/init.c
gcc/cp/input.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/new.cc [new file with mode: 0644]
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/tinfo.cc [new file with mode: 0644]
gcc/cp/tinfo2.cc [new file with mode: 0644]
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 1888c1b..7a518d1 100644 (file)
@@ -1,3 +1,174 @@
+Mon Sep 30 12:58:40 1996  Mike Stump  <mrs@cygnus.com>
+
+       * input.c (sub_getch): Handle 8-bit characters in string literals.
+
+Sun Sep 29 03:12:01 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * tree.c (mapcar): Handle CONSTRUCTORs.
+       (copy_to_permanent): Handle expression_obstack properly.
+
+       * Make-lang.in (cplib2.txt): Also depend on the headers.
+
+       * rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE ==
+       INT_TYPE_SIZE.
+       (expand_class_desc): Use USItype for offset field.
+       * tinfo.h (struct __class_type_info): Likewise.
+
+       * method.c (build_overload_int): TYPE_PRECISION should be applied
+       to types.
+
+Sat Sep 28 14:44:50 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (build_new_op): A COND_EXPR involving void must be a
+       builtin.
+
+Fri Sep 27 16:40:30 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (build_x_component_ref): New fn.
+       (build_object_ref): Use it.
+       * parse.y (primary): Use it.
+       * decl2.c (build_expr_from_tree): Use it.
+       * cp-tree.h: Declare it.
+
+       * decl.c (start_decl): variable-sized arrays cannot be initialized.
+       * error.c (dump_type_suffix): Handle variable arrays.
+
+Fri Sep 27 13:14:05 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * Make-lang.in (exception.o): Put back compiling it with -fPIC.
+
+Fri Sep 27 03:00:09 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (lookup_name_real): Don't try to look up anything in a
+       TYPENAME_TYPE.
+
+       * tinfo2.cc (__throw_type_match_rtti): Oops.
+
+Thu Sep 26 22:11:05 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * Make-lang.in (exception.o): Use -fno-PIC for now.
+
+Thu Sep 26 10:59:00 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * rtti.c (build_dynamic_cast): Pass tinfo fns rather than
+       calling them.
+       (get_tinfo_fn_dynamic): Extracted from build_typeid.
+       * tinfo2.cc (__dynamic_cast): Adjust.
+       
+       * rtti.c (build_typeid): Use resolves_to_fixed_type_p.
+       (build_x_typeid): Likewise.
+
+       * parse.y: Call build_x_typeid instead of build_typeid.
+       * cp-tree.def: Add TYPEID_EXPR.
+       * pt.c (tsubst_copy): Handle typeid.
+       * decl2.c (build_expr_from_tree): Likewise.
+       * rtti.c (build_x_typeid): Throw bad_typeid from here.
+       (build_typeid): Not here.
+       * cp-tree.h: Declare build_x_typeid.
+
+Wed Sep 25 17:26:16 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (convert_like): Pull out constant values.
+
+       * tree.c (mapcar): Use build_cplus_array_type, not build_array_type.
+
+Wed Sep 25 17:28:53 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * decl.c (init_decl_processing): Create short int types before
+       creating size_t in case a machine description needs to use
+       unsigned short for size_t.
+
+Tue Sep 24 18:18:44 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * Make-lang.in (exception.o): Turn off pic.
+
+       * tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same
+       type, multi-level ptr conversions.
+
+       * rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast.
+       (throw_bad_cast): Use it.
+       (throw_bad_typeid): New fn.
+       (build_typeid): Throw bad_typeid as needed.
+       Use build_call.
+       (synthesize_tinfo_fn): Handle functions and arrays before checking
+       for cv-quals.
+
+       * Remove .h from standard C++ headers, add new.h, move into inc
+       subdirectory.
+
+       * exception*: Remove pointer from object, constructors.  Add
+       default exception::what that uses type_info::name.  Add
+       __throw_bad_typeid.
+
+       * init.c (build_new): Don't add a cookie to new (void *) T[2].
+
+Mon Sep 23 15:21:53 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * Make-lang.in: Building C++ code depends on cc1plus.
+
+Mon Sep 23 12:38:40 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as
+       a HOST_WIDE_INT, not a tree.
+
+Mon Sep 23 12:36:02 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * exception.cc: Don't include <stdlib.h>.
+
+       * Make-lang.in (c++.clean): Remove cplib2.*.
+
+Mon Sep 23 09:42:19 1996  Doug Evans  <dje@canuck.cygnus.com>
+
+       * parse.y (component_decl_1, component_costructor_declarator case):
+       Pass attributes/prefix_attributes in tree list.
+
+Mon Sep 23 01:18:50 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * tinfo{,2}.cc: #include <stddef.h> instead of <stdlib.h>.
+
+Sun Sep 22 05:31:22 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lex.c (do_identifier): Don't do deferred lookup in a template
+       header.
+
+       * typeck2.c (store_init_value): Oops.
+
+       * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}: 
+       New files for C++ lang-support library.
+       * Make-lang.in (CXX_EXTRA_HEADERS): Define.
+       (CXX_LIB2FUNCS): Define.
+       And rules for building the C++ lang-support code.
+       * config-lang.in (headers): Define.
+       (lib2funcs): Define.
+
+Sat Sep 21 19:17:28 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call
+       digest_init.
+       * pt.c (tsubst_copy): Compute type for CONSTRUCTOR.
+       * typeck2.c (store_init_value): Check for initializing pmf with { }
+       here.
+       (process_init_constructor): Not here.
+
+Thu Sep 19 16:41:07 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (begin_template_parm_list): Increment
+       processing_template_decl here.
+       (end_template_parm_list): Not here.
+       (process_template_parm): No need to add 1 to it now.
+       * *.c: Use processing_template_decl instead of current_template_parms
+       to check for being in a template.
+
+       * pt.c (uses_template_parms): Handle SCOPE_REF.  Fix CONSTRUCTOR.
+       (tsubst_copy): Handle CONSTRUCTOR.
+       (instantiate_decl): Set up context properly for variables.
+       * decl2.c (build_expr_from_tree): Handle CONSTRUCTOR.
+       * class.c (finish_struct): Reverse CLASSTYPE_TAGS.
+
+Wed Sep 18 13:30:20 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back.
+
 Wed Sep 18 04:24:07 1996  Jason Merrill  <jason@yorick.cygnus.com>
 
        * method.c (make_thunk): Call comdat_linkage before setting the
index c6a227b..f7265c9 100644 (file)
@@ -52,6 +52,15 @@ GXX_CROSS_NAME = `t='$(program_transform_cross_name)'; echo g++ | sed $$t`
 
 # The name to use for the demangler program.
 DEMANGLER_PROG = c++filt
+
+# Extra headers to install.
+CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
+       $(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
+
+# Extra code to include in libgcc2.
+CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o exception.o
+CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/exception.cc \
+       $(srcdir)/cp/tinfo.cc $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
 \f
 # 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
 \f
 # 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
index 0b749f6..9ae201c 100644 (file)
@@ -1410,7 +1410,7 @@ build_scoped_method_call (exp, basetype, name, parms)
       || basetype == error_mark_node)
     return error_mark_node;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (TREE_CODE (name) == BIT_NOT_EXPR)
        {
@@ -1681,7 +1681,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
       || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
     return error_mark_node;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (TREE_CODE (name) == BIT_NOT_EXPR)
        {
@@ -4545,9 +4545,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
   if (arg3 && TREE_CODE (arg3) == OFFSET_REF)
     arg3 = resolve_offset_ref (arg3);
 
-  if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
-      && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)))
-      && (! arg3 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
+  if (code == COND_EXPR)
+    {
+      if (TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE
+         || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE
+         || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))
+             && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3))))
+       goto builtin;
+    }
+  else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1))
+          && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2))))
     goto builtin;
 
   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
@@ -4871,6 +4878,8 @@ convert_like (convs, expr)
     case IDENTITY_CONV:
       if (type_unknown_p (expr))
        expr = instantiate_type (TREE_TYPE (convs), expr, 1);
+      if (TREE_READONLY_DECL_P (expr))
+       expr = decl_constant_value (expr);
       return expr;
     case AMBIG_CONV:
       /* Call build_user_type_conversion again for the error.  */
index 676b136..424c10c 100644 (file)
@@ -4341,7 +4341,10 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
      defined for this type.  */
   if (CLASSTYPE_TAGS (t) || dummy)
     {
-      x = CLASSTYPE_TAGS (t);
+      /* The list of tags was built up in pushtag in reverse order; we need
+        to fix that so that enumerators will be processed in forward order
+        in template instantiation.  */
+      CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t));
       while (x)
        {
          tree tag = TYPE_NAME (TREE_VALUE (x));
index 7a9a5c5..66fe112 100644 (file)
@@ -33,3 +33,7 @@ compilers="cc1plus\$(exeext)"
 stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
 
 diff_excludes="-x cp/parse.c -x cp/parse.h"
+
+headers='$(CXX_EXTRA_HEADERS)'
+
+lib2funcs=cplib2.txt
index de30bda..ab271ea 100644 (file)
@@ -120,6 +120,7 @@ DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", "1", 1)
 DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
 DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
 DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
+DEFTREECODE (TYPEID_EXPR, "typeid_expr", "e", 1)
 
 DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
 DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)
index 12552ec..0d5189f 100644 (file)
@@ -2169,7 +2169,9 @@ extern void finish_repo                           PROTO((void));
 
 /* in rtti.c */
 extern tree get_tinfo_fn                       PROTO((tree));
+extern tree get_tinfo_fn_dynamic               PROTO((tree));
 extern tree build_typeid                       PROTO((tree));
+extern tree build_x_typeid                     PROTO((tree));
 extern tree get_typeid                         PROTO((tree));
 extern tree build_dynamic_cast                 PROTO((tree, tree));
 
@@ -2454,6 +2456,7 @@ extern tree default_conversion                    PROTO((tree));
 extern tree build_object_ref                   PROTO((tree, tree, tree));
 extern tree build_component_ref_1              PROTO((tree, tree, int));
 extern tree build_component_ref                        PROTO((tree, tree, tree, int));
+extern tree build_x_component_ref              PROTO((tree, tree, tree, int));
 extern tree build_x_indirect_ref               PROTO((tree, char *));
 extern tree build_indirect_ref                 PROTO((tree, char *));
 extern tree build_x_array_ref                  PROTO((tree, tree));
index 01af1a5..245d521 100644 (file)
@@ -1773,6 +1773,7 @@ struct saved_scope {
   int minimal_parse_mode;
   tree last_function_parms;
   tree template_parms;
+  HOST_WIDE_INT processing_template_decl;
   tree previous_class_type, previous_class_values;
 };
 static struct saved_scope *current_saved_scope;
@@ -1869,6 +1870,7 @@ maybe_push_to_top_level (pseudo)
   s->minimal_parse_mode = minimal_parse_mode;
   s->last_function_parms = last_function_parms;
   s->template_parms = current_template_parms;
+  s->processing_template_decl = processing_template_decl;
   s->previous_class_type = previous_class_type;
   s->previous_class_values = previous_class_values;
 
@@ -1884,7 +1886,10 @@ maybe_push_to_top_level (pseudo)
   minimal_parse_mode = 0;
   previous_class_type = previous_class_values = NULL_TREE;
   if (!pseudo)
-    current_template_parms = NULL_TREE;
+    {
+      current_template_parms = NULL_TREE;
+      processing_template_decl = 0;
+    }
 
   s->prev = current_saved_scope;
   s->old_bindings = old_bindings;
@@ -1943,6 +1948,7 @@ pop_from_top_level ()
   minimal_parse_mode = s->minimal_parse_mode;
   last_function_parms = s->last_function_parms;
   current_template_parms = s->template_parms;
+  processing_template_decl = s->processing_template_decl;
   previous_class_type = s->previous_class_type;
   previous_class_values = s->previous_class_values;
 
@@ -2078,7 +2084,7 @@ pushtag (name, type, globalize)
 
              TYPE_NAME (type) = d;
              DECL_CONTEXT (d) = context;
-             if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
+             if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
                push_template_decl (d);
 
              /* If it is anonymous, then we are called from pushdecl,
@@ -2110,7 +2116,7 @@ pushtag (name, type, globalize)
 
              TYPE_MAIN_DECL (type) = d;
              DECL_CONTEXT (d) = context;
-             if (! globalize && current_template_parms && IS_AGGR_TYPE (type))
+             if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
                push_template_decl (d);
 
              d = pushdecl_class_level (d);
@@ -2723,7 +2729,7 @@ duplicate_decls (newdecl, olddecl)
       /* Lay the type out, unless already done.  */
       if (oldtype != TREE_TYPE (newdecl)
          && TREE_TYPE (newdecl) != error_mark_node
-         && !(current_template_parms && uses_template_parms (newdecl)))
+         && !(processing_template_decl && uses_template_parms (newdecl)))
        layout_type (TREE_TYPE (newdecl));
 
       if ((TREE_CODE (newdecl) == VAR_DECL
@@ -2731,7 +2737,7 @@ duplicate_decls (newdecl, olddecl)
           || TREE_CODE (newdecl) == RESULT_DECL
           || TREE_CODE (newdecl) == FIELD_DECL
           || TREE_CODE (newdecl) == TYPE_DECL)
-         && !(current_template_parms && uses_template_parms (newdecl)))
+         && !(processing_template_decl && uses_template_parms (newdecl)))
        layout_decl (newdecl, 0);
 
       /* Merge the type qualifiers.  */
@@ -4312,7 +4318,7 @@ make_typename_type (context, name)
   else if (TREE_CODE (name) != IDENTIFIER_NODE)
     my_friendly_abort (2000);
 
-  if (! current_template_parms
+  if (! processing_template_decl
       || ! uses_template_parms (context)
       || context == current_class_type)
     {
@@ -4325,11 +4331,11 @@ make_typename_type (context, name)
       return TREE_TYPE (t);
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     push_obstacks (&permanent_obstack, &permanent_obstack);
   t = make_lang_type (TYPENAME_TYPE);
   d = build_decl (TYPE_DECL, name, t);
-  if (current_template_parms)
+  if (processing_template_decl)
     pop_obstacks ();
 
   TYPE_CONTEXT (t) = context;
@@ -4389,7 +4395,8 @@ lookup_name_real (name, prefer_type, nonclass)
              val = lookup_namespace_name (type, name);
            }
          else if (! IS_AGGR_TYPE (type)
-                  || TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+                  || TREE_CODE (type) == TEMPLATE_TYPE_PARM
+                  || TREE_CODE (type) == TYPENAME_TYPE)
            /* Someone else will give an error about this if needed.  */
            val = NULL_TREE;
          else if (TYPE_BEING_DEFINED (type))
@@ -4421,7 +4428,7 @@ lookup_name_real (name, prefer_type, nonclass)
        val = NULL_TREE;
 
 #if 1
-      if (got_scope && current_template_parms
+      if (got_scope && processing_template_decl
          && got_scope != current_class_type
          && uses_template_parms (got_scope)
          && val && TREE_CODE (val) == TYPE_DECL
@@ -4805,6 +4812,12 @@ init_decl_processing ()
   record_builtin_type (RID_MAX, "long long unsigned",
                       long_long_unsigned_type_node);
 
+  short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
+  record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
+  short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
+  record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
+  record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
+
   /* `unsigned long' is the standard type for sizeof.
      Traditionally, use a signed type.
      Note that stddef.h uses `unsigned long',
@@ -4824,12 +4837,8 @@ init_decl_processing ()
   TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
   TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
   TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
-
-  short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
-  record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
-  short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
-  record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node);
-  record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node);
+  TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
+  TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
 
   /* Define both `signed char' and `unsigned char'.  */
   signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
@@ -5646,7 +5655,7 @@ shadow_tag (declspecs)
                  && TYPE_SIZE (value) == NULL_TREE)
                {
                  SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value);
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    push_template_decl (TYPE_MAIN_DECL (value));
                }
              else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value))
@@ -5782,7 +5791,7 @@ start_decl (declarator, declspecs, initialized)
   type = TREE_TYPE (decl);
 
   /* Don't lose if destructors must be executed at file-level.  */
-  if (! current_template_parms && TREE_STATIC (decl)
+  if (! processing_template_decl && TREE_STATIC (decl)
       && TYPE_NEEDS_DESTRUCTOR (complete_type (type))
       && !TREE_PERMANENT (decl))
     {
@@ -5829,11 +5838,23 @@ start_decl (declarator, declspecs, initialized)
        break;
 
       default:
-       if (TREE_CODE (type) == ARRAY_TYPE && ! current_template_parms
-           && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
+       if (! processing_template_decl)
          {
-           cp_error ("elements of array `%#D' have incomplete type", decl);
-           initialized = 0;
+           if (TYPE_SIZE (type) != NULL_TREE
+               && ! TREE_CONSTANT (TYPE_SIZE (type)))
+             {
+               cp_error
+                 ("variable-sized object `%D' may not be initialized", decl);
+               initialized = 0;
+             }
+
+           if (TREE_CODE (type) == ARRAY_TYPE
+               && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE)
+             {
+               cp_error
+                 ("elements of array `%#D' have incomplete type", decl);
+               initialized = 0;
+             }
          }
       }
 
@@ -5901,7 +5922,7 @@ start_decl (declarator, declspecs, initialized)
   else
     tem = pushdecl (decl);
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (! current_function_decl)
        push_template_decl (tem);
@@ -5922,7 +5943,7 @@ start_decl (declarator, declspecs, initialized)
   DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
 #endif
 
-  if (! current_template_parms)
+  if (! processing_template_decl)
     start_decl_1 (tem);
 
   /* Corresponding pop_obstacks is done in `cp_finish_decl'.  */
@@ -5942,7 +5963,7 @@ start_decl (declarator, declspecs, initialized)
         use temporary storage.  Do this even if we will ignore the value.  */
       if (toplevel_bindings_p () && debug_temp_inits)
        {
-         if (current_template_parms
+         if (processing_template_decl
              || TYPE_NEEDS_CONSTRUCTING (type)
              || TREE_CODE (type) == REFERENCE_TYPE)
            /* In this case, the initializer must lay down in permanent
@@ -6002,7 +6023,7 @@ start_decl_1 (decl)
       && TREE_CODE (decl) != TEMPLATE_DECL
       && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl))
     {
-      if ((! current_template_parms || ! uses_template_parms (type))
+      if ((! processing_template_decl || ! uses_template_parms (type))
          && TYPE_SIZE (complete_type (type)) == NULL_TREE)
        {
          cp_error ("aggregate `%#D' has incomplete type and cannot be initialized",
@@ -6228,7 +6249,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
       return;
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (init && DECL_INITIAL (decl))
        DECL_INITIAL (decl) = init;
@@ -6796,7 +6817,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
   /* If requested, warn about definitions of large data objects.  */
 
   if (warn_larger_than
-      && ! current_template_parms
+      && ! processing_template_decl
       && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
       && !DECL_EXTERNAL (decl))
     {
@@ -8393,7 +8414,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
                /* If this involves a template parameter, it'll be
                   constant, but we don't know what the value is yet.  */
-               if (current_template_parms)
+               if (processing_template_decl)
                  {
                    itype = make_node (INTEGER_TYPE);
                    TYPE_MIN_VALUE (itype) = size_zero_node;
@@ -9481,7 +9502,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              }
 
            if (current_lang_name == lang_name_cplusplus
-               && ! current_template_parms
+               && ! processing_template_decl
                && ! (IDENTIFIER_LENGTH (original_name) == 4
                      && IDENTIFIER_POINTER (original_name)[0] == 'm'
                      && strcmp (IDENTIFIER_POINTER (original_name), "main") == 0)
@@ -9873,7 +9894,7 @@ grokparms (first_parm, funcdef_flag)
                      any_init++;
                      if (TREE_CODE (init) == SAVE_EXPR)
                        PARM_DECL_EXPR (init) = 1;
-                     else if (current_template_parms)
+                     else if (processing_template_decl)
                        ;
                      else if (TREE_CODE (init) == VAR_DECL
                               || TREE_CODE (init) == PARM_DECL)
@@ -9893,7 +9914,7 @@ grokparms (first_parm, funcdef_flag)
                        }
                      else
                        init = require_instantiated_type (type, init, integer_zero_node);
-                     if (! current_template_parms
+                     if (! processing_template_decl
                          && ! can_convert_arg (type, TREE_TYPE (init), init))
                        cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
                                    TREE_TYPE (init), decl);
@@ -10229,7 +10250,7 @@ grok_op_properties (decl, virtualp, friendp)
            {
              if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
                   || name == ansi_opname[(int) POSTDECREMENT_EXPR])
-                 && ! current_template_parms
+                 && ! processing_template_decl
                  && TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
                {
                  if (methodp)
@@ -10688,7 +10709,7 @@ finish_enum (enumtype, values)
       register tree pair;
       register tree value = DECL_INITIAL (TREE_VALUE (values));
 
-      if (! current_template_parms)
+      if (! processing_template_decl)
        {
          /* Speed up the main loop by performing some precalculations */
          TREE_TYPE (TREE_VALUE (values)) = enumtype;
@@ -10700,7 +10721,7 @@ finish_enum (enumtype, values)
       for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair))
        {
          value = DECL_INITIAL (TREE_VALUE (pair));
-         if (! current_template_parms)
+         if (! processing_template_decl)
            {
              TREE_TYPE (TREE_VALUE (pair)) = enumtype;
              TREE_TYPE (value) = enumtype;
@@ -10717,7 +10738,7 @@ finish_enum (enumtype, values)
 
   TYPE_VALUES (enumtype) = values;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return enumtype;
 
   {
@@ -10786,7 +10807,7 @@ build_enumerator (name, value)
   if (value)
     STRIP_TYPE_NOPS (value);
 
- if (! current_template_parms)
+ if (! processing_template_decl)
    {
      /* Validate and default VALUE.  */
      if (value != NULL_TREE)
@@ -10807,7 +10828,7 @@ build_enumerator (name, value)
        }
 
      /* Default based on previous value.  */
-     if (value == NULL_TREE && ! current_template_parms)
+     if (value == NULL_TREE && ! processing_template_decl)
        {
         value = enum_next_value;
         if (enum_overflow)
@@ -10849,7 +10870,7 @@ build_enumerator (name, value)
       GNU_xref_decl (current_function_decl, decl);
     }
 
- if (! current_template_parms)
+ if (! processing_template_decl)
    {
      /* Set basis for default for next value.  */
      enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value,
@@ -11059,7 +11080,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
 
   announce_function (decl1);
 
-  if (! current_template_parms)
+  if (! processing_template_decl)
     {
       if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE)
        {
@@ -11105,7 +11126,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
      If we already have a decl for this name, and it is a FUNCTION_DECL,
      use the old decl.  */
 
-  if (current_template_parms)
+  if (processing_template_decl)
     push_template_decl (decl1);
   else if (pre_parsed_p == 0)
     {
@@ -11129,7 +11150,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
               || flag_alt_external_templates))
     {
       if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)
-         || current_template_parms)
+         || processing_template_decl)
        DECL_EXTERNAL (decl1)
          = (interface_only
             || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
@@ -11246,7 +11267,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
        of this function only.  Tiemann moved up here from bottom of fn.  */
     temporary_allocation ();
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       extern tree last_tree;
       ++minimal_parse_mode;
@@ -11395,7 +11416,7 @@ store_parm_decls ()
 
                  pushdecl (parm);
                }
-             if (! current_template_parms
+             if (! processing_template_decl
                  && (cleanup = maybe_build_cleanup (parm), cleanup))
                {
                  expand_decl (parm);
@@ -11433,7 +11454,7 @@ store_parm_decls ()
 
   /* Initialize the RTL code for the function.  */
   DECL_SAVED_INSNS (fndecl) = NULL_RTX;
-  if (! current_template_parms)
+  if (! processing_template_decl)
     expand_function_start (fndecl, parms_have_cleanups);
 
   /* Create a binding contour which can be used to catch
@@ -11458,7 +11479,7 @@ store_parm_decls ()
     }
 
   /* Take care of exception handling things. */
-  if (! current_template_parms && flag_exceptions)
+  if (! processing_template_decl && flag_exceptions)
     {
       rtx insns;
       start_sequence ();
@@ -11589,7 +11610,7 @@ finish_function (lineno, call_poplevel, nested)
       store_parm_decls ();
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel)
        {
@@ -12017,7 +12038,7 @@ finish_function (lineno, call_poplevel, nested)
      to the FUNCTION_DECL node itself.  */
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
 
-  if (! current_template_parms)
+  if (! processing_template_decl)
     {
       /* So we can tell if jump_optimize sets it to 1.  */
       can_reach_end = 0;
@@ -12070,7 +12091,7 @@ finish_function (lineno, call_poplevel, nested)
   /* Free all the tree nodes making up this function.  */
   /* Switch back to allocating nodes permanently
      until we start another function.  */
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       --minimal_parse_mode;
       DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
@@ -12086,7 +12107,7 @@ finish_function (lineno, call_poplevel, nested)
         was an actual function definition.  */
       DECL_INITIAL (fndecl) = error_mark_node;
       /* And we need the arguments for template instantiation.  */
-      if (! current_template_parms)
+      if (! processing_template_decl)
        {
          if (! DECL_CONSTRUCTOR_P (fndecl)
              || !(TYPE_USES_VIRTUAL_BASECLASSES
@@ -12178,7 +12199,7 @@ start_method (declspecs, declarator)
   if (flag_default_inline)
     DECL_INLINE (fndecl) = 1;
 
-  if (current_template_parms && ! current_function_decl)
+  if (processing_template_decl && ! current_function_decl)
     push_template_decl (fndecl);
 
   /* We read in the parameters on the maybepermanent_obstack,
@@ -12437,7 +12458,7 @@ cplus_expand_expr_stmt (exp)
   push_temp_slots ();
   target_temp_slot_level = temp_slot_level;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       add_tree (build_min_nt (EXPR_STMT, exp));
       return;
index 39a2572..2a26a59 100644 (file)
@@ -1053,7 +1053,7 @@ grok_array_decl (array_expr, index_exp)
 
   if (type == error_mark_node || index_exp == error_mark_node)
     return error_mark_node;
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
                      array_expr, index_exp);
 
@@ -1133,7 +1133,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
   if (exp == error_mark_node)
     return exp;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       t = build_min (DELETE_EXPR, void_type_node, exp, size);
       DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
@@ -1455,7 +1455,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
               because `decl_const_value' would mis-interpret it
               as only meaning that this VAR_DECL is defined.  */
            init = build1 (NOP_EXPR, TREE_TYPE (value), init);
-         else if (current_template_parms)
+         else if (processing_template_decl)
            ;
          else if (! TREE_CONSTANT (init))
            {
@@ -1476,7 +1476,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
   /* The corresponding pop_obstacks is in cp_finish_decl.  */
   push_obstacks_nochange ();
 
-  if (current_template_parms && ! current_function_decl
+  if (processing_template_decl && ! current_function_decl
       && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
     push_template_decl (value);
 
@@ -1500,7 +1500,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
              DECL_ASSEMBLER_NAME (value)
                = build_static_name (current_class_type, DECL_NAME (value));
            }
-         if (! current_template_parms)
+         if (! processing_template_decl)
            pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
 
          /* Static consts need not be initialized in the class definition.  */
@@ -1839,7 +1839,7 @@ setup_vtbl_ptr ()
   if (base_init_expr == 0
       && DECL_CONSTRUCTOR_P (current_function_decl))
     {
-      if (current_template_parms)
+      if (processing_template_decl)
        add_tree (build_min_nt
                  (CTOR_INITIALIZER,
                   current_member_init_list, current_base_init_list));
@@ -3412,13 +3412,26 @@ build_expr_from_tree (t)
       }
 
     case COMPONENT_REF:
-      return build_component_ref
+      return build_x_component_ref
        (build_expr_from_tree (TREE_OPERAND (t, 0)),
         TREE_OPERAND (t, 1), NULL_TREE, 1);
 
     case THROW_EXPR:
       return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
 
+    case CONSTRUCTOR:
+      {
+       tree r = build_nt (CONSTRUCTOR, NULL_TREE,
+                          build_expr_from_tree (CONSTRUCTOR_ELTS (t)));
+
+       if (TREE_TYPE (t))
+         return digest_init (TREE_TYPE (t), r, 0);
+       return r;
+      }
+
+    case TYPEID_EXPR:
+      return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
+
     default:
       return t;
     }
@@ -3629,7 +3642,7 @@ mark_used (decl)
      tree decl;
 {
   TREE_USED (decl) = 1;
-  if (current_template_parms)
+  if (processing_template_decl)
     return;
   assemble_external (decl);
   /* Is it a synthesized method that needs to be synthesized?  */
index 755b54b..80eb8e9 100644 (file)
@@ -487,7 +487,16 @@ dump_type_suffix (t, v)
     case ARRAY_TYPE:
       OB_PUTC ('[');
       if (TYPE_DOMAIN (t))
-       OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
+       {
+         if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
+           OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
+         else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
+           dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0);
+         else
+           dump_expr (fold (build_binary_op
+                            (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
+                             integer_one_node, 1)), 0);
+       }
       OB_PUTC (']');
       dump_type_suffix (TREE_TYPE (t), v);
       break;
index 2863e21..fefcd02 100644 (file)
@@ -1132,7 +1132,7 @@ build_throw (e)
 {
   if (e != error_mark_node)
     {
-      if (current_template_parms)
+      if (processing_template_decl)
        return build_min (THROW_EXPR, void_type_node, e);
       e = build1 (THROW_EXPR, void_type_node, e);
       TREE_SIDE_EFFECTS (e) = 1;
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
new file mode 100644 (file)
index 0000000..8cf227a
--- /dev/null
@@ -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 ();
+}
index 7e8673b..506d64c 100644 (file)
@@ -373,7 +373,7 @@ do_case (start, end)
   if (end && pedantic)
     pedwarn ("ANSI C++ forbids range expressions in switch statement");
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       add_tree (build_min_nt (CASE_LABEL, start, end));
       return;
index be3d896..dbfc234 100644 (file)
@@ -1176,10 +1176,9 @@ thrown is used instead.  All code that originates exceptions, even code
 that throws exceptions as a side effect, like dynamic casting, and all
 code that catches exceptions must be compiled with either -frtti, or
 -fno-rtti.  It is not possible to mix rtti base exception handling
-objects with code that doesn't use rtti.  Also, -frtti can alter the
-binary layout of classes, so mixing -frtti code and -fno-rtti code can
-be dangerous.  The exceptions to this, are code that doesn't catch or
-throw exceptions, catch (...), and code that just rethrows an exception.
+objects with code that doesn't use rtti.  The exceptions to this, are
+code that doesn't catch or throw exceptions, catch (...), and code that
+just rethrows an exception.
 
 Currently we use the normal mangling used in building functions names
 (int's are "i", const char * is PCc) to build the non-rtti base type
diff --git a/gcc/cp/inc/exception b/gcc/cp/inc/exception
new file mode 100644 (file)
index 0000000..d38806b
--- /dev/null
@@ -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 (file)
index 0000000..4bfb960
--- /dev/null
@@ -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 (file)
index 0000000..eed0910
--- /dev/null
@@ -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 (file)
index 0000000..bad3b66
--- /dev/null
@@ -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
index 8ac11e8..af629ca 100644 (file)
@@ -1803,7 +1803,7 @@ build_offset_ref (type, name)
   tree basebinfo = NULL_TREE;
   int dtor = 0;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min_nt (SCOPE_REF, type, name);
 
   /* Handle namespace names fully here.  */
@@ -2601,6 +2601,7 @@ build_new (placement, decl, init, use_global_new)
   tree alloc_expr, alloc_temp;
   int has_array = 0;
   enum tree_code code = NEW_EXPR;
+  int use_cookie;
 
   tree pending_sizes = NULL_TREE;
 
@@ -2648,7 +2649,7 @@ build_new (placement, decl, init, use_global_new)
            {
              if (this_nelts == NULL_TREE)
                error ("new of array type fails to specify size");
-             else if (current_template_parms)
+             else if (processing_template_decl)
                {
                  nelts = this_nelts;
                  absdcl = TREE_OPERAND (absdcl, 0);
@@ -2718,7 +2719,7 @@ build_new (placement, decl, init, use_global_new)
       decl = TYPE_NAME (type);
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       tree t;
       if (has_array)
@@ -2801,9 +2802,25 @@ build_new (placement, decl, init, use_global_new)
       return error_mark_node;
     }
 
+#if 1
   /* Get a little extra space to store a couple of things before the new'ed
-     array.  */
-  if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
+     array, if this isn't the default placement new.  */
+
+  use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
+               && ! (placement && ! TREE_CHAIN (placement)
+                     && TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node));
+#else
+  /* Get a little extra space to store a couple of things before the new'ed
+     array, if this is either non-placement new or new (nothrow).  */
+  
+  use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
+               && (! placement
+                   || (IS_AGGR_TYPE (TREE_TYPE (placement))
+                       && (TYPE_IDENTIFIER (TREE_TYPE (placement))
+                           == get_identifier ("nothrow_t")))));
+#endif
+
+  if (use_cookie)
     {
       tree extra = BI_header_size;
 
@@ -2857,7 +2874,7 @@ build_new (placement, decl, init, use_global_new)
      sure we have some extra bytes in that case for the BI_header_size
      cookies? And how does that interact with the code below? (mrs) */
   /* Finish up some magic for new'ed arrays */
-  if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE)
+  if (use_cookie && rval != NULL_TREE)
     {
       tree extra = BI_header_size;
       tree cookie, exp1;
index 364b8e2..e142bf4 100644 (file)
@@ -163,7 +163,7 @@ sub_getch ()
          return getch ();
        }
       if (input)
-       return input->str[input->offset++];
+       return (unsigned char)input->str[input->offset++];
     }
   return getc (finput);
 }
index f5701f4..f91d939 100644 (file)
@@ -2654,7 +2654,7 @@ do_identifier (token, parsing)
            cp_error ("enum `%D' is private", id);
          /* protected is OK, since it's an enum of `this'.  */
        }
-      if (! current_template_parms
+      if (! processing_template_decl
          || (DECL_INITIAL (id)
              && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
        id = DECL_INITIAL (id);
@@ -2691,7 +2691,7 @@ do_scoped_id (token, parsing)
     yychar = yylex ();
   if (! id)
     {
-      if (current_template_parms)
+      if (processing_template_decl)
        {
          id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
          LOOKUP_EXPR_GLOBAL (id) = 1;
@@ -2716,7 +2716,7 @@ do_scoped_id (token, parsing)
       else if (TREE_CODE (id) != TREE_LIST)
        mark_used (id);
     }
-  if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
+  if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
     {
       /* XXX CHS - should we set TREE_USED of the constant? */
       id = DECL_INITIAL (id);
@@ -2726,7 +2726,7 @@ do_scoped_id (token, parsing)
       TREE_CONSTANT (id) = 1;
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       if (is_overloaded_fn (id))
        {
@@ -3796,19 +3796,19 @@ real_yylex ()
              len = p - token_buffer - 1;
            }
 #endif
-           if (current_template_parms)
+           if (processing_template_decl)
              push_obstacks (&permanent_obstack, &permanent_obstack);
            yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
-           if (current_template_parms)
+           if (processing_template_decl)
              pop_obstacks ();
            TREE_TYPE (yylval.ttype) = wchar_array_type_node;
          }
        else
          {
-           if (current_template_parms)
+           if (processing_template_decl)
              push_obstacks (&permanent_obstack, &permanent_obstack);
            yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
-           if (current_template_parms)
+           if (processing_template_decl)
              pop_obstacks ();
            TREE_TYPE (yylval.ttype) = char_array_type_node;
          }
@@ -4027,6 +4027,30 @@ is_rid (t)
 }
 
 #ifdef GATHER_STATISTICS
+/* The original for tree_node_kind is in the toplevel tree.c; changes there
+   need to be brought into here, unless this were actually put into a header
+   instead.  */
+/* Statistics-gathering stuff.  */
+typedef enum
+{
+  d_kind,
+  t_kind,
+  b_kind,
+  s_kind,
+  r_kind,
+  e_kind,
+  c_kind,
+  id_kind,
+  op_id_kind,
+  perm_list_kind,
+  temp_list_kind,
+  vec_kind,
+  x_kind,
+  lang_decl,
+  lang_type,
+  all_kinds
+} tree_node_kind;
+
 extern int tree_node_counts[];
 extern int tree_node_sizes[];
 #endif
index c7c63d7..b127002 100644 (file)
@@ -369,7 +369,7 @@ build_overload_int (value)
        OB_PUTC ('_');
       return;
     }
-  else if (current_template_parms
+  else if (processing_template_decl
           && TREE_CODE (value) != INTEGER_CST)
     /* We don't ever want this output, but it's inconvenient not to
        be able to build the string.  This should cause assembler
@@ -382,7 +382,7 @@ build_overload_int (value)
     }
 
   my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
-  if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
+  if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)
     {
       if (tree_int_cst_lt (value, integer_zero_node))
        {
@@ -1656,7 +1656,7 @@ hack_identifier (value, name)
       return value;
     }
 
-  if (TREE_CODE (type) == REFERENCE_TYPE && ! current_template_parms)
+  if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl)
     value = convert_from_reference (value);
   return value;
 }
diff --git a/gcc/cp/new.cc b/gcc/cp/new.cc
new file mode 100644 (file)
index 0000000..297b395
--- /dev/null
@@ -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"
index c0a2c45..774bb04 100644 (file)
@@ -990,7 +990,7 @@ compstmtend:
 already_scoped_stmt:
          '{'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
                      COMPOUND_STMT_NO_SCOPE ($<ttype>$) = 1;
@@ -999,7 +999,7 @@ already_scoped_stmt:
                }
          compstmtend
                { 
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -1287,10 +1287,10 @@ primary:
        | boolean.literal
        | string
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    push_obstacks (&permanent_obstack, &permanent_obstack);
                  $$ = combine_strings ($$);
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    pop_obstacks ();
                }
        | '(' expr ')'
@@ -1455,7 +1455,7 @@ primary:
                  check_for_new_type ("const_cast", $3);
                  $$ = build_const_cast (type, $6); }
        | TYPEID '(' expr ')'
-               { $$ = build_typeid ($3); }
+               { $$ = build_x_typeid ($3); }
        | TYPEID '(' type_id ')'
                { tree type = groktypename ($3.t);
                  check_for_new_type ("typeid", $3);
@@ -1473,20 +1473,20 @@ primary:
        | overqualified_id  %prec HYPERUNARY
                { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
        | overqualified_id '(' nonnull_exprlist ')'
-               { if (current_template_parms)
+               { if (processing_template_decl)
                    $$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), $3, NULL_TREE);
                  else
                    $$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
        | overqualified_id LEFT_RIGHT
-               { if (current_template_parms)
+               { if (processing_template_decl)
                    $$ = build_min_nt (CALL_EXPR, copy_to_permanent ($1), 
                                       NULL_TREE, NULL_TREE);
                  else
                    $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
        | object unqualified_id  %prec UNARY
-               { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
+               { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); }
        | object overqualified_id  %prec UNARY
-               { if (current_template_parms)
+               { if (processing_template_decl)
                    $$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2));
                  else
                    $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
@@ -2294,7 +2294,7 @@ named_class_head:
                              && TYPE_SIZE ($$) == NULL_TREE)
                            {
                              SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
-                             if (current_template_parms)
+                             if (processing_template_decl)
                                push_template_decl (TYPE_MAIN_DECL ($$));
                            }
                          else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
@@ -2496,7 +2496,7 @@ left_curly:
                       pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
                       $<ttype>0 = t;
                     }
-                 if (current_template_parms && TYPE_CONTEXT (t)
+                 if (processing_template_decl && TYPE_CONTEXT (t)
                      && ! current_class_type)
                    push_template_decl (TYPE_STUB_DECL (t));
                  pushclass (t, 0);
@@ -2507,7 +2507,7 @@ left_curly:
                          && TYPE_SIZE (t) == NULL_TREE)
                        {
                          SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
-                         if (current_template_parms)
+                         if (processing_template_decl)
                            push_template_decl (TYPE_MAIN_DECL (t));
                        }
                      else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
@@ -2672,7 +2672,8 @@ component_decl_1:
                  $$ = grokfield ($2, specs, $5, $3,
                                  build_tree_list ($4, attrs)); }
        | component_constructor_declarator maybeasm maybe_attribute maybe_init
-               { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); }
+               { $$ = grokfield ($$, NULL_TREE, $4, $2,
+                                 build_tree_list ($3, NULL_TREE)); }
        | using_decl
                { $$ = do_class_using_decl ($1); }
        ;
@@ -3242,7 +3243,7 @@ compstmt_or_error:
 compstmt:
          '{'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
                      add_tree ($<ttype>$);
@@ -3250,7 +3251,7 @@ compstmt:
                }
          .pushlevel compstmtend .poplevel
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3263,7 +3264,7 @@ compstmt:
 simple_if:
          IF
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (IF_STMT, NULL_TREE, NULL_TREE,
                                                NULL_TREE);
@@ -3273,7 +3274,7 @@ simple_if:
                }
          .pushlevel paren_cond_or_null
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      if (last_tree != $<ttype>2)
                        {
@@ -3292,7 +3293,7 @@ simple_if:
                }
          implicitly_scoped_stmt
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3306,7 +3307,7 @@ implicitly_scoped_stmt:
                { finish_stmt (); }
        | .pushlevel
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (COMPOUND_STMT, NULL_TREE);
                      add_tree ($<ttype>$);
@@ -3314,7 +3315,7 @@ implicitly_scoped_stmt:
                }
          simple_stmt .poplevel
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3336,7 +3337,7 @@ simple_stmt:
        | expr ';'
                {
                  tree expr = $1;
-                 if (! current_template_parms)
+                 if (! processing_template_decl)
                    {
                      emit_line_note (input_filename, lineno);
                      /* Do default conversion if safe and possibly important,
@@ -3350,10 +3351,10 @@ simple_stmt:
                  clear_momentary ();
                  finish_stmt (); }
        | simple_if ELSE
-               { if (! current_template_parms) expand_start_else (); }
+               { if (! processing_template_decl) expand_start_else (); }
          implicitly_scoped_stmt
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>1, 2) = TREE_CHAIN ($<ttype>1);
                      TREE_CHAIN ($<ttype>1) = NULL_TREE;
@@ -3365,12 +3366,12 @@ simple_stmt:
          .poplevel
                { finish_stmt (); }
        | simple_if  %prec IF
-               { if (! current_template_parms) expand_end_cond ();
+               { if (! processing_template_decl) expand_end_cond ();
                  do_poplevel ();
                  finish_stmt (); }
        | WHILE
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (WHILE_STMT, NULL_TREE, NULL_TREE);
                      add_tree ($<ttype>$);
@@ -3385,7 +3386,7 @@ simple_stmt:
                }
          .pushlevel paren_cond_or_null
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      if (last_tree != $<ttype>2)
                        {
@@ -3404,7 +3405,7 @@ simple_stmt:
                }
          already_scoped_stmt .poplevel
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 1) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3416,7 +3417,7 @@ simple_stmt:
                }
        | DO
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (DO_STMT, NULL_TREE, NULL_TREE);
                      add_tree ($<ttype>$);
@@ -3430,7 +3431,7 @@ simple_stmt:
                }
          implicitly_scoped_stmt WHILE
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 0) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3444,7 +3445,7 @@ simple_stmt:
                }
          paren_expr_or_null ';'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    TREE_OPERAND ($<ttype>2, 1) = $6;
                  else
                    {
@@ -3456,7 +3457,7 @@ simple_stmt:
                  finish_stmt ();
                }
        | FOR
-               { if (current_template_parms)
+               { if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (FOR_STMT, NULL_TREE, NULL_TREE, 
                                                NULL_TREE, NULL_TREE);
@@ -3476,7 +3477,7 @@ simple_stmt:
                }
          '(' for.init.statement
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      if (last_tree != $<ttype>2)
                        {
@@ -3494,7 +3495,7 @@ simple_stmt:
                }
          .pushlevel xcond ';'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      if (last_tree != $<ttype>2)
                        {
@@ -3515,13 +3516,13 @@ simple_stmt:
                /* Don't let the tree nodes for $10 be discarded
                   by clear_momentary during the parsing of the next stmt.  */
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    TREE_OPERAND ($<ttype>2, 2) = $10;
                  push_momentary ();
                }
          already_scoped_stmt .poplevel
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>2, 3) = TREE_CHAIN ($<ttype>2);
                      TREE_CHAIN ($<ttype>2) = NULL_TREE;
@@ -3542,7 +3543,7 @@ simple_stmt:
                  finish_stmt (); }
        | SWITCH .pushlevel '(' condition ')'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      $<ttype>$ = build_min_nt (SWITCH_STMT, $4, NULL_TREE);
                      add_tree ($<ttype>$);
@@ -3559,7 +3560,7 @@ simple_stmt:
                }
          implicitly_scoped_stmt
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    {
                      TREE_OPERAND ($<ttype>6, 1) = TREE_CHAIN ($<ttype>6);
                      TREE_CHAIN ($<ttype>6) = NULL_TREE;
@@ -3583,13 +3584,13 @@ simple_stmt:
          stmt
        | BREAK ';'
                { emit_line_note (input_filename, lineno);
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    add_tree (build_min_nt (BREAK_STMT));
                  else if ( ! expand_exit_something ())
                    error ("break statement not within loop or switch"); }
        | CONTINUE ';'
                { emit_line_note (input_filename, lineno);
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    add_tree (build_min_nt (CONTINUE_STMT));
                  else if (! expand_continue_loop (0))
                    error ("continue statement not within a loop"); }
@@ -3637,7 +3638,7 @@ simple_stmt:
                }
        | GOTO '*' expr ';'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    add_tree (build_min_nt (GOTO_STMT, $3));
                  else
                    { emit_line_note (input_filename, lineno);
@@ -3645,7 +3646,7 @@ simple_stmt:
                }
        | GOTO identifier ';'
                {
-                 if (current_template_parms)
+                 if (processing_template_decl)
                    add_tree (build_min_nt (GOTO_STMT, $2));
                  else
                    {
index f8161fa..5b7caf3 100644 (file)
@@ -80,6 +80,7 @@ begin_template_parm_list ()
 {
   pushlevel (0);
   declare_pseudo_global_level ();
+  ++processing_template_decl;
 }
 
 /* Process information from new template parameter NEXT and append it to the
@@ -141,7 +142,7 @@ process_template_parm (list, next)
       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
       DECL_INITIAL (decl) = tinfo;
       DECL_INITIAL (parm) = tinfo;
-      TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl + 1);
+      TEMPLATE_CONST_SET_INFO (tinfo, idx, processing_template_decl);
     }
   else
     {
@@ -150,7 +151,7 @@ process_template_parm (list, next)
       decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
       TYPE_MAIN_DECL (t) = decl;
       parm = decl;
-      TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl + 1);
+      TEMPLATE_TYPE_SET_INFO (t, idx, processing_template_decl);
     }
   SET_DECL_ARTIFICIAL (decl);
   pushdecl (decl);
@@ -171,7 +172,6 @@ end_template_parm_list (parms)
   tree parm;
   tree saved_parmlist = make_tree_vec (list_length (parms));
 
-  ++processing_template_decl;
   current_template_parms
     = tree_cons (build_int_2 (0, processing_template_decl),
                 saved_parmlist, current_template_parms);
@@ -187,7 +187,7 @@ end_template_parm_list (parms)
 void
 end_template_decl ()
 {
-  if (! current_template_parms)
+  if (! processing_template_decl)
     return;
 
   /* This matches the pushlevel in begin_template_parm_list.  */
@@ -404,7 +404,7 @@ coerce_template_parms (parms, arglist, in_decl)
       if (is_type)
        {
          val = groktypename (arg);
-         if (! current_template_parms)
+         if (! processing_template_decl)
            {
              tree t = target_type (val);
              if (IS_AGGR_TYPE (t)
@@ -419,12 +419,12 @@ coerce_template_parms (parms, arglist, in_decl)
        {
          tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
                           TREE_VEC_LENGTH (vec), in_decl);
-         if (current_template_parms)
+         if (processing_template_decl)
            val = arg;
          else
            val = digest_init (t, arg, (tree *) 0);
 
-         if (val == error_mark_node || current_template_parms)
+         if (val == error_mark_node || processing_template_decl)
            ;
 
          /* 14.2: Other template-arguments must be constant-expressions,
@@ -743,10 +743,10 @@ lookup_template_class (d1, arglist, in_decl)
 
       if (TYPE_BEING_DEFINED (ctx) && ctx == current_class_type)
        {
-         tree save_parms = current_template_parms;
-         current_template_parms = NULL_TREE;
+         int save_temp = processing_template_decl;
+         processing_template_decl = 0;
          t = xref_tag_from_type (TREE_TYPE (template), id, 0);
-         current_template_parms = save_parms;
+         processing_template_decl = save_temp;
        }
       else
        {
@@ -910,10 +910,13 @@ uses_template_parms (t)
     case TYPENAME_TYPE:
       return 1;
 
+    case SCOPE_REF:
+      return uses_template_parms (TREE_OPERAND (t, 0));
+
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
        return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
-      /* else fall through */
+      return uses_template_parms (TREE_OPERAND (t, 1));
 
     default:
       switch (TREE_CODE_CLASS (TREE_CODE (t)))
@@ -1384,7 +1387,7 @@ tsubst (t, args, nargs, in_decl)
 
       {
        tree max = tsubst_expr (TYPE_MAX_VALUE (t), args, nargs, in_decl);
-       if (current_template_parms)
+       if (processing_template_decl)
          {
            tree itype = make_node (INTEGER_TYPE);
            TYPE_MIN_VALUE (itype) = size_zero_node;
@@ -1986,6 +1989,7 @@ tsubst_copy (t, args, nargs, in_decl)
     case SIZEOF_EXPR:
     case ARROW_EXPR:
     case THROW_EXPR:
+    case TYPEID_EXPR:
       return build1
        (code, NULL_TREE,
         tsubst_copy (TREE_OPERAND (t, 0), args, nargs, in_decl));
@@ -2139,6 +2143,11 @@ tsubst_copy (t, args, nargs, in_decl)
       else
        return t;
 
+    case CONSTRUCTOR:
+      return build
+       (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, nargs, in_decl), NULL_TREE,
+        tsubst_copy (CONSTRUCTOR_ELTS (t), args, nargs, in_decl));
+
     default:
       return t;
     }
@@ -2153,7 +2162,7 @@ tsubst_expr (t, args, nargs, in_decl)
   if (t == NULL_TREE || t == error_mark_node)
     return t;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return tsubst_copy (t, args, nargs, in_decl);
 
   switch (TREE_CODE (t))
@@ -3255,6 +3264,8 @@ instantiate_decl (d)
   int nested = in_function_p ();
   int d_defined;
   int pattern_defined;
+  int line = lineno;
+  char *file = input_filename;
 
   if (TREE_CODE (d) == FUNCTION_DECL)
     {
@@ -3297,9 +3308,19 @@ instantiate_decl (d)
      variable is a static const initialized in the class body.  */
   if (TREE_CODE (d) == VAR_DECL
       && ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
-    DECL_INITIAL (d) = tsubst_expr
-      (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
-       TREE_VEC_LENGTH (args), tmpl);
+    {
+      lineno = DECL_SOURCE_LINE (d);
+      input_filename = DECL_SOURCE_FILE (d);
+
+      pushclass (DECL_CONTEXT (d), 2);
+      DECL_INITIAL (d) = tsubst_expr
+       (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
+        TREE_VEC_LENGTH (args), tmpl);
+      popclass (1);
+
+      lineno = line;
+      input_filename = file;
+    }
 
   if (! pattern_defined
       || (TREE_CODE (d) == FUNCTION_DECL && ! DECL_INLINE (d)
@@ -3320,6 +3341,9 @@ instantiate_decl (d)
 
   push_to_top_level ();
 
+  lineno = DECL_SOURCE_LINE (d);
+  input_filename = DECL_SOURCE_FILE (d);
+
   /* Trick tsubst into giving us a new decl in case the template changed.  */
   save_ti = DECL_TEMPLATE_INFO (pattern);
   DECL_TEMPLATE_INFO (pattern) = NULL_TREE;
@@ -3328,9 +3352,13 @@ instantiate_decl (d)
 
   /* And set up DECL_INITIAL, since tsubst doesn't.  */
   if (TREE_CODE (td) == VAR_DECL)
-    DECL_INITIAL (td) = tsubst_expr
-      (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
-       TREE_VEC_LENGTH (args), tmpl);
+    {
+      pushclass (DECL_CONTEXT (d), 2);
+      DECL_INITIAL (td) = tsubst_expr
+       (DECL_INITIAL (pattern), &TREE_VEC_ELT (args, 0),
+        TREE_VEC_LENGTH (args), tmpl);
+      popclass (1);
+    }
 
   /* Convince duplicate_decls to use the DECL_ARGUMENTS from the new decl.  */
   if (TREE_CODE (d) == FUNCTION_DECL)
@@ -3354,11 +3382,6 @@ instantiate_decl (d)
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
       tree t = DECL_SAVED_TREE (pattern);
-      int line = lineno;
-      char *file = input_filename;
-
-      lineno = DECL_SOURCE_LINE (d);
-      input_filename = DECL_SOURCE_FILE (d);
 
       start_function (NULL_TREE, d, NULL_TREE, 1);
       store_parm_decls ();
@@ -3392,11 +3415,11 @@ instantiate_decl (d)
                   TREE_VEC_LENGTH (args), tmpl);
 
       finish_function (lineno, 0, nested);
-
-      lineno = line;
-      input_filename = file;
     }
 
+  lineno = line;
+  input_filename = file;
+
   pop_from_top_level ();
   pop_tinst_level ();
 
index 69513ac..f51ea64 100644 (file)
@@ -30,6 +30,10 @@ Boston, MA 02111-1307, USA.  */
 #undef NULL
 #define NULL 0
 
+#ifndef INT_TYPE_SIZE
+#define INT_TYPE_SIZE BITS_PER_WORD
+#endif
+
 extern tree define_function ();
 extern tree build_t_desc_overload ();
 extern struct obstack *permanent_obstack;
@@ -111,13 +115,59 @@ build_headof (exp)
   return build (PLUS_EXPR, type, exp,
                convert (ptrdiff_type_node, offset));
 }
+
+/* Build a call to a generic entry point taking and returning void.  */
+
+static tree
+call_void_fn (name)
+     char *name;
+{
+  tree d = get_identifier (name);
+  tree type;
+  
+  if (IDENTIFIER_GLOBAL_VALUE (d))
+    d = IDENTIFIER_GLOBAL_VALUE (d);
+  else
+    {
+      push_obstacks (&permanent_obstack, &permanent_obstack);
+
+      type = build_function_type (void_type_node, void_list_node);
+      d = build_lang_decl (FUNCTION_DECL, d, type);
+      DECL_EXTERNAL (d) = 1;
+      TREE_PUBLIC (d) = 1;
+      DECL_ARTIFICIAL (d) = 1;
+      pushdecl_top_level (d);
+      make_function_rtl (d);
+      assemble_external (d);
+
+      pop_obstacks ();
+    }
+
+  return build_call (d, void_type_node, NULL_TREE);
+}
+
+/* Get a bad_cast node for the program to throw...
+
+   See libstdc++/exception.cc for __throw_bad_cast */
+
+static tree
+throw_bad_cast ()
+{
+  return call_void_fn ("__throw_bad_cast");
+}
+
+static tree
+throw_bad_typeid ()
+{
+  return call_void_fn ("__throw_bad_typeid");
+}
 \f
-/* 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 (file)
index 0000000..d82aaaf
--- /dev/null
@@ -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 (file)
index 0000000..10290a8
--- /dev/null
@@ -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);
index ceb9acc..0d0dc05 100644 (file)
@@ -356,6 +356,7 @@ break_out_calls (exp)
 extern struct obstack *current_obstack;
 extern struct obstack permanent_obstack, class_obstack;
 extern struct obstack *saveable_obstack;
+extern struct obstack *expression_obstack;
 
 /* Here is how primitive or already-canonicalized types' hash
    codes are made.  MUST BE CONSISTENT WITH tree.c !!! */
@@ -421,7 +422,7 @@ build_cplus_array_type_1 (elt_type, index_type)
       saveable_obstack = &permanent_obstack;
     }
 
-  if (current_template_parms)
+  if (processing_template_decl)
     {
       t = make_node (ARRAY_TYPE);
       TREE_TYPE (t) = elt_type;
@@ -1615,8 +1616,8 @@ mapcar (t, func)
                                 mapcar (TYPE_ARG_TYPES (t), func));
       return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
     case ARRAY_TYPE:
-      tmp = build_array_type (mapcar (TREE_TYPE (t), func),
-                             mapcar (TYPE_DOMAIN (t), func));
+      tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
+                                   mapcar (TYPE_DOMAIN (t), func));
       return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
     case INTEGER_TYPE:
       tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
@@ -1632,6 +1633,11 @@ mapcar (t, func)
         mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
       return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
 
+    case CONSTRUCTOR:
+      t = copy_node (t);
+      CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
+      return t;
+
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        return build_ptrmemfunc_type
@@ -1673,20 +1679,20 @@ copy_to_permanent (t)
 {
   register struct obstack *ambient_obstack = current_obstack;
   register struct obstack *ambient_saveable_obstack = saveable_obstack;
-  int resume;
+  register struct obstack *ambient_expression_obstack = expression_obstack;
 
   if (t == NULL_TREE || TREE_PERMANENT (t))
     return t;
 
   saveable_obstack = &permanent_obstack;
   current_obstack = saveable_obstack;
-  resume = suspend_momentary ();
+  expression_obstack = saveable_obstack;
 
   t = mapcar (t, perm_manip);
 
-  resume_momentary (resume);
   current_obstack = ambient_obstack;
   saveable_obstack = ambient_saveable_obstack;
+  expression_obstack = ambient_expression_obstack;
 
   return t;
 }
index 944acc6..8d77956 100644 (file)
@@ -83,7 +83,7 @@ require_complete_type (value)
 {
   tree type;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return value;
 
   type = TREE_TYPE (value);
@@ -132,8 +132,7 @@ complete_type (type)
   else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
     {
       tree t = complete_type (TREE_TYPE (type));
-      if (TYPE_SIZE (t) != NULL_TREE
-         && current_template_parms == NULL_TREE)
+      if (TYPE_SIZE (t) != NULL_TREE && ! processing_template_decl)
        layout_type (type);
       TYPE_NEEDS_CONSTRUCTING (type)
        = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
@@ -1275,7 +1274,7 @@ c_sizeof (type)
   enum tree_code code = TREE_CODE (type);
   tree t;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min (SIZEOF_EXPR, sizetype, type);
 
   if (code == FUNCTION_TYPE)
@@ -1341,7 +1340,7 @@ tree
 expr_sizeof (e)
      tree e;
 {
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min (SIZEOF_EXPR, sizetype, e);
 
   if (TREE_CODE (e) == COMPONENT_REF
@@ -1623,8 +1622,8 @@ build_object_ref (datum, basetype, field)
     {
       tree binfo = binfo_or_else (basetype, dtype);
       if (binfo)
-       return build_component_ref (build_scoped_ref (datum, basetype),
-                                   field, binfo, 1);
+       return build_x_component_ref (build_scoped_ref (datum, basetype),
+                                     field, binfo, 1);
     }
   return error_mark_node;
 }
@@ -1709,7 +1708,7 @@ build_component_ref (datum, component, basetype_path, protect)
   register tree field = NULL;
   register tree ref;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min_nt (COMPONENT_REF, datum, component);
 
   /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference
@@ -1937,6 +1936,22 @@ build_component_ref (datum, component, basetype_path, protect)
 
   return ref;
 }
+
+/* Variant of build_component_ref for use in expressions, which should
+   never have REFERENCE_TYPE.  */
+
+tree
+build_x_component_ref (datum, component, basetype_path, protect)
+     tree datum, component, basetype_path;
+     int protect;
+{
+  tree t = build_component_ref (datum, component, basetype_path, protect);
+
+  if (! processing_template_decl)
+    t = convert_from_reference (t);
+
+  return t;
+}
 \f
 /* 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;
index 16b29dc..786ca79 100644 (file)
@@ -607,6 +607,10 @@ store_init_value (decl, init)
        }
     }
 
+  if (TYPE_PTRMEMFUNC_P (type) && TREE_CODE (init) == CONSTRUCTOR
+      && TREE_TYPE (init) == NULL_TREE)
+    cp_pedwarn ("initializer list for `%T'", type);
+
   /* End of special C++ code.  */
 
   /* Digest the specified initializer into an expression.  */
@@ -1011,9 +1015,6 @@ process_init_constructor (type, init, elts)
              sorry ("initializer list for object using virtual functions");
              return error_mark_node;
            }
-
-         if (TYPE_PTRMEMFUNC_P (type))
-           cp_pedwarn ("initializer list for `%T'", type);
        }
 
       for (field = TYPE_FIELDS (type); field && tail;
@@ -1262,7 +1263,7 @@ build_x_arrow (datum)
   if (type == error_mark_node)
     return error_mark_node;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min_nt (ARROW_EXPR, rval);
 
   if (TREE_CODE (rval) == OFFSET_REF)
@@ -1338,7 +1339,7 @@ build_m_component_ref (datum, component)
   tree rettype;
   tree binfo;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min_nt (DOTSTAR_EXPR, datum, component);
 
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
@@ -1423,7 +1424,7 @@ build_functional_cast (exp, parms)
   else
     type = exp;
 
-  if (current_template_parms)
+  if (processing_template_decl)
     return build_min (CAST_EXPR, type, parms);
 
   if (IS_SIGNATURE (type))