OSDN Git Service

68th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 May 1995 21:36:30 +0000 (21:36 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 May 1995 21:36:30 +0000 (21:36 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@9555 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/expr.c
gcc/cp/gxxint.texi
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index f11cf72..8347b18 100644 (file)
@@ -1,3 +1,97 @@
+Fri Apr 28 07:58:41 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * lex.c (cons_up_default_function): Fix linkage of #pragma
+       implemented functions.
+
+Thu Apr 27 16:56:24 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * method.c (build_overload_name): Simplify and fix repeated type
+       folding.
+
+       * decl.c (grokdeclarator): Prohibit pointers to void or reference
+        members.
+
+Thu Apr 27 09:49:07 1995  Mike Stump  <mrs@cygnus.com>
+
+       * typeck2.c (process_init_constructor): Make sure initializers are
+       fully digested.
+
+Thu Apr 27 01:11:55 1995  Jason Merrill  <jason@python.cygnus.com>
+
+       * lex.c (cons_up_default_function): Always defer synthesis.
+
+Thu Apr 27 00:20:37 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * decl2.c (mark_inline_for_output): Don't play with pending_inline
+       stuff.
+
+Wed Apr 26 17:48:24 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * call.c (user_harshness): New function; like build_type_conversion,
+       but doesn't actually build anything.
+       (compute_conversion_costs): Use it instead of build_type_conversion.
+
+Wed Apr 26 17:11:25 1995  Jason Merrill  <jason@deneb.cygnus.com>
+
+       * typeck.c (build_function_call_real): Improve error message for
+       calling a non-function.
+
+       * method.c (hack_identifier): Lose check for calling a data member.
+
+Wed Apr 26 16:59:13 1995  Mike Stump  <mrs@cygnus.com>
+
+       * typeck2.c (build_functional_cast): Remove very old cruft.
+       Seems like good code is generated without it.
+
+Wed Apr 26 00:47:16 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * method.c (do_build_assign_ref): Fix handling of anonymous unions.
+       (do_build_copy_constructor): Ditto.
+
+       * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch.
+
+       * decl.c (push_switch): New function.
+       (pop_switch): Ditto.
+       (define_case_label): Check for jumping over initialization.
+
+       * call.c (build_method_call): Check for an inline function being
+       called before its definition has been seen.
+       * typeck.c (build_function_call_real): Ditto.
+
+       * decl.c (duplicate_decls): Check for a function being redeclared
+       inline after its address has been taken.
+
+       * typeck.c (build_conditional_expr): Handle related class lvalues.
+
+Tue Apr 25 13:20:45 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * pt.c (do_pending_expansions): Don't expand unused templates.
+
+       * parse.y (component_decl): Accept a lone semicolon.
+
+Tue Apr 25 00:25:56 1995  Jason Merrill  <jason@rtl.cygnus.com>
+
+       * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the
+       object parameter anymore.
+
+       * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns.
+
+Mon Apr 24 12:35:48 1995  Jason Merrill  <jason@phydeaux.cygnus.com>
+
+       * parse.y (simple_stmt, decl case): Clear prefix_attributes.
+       (lang_extdef): Ditto.
+
+       * parse.y (maybe_parmlist): New rule for use in declarators where
+       this could either be a list of expressions or parameters.  Calls
+       suspend_momentary before deciding which.
+       (direct_after_type_declarator): Use it.
+       (complex_direct_notype_declarator): Use it.
+
+       * pt.c (tsubst): Propagate attributes const and noreturn.
+
+       * typeck.c (build_modify_expr): If warn_synth, call build_opfncall
+       before doing the default thing.
+
 Thu Apr 27 21:49:36 1995  Doug Evans  <dje@cygnus.com>
 
        * typeck.c (common_type): Call lookup_attribute instead of
index fa92ed8..6779c84 100644 (file)
@@ -586,6 +586,47 @@ convert_harshness (type, parmtype, parm)
 }
 
 int
+user_harshness (type, parmtype, parm)
+     register tree type, parmtype;
+     tree parm;
+{
+  tree conv;
+  tree winner = NULL_TREE;
+  int code;
+
+  {
+    tree typename = build_typename_overload (type);
+    if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0))
+      return 0;
+  }
+                       
+  for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv))
+    {
+      struct harshness_code tmp;
+
+      if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
+       continue;
+
+      if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
+         tmp.code < USER_CODE)
+       {
+         if (winner)
+           return EVIL_CODE;
+         else
+           {
+             winner = conv;
+             code = tmp.code;
+           }
+       }
+    }
+
+  if (winner)
+    return code;
+
+  return -1;
+}
+
+int
 can_convert (to, from)
      tree to, from;
 {
@@ -884,30 +925,14 @@ compute_conversion_costs (function, tta_in, cp, arglen)
                  if (TYPE_LANG_SPECIFIC (actual_type)
                      && TYPE_HAS_CONVERSION (actual_type))
                    {
-                     tree conv;
-                     /* Don't issue warnings since we're only groping
-                        around for the right answer, we haven't yet
-                        committed to going with this solution.  */
-                     int old_inhibit_warnings = inhibit_warnings;
-
-                     inhibit_warnings = 1;
-                     conv = build_type_conversion
-                       (CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
-                     inhibit_warnings = old_inhibit_warnings;
-
-                     if (conv)
+                     int extra = user_harshness (formal_type, actual_type);
+
+                     if (extra == EVIL_CODE)
+                       win += 2;
+                     else if (extra >= 0)
                        {
-                         if (conv == error_mark_node
-                             || (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE
-                                 && ! TYPE_READONLY (TREE_VALUE (TREE_VALUE (ttf)))
-                                 && ! lvalue_p (conv)))
-                           win += 2;
-                         else
-                           {
-                             win++;
-                             if (TREE_CODE (conv) != CALL_EXPR)
-                               extra_conversions = 1;
-                           }
+                         win++;
+                         extra_conversions = extra;
                        }
                    }
                }
@@ -1789,11 +1814,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
            }
          else
            {
-             if (TREE_CODE (instance) != CALL_EXPR
-#ifdef PCC_STATIC_STRUCT_RETURN
-                 && TREE_CODE (instance) != RTL_EXPR
-#endif
-                 )
+             if (TREE_CODE (instance) != CALL_EXPR)
                my_friendly_abort (125);
              if (TYPE_NEEDS_CONSTRUCTING (basetype))
                instance = build_cplus_new (basetype, instance, 0);
@@ -2397,13 +2418,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
 #if 1
   /* Is it a synthesized method that needs to be synthesized?  */
   if (DECL_ARTIFICIAL (function) && ! flag_no_inline
-      && DECL_SAVED_INSNS (function) == 0
-      && ! TREE_ASM_WRITTEN (function)
+      && ! DECL_INITIAL (function)
       /* Kludge: don't synthesize for default args.  */
       && current_function_decl)
     synthesize_method (function);
 #endif
 
+  if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function)
+       && ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function))
+    cp_pedwarn ("inline function `%#D' called before definition", function);
+
   fntype = TREE_TYPE (function);
   if (TREE_CODE (fntype) == POINTER_TYPE)
     fntype = TREE_TYPE (fntype);
index 74dca4f..dcabbd2 100644 (file)
@@ -2315,6 +2315,11 @@ duplicate_decls (newdecl, olddecl)
                                 olddecl);
                  }
              }
+
+         if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl)
+             && TREE_ADDRESSABLE (olddecl))
+           cp_pedwarn ("`%#D' was used before it was declared inline",
+                       newdecl);
        }
       /* These bits are logically part of the type for non-functions.  */
       else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
@@ -3660,6 +3665,30 @@ define_label (filename, line, name)
     }
 }
 
+struct cp_switch
+{
+  struct binding_level *level;
+  struct cp_switch *next;
+};
+
+static struct cp_switch *switch_stack;
+
+void
+push_switch ()
+{
+  struct cp_switch *p
+    = (struct cp_switch *) oballoc (sizeof (struct cp_switch));
+  p->level = current_binding_level;
+  p->next = switch_stack;
+  switch_stack = p;
+}
+
+void
+pop_switch ()
+{
+  switch_stack = switch_stack->next;
+}
+
 /* Same, but for CASE labels.  If DECL is NULL_TREE, it's the default.  */
 /* XXX Note decl is never actually used. (bpk) */
 void
@@ -3667,19 +3696,46 @@ define_case_label (decl)
      tree decl;
 {
   tree cleanup = last_cleanup_this_contour ();
+  struct binding_level *b = current_binding_level;
+  int identified = 0;
+
   if (cleanup)
     {
       static int explained = 0;
-      cp_error_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
-      error ("where case label appears here");
+      cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
+      warning ("where case label appears here");
       if (!explained)
        {
-         error ("(enclose actions of previous case statements requiring");
-         error ("destructors in their own binding contours.)");
+         warning ("(enclose actions of previous case statements requiring");
+         warning ("destructors in their own binding contours.)");
          explained = 1;
        }
     }
 
+  for (; b && b != switch_stack->level; b = b->level_chain)
+    {
+      tree new_decls = b->names;
+      for (; new_decls; new_decls = TREE_CHAIN (new_decls))
+       {
+         if (TREE_CODE (new_decls) == VAR_DECL
+             /* Don't complain about crossing initialization
+                of internal entities.  They can't be accessed,
+                and they should be cleaned up
+                by the time we get to the label.  */
+             && ! DECL_ARTIFICIAL (new_decls)
+             && ((DECL_INITIAL (new_decls) != NULL_TREE
+                  && DECL_INITIAL (new_decls) != error_mark_node)
+                 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
+           {
+             if (! identified)
+               error ("jump to case label");
+             identified = 1;
+             cp_error_at ("  crosses initialization of `%#D'",
+                          new_decls);
+           }
+       }
+    }
+
   /* After labels, make any new cleanups go into their
      own new (temporary) binding contour.  */
 
@@ -8428,6 +8484,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
              continue;
            }
 
+         if (TREE_CODE (type) == OFFSET_TYPE
+             && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE
+                 || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE))
+           {
+             cp_error ("cannot declare pointer to `%#T' member",
+                       TREE_TYPE (type));
+             type = TREE_TYPE (type);
+           }
+
          /* Merge any constancy or volatility into the target type
             for the pointer.  */
 
index 5952d85..6e4ad20 100644 (file)
@@ -2078,6 +2078,7 @@ mark_inline_for_output (decl)
     return;
   my_friendly_assert (TREE_PERMANENT (decl), 363);
   DECL_SAVED_INLINE (decl) = 1;
+#if 0
   if (DECL_PENDING_INLINE_INFO (decl) != 0
       && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)
     {
@@ -2097,6 +2098,7 @@ mark_inline_for_output (decl)
        }
       DECL_PENDING_INLINE_INFO (decl) = 0;
     }
+#endif
   saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines);
 }
 
index c6630cb..c722dcb 100644 (file)
@@ -151,8 +151,9 @@ cplus_expand_expr (exp, target, tmode, modifier)
                extern int flag_access_control;
                int old_ac = flag_access_control;
 
-               tree init = build (RTL_EXPR, type, 0, return_target);
+               tree init = build_decl (VAR_DECL, 0, type);
                TREE_ADDRESSABLE (init) = 1;
+               DECL_RTL (init) = return_target;
 
                flag_access_control = 0;
                expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
@@ -160,8 +161,10 @@ cplus_expand_expr (exp, target, tmode, modifier)
 
                if (TYPE_NEEDS_DESTRUCTOR (type))
                  {
-                   init = build (RTL_EXPR, build_reference_type (type), 0,
-                                 XEXP (return_target, 0));
+                   init = build_decl (VAR_DECL, 0,
+                                      build_reference_type (type));
+                   DECL_RTL (init) = XEXP (return_target, 0);
+
                    init = maybe_build_cleanup (convert_from_reference (init));
                    if (init != NULL_TREE)
                      expand_expr (init, 0, 0, 0);
index cb3beab..68623b2 100644 (file)
@@ -1321,6 +1321,17 @@ main()
 @}
 @end example
 
+@section Linkage
+The linkage code in g++ is horribly twisted in order to meet two design goals:
+
+1) Avoid unnecessary emission of inlines and vtables.
+
+2) Support pedantic assemblers like the one in AIX.
+
+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 Concept Index,  , Free Store, Top
 @section Concept Index
 
index 7c6b791..0585787 100644 (file)
@@ -1797,13 +1797,13 @@ cons_up_default_function (type, full_name, kind)
   if (CLASSTYPE_INTERFACE_KNOWN (type))
     {
       DECL_INTERFACE_KNOWN (fn) = 1;
-      DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
-                           || ! flag_implement_inlines);
-      TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
+      DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
+                                    && flag_implement_inlines);
     }
   else
     DECL_NOT_REALLY_EXTERN (fn) = 1;
 
+#if 0
   /* When on-the-fly synthesis works properly, remove the second and third
      conditions here.  */
   if (flag_keep_inline_functions
@@ -1822,6 +1822,7 @@ cons_up_default_function (type, full_name, kind)
       store_pending_inline (fn, t);
     }
   else
+#endif
     mark_inline_for_output (fn);
 
 #ifdef DEBUG_DEFAULT_FUNCTIONS
index ddf65b1..1e26e20 100644 (file)
@@ -562,44 +562,30 @@ build_overload_name (parmtypes, begin, end)
 
     only_one:
 
-      if (! nofold)
+      if (! nofold && ! just_one)
        {
-         if (! just_one)
-           /* Every argument gets counted.  */
-           typevec[maxtype++] = parmtype;
+         /* Every argument gets counted.  */
+         typevec[maxtype++] = parmtype;
 
-         if (TREE_USED (parmtype))
+         if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
            {
-             if (! just_one && parmtype == typevec[maxtype-2])
-               nrepeats++;
-             else
-               {
-                 if (nrepeats)
-                   flush_repeats (parmtype);
-                 if (! just_one && TREE_CHAIN (parmtypes)
-                     && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
-                   nrepeats++;
-                 else
-                   {
-                     int tindex = 0;
-
-                     while (typevec[tindex] != parmtype)
-                       tindex++;
-                     OB_PUTC ('T');
-                     icat (tindex);
-                     if (tindex > 9)
-                       OB_PUTC ('_');
-                   }
-               }
+             nrepeats++;
              goto next;
            }
+
          if (nrepeats)
            flush_repeats (typevec[maxtype-2]);
-         if (! just_one
-             /* Only cache types which take more than one character.  */
-             && (parmtype != TYPE_MAIN_VARIANT (parmtype)
-                 || (TREE_CODE (parmtype) != INTEGER_TYPE
-                     && TREE_CODE (parmtype) != REAL_TYPE)))
+
+         if (TREE_USED (parmtype))
+           {
+             flush_repeats (parmtype);
+             goto next;
+           }
+
+         /* Only cache types which take more than one character.  */
+         if (parmtype != TYPE_MAIN_VARIANT (parmtype)
+             || (TREE_CODE (parmtype) != INTEGER_TYPE
+                 && TREE_CODE (parmtype) != REAL_TYPE))
            TREE_USED (parmtype) = 1;
        }
 
@@ -1496,23 +1482,7 @@ hack_identifier (value, name, yychar)
          return error_mark_node;
        }
       TREE_USED (current_class_decl) = 1;
-      if (yychar == '(')
-       if (! ((TYPE_LANG_SPECIFIC (type)
-               && TYPE_OVERLOADS_CALL_EXPR (type))
-              || (TREE_CODE (type) == REFERENCE_TYPE
-                  && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
-                  && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
-           && TREE_CODE (type) != FUNCTION_TYPE
-           && TREE_CODE (type) != METHOD_TYPE
-           && !TYPE_PTRMEMFUNC_P (type)
-           && (TREE_CODE (type) != POINTER_TYPE
-               || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
-                   && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
-         {
-           error ("component `%s' is not a method",
-                  IDENTIFIER_POINTER (name));
-           return error_mark_node;
-         }
+
       /* Mark so that if we are in a constructor, and then find that
         this field was initialized by a base initializer,
         we can emit an error message.  */
@@ -2094,32 +2064,34 @@ do_build_copy_constructor (fndecl)
       for (; fields; fields = TREE_CHAIN (fields))
        {
          tree name, init, t;
-         if (TREE_CODE (fields) != FIELD_DECL)
+         tree field = fields;
+
+         if (TREE_CODE (field) != FIELD_DECL)
            continue;
-         if (DECL_NAME (fields))
+         if (DECL_NAME (field))
            {
-             if (VFIELD_NAME_P (DECL_NAME (fields)))
+             if (VFIELD_NAME_P (DECL_NAME (field)))
                continue;
-             if (VBASE_NAME_P (DECL_NAME (fields)))
+             if (VBASE_NAME_P (DECL_NAME (field)))
                continue;
 
              /* True for duplicate members.  */
-             if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
+             if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
                continue;
            }
-         else if ((t = TREE_TYPE (fields)) != NULL_TREE
+         else if ((t = TREE_TYPE (field)) != NULL_TREE
                   && TREE_CODE (t) == UNION_TYPE
                   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
                   && TYPE_FIELDS (t) != NULL_TREE)
-           fields = largest_union_member (t);
+           field = largest_union_member (t);
          else
            continue;
 
-         init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
+         init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
          init = build_tree_list (NULL_TREE, init);
 
          current_member_init_list
-           = tree_cons (DECL_NAME (fields), init, current_member_init_list);
+           = tree_cons (DECL_NAME (field), init, current_member_init_list);
        }
       current_member_init_list = nreverse (current_member_init_list);
       current_base_init_list = nreverse (current_base_init_list);
@@ -2171,29 +2143,31 @@ do_build_assign_ref (fndecl)
       for (; fields; fields = TREE_CHAIN (fields))
        {
          tree comp, init, t;
-         if (TREE_CODE (fields) != FIELD_DECL)
+         tree field = fields;
+
+         if (TREE_CODE (field) != FIELD_DECL)
            continue;
-         if (DECL_NAME (fields))
+         if (DECL_NAME (field))
            {
-             if (VFIELD_NAME_P (DECL_NAME (fields)))
+             if (VFIELD_NAME_P (DECL_NAME (field)))
                continue;
-             if (VBASE_NAME_P (DECL_NAME (fields)))
+             if (VBASE_NAME_P (DECL_NAME (field)))
                continue;
 
              /* True for duplicate members.  */
-             if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
+             if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
                continue;
            }
-         else if ((t = TREE_TYPE (fields)) != NULL_TREE
+         else if ((t = TREE_TYPE (field)) != NULL_TREE
                   && TREE_CODE (t) == UNION_TYPE
                   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
                   && TYPE_FIELDS (t) != NULL_TREE)
-           fields = largest_union_member (t);
+           field = largest_union_member (t);
          else
            continue;
 
-         comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields);
-         init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
+         comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
+         init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
 
          expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
        }
index 46eb2b4..d700592 100644 (file)
@@ -25,20 +25,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    all derivations; this is applied before the explicit action, if one
    is given.  Keep this in mind when reading the actions.  */
 
-/* Also note: this version contains experimental exception
-   handling features.  They could break, change, disappear,
-   or otherwise exhibit volatile behavior.  Don't depend on
-   me (Michael Tiemann) to protect you from any negative impact
-   this may have on your professional, personal, or spiritual life.
-
-   NEWS FLASH:  This version now supports the exception handling
-   syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given.
-   THIS IS WORK IN PROGRESS!!!  The type of the 'throw' and the
-   'catch' much match EXACTLY (no inheritance support or coercions).
-   Also, throw-specifications of functions don't work.
-   Destructors aren't called correctly.  Etc, etc.  --Per Bothner.
-  */
-
 %{
 /* Cause the `yydebug' variable to be defined.  */
 #define YYDEBUG 1
@@ -251,7 +237,7 @@ empty_parms ()
 %type <ttype> object aggr
 %type <itype> new delete
 /* %type <ttype> primary_no_id */
-%type <ttype> nonmomentary_expr
+%type <ttype> nonmomentary_expr maybe_parmlist
 %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
 %type <ttype> template_header template_parm_list template_parm
 %type <ttype> template_type_parm
@@ -346,7 +332,8 @@ lang_extdef:
          { if (pending_lang_change) do_pending_lang_change(); }
          extdef
          { if (! global_bindings_p () && ! pseudo_global_level_p())
-             pop_everything (); }
+             pop_everything ();
+           prefix_attributes = NULL_TREE; }
        ;
 
 extdef:
@@ -2600,7 +2587,6 @@ component_decl_list:
                        $$ = $2;
                    }
                }
-       | component_decl_list ';'
        ;
 
 component_decl:
@@ -2614,6 +2600,8 @@ component_decl:
                { $$ = finish_method ($$); }
        | fn.def2 '{' /* nodecls compstmt */
                { $$ = finish_method ($$); }
+       | ';'
+               { $$ = NULL_TREE; }
        ;
 
 component_decl_1:
@@ -2796,12 +2784,27 @@ nonempty_type_quals:
 /* These rules must follow the rules for function declarations
    and component declarations.  That way, longer rules are preferred.  */
 
+suspend_mom:
+       { $<itype>$ = suspend_momentary (); } 
+
 /* An expression which will not live on the momentary obstack.  */
 nonmomentary_expr:
-       { $<itype>$ = suspend_momentary (); } expr
+       suspend_mom expr
        { resume_momentary ((int) $<itype>1); $$ = $2; }
        ;
 
+/* An expression which will not live on the momentary obstack.  */
+maybe_parmlist:
+         suspend_mom '(' nonnull_exprlist ')'
+               { resume_momentary ((int) $<itype>1); $$ = $3; }
+       | suspend_mom '(' parmlist ')'
+               { resume_momentary ((int) $<itype>1); $$ = $3; }
+       | suspend_mom LEFT_RIGHT
+               { resume_momentary ((int) $<itype>1); $$ = empty_parms (); }
+       | suspend_mom '(' error ')'
+               { resume_momentary ((int) $<itype>1); $$ = NULL_TREE; }
+       ;
+
 /* A declarator that is allowed only after an explicit typespec.  */
 /* may all be followed by prec '.' */
 after_type_declarator:
@@ -2843,14 +2846,8 @@ nested_type:
        ;
 
 direct_after_type_declarator:
-         direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
-       | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
-       | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
-       | direct_after_type_declarator '(' error ')' type_quals %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
+         direct_after_type_declarator maybe_parmlist type_quals %prec '.'
+               { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
        | direct_after_type_declarator '[' nonmomentary_expr ']'
                { $$ = build_parse_node (ARRAY_REF, $$, $3); }
        | direct_after_type_declarator '[' ']'
@@ -2900,14 +2897,8 @@ complex_notype_declarator:
        ;
 
 complex_direct_notype_declarator:
-         direct_notype_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
-       | direct_notype_declarator '(' parmlist ')' type_quals  %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
-       | direct_notype_declarator LEFT_RIGHT type_quals  %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
-       | direct_notype_declarator '(' error ')' type_quals  %prec '.'
-               { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
+         direct_notype_declarator maybe_parmlist type_quals  %prec '.'
+               { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
        | '(' complex_notype_declarator ')'
                { $$ = $2; }
        | direct_notype_declarator '[' nonmomentary_expr ']'
@@ -3192,7 +3183,8 @@ stmt:
 
 simple_stmt:
          decl
-               { finish_stmt (); }
+               { finish_stmt ();
+                 prefix_attributes = NULL_TREE; }
        | expr ';'
                {
                  tree expr = $1;
@@ -3294,12 +3286,14 @@ simple_stmt:
        | SWITCH .pushlevel '(' condition ')'
                { emit_line_note (input_filename, lineno);
                  c_expand_start_case ($4);
+                 push_switch ();
                  /* Don't let the tree nodes for $4 be discarded by
                     clear_momentary during the parsing of the next stmt.  */
                  push_momentary (); }
          implicitly_scoped_stmt
                { expand_end_case ($4);
                  pop_momentary ();
+                 pop_switch ();
                  expand_end_bindings (getdecls (), kept_level_p (), 1);
                  poplevel (kept_level_p (), 1, 0);
                  pop_momentary ();
index 9d6266f..8c995a8 100644 (file)
@@ -1452,6 +1452,8 @@ tsubst (t, args, nargs, in_decl)
        DECL_INTERFACE_KNOWN (r) = 0;
        DECL_INLINE (r) = DECL_INLINE (t);
        DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);
+       TREE_READONLY (r) = TREE_READONLY (t);
+       TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t);
        {
 #if 0                          /* Maybe later.  -jason  */
          struct tinst_level *til = tinst_for_decl();
@@ -2412,7 +2414,7 @@ do_pending_expansions ()
             If `interface', ext ref.  */
          if (CLASSTYPE_INTERFACE_KNOWN (context))
            DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
-#if 0 /* This doesn't get us stuff needed only by the file initializer.  */
+#if 1 /* This doesn't get us stuff needed only by the file initializer.  */
          DECIDE (TREE_USED (t));
 #else /* This compiles too much stuff, but that's probably better in
         most cases than never compiling the stuff we need.  */
index afdd357..8580c9b 100644 (file)
@@ -51,6 +51,7 @@ static tree convert_sequence ();
 static tree get_delta_difference PROTO((tree, tree, int));
 
 extern rtx original_result_rtx;
+extern int warn_synth;
 
 /* Return the target type of TYPE, which meas return T for:
    T*, T&, T[], T (...), and otherwise, just T.  */
@@ -2359,6 +2360,12 @@ build_function_call_real (function, params, require_complete, flags)
          pedwarn ("ANSI C++ forbids calling `main' from within program");
        }
 
+      if (pedantic && DECL_THIS_INLINE (function) && ! DECL_INITIAL (function)
+         && ! DECL_ARTIFICIAL (function)
+         && ! DECL_PENDING_INLINE_INFO (function))
+       cp_pedwarn ("inline function `%#D' called before definition",
+                   function);
+
       /* Differs from default_conversion by not setting TREE_ADDRESSABLE
         (because calling an inline function does not mean the function
         needs to be separately compiled).  */
@@ -2403,7 +2410,7 @@ build_function_call_real (function, params, require_complete, flags)
         && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
        || is_method))
     {
-      error ("called object is not a function");
+      cp_error ("`%E' cannot be used as a function", function);
       return error_mark_node;
     }
 
@@ -4617,9 +4624,21 @@ build_conditional_expr (ifexp, op1, op2)
       code2 = TREE_CODE (type2);
     }
 
+  if (code1 == RECORD_TYPE && code2 == RECORD_TYPE
+      && real_lvalue_p (op1) && real_lvalue_p (op2)
+      && comptypes (type1, type2, -1))
+    {
+      type1 = build_reference_type (type1);
+      type2 = build_reference_type (type2);
+      result_type = common_type (type1, type2);
+      op1 = convert_to_reference (result_type, op1, CONV_IMPLICIT,
+                                 LOOKUP_NORMAL, NULL_TREE);
+      op2 = convert_to_reference (result_type, op2, CONV_IMPLICIT,
+                                 LOOKUP_NORMAL, NULL_TREE);
+    }
   /* Quickly detect the usual case where op1 and op2 have the same type
      after promotion.  */
-  if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
+  else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
     {
       if (type1 == type2)
        result_type = type1;
@@ -4814,7 +4833,8 @@ build_conditional_expr (ifexp, op1, op2)
   if (TREE_CONSTANT (ifexp))
     return integer_zerop (ifexp) ? op2 : op1;
 
-  return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
+  return convert_from_reference
+    (fold (build (COND_EXPR, result_type, ifexp, op1, op2)));
 }
 \f
 /* Handle overloading of the ',' operator when needed.  Otherwise,
@@ -5630,7 +5650,14 @@ build_modify_expr (lhs, modifycode, rhs)
        cp_error ("`%T' does not define operator=", lhstype);
       else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
               && TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
-       /* Do the default thing */;
+       {
+         if (warn_synth)
+           /* If we care about this, do overload resolution.  */
+           build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
+                           lhs, rhs, make_node (NOP_EXPR));
+
+         /* Do the default thing */;
+       }
       else
        {
          result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
index 1c719aa..e69ada4 100644 (file)
@@ -975,6 +975,13 @@ process_init_constructor (type, init, elts)
              tree tail1 = tail;
              next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
                                   TREE_VALUE (tail), &tail1);
+             if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
+                 && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
+               {
+                 /* The fact this needs to be done suggests this code needs
+                    to be totally rewritten.  */
+                 next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
+               }
              my_friendly_assert (tail1 == 0
                                  || TREE_CODE (tail1) == TREE_LIST, 319);
              if (tail == tail1 && len < 0)
@@ -1529,37 +1536,7 @@ build_functional_cast (exp, parms)
   if (expr_as_ctor == error_mark_node)
     return error_mark_node;
 
-  if (current_function_decl)
-    return build_cplus_new (type, expr_as_ctor, 1);
-
-  {
-    register tree parm = TREE_OPERAND (expr_as_ctor, 1);
-
-    /* Initializers for static variables and parameters have
-       to handle doing the initialization and cleanup themselves.  */
-    my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322);
-#if 0
-    /* The following assertion fails in cases where we are initializing
-       a static member variable of a particular instance of a template
-       class with a call to a constructor of the given instance, as in:
-       
-       TMPL<int> object = TMPL<int>();
-       
-       Curiously, the assertion does not fail if we do the same thing
-       for a static member of a non-template class, as in:
-       
-       T object = T();
-       
-       I can't see why we should care here whether or not the initializer
-       expression involves a call to `new', so for the time being, it
-       seems best to just avoid doing this assertion.  */
-    my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323);
-#endif
-    TREE_VALUE (parm) = NULL_TREE;
-    expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR);
-    TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1;
-  }
-  return expr_as_ctor;
+  return build_cplus_new (type, expr_as_ctor, 1);
 }
 \f
 /* Return the character string for the name that encodes the