92th Cygnus<->FSF quick merge
authorBrendan Kehoe <brendan@gcc.gnu.org>
Thu, 24 Jul 1997 21:09:25 +0000 (17:09 -0400)
committerBrendan Kehoe <brendan@gcc.gnu.org>
Thu, 24 Jul 1997 21:09:25 +0000 (17:09 -0400)
From-SVN: r14524

19 files changed:
gcc/cp/ChangeLog
gcc/cp/Makefile.in
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/gxxint.texi
gcc/cp/init.c
gcc/cp/input.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/spew.c
gcc/cp/tree.c
gcc/cp/typeck.c

index 9047946..164551b 100644 (file)
@@ -1,3 +1,126 @@
+Wed Jul 23 13:36:25 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (struct cp_function): Add static_labelno.
+       (push_cp_function_context): Save it.
+       (pop_cp_function_context): Restore it.
+
+Tue Jul 22 14:43:29 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (build_component_ref_1): Convert from reference.
+
+Tue Jul 22 11:06:23 1997  Brendan Kehoe  <brendan@lisa.cygnus.com>
+
+       * parse.y (current_declspecs, prefix_attributes): Initialize to
+       NULL_TREE.
+
+       * parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil
+       before we try to force it to be a TREE_LIST.
+       (decl): Make sure $1.t is non-nil.
+
+Sun Jul 20 11:53:07 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (uses_template_parms): Handle template first-parse codes.
+
+       * decl.c (cp_finish_decl): Only warn about user-defined statics.
+
+Fri Jul 18 17:56:08 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (unify): Handle BOOLEAN_TYPE.
+
+       * cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE.
+       * pt.c (tsubst): Don't set it.
+       * call.c (build_over_call): Use uses_template_parms.
+
+Thu Jul 17 18:06:30 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * method.c (build_overload_nested_name): Use static_labelno
+       instead of var_labelno.
+       (build_qualified_name): New fn.
+       (build_overload_name): Split out from here.
+       (build_static_name): Use build_qualified_name.
+       * decl.c (cp_finish_decl): Statics in extern inline functions 
+       have comdat linkage.
+       (start_function): Initialize static_labelno.
+
+Thu Jul 17 11:20:17 1997  Benjamin Kosnik  <bkoz@rhino.cygnus.com>
+
+       * class.c (finish_struct_methods): add check of warn_ctor_dtor_privacy
+       before "all member functions in class [] are private"
+
+Wed Jul 16 23:47:08 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * lex.c (do_scoped_id): convert_from_reference.
+       * init.c (build_offset_ref): Likewise.
+
+Wed Jul 16 15:57:42 1997  Benjamin Kosnik  <bkoz@rhino.cygnus.com>
+
+       * parse.y (empty_parms): Only use VOID_LIST_NODE for the PARMS if
+       we're in a C++ struct/class, not if we're doing `extern "C"'.
+
+Wed Jul 16 12:34:29 1997  Benjamin Kosnik  <bkoz@lisa.cygnus.com>
+
+       * error.c (dump_expr): Check TREE_OPERAND before dump_expr_list.
+
+Mon Jul 14 03:23:46 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * typeck.c (get_member_function_from_ptrfunc): Promote index
+       before saving it.
+
+Sun Jul 13 00:11:52 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * tree.c (layout_basetypes): Move non-virtual destructor warning.
+       * decl.c (xref_basetypes): Remove non-virtual destructor warning.
+
+Sat Jul 12 12:47:12 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (grokdeclarator): Call add_defarg_fn for the function
+       type, too.
+       * lex.c (add_defarg_fn): Adjust.
+       (do_pending_defargs): Adjust.  Don't skip the first parm.
+
+Fri Jul 11 01:39:50 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (build_enumerator): Global enumerators are also readonly.
+
+       * rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast.
+       (build_dynamic_cast): Call it and convert_from_reference.
+
+       * lex.c (add_defarg_fn): New fn.
+       (snarf_defarg): Don't add to defarg_types.
+       (do_pending_defargs): Lose defarg_types.  All fns we process now
+       have defargs.
+       * decl.c (grokfndecl): Call add_defarg_fn.
+
+       * Makefile.in (CONFLICTS): Expect 18 s/r conflicts.
+       * cp-tree.def: Add DEFAULT_ARG.
+       * spew.c (yylex): Call snarf_defarg as appropriate.
+       * parse.y: New tokens DEFARG and DEFARG_MARKER.
+       (defarg_again, pending_defargs, defarg, defarg1): New rules.
+       (structsp): Use pending_defargs.
+       (parms, full_parm): Use defarg.
+       * lex.c (init_lex): Initialize inline_text_firstobj.
+       (do_pending_inlines): Never pass the obstack to feed_input.
+       (process_next_inline): Call end_input instead of restore_pending_input.
+       (clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs,
+       finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns.
+       * input.c (end_input): New fn.
+       (sub_getch): At the end of some fed input, just keep returning EOF
+       until someone calls end_input.
+       Remove 'obstack' field from struct input_source.
+       * decl.c (grokparms): Handle DEFAULT_ARG.
+       (replace_defarg): New fn.
+       * cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros.
+
+Wed Jul  9 13:44:12 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * call.c (implicit_conversion): If nothing else works, try binding
+       an rvalue to a reference.
+
+Wed Jul  9 13:04:38 1997  Geoffrey Noer  <noer@cygnus.com>
+
+       * decl.c (init_decl_processing): fix Jun 30 patch -- move
+       ifndef for Cygwin32 to include SIGSEGV.
+
 Thu Jul  3 01:44:05 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * class.c (finish_struct_1): Only complain about pointers without
@@ -16,10 +139,11 @@ Thu Jul  3 01:44:05 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
 Mon Jun 30 17:53:21 1997  Geoffrey Noer  <noer@cygnus.com>
 
-        * decl.c: Stop trying to catch signals other than SIGABRT
-        since the Cygwin32 library doesn't support them correctly
-        yet.  This fixes a situation in which g++ causes a hang on
-        SIGSEGVs and other such signals in our Win32-hosted tools.
+        * decl.c (init_decl_processing): Stop trying to catch signals
+       other than SIGABRT since the Cygwin32 library doesn't support
+       them correctly yet.  This fixes a situation in which g++ causes
+       a hang on SIGSEGVs and other such signals in our Win32-hosted
+       tools.
 
 Mon Jun 30 14:50:01 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
index 9a7bb0b..b7f3826 100644 (file)
@@ -195,7 +195,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
   `echo $(PARSE_C) | sed 's,^\./,,'`
 
-CONFLICTS = expect 16 shift/reduce conflicts and 39 reduce/reduce conflicts.
+CONFLICTS = expect 18 shift/reduce conflicts and 39 reduce/reduce conflicts.
 $(PARSE_H) : $(PARSE_C)
 $(PARSE_C) : $(srcdir)/parse.y
        @echo $(CONFLICTS)
index 39bd13e..14f8408 100644 (file)
@@ -3281,14 +3281,19 @@ implicit_conversion (to, from, expr, flags)
        conv = cand->second_conv;
       if ((! conv || ICS_BAD_FLAG (conv))
          && TREE_CODE (to) == REFERENCE_TYPE
-         && TYPE_READONLY (TREE_TYPE (to))
-         && ! TYPE_VOLATILE (TREE_TYPE (to))
          && (flags & LOOKUP_NO_TEMP_BIND) == 0)
        {
          cand = build_user_type_conversion_1
            (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
          if (cand)
-           conv = build_conv (REF_BIND, to, cand->second_conv);
+           {
+             if (! TYPE_READONLY (TREE_TYPE (to))
+                 || TYPE_VOLATILE (TREE_TYPE (to)))
+               ICS_BAD_FLAG (cand->second_conv) = 1;
+             if (!conv || (ICS_BAD_FLAG (conv)
+                           > ICS_BAD_FLAG (cand->second_conv)))
+               conv = build_conv (REF_BIND, to, cand->second_conv);
+           }
        }
     }
 
@@ -5108,10 +5113,11 @@ build_over_call (fn, convs, args, flags)
     {
       tree arg = TREE_PURPOSE (parm);
 
-      if (PARM_DEFAULT_FROM_TEMPLATE (parm))
+      if (DECL_TEMPLATE_INFO (fn) && uses_template_parms (arg))
        /* This came from a template.  Instantiate the default arg here,
           not in tsubst.  */
-       arg = tsubst_expr (arg, &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
+       arg = tsubst_expr (arg,
+                          &TREE_VEC_ELT (DECL_TI_ARGS (fn), 0),
                           TREE_VEC_LENGTH (DECL_TI_ARGS (fn)), NULL_TREE);
       converted_args = tree_cons
        (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg),
index 6275332..5ab1658 100644 (file)
@@ -2011,7 +2011,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
            nonprivate_method = 1;
            break;
          }
-      if (nonprivate_method == 0)
+      if (nonprivate_method == 0 
+         && warn_ctor_dtor_privacy)
        cp_warning ("all member functions in class `%T' are private", t);
     }
 
index 39ccfae..a92bf8a 100644 (file)
@@ -110,6 +110,11 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
    This is not an alias, but is later expanded into multiple aliases.  */
 DEFTREECODE (USING_DECL, "using_decl", "d", 0)
 
+/* An un-parsed default argument.  Looks like an IDENTIFIER_NODE.  */
+DEFTREECODE (DEFAULT_ARG, "default_arg", "c", 2)
+
+/* A whole bunch of tree codes for the initial, superficial parsing of
+   templates.  */
 DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
 DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
 DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)
index 70fc150..201db3e 100644 (file)
@@ -1094,10 +1094,6 @@ struct lang_decl
 #define DELETE_EXPR_USE_VEC(NODE)      TREE_LANG_FLAG_1 (NODE)
 #define LOOKUP_EXPR_GLOBAL(NODE)       TREE_LANG_FLAG_0 (NODE)
 
-/* For a TREE_LIST node representing a function parm type and its default arg,
-   did the default arg come from a template?  */
-#define PARM_DEFAULT_FROM_TEMPLATE(NODE) TREE_LANG_FLAG_0 (NODE)
-
 /* Nonzero in INT_CST means that this int is negative by dint of
    using a twos-complement negated operand.  */
 #define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE))
@@ -1418,6 +1414,10 @@ extern int flag_new_for_scope;
 #define UPT_TEMPLATE(NODE)      TREE_PURPOSE(TYPE_VALUES(NODE))
 #define UPT_PARMS(NODE)         TREE_VALUE(TYPE_VALUES(NODE))
 
+/* An un-parsed default argument looks like an identifier.  */
+#define DEFARG_LENGTH(NODE)    IDENTIFIER_LENGTH(NODE)
+#define DEFARG_POINTER(NODE)   IDENTIFIER_POINTER(NODE)
+
 #define builtin_function(NAME, TYPE, CODE, LIBNAME) \
   define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME)
 
index 248275e..a1aa9bb 100644 (file)
@@ -51,6 +51,8 @@ extern int current_class_depth;
 
 extern tree static_ctors, static_dtors;
 
+extern int static_labelno;
+
 /* Stack of places to restore the search obstack back to.  */
    
 /* Obstack used for remembering local class declarations (like
@@ -4672,12 +4674,12 @@ init_decl_processing ()
   current_binding_level = NULL_BINDING_LEVEL;
   free_binding_level = NULL_BINDING_LEVEL;
 
+#ifndef __CYGWIN32__
   /* Because most segmentation signals can be traced back into user
      code, catch them and at least give the user a chance of working
      around compiler bugs.  */
   signal (SIGSEGV, signal_catch);
 
-#ifndef __CYGWIN32__
   /* We will also catch aborts in the back-end through signal_catch and
      give the user a chance to see where the error might be, and to defeat
      aborts in the back-end when there have been errors previously in their
@@ -6532,6 +6534,32 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
       if (was_temp)
        end_temporary_allocation ();
 
+      /* Extern inline function static data has external linkage.  */
+      if (TREE_CODE (decl) == VAR_DECL
+         && TREE_STATIC (decl)
+         && current_function_decl
+         && DECL_CONTEXT (decl) == current_function_decl
+         && DECL_THIS_INLINE (current_function_decl)
+         && DECL_PUBLIC (current_function_decl))
+       {
+         /* We can only do this if we can use common or weak, and we
+            can't if it has been initialized and we don't support weak.  */
+         if (DECL_INITIAL (decl) == NULL_TREE
+             || DECL_INITIAL (decl) == error_mark_node)
+           {
+             TREE_PUBLIC (decl) = 1;
+             DECL_COMMON (decl) = 1;
+           }
+         else if (flag_weak)
+           make_decl_one_only (decl);
+
+         if (TREE_PUBLIC (decl))
+           DECL_ASSEMBLER_NAME (decl)
+             = build_static_name (current_function_decl, DECL_NAME (decl));
+         else if (! DECL_ARTIFICIAL (decl))
+           cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
+       }
+
       if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
        make_decl_rtl (decl, NULL_PTR, toplev);
       else if (TREE_CODE (decl) == VAR_DECL
@@ -7067,6 +7095,7 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
 {
   tree cname, decl;
   int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
+  tree t;
 
   if (ctype)
     cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL
@@ -7128,6 +7157,14 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
   if (ctype && hack_decl_function_context (decl))
       DECL_NO_STATIC_CHAIN (decl) = 1;
 
+  for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
+    if (TREE_PURPOSE (t)
+       && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
+      {
+       add_defarg_fn (decl);
+       break;
+      }
+
   /* Caller will do the rest of this.  */
   if (check < 0)
     return decl;
@@ -8672,6 +8709,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
            /* ANSI says that `const int foo ();'
               does not make the function foo const.  */
            type = build_function_type (type, arg_types);
+
+           {
+             tree t;
+             for (t = arg_types; t; t = TREE_CHAIN (t))
+               if (TREE_PURPOSE (t)
+                   && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
+                 {
+                   add_defarg_fn (type);
+                   break;
+                 }
+           }
          }
          break;
 
@@ -9858,6 +9906,9 @@ grokparms (first_parm, funcdef_flag)
                        PARM_DECL_EXPR (init) = 1;
                      else if (processing_template_decl)
                        ;
+                     /* Unparsed default arg from in-class decl.  */
+                     else if (TREE_CODE (init) == DEFAULT_ARG)
+                       ;
                      else if (TREE_CODE (init) == VAR_DECL
                               || TREE_CODE (init) == PARM_DECL)
                        {
@@ -9877,6 +9928,7 @@ grokparms (first_parm, funcdef_flag)
                      else
                        init = require_instantiated_type (type, init, integer_zero_node);
                      if (! processing_template_decl
+                         && TREE_CODE (init) != DEFAULT_ARG
                          && ! can_convert_arg (type, TREE_TYPE (init), init))
                        cp_pedwarn ("invalid type `%T' for default argument to `%#D'",
                                    TREE_TYPE (init), decl);
@@ -9931,6 +9983,21 @@ grokparms (first_parm, funcdef_flag)
 
   return result;
 }
+
+/* Called from the parser to update an element of TYPE_ARG_TYPES for some
+   FUNCTION_TYPE with the newly parsed version of its default argument, which
+   was previously digested as text.  See snarf_defarg et al in lex.c.  */
+
+void
+replace_defarg (arg, init)
+     tree arg, init;
+{
+  if (! processing_template_decl
+      && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init))
+    cp_pedwarn ("invalid type `%T' for default argument to `%T'",
+               TREE_TYPE (init), TREE_VALUE (arg));
+  TREE_PURPOSE (arg) = init;
+}
 \f
 int
 copy_args_p (d)
@@ -10595,13 +10662,6 @@ xref_basetypes (code_type_node, name, ref, binfo)
              continue;
            }
 
-         /* Effective C++ rule 14.  The case of virtual functions but
-            non-virtual dtor is handled in finish_struct_1.  */
-         if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
-             && TYPE_HAS_DESTRUCTOR (basetype))
-           cp_warning ("base class `%#T' has a non-virtual destructor",
-                       basetype);
-
          /* Note that the BINFO records which describe individual
             inheritances are *not* shared in the lattice!  They
             cannot be shared because a given baseclass may be
@@ -10891,6 +10951,7 @@ build_enumerator (name, value)
         a function could mean local to a class method.  */
       decl = build_decl (CONST_DECL, name, integer_type_node);
       DECL_INITIAL (decl) = value;
+      TREE_READONLY (decl) = 1;
 
       pushdecl (decl);
       GNU_xref_decl (current_function_decl, decl);
@@ -10988,6 +11049,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
   current_base_init_list = NULL_TREE;
   current_member_init_list = NULL_TREE;
   ctor_label = dtor_label = NULL_TREE;
+  static_labelno = 0;
 
   clear_temp_name ();
 
@@ -12606,6 +12668,7 @@ struct cp_function
   rtx result_rtx;
   struct cp_function *next;
   struct binding_level *binding_level;
+  int static_labelno;
 };
 
 static struct cp_function *cp_function_chain;
@@ -12647,6 +12710,7 @@ push_cp_function_context (context)
   p->member_init_list = current_member_init_list;
   p->current_class_ptr = current_class_ptr;
   p->current_class_ref = current_class_ref;
+  p->static_labelno = static_labelno;
 }
 
 /* Restore the variables used during compilation of a C++ function.  */
@@ -12688,6 +12752,7 @@ pop_cp_function_context (context)
   current_member_init_list = p->member_init_list;
   current_class_ptr = p->current_class_ptr;
   current_class_ref = p->current_class_ref;
+  static_labelno = p->static_labelno;
 
   free (p);
 }
index e8eac16..98ca15f 100644 (file)
@@ -1081,7 +1081,8 @@ dump_expr (t, nop)
     case NEW_EXPR:
       OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
       OB_PUTC ('(');
-      dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
+      if (TREE_OPERAND (t, 1))
+       dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
       OB_PUTC (')');
       break;
 
index 3194600..5fe34b0 100644 (file)
@@ -26,6 +26,7 @@ Questions and comments to Mike Stump @code{<mrs@@cygnus.com>}.
 * Copying Objects::             
 * Exception Handling::          
 * Free Store::                  
+* Mangling::  Function name mangling for C++ and Java
 * Concept Index::               
 @end menu
 
@@ -1472,7 +1473,7 @@ would do the hard work of fixing up the registers, adjusting the stack
 pointer, frame pointer, arg pointer and so on.
 
 
-@node Free Store, Concept Index, Exception Handling, Top
+@node Free Store, Mangling, Exception Handling, Top
 @section Free Store
 
 @code{operator new []} adds a magic cookie to the beginning of arrays
@@ -1518,8 +1519,246 @@ The linkage code in g++ is horribly twisted in order to meet two design goals:
 To meet the first goal, we defer emission of inlines and vtables until
 the end of the translation unit, where we can decide whether or not they
 are needed, and how to emit them if they are.
+        
+@node Mangling, Concept Index, Free Store, Top
+@section Function name mangling for C++ and Java
+
+Both C++ and Jave provide overloaded function and methods,
+which are methods with the same types but different parameter lists.
+Selecting the correct version is done at compile time.
+Though the overloaded functions have the same name in the source code,
+they need to be translated into different assembler-level names,
+since typical assemblers and linkers cannot handle overloading.
+This process of encoding the parameter types with the method name
+into a unique name is called @dfn{name mangling}.  The inverse
+process is called @dfn{demangling}.
+
+It is convenient that C++ and Java use compatible mangling schemes,
+since the makes life easier for tools such as gdb, and it eases
+integration between C++ and Java.
+
+Note there is also a standard "Jave Native Interface" (JNI) which
+implements a different calling convention, and uses a different
+mangling scheme.  The JNI is a rather abstract ABI so Java can call methods
+written in C or C++; 
+we are concerned here about a lower-level interface primarily
+intended for methods written in Java, but that can also be used for C++
+(and less easily C).
+
+@subsection Method name mangling
+
+C++ mangles a method by emitting the function name, followed by @code{__},
+followed by encodings of any method qualifiers (such as @code{const}),
+followed by the mangling of the method's class,
+followed by the mangling of the parameters, in order.
+
+For example @code{Foo::bar(int, long) const} is mangled
+as @samp{bar__C3Fooil}.
+
+For a constructor, the method name is left out.
+That is @code{Foo::Foo(int, long) const}  is mangled 
+as @samp{__C3Fooil}. 
+
+GNU Java does the same.
+
+@subsection Primitive types
+
+The C++ types @code{int}, @code{long}, @code{short}, @code{char},
+and @code{long long} are mangled as @samp{i}, @samp{l},
+@samp{s}, @samp{c}, and @samp{x}, respectively.
+The corresponding unsigned types have @samp{U} prefixed
+to the mangling.  The type @code{signed char} is mangled @samp{Sc}.
+
+The C++ and Java floating-point types @code{float} and @code{double}
+are mangled as @samp{f} and @samp{d} respectively.
+
+The C++ @code{bool} type and the Java @code{boolean} type are
+mangled as @samp{b}.
+
+The C++ @code{wchar_t} and the Java @code{char} types are
+mangled as @samp{w}.
+
+The Java integral types @code{byte}, @code{short}, @code{int}
+and @code{long} are mangled as @samp{c}, @samp{s}, @samp{i},
+and @samp{x}, respectively.
+
+C++ code that has included @code{javatypes.h} will mangle
+the typedefs  @code{jbyte}, @code{jshort}, @code{jint}
+and @code{jlong} as respectively @samp{c}, @samp{s}, @samp{i},
+and @samp{x}.  (This has not been implemented yet.)
+
+@subsection Mangling of simple names
+
+A simple class, package, template, or namespace name is
+encoded as the number of characters in the name, followed by
+the actual characters.  Thus the class @code{Foo}
+is encoded as @samp{3Foo}.
+
+If any of the characters in the name are not alphanumeric
+(i.e not one of the standard ASCII letters, digits, or '_'),
+or the initial character is a digit, then the name is
+mangled as a sequence of encoded Unicode letters.
+A Unicode encoding starts with a @samp{U} to indicate
+that Unicode escapes are used, followed by the number of
+bytes used by the Unicode encoding, followed by the bytes
+representing the encoding.  ASSCI letters and
+non-initial digits are encoded without change.  However, all
+other characters (including underscore and initial digits) are
+translated into a sequence starting with an underscore,
+followed by the big-endian 4-hex-digit lower-case encoding of the character.
+
+If a method name contains Unicode-escaped characters, the
+entire mangled method name is followed by a @samp{U}.
+
+For example, the method @code{X\u0319::M\u002B(int)} is encoded as
+@samp{M_002b__U6X_0319iU}.
+
+@subsection Pointer and reference types
+
+A C++ pointer type is mangled as @samp{P} followed by the
+mangling of the type pointed to.
+
+A C++ reference type as mangled as @samp{R} followed by the
+mangling of the type referenced.
+
+A Java object reference type is equivalent
+to a C++ pointer parameter, so we mangle such an parameter type
+as @samp{P} followed by the mangling of the class name.
+
+@subsection Qualified names
+
+Both C++ and Java allow a class to be lexically nested inside another
+class.  C++ also supports namespaces (not yet implemented by G++).
+Java also supports packages.
+
+These are all mangled the same way:  First the letter @samp{Q}
+indicates that we are emitting a qualified name.
+That is followed by the number of parts in the qualified name.
+If that number is 9 or less, it is emitted with no delimiters.
+Otherwise, an underscore is written before and after the count.
+Then follows each part of the qualified name, as described above.
+
+For example @code{Foo::\u0319::Bar} is encoded as
+@samp{Q33FooU5_03193Bar}.
+
+@subsection Templates
+
+A template instantiation is encoded as the letter @samp{t},
+followed by the encoding of the template name, followed
+the number of template parameters, followed by encoding of the template
+parameters.  If a template parameter is a type, it is written
+as a @samp{Z} followed by the encoding of the type.
+
+@subsection Arrays
+
+C++ array types are mangled by emitting @samp{A}, followed by
+the length of the array, followed by an @samp{_}, followed by
+the mangling of the element type.  Of course, normally
+array parameter types decay into a pointer types, so you
+don't see this.
+
+Java arrays are objects.  A Java type @code{T[]} is mangled
+as if it were the C++ type @code{JArray<T>}.
+For example @code{java.lang.String[]} is encoded as
+@samp{Pt6JArray1ZPQ34java4lang6String}.
+
+@subsection Table of demangling code characters
+
+The following special characters are used in mangling:
+
+@table @samp
+@item A
+Indicates a C++ array type.
+
+@item b
+Encodes the C++ @code{bool} type,
+and the Java @code{boolean} type.
+
+@item c
+Encodes the C++ @code{char} type, and the Java @code{byte} type.
+
+@item C
+A modifier to indicate a @code{const} type.
+Also used to indicate a @code{const} member function
+(in which cases it precedes the encoding of the method's class).
+
+@item d
+Encodes the C++ and Java @code{double} types.
+
+@item e
+Indicates extra unknown arguments @code{...}.
+
+@item f
+Encodes the C++ and Java @code{float} types.
+
+@item F
+Used to indicate a function type.
+
+@item i
+Encodes the C++ and Java @code{int} types.
+
+@item J
+Indicates a complex type.
+
+@item l
+Encodes the C++ @code{long} type.
+
+@item P
+Indicates a pointer type.  Followed by the type pointed to.
+
+@item Q
+Used to mangle qualified names, which arise from nested classes.
+Should also be used for namespaces (?).
+In Java used to mangle package-qualified names, and inner classes.
+
+@item r
+Encodes the GNU C++ @code{long double} type.
+
+@item R
+Indicates a reference type.  Followed by the referenced type.
+
+@item s
+Encodes the C++ and java @code{short} types.
+
+@item S
+A modifier that indicates that the following integer type is signed.
+Only used with @code{char}.
+
+Also used as a modifier to indicate a static member function.
+
+@item t
+Indicates a template instantiation.
+
+@item T
+A back reference to a previously seen type.
+
+@item U
+A modifier that indicates that the following integer type is unsigned.
+Also used to indicate that the following class or namespace name
+is encoded using Unicode-mangling.
+
+@item v
+Encodes the C++ and Java @code{void} types.
+
+@item V
+A modified for a @code{const} type or method.
+
+@item w
+Encodes the C++ @code{wchar_t} type, and the Java @code{char} types.
+
+@item x
+Encodes the GNU C++ @code{long long} type, and the Java @code{long} type.
+
+@item Z
+Used for template type parameters. 
+
+@end table
+
+The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p}
+also seem to be used for obscure purposes ...
+
+@node Concept Index,  , Mangling, Top
 
-@node Concept Index,  , Free Store, Top
 @section Concept Index
 
 @printindex cp
index 06203fb..1985339 100644 (file)
@@ -1963,7 +1963,7 @@ build_offset_ref (type, name)
   if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
     {
       mark_used (t);
-      return t;
+      return convert_from_reference (t);
     }
 
   if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))
index e142bf4..923f27c 100644 (file)
@@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA.  */
    inlining).  */
 
 #include <stdio.h>
-#include "obstack.h"
 
 extern FILE *finput;
 
@@ -43,8 +42,6 @@ struct input_source {
   int length;
   /* current position, when reading as input */
   int offset;
-  /* obstack to free this input string from when finished, if any */
-  struct obstack *obstack;
   /* linked list maintenance */
   struct input_source *next;
   /* values to restore after reading all of current string */
@@ -78,7 +75,6 @@ allocate_input ()
     }
   inp = (struct input_source *) xmalloc (sizeof (struct input_source));
   inp->next = 0;
-  inp->obstack = 0;
   return inp;
 }
 
@@ -86,9 +82,6 @@ static inline void
 free_input (inp)
      struct input_source *inp;
 {
-  if (inp->obstack)
-    obstack_free (inp->obstack, inp->str);
-  inp->obstack = 0;
   inp->str = 0;
   inp->length = 0;
   inp->next = free_inputs;
@@ -102,10 +95,9 @@ static int putback_char = -1;
 
 inline
 void
-feed_input (str, len, delete)
+feed_input (str, len)
      char *str;
      int len;
-     struct obstack *delete;
 {
   struct input_source *inp = allocate_input ();
 
@@ -115,7 +107,6 @@ feed_input (str, len, delete)
 
   inp->str = str;
   inp->length = len;
-  inp->obstack = delete;
   inp->offset = 0;
   inp->next = input;
   inp->filename = input_filename;
@@ -129,6 +120,22 @@ feed_input (str, len, delete)
 struct pending_input *to_be_restored; /* XXX */
 extern int end_of_file;
 
+static inline void
+end_input ()
+{
+  struct input_source *inp = input;
+
+  end_of_file = 0;
+  input = inp->next;
+  input_filename = inp->filename;
+  lineno = inp->lineno;
+  /* Get interface/implementation back in sync.  */
+  extract_interface_info ();
+  putback_char = inp->putback_char;
+  restore_pending_input (inp->input);
+  free_input (inp);
+}
+
 static inline int
 sub_getch ()
 {
@@ -140,30 +147,12 @@ sub_getch ()
     }
   if (input)
     {
-      if (input->offset == input->length)
+      if (input->offset >= input->length)
        {
-         struct input_source *inp = input;
          my_friendly_assert (putback_char == -1, 223);
-         to_be_restored = inp->input;
-         input->offset++;
          return EOF;
        }
-      else if (input->offset > input->length)
-       {
-         struct input_source *inp = input;
-
-         end_of_file = 0;
-         input = inp->next;
-         input_filename = inp->filename;
-         lineno = inp->lineno;
-         /* Get interface/implementation back in sync.  */
-         extract_interface_info ();
-         putback_char = inp->putback_char;
-         free_input (inp);
-         return getch ();
-       }
-      if (input)
-       return (unsigned char)input->str[input->offset++];
+      return (unsigned char)input->str[input->offset++];
     }
   return getc (finput);
 }
index 941a677..0e5e13e 100644 (file)
@@ -72,6 +72,7 @@ void yyerror ();
 /* This obstack is needed to hold text.  It is not safe to use
    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
 struct obstack inline_text_obstack;
+char *inline_text_firstobj;
 
 int end_of_file;
 
@@ -91,7 +92,7 @@ extern struct obstack token_obstack;
 #else
 extern void put_back (/* int */);
 extern int input_redirected ();
-extern void feed_input (/* char *, int, struct obstack * */);
+extern void feed_input (/* char *, int */);
 #endif
 
 /* Holds translations from TREE_CODEs to operator name strings,
@@ -575,6 +576,7 @@ init_lex ()
   init_method ();
   init_error ();
   gcc_obstack_init (&inline_text_obstack);
+  inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
 
   /* Start it at 0, because check_newline is called at the very beginning
      and will increment it to 1.  */
@@ -1170,7 +1172,7 @@ do_pending_inlines ()
     push_cp_function_context (context);
   if (t->len > 0)
     {
-      feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
+      feed_input (t->buf, t->len);
       lineno = t->lineno;
 #if 0
       if (input_filename != t->filename)
@@ -1192,7 +1194,6 @@ do_pending_inlines ()
   DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
 }
 
-extern struct pending_input *to_be_restored;
 static int nextchar = -1;
 
 /* Called from the fndecl rule in the parser when the function just parsed
@@ -1222,16 +1223,13 @@ process_next_inline (t)
       nextchar = -1;
     }
   yychar = YYEMPTY;
-  if (to_be_restored == 0)
-    my_friendly_abort (123);
-  restore_pending_input (to_be_restored);
-  to_be_restored = 0;
+  end_input ();
   if (i && i->fndecl != NULL_TREE)
     {
       context = hack_decl_function_context (i->fndecl);
       if (context)
        push_cp_function_context (context);
-      feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
+      feed_input (i->buf, i->len);
       lineno = i->lineno;
       input_filename = i->filename;
       yychar = PRE_PARSED_FUNCTION_DECL;
@@ -1392,6 +1390,12 @@ yyungetc (ch, rescan)
     }
 }
 
+void
+clear_inline_text_obstack ()
+{
+  obstack_free (&inline_text_obstack, inline_text_firstobj);
+}
+
 /* This function stores away the text for an inline function that should
    be processed later.  It decides how much later, and may need to move
    the info between obstacks; therefore, the caller should not refer to
@@ -1448,7 +1452,6 @@ reinit_parse_for_method (yychar, decl)
       t->token_value = 0;
       t->buf = buf;
       t->len = len;
-      t->can_free = 1;
       t->deja_vu = 0;
 #if 0
       if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
@@ -1625,6 +1628,259 @@ reinit_parse_for_block (pyychar, obstackp)
   obstack_1grow (obstackp, '\0');
 }
 
+/* Consume a no-commas expression -- actually, a default argument -- and
+   save it away on the specified obstack.  */
+
+static void
+reinit_parse_for_expr (obstackp)
+     struct obstack *obstackp;
+{
+  register int c = 0;
+  int starting_lineno = lineno;
+  char *starting_filename = input_filename;
+  int len;
+  int look_for_semicolon = 0;
+  int look_for_lbrac = 0;
+  int plev = 0;
+
+  if (nextchar != EOF)
+    {
+      c = nextchar;
+      nextchar = EOF;
+    }
+  else
+    c = getch ();
+  
+  while (c != EOF)
+    {
+      int this_lineno = lineno;
+
+      c = skip_white_space (c);
+
+      /* Don't lose our cool if there are lots of comments.  */
+      if (lineno == this_lineno + 1)
+       obstack_1grow (obstackp, '\n');
+      else if (lineno == this_lineno)
+       ;
+      else if (lineno - this_lineno < 10)
+       {
+         int i;
+         for (i = lineno - this_lineno; i > 0; --i)
+           obstack_1grow (obstackp, '\n');
+       }
+      else
+       {
+         char buf[16];
+         sprintf (buf, "\n# %d \"", lineno);
+         len = strlen (buf);
+         obstack_grow (obstackp, buf, len);
+
+         len = strlen (input_filename);
+         obstack_grow (obstackp, input_filename, len);
+         obstack_1grow (obstackp, '\"');
+         obstack_1grow (obstackp, '\n');
+       }
+
+      while (c > ' ')          /* ASCII dependent...  */
+       {
+         if (plev <= 0 && (c == ')' || c == ','))
+           {
+             put_back (c);
+             goto done;
+           }
+         obstack_1grow (obstackp, c);
+         if (c == '(' || c == '[')
+           ++plev;
+         else if (c == ']' || c == ')')
+           --plev;
+         else if (c == '\\')
+           {
+             /* Don't act on the next character...e.g, doing an escaped
+                double-quote.  */
+             c = getch ();
+             if (c == EOF)
+               {
+                 error_with_file_and_line (starting_filename,
+                                           starting_lineno,
+                                           "end of file read inside definition");
+                 goto done;
+               }
+             obstack_1grow (obstackp, c);
+           }
+         else if (c == '\"')
+           consume_string (obstackp, c);
+         else if (c == '\'')
+           consume_string (obstackp, c);
+         c = getch ();
+       }
+
+      if (c == EOF)
+       {
+         error_with_file_and_line (starting_filename,
+                                   starting_lineno,
+                                   "end of file read inside definition");
+         goto done;
+       }
+      else if (c != '\n')
+       {
+         obstack_1grow (obstackp, c);
+         c = getch ();
+       }
+    }
+ done:
+  obstack_1grow (obstackp, '\0');
+}
+
+int do_snarf_defarg;
+
+/* Decide whether the default argument we are about to see should be
+   gobbled up as text for later parsing.  */
+
+void
+maybe_snarf_defarg ()
+{
+  if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
+    do_snarf_defarg = 1;
+}
+
+/* When we see a default argument in a method declaration, we snarf it as
+   text using snarf_defarg.  When we get up to namespace scope, we then go
+   through and parse all of them using do_pending_defargs.  Since yacc
+   parsers are not reentrant, we retain defargs state in these two
+   variables so that subsequent calls to do_pending_defargs can resume
+   where the previous call left off.  */
+
+tree defarg_fns;
+tree defarg_parm;
+
+tree
+snarf_defarg ()
+{
+  int len;
+  char *buf;
+  tree arg;
+  struct pending_inline *t;
+
+  reinit_parse_for_expr (&inline_text_obstack);
+  len = obstack_object_size (&inline_text_obstack);
+  buf = obstack_finish (&inline_text_obstack);
+
+  push_obstacks (&inline_text_obstack, &inline_text_obstack);
+  arg = make_node (DEFAULT_ARG);
+  DEFARG_LENGTH (arg) = len - 1;
+  DEFARG_POINTER (arg) = buf;
+  pop_obstacks ();
+
+  return arg;
+}
+
+/* Called from grokfndecl to note a function decl with unparsed default
+   arguments for later processing.  Also called from grokdeclarator
+   for function types with unparsed defargs; the call from grokfndecl
+   will always come second, so we can overwrite the entry from the type.  */
+
+void
+add_defarg_fn (decl)
+     tree decl;
+{
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    TREE_VALUE (defarg_fns) = decl;
+  else
+    {
+      push_obstacks (&inline_text_obstack, &inline_text_obstack);
+      defarg_fns = tree_cons (current_class_type, decl, defarg_fns);  
+      pop_obstacks ();
+    }
+}
+
+/* Helper for do_pending_defargs.  Starts the parsing of a default arg.  */
+
+static void
+feed_defarg (f, p)
+     tree f, p;
+{
+  tree d = TREE_PURPOSE (p);
+  feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
+  if (TREE_CODE (f) == FUNCTION_DECL)
+    {
+      lineno = DECL_SOURCE_LINE (f);
+      input_filename = DECL_SOURCE_FILE (f);
+    }
+  yychar = DEFARG_MARKER;
+  yylval.ttype = p;
+}
+
+/* Helper for do_pending_defargs.  Ends the parsing of a default arg.  */
+
+static void
+finish_defarg ()
+{
+  if (yychar == YYEMPTY)
+    yychar = yylex ();
+  if (yychar != END_OF_SAVED_INPUT)
+    {
+      error ("parse error at end of saved function text");
+
+      /* restore_pending_input will abort unless yychar is either
+         END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
+         hosed, feed back YYEMPTY.  We also need to discard nextchar,
+         since that may have gotten set as well.  */
+      nextchar = -1;
+    }
+  yychar = YYEMPTY;
+  end_input ();
+}  
+
+/* Main function for deferred parsing of default arguments.  Called from
+   the parser.  */
+
+void
+do_pending_defargs ()
+{
+  if (defarg_parm)
+    finish_defarg ();
+
+  for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
+    {
+      tree defarg_fn = TREE_VALUE (defarg_fns);
+      if (defarg_parm == NULL_TREE)
+       {
+         tree p;
+
+         push_nested_class (TREE_PURPOSE (defarg_fns), 1);
+         pushlevel (0);
+
+         if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
+           {
+#if 0
+             for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
+               pushdecl (copy_node (p));
+#endif
+             defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
+           }
+         else
+           defarg_parm = TYPE_ARG_TYPES (defarg_fn);
+       }
+      else
+       defarg_parm = TREE_CHAIN (defarg_parm);
+
+      for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
+       if (TREE_PURPOSE (defarg_parm))
+         {
+           my_friendly_assert (TREE_CODE (TREE_PURPOSE (defarg_parm))
+                               == DEFAULT_ARG, 2349);
+           feed_defarg (defarg_fn, defarg_parm);
+
+           /* Return to the parser, which will process this defarg
+              and call us again.  */
+           return;
+         }
+
+      poplevel (0, 0, 0);
+      pop_nested_class (1);
+    }
+}
+
 /* Build a default function named NAME for type TYPE.
    KIND says what to build.
 
@@ -2716,7 +2972,7 @@ do_scoped_id (token, parsing)
        }
       /* else just use the decl */
     }
-  return id;
+  return convert_from_reference (id);
 }
 
 tree
index de641d4..7a3a722 100644 (file)
@@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA.  */
    processed.  */
 struct pending_inline *pending_inlines;
 
+int static_labelno;
+
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
@@ -371,18 +373,15 @@ build_overload_nested_name (decl)
     {
       tree name = DECL_ASSEMBLER_NAME (decl);
       char *label;
-      extern int var_labelno;
 
-      ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
-      var_labelno++;
+      ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno);
+      static_labelno++;
 
       if (numeric_output_need_bar)
-       {
-         OB_PUTC ('_');
-         numeric_output_need_bar = 0;
-       }
+       OB_PUTC ('_');
       icat (strlen (label));
       OB_PUTCP (label);
+      numeric_output_need_bar = 1;
     }
   else                         /* TYPE_DECL */
     build_overload_identifier (decl);
@@ -669,6 +668,49 @@ build_overload_identifier (name)
     }
 }
 
+/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce
+   the mangling for it.  Used by build_overload_name and build_static_name.  */
+
+static void
+build_qualified_name (decl)
+     tree decl;
+{
+  tree context;
+  int i = 1;
+
+  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
+    decl = TYPE_NAME (decl);
+
+  /* If DECL_ASSEMBLER_NAME has been set properly, use it.  */
+  if (TREE_CODE (decl) == TYPE_DECL
+      && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
+    {
+      OB_PUTID (DECL_ASSEMBLER_NAME (decl));
+      return;
+    }
+
+  context = decl;
+  while (DECL_CONTEXT (context))
+    {
+      i += 1;
+      context = DECL_CONTEXT (context);
+      if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
+       context = TYPE_NAME (context);
+    }
+
+  if (i > 1)
+    {
+      OB_PUTC ('Q');
+      if (i > 9)
+       OB_PUTC ('_');
+      icat (i);
+      if (i > 9)
+       OB_PUTC ('_');
+      numeric_output_need_bar = 0;
+    }
+  build_overload_nested_name (decl);
+}
+
 /* Given a list of parameters in PARMTYPES, create an unambiguous
    overload string. Should distinguish any type that C (or C++) can
    distinguish. I.e., pointers to functions are treated correctly.
@@ -931,41 +973,15 @@ build_overload_name (parmtypes, begin, end)
        common:
          {
            tree name = TYPE_NAME (parmtype);
-           int i = 1;
 
-           if (TREE_CODE (name) == TYPE_DECL)
+           if (TREE_CODE (name) == IDENTIFIER_NODE)
              {
-               tree context = name;
-
-               /* If DECL_ASSEMBLER_NAME has been set properly, use it.  */
-               if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
-                 {
-                   OB_PUTID (DECL_ASSEMBLER_NAME (context));
-                   break;
-                 }
-               while (DECL_CONTEXT (context))
-                 {
-                   i += 1;
-                   context = DECL_CONTEXT (context);
-                   if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
-                     context = TYPE_NAME (context);
-                 }
-               name = DECL_NAME (name);
+               build_overload_identifier (TYPE_NAME (parmtype));
+               break;
              }
-           my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
-           if (i > 1)
-             {
-               OB_PUTC ('Q');
-               if (i > 9)
-                 OB_PUTC ('_');
-               icat (i);
-               if (i > 9)
-                 OB_PUTC ('_');
-               numeric_output_need_bar = 0;
-               build_overload_nested_name (TYPE_NAME (parmtype));
-             }
-           else              
-             build_overload_identifier (TYPE_NAME (parmtype));
+           my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248);
+
+           build_qualified_name (name);
            break;
          }
 
@@ -1015,17 +1031,29 @@ build_overload_name (parmtypes, begin, end)
   return (char *)obstack_base (&scratch_obstack);
 }
 
+/* Produce the mangling for a variable named NAME in CONTEXT, which can
+   be either a class TYPE or a FUNCTION_DECL.  */
+
 tree
-build_static_name (basetype, name)
-  tree basetype, name;
+build_static_name (context, name)
+     tree context, name;
 {
-  char *basename  = build_overload_name (basetype, 1, 1);
-  char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
-                              + sizeof (STATIC_NAME_FORMAT)
-                              + strlen (basename));
-  sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
-  return get_identifier (buf);
-}  
+  OB_INIT ();
+  numeric_output_need_bar = 0;
+#ifdef JOINER
+  OB_PUTC ('_');
+  build_qualified_name (context);
+  OB_PUTC (JOINER);
+#else
+  OB_PUTS ("__static_");
+  build_qualified_name (context);
+  OB_PUTC (' ');
+#endif
+  OB_PUTID (name);
+  OB_FINISH ();
+
+  return get_identifier ((char *)obstack_base (&scratch_obstack));
+}
 \f
 /* Change the name of a function definition so that it may be
    overloaded. NAME is the name of the function to overload,
index ab11230..fe519b8 100644 (file)
@@ -89,7 +89,10 @@ empty_parms ()
   tree parms;
 
   if (strict_prototype
-      || current_class_type != NULL)
+      /* Only go ahead with using the void list node if we're actually
+        parsing a class in C++, not a struct in extern "C" mode.  */
+      || (current_class_type != NULL
+         && current_lang_name == lang_name_cplusplus))
     parms = void_list_node;
   else
     parms = NULL_TREE;
@@ -201,7 +204,7 @@ empty_parms ()
 %type <ttype> declmods 
 %type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
 %type <itype> initdecls notype_initdecls initdcl       /* C++ modification */
-%type <ttype> init initlist maybeasm maybe_init
+%type <ttype> init initlist maybeasm maybe_init defarg defarg1
 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
 %type <ttype> maybe_attribute attributes attribute attribute_list attrib
 %type <ttype> any_word
@@ -236,7 +239,7 @@ empty_parms ()
 /* C++ extensions */
 %token <ttype> TYPENAME_ELLIPSIS PTYPENAME
 %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
-%token <ttype> PRE_PARSED_CLASS_DECL
+%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
 %type <ttype> fn.def1 /* Not really! */ component_constructor_declarator
 %type <ttype> fn.def2 return_id fn.defpen constructor_declarator
 %type <itype> ctor_initializer_opt
@@ -284,13 +287,13 @@ empty_parms ()
 \f
 %{
 /* List of types and structure classes of the current declaration.  */
-static tree current_declspecs;
+static tree current_declspecs = NULL_TREE;
 /* List of prefix attributes in effect.
    Prefix attributes are parsed by the reserved_declspecs and declmods
    rules.  They create a list that contains *both* declspecs and attrs.  */
 /* ??? It is not clear yet that all cases where an attribute can now appear in
    a declspec list have been updated.  */
-static tree prefix_attributes;
+static tree prefix_attributes = NULL_TREE;
 
 /* When defining an aggregate, this is the most recent one being defined.  */
 static tree current_aggr;
@@ -1661,7 +1664,7 @@ decl:
          typespec initdecls ';'
                {
                  resume_momentary ($2);
-                 if (IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
+                 if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t)))
                    note_got_semicolon ($1.t);
                }
        | typed_declspecs initdecls ';'
@@ -1907,7 +1910,8 @@ initdcl0:
          declarator maybeasm maybe_attribute '='
                { split_specs_attrs ($<ttype>0, &current_declspecs,
                                     &prefix_attributes);
-                 if (TREE_CODE (current_declspecs) != TREE_LIST)
+                 if (current_declspecs
+                     && TREE_CODE (current_declspecs) != TREE_LIST)
                    current_declspecs = get_decl_list (current_declspecs);
                  if (have_extern_spec && !used_extern_spec)
                    {
@@ -1927,7 +1931,8 @@ initdcl0:
                { tree d;
                  split_specs_attrs ($<ttype>0, &current_declspecs,
                                     &prefix_attributes);
-                 if (TREE_CODE (current_declspecs) != TREE_LIST)
+                 if (current_declspecs
+                     && TREE_CODE (current_declspecs) != TREE_LIST)
                    current_declspecs = get_decl_list (current_declspecs);
                  if (have_extern_spec && !used_extern_spec)
                    {
@@ -2119,6 +2124,20 @@ pending_inlines:
          eat_saved_input
        ;
 
+/* A regurgitated default argument.  The value of DEFARG_MARKER will be
+   the TREE_LIST node for the parameter in question.  */
+defarg_again:
+       DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT
+               { replace_defarg ($1, $2); }
+
+pending_defargs:
+         /* empty */ %prec EMPTY
+       | pending_defargs defarg_again
+               { do_pending_defargs (); }
+       | pending_defargs error
+               { do_pending_defargs (); }
+       ;
+
 structsp:
          ENUM identifier '{'
                { $<itype>3 = suspend_momentary ();
@@ -2188,13 +2207,22 @@ structsp:
 
                  if (! semi)
                    check_for_missing_semicolon ($1); 
+                 if (current_scope () == current_function_decl)
+                   do_pending_defargs ($1);
+               }
+         pending_defargs
+               {
                  if (pending_inlines 
                      && current_scope () == current_function_decl)
                    do_pending_inlines ();
                }
          pending_inlines
-               { $$.t = $<ttype>6;
-                 $$.new_type_flag = 1; }
+               { 
+                 $$.t = $<ttype>6;
+                 $$.new_type_flag = 1; 
+                 if (current_scope () == current_function_decl)
+                   clear_inline_text_obstack (); 
+               }
        | class_head  %prec EMPTY
                {
                  $$.t = $1;
@@ -3951,14 +3979,27 @@ complex_parmlist:
                }
        ;
 
+/* A default argument to a */
+defarg:
+         '='
+               { maybe_snarf_defarg (); }
+         defarg1
+               { $$ = $3; }
+       ;
+
+defarg1:
+         DEFARG
+       | init
+       ;
+
 /* A nonempty list of parameter declarations or type names.  */
 parms:
          named_parm
                { check_for_new_type ("in a parameter list", $1);
                  $$ = build_tree_list (NULL_TREE, $1.t); }
-       | parm '=' init
+       | parm defarg
                { check_for_new_type ("in a parameter list", $1);
-                 $$ = build_tree_list ($3, $1.t); }
+                 $$ = build_tree_list ($2, $1.t); }
        | parms_comma full_parm
                { check_for_new_type ("in a parameter list", $2);
                  $$ = chainon ($$, $2.t); }
@@ -4005,7 +4046,10 @@ named_parm:
        ;
 
 full_parm:
-         parm maybe_init
+         parm
+               { $$.t = build_tree_list (NULL_TREE, $1.t);
+                 $$.new_type_flag = $1.new_type_flag;  }
+       | parm defarg
                { $$.t = build_tree_list ($2, $1.t);
                  $$.new_type_flag = $1.new_type_flag;  }
        ;
index 291e33b..f43488d 100644 (file)
@@ -962,6 +962,18 @@ uses_template_parms (t)
        return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
       return uses_template_parms (TREE_OPERAND (t, 1));
 
+    case MODOP_EXPR:
+    case CAST_EXPR:
+    case REINTERPRET_CAST_EXPR:
+    case CONST_CAST_EXPR:
+    case STATIC_CAST_EXPR:
+    case DYNAMIC_CAST_EXPR:
+    case SIZEOF_EXPR:
+    case ARROW_EXPR:
+    case DOTSTAR_EXPR:
+    case TYPEID_EXPR:
+      return 1;
+
     default:
       switch (TREE_CODE_CLASS (TREE_CODE (t)))
        {
@@ -1849,9 +1861,6 @@ tsubst (t, args, nargs, in_decl)
                tree purpose = TREE_PURPOSE (values);
                tree x = build_tree_list (purpose, value);
 
-               if (purpose)
-                 PARM_DEFAULT_FROM_TEMPLATE (x) = 1;
-
                if (first)
                  TREE_CHAIN (last) = x;
                else
@@ -2828,6 +2837,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
     case REAL_TYPE:
     case COMPLEX_TYPE:
     case INTEGER_TYPE:
+    case BOOLEAN_TYPE:
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return 1;
 
index 1384324..929298c 100644 (file)
@@ -405,8 +405,8 @@ ifnonnull (test, result)
 /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
    paper.  */
 
-tree
-build_dynamic_cast (type, expr)
+static tree
+build_dynamic_cast_1 (type, expr)
      tree type, expr;
 {
   enum tree_code tc = TREE_CODE (type);
@@ -628,6 +628,13 @@ build_dynamic_cast (type, expr)
            expr, exprtype, type);
   return error_mark_node;
 }
+
+tree
+build_dynamic_cast (type, expr)
+     tree type, expr;
+{
+  return convert_from_reference (build_dynamic_cast_1 (type, expr));
+}
 \f
 /* Build and initialize various sorts of descriptors.  Every descriptor
    node has a name associated with it (the name created by mangling).
index 49c64d7..15a1aa9 100644 (file)
@@ -215,6 +215,7 @@ probe_obstack (h, obj, nlevels)
    Value is 0 if we treat this name in a default fashion.  */
 extern int looking_for_typename;
 int looking_for_template;
+extern int do_snarf_defarg;
 
 extern struct obstack *current_obstack, *saveable_obstack;
 tree got_scope;
@@ -227,6 +228,8 @@ peekyylex ()
   return nth_token (0)->yychar;
 }
 
+extern tree snarf_defarg ();
+
 int
 yylex ()
 {
@@ -242,8 +245,18 @@ yylex ()
   }
 #endif
 
+  if (do_snarf_defarg)
+    {
+      my_friendly_assert (num_tokens () == 0, 2837);
+      tmp_token.yychar = DEFARG;
+      tmp_token.yylval.ttype = snarf_defarg ();
+      tmp_token.end_of_file = 0;
+      do_snarf_defarg = 0;
+      add_token (&tmp_token);
+    }
+
   /* if we've got tokens, send them */
-  if (num_tokens ())
+  else if (num_tokens ())
     {
       tmp_token= *nth_token (0);
 
index e6c0e50..d212bb2 100644 (file)
@@ -832,20 +832,18 @@ layout_basetypes (rec, binfos)
          BINFO_VPTR_FIELD (base_binfo) = decl;
          vbase_decls = decl;
 
-         if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
-             && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
-           {
-             warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
-                                "destructor `%s' non-virtual");
-             warning ("in inheritance relationship `%s: virtual %s'",
-                      TYPE_NAME_STRING (rec),
-                      TYPE_NAME_STRING (basetype));
-           }
        got_it:
          /* The space this decl occupies has already been accounted for.  */
          continue;
        }
 
+      /* Effective C++ rule 14.  We only need to check TYPE_VIRTUAL_P
+        here because the case of virtual functions but non-virtual
+        dtor is handled in finish_struct_1.  */
+      if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
+         && TYPE_HAS_DESTRUCTOR (basetype))
+       cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
+
       if (const_size == 0)
        offset = integer_zero_node;
       else
@@ -854,22 +852,6 @@ layout_basetypes (rec, binfos)
          const_size = CEIL (const_size, TYPE_ALIGN (basetype))
            * TYPE_ALIGN (basetype);
          offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
-
-#if 0
-         /* bpk: Disabled this check until someone is willing to
-            claim it as theirs and explain exactly what circumstances
-            warrant the warning.  */ 
-         if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
-             && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1)) == NULL_TREE)
-           {
-             warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1),
-                                "destructor `%s' non-virtual");
-             warning ("in inheritance relationship `%s:%s %s'",
-                      TYPE_NAME_STRING (rec),
-                      TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",
-                      TYPE_NAME_STRING (basetype));
-           }
-#endif
        }
       BINFO_OFFSET (base_binfo) = offset;
       if (CLASSTYPE_VSIZE (basetype))
index e636593..0be5b08 100644 (file)
@@ -1652,15 +1652,17 @@ build_object_ref (datum, basetype, field)
   return error_mark_node;
 }
 
-/* Like `build_component_ref, but uses an already found field.
-   Must compute access for current_class_ref.  Otherwise, ok.  */
+/* Like `build_component_ref, but uses an already found field, and converts
+   from a reference.  Must compute access for current_class_ref.
+   Otherwise, ok.  */
 
 tree
 build_component_ref_1 (datum, field, protect)
      tree datum, field;
      int protect;
 {
-  return build_component_ref (datum, field, NULL_TREE, protect);
+  return convert_from_reference
+    (build_component_ref (datum, field, NULL_TREE, protect));
 }
 
 /* Given a COND_EXPR in T, return it in a form that we can, for
@@ -2484,11 +2486,17 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
        function = save_expr (function);
 
       fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
-      idx = save_expr (build_component_ref (function,
-                                           index_identifier,
-                                           NULL_TREE, 0));
-      e1 = fold (build (GT_EXPR, boolean_type_node, idx,
-                       cp_convert (delta_type_node, integer_zero_node)));
+
+      /* Promoting idx before saving it improves performance on RISC
+        targets.  Without promoting, the first compare used
+        load-with-sign-extend, while the second used normal load then
+        shift to sign-extend.  An optimizer flaw, perhaps, but it's easier
+        to make this change.  */
+      idx = save_expr (default_conversion
+                      (build_component_ref (function,
+                                            index_identifier,
+                                            NULL_TREE, 0)));
+      e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
       delta = cp_convert (ptrdiff_type_node,
                          build_component_ref (function, delta_identifier, NULL_TREE, 0));
       delta2 = DELTA2_FROM_PTRMEMFUNC (function);