]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
35th Cygnus<->FSF merge
authorMike Stump <mrs@gcc.gnu.org>
Thu, 5 May 1994 22:19:26 +0000 (22:19 +0000)
committerMike Stump <mrs@gcc.gnu.org>
Thu, 5 May 1994 22:19:26 +0000 (22:19 +0000)
From-SVN: r7217

16 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 27a7b119aa60ba76ed66c2c234ce8f3b53c294ba..d5443014a11ab3bc43a93a7725be26a93b125188 100644 (file)
-Tue May  3 19:11:24 1994  Jason Merrill  (jason@deneb.cygnus.com)
+Thu May  5 09:35:35 1994  Brendan Kehoe  (brendan@lisa.cygnus.com)
+
+       * typeck.c (build_modify_expr): Warn about assignment to `this'.
+
+Wed May  4 15:55:49 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * init.c (build_delete): Use the global operator delete when
+       requested.
+
+       * decl.c (lookup_name_real): If we find the type we're looking in a
+       base class while defining a class, set IDENTIFIER_CLASS_VALUE for
+       the type.
+
+       * class.c (finish_struct): Remove a couple of dependencies on
+       language linkage.
+
+       * decl.c (pushtag): Classes do nest in extern "C" blocks.
+       (pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for
+       the type.
+       (pushtag): Remove another dependency on the language linkage.
+
+       * lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to
+       a const-qualified type.
+
+       * decl.c (push_overloaded_decl): Throw away built-in decls here.
+       (duplicate_decls): Instead of here.
+
+Wed May  4 15:27:40 1994  Per Bothner  (bothner@kalessin.cygnus.com)
+
+       * typeck.c (get_member_function_from_ptrfunc):  Do The Right
+       Thing (I hope) if we're using thunks.
+
+Wed May  4 13:52:38 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (specialization): aggr template_type_name ';'.
+       (named_class_head_sans_basetype): Use it.
+       (explicit_instantiation): Ditto.
+       (tmpl.2): Revert.
+
+       * cvt.c (build_type_conversion_1): Use convert_for_initialization,
+       rather than convert, to do conversions after the UDC.
+
+       * cp-tree.h (SHARED_MEMBER_P): This member is shared between all
+       instances of the class.
+
+       * search.c (lookup_field): If the entity found by two routes is the
+       same, it's not ambiguous.
+
+Wed May  4 12:10:00 1994  Per Bothner  (bothner@kalessin.cygnus.com)
+
+       * decl.c (lookup_name_real):  Check for a NULL TREE_VALUE,
+       to prevent the compiler from crashing ...
+
+Wed May  4 11:19:45 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * call.c (build_method_call): If we don't have an object, check
+       basetype_path to figure out where to look up the function.
+
+       * typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to
+       build_method_call in case exp is NULL_TREE.
+
+Tue May  3 16:02:53 1994  Per Bothner  (bothner@kalessin.cygnus.com)
+
+       Give a vtable entries a unique named type, for the sake of gdb.
+       * class.c (build_vtable_entry):  The addres of a thunk now has
+       type vtable_entry_type, not ptr_type_node.
+       * method.c (make_thunk):  Fix type of THUNK_DECL.
+       * class.c (add_virtual_function, override_one_vtable):  Use
+       vfunc_ptr_type_node, instead of ptr_type_node.
+       * cp-tree.h (vfunc_ptr_type_node):  New macro.
+       * decl.c (init_decl_processing):  Make vtable_entry_type
+       be a unique type of pointer to a unique function type.
+
+Tue May  3 09:20:44 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (do_explicit): Sets doing_explicit to 1.
+       (explicit_instantiation): Use do_explicit rather than TEMPLATE
+       directly, add "do_explicit error" rule.
+       (datadef): Set doing_explicit to 0 after an explicit instantiation.
+       (tmpl.2): Don't instantiate if we see a ';' unless we're doing an
+       explicit instantiation.
+       (named_class_head_sans_basetype): Remove aggr template_type_name
+       ';' again.
+
+Mon May  2 23:17:21 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * search.c (lookup_nested_tag): Lose.
+
+       * decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs.
+       (lookup_name_nonclass): Lose.
+
+       * decl.c (poplevel_class): Add force parameter.
+       (lookup_name_real): Fix handling of explicit scoping which specifies
+       a class currently being defined.  Add 'nonclass' argument.
+       (lookup_name, lookup_name_nonclass): Shells for lookup_name_real.
+
+       * class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here.
+       (popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being
+       called from finish_struct.
+
+Mon May  2 19:06:21 1994  Per Bothner  (bothner@kalessin.cygnus.com)
+
+       * decl.c (init_decl_processing), cp-tree.h:  Removed memptr_type.
+       (It seeems redundant, given build_ptrmemfunc_type.)
+       * typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof,
+       build_classof):  Use vtable_entry_type instead of memptr_type.
+       * method.c (emit_thunk):  Call poplevel with functionbody==0
+       to prevent DECL_INITIAL being set to a BLOCK.
+
+Mon May  2 15:02:11 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * parse.y (named_class_head_sans_basetype): Add "aggr
+       template_type_name ';'" rule for forward declaration of
+       specializations.
+
+Mon May  2 15:02:11 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * class.c (instantiate_type): Deal with pmf's.
 
        * Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since
        stamp-objlist does.
+
        * Makefile.in (../cc1plus): Depend on OBJDEPS.
        (OBJDEPS): Dependency version of OBJS.
 
+Mon May  2 12:51:31 1994  Kung Hsu  (kung@mexican.cygnus.com)
+
+       * search.c (dfs_debug_mark): unmark TYPE_DECL_SUPPRESS_DEBUG, not
+       DECL_IGNORED_P.
+
+Fri Apr 29 12:29:56 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * class.c (finish_struct): Clear out memory of local tags.  And
+       typedefs.
+
+       * decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified
+       type.
+       * search.c (get_matching_virtual): Be more helpful in error message.
+
+       * *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED).
+
+       * lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work.
+       (default_copy_constructor_body): Ditto.
+
+       * class.c (finish_struct): Don't gratuitously create multiple decls
+       for nested classes.
+
+Thu Apr 28 23:39:38 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       Avoid clobbering the arg types of other functions when reverting
+       static member functions.
+       * decl.c (revert_static_member_fn): Rearrange arguments, don't
+       require values for 'fn' and 'argtypes', add warning to comment
+       above.
+       (decls_match): Rearrange arguments in call to rsmf.
+       (grok_op_properties): Don't pass values for fn and argtypes.
+       * pt.c (instantiate_template): Don't pass values for fn and argtypes.
+
 Thu Apr 28 16:29:11 1994  Doug Evans  (dje@canuck.cygnus.com)
 
        * Make-lang.in (cc1plus): Depend on stamp-objlist.
        * Makefile.in (BC_OBJS): Delete.
-       (OBJS): Cat ../stamp-objlist to get everything, except ../c-common.o.
+       (OBJS): Cat ../stamp-objlist to get language independent files.
+       Include ../c-common.o.
        (../cc1plus): Delete reference to BC_OBJS.
 
+Thu Apr 28 02:12:08 1994  Jason Merrill  (jason@deneb.cygnus.com)
+
+       * search.c (compute_access): No really, deal with static members
+       properly.  Would I lie to you?
+
+       Implement lexical hiding of function declarations.
+       * pt.c (tsubst): Use lookup_name to look for function decls to guide
+       instantiation.
+       * method.c (build_opfncall): Use lookup_name_nonclass to look for
+       non-member functions.
+       * init.c (do_friend): Use lookup_name_nonclass to look for
+       functions.
+       * error.c (ident_fndecl): Use lookup_name to look for functions.
+       * decl2.c (lookup_name_nonclass): New function, skips over
+       CLASS_VALUE.
+       * decl.c (struct binding_level): Lose overloads_shadowed field.
+       (poplevel): Don't deal with overloads_shadowed.
+       (push_overloaded_decl): Do lexical hiding for functions.
+       * class.c (instantiate_type): Don't check non-members if we have
+       members with the same name.
+       * call.c (build_method_call): Use lookup_name_nonclass instead of
+       IDENTIFIER_GLOBAL_VALUE to check for non-member functions.
+       (build_overload_call_real): Ditto.
+
+       * decl.c (duplicate_decls): Check for ambiguous overloads here.
+       (push_overloaded_decl): Instead of here.
+       
+       * decl.c (pushdecl): Back out Chip's last change.
+
+       * decl.c (grok_op_properties): operators cannot be static members.
+
+       * cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0
+       (SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0
+       * lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED.
+
+       * method.c (do_inline_function_hair): Don't put friends of local
+       classes into global scope, either.
+
+       * typeck2.c (build_functional_cast): Don't look for a function call
+       interpretation.
+
 Thu Apr 28 15:19:46 1994  Mike Stump  (mrs@cygnus.com)
 
        * cp-tree.h: disable use of backend EH.
@@ -170,6 +363,17 @@ Sun Apr 24 16:52:51 1994  Doug Evans  (dje@canuck.cygnus.com)
        (*.o): Use complete pathname to headers in parent dir.
        (doc, info, dvi): Delete.
 
+Sun Apr 24 16:52:51 1994  Doug Evans  (dje@canuck.cygnus.com)
+
+       * Make-lang.in (c++.install-common): Check for g++-cross.
+       * Makefile.in: Remove Cygnus cruft.
+       (config.status): Delete.
+       (RTL_H): Define.
+       (TREE_H): Use complete pathname, some native makes have minimal
+       VPATH support.
+       (*.o): Use complete pathname to headers in parent dir.
+       (doc, info, dvi): Delete.
+
 Sun Apr 24 00:47:49 1994  Jason Merrill  (jason@deneb.cygnus.com)
 
        * decl.c (pushdecl): Avoid redundant warning on redeclaring function
@@ -290,6 +494,11 @@ Fri Apr 22 03:27:26 1994  Doug Evans  (dje@cygnus.com)
        * Language directory reorganization.
        See parent makefile.
 
+Fri Apr 22 03:27:26 1994  Doug Evans  (dje@cygnus.com)
+
+       * Language directory reorganization.
+       See parent makefile.
+
 Thu Apr 21 18:27:57 1994  Per Bothner  (bothner@kalessin.cygnus.com)
 
        * cp-tree.h (THUNK_DELTA):  It is normally negative, so
index 62ca226904e939a60f3f68e91b01ba8115cf52c9..bc3b7314b911d8335abf43a37cd5185fb2988eb2 100644 (file)
@@ -2859,6 +2859,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
       if (basetype != NULL_TREE)
        ;
       /* call to a constructor... */
+      else if (basetype_path)
+       basetype = BINFO_TYPE (basetype_path);
       else if (IDENTIFIER_HAS_TYPE_VALUE (name))
        {
          basetype = IDENTIFIER_TYPE_VALUE (name);
@@ -3429,7 +3431,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
        }
       if (pass == 0)
        {
-         tree igv = IDENTIFIER_GLOBAL_VALUE (name);
+         tree igv = lookup_name_nonclass (name);
 
          /* No exact match could be found.  Now try to find match
             using default conversions.  */
@@ -3516,7 +3518,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
          goto found_and_maybe_warn;
        }
 
-      if ((flags & ~LOOKUP_GLOBAL) & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY))
+      if (flags & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY))
        {
          if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN))
              == LOOKUP_SPECULATIVELY)
@@ -3925,23 +3927,25 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
 
   if (! flag_ansi_overloading)
     {
+      tree fn;
+
       /* This is a speed improvement that ends up not working properly in
         the situation of fns with and without default parameters.  I turned
         this off in the new method so it'll go through the argument matching
         code to properly diagnose a match/failure. (bpk)  */
       overload_name = build_decl_overload (fnname, parmtypes, 0);
+      fn = lookup_name_nonclass (overload_name);
 
       /* Now check to see whether or not we can win.
         Note that if we are called from `build_method_call',
         then we cannot have a mis-match, because we would have
         already found such a winning case.  */
 
-      if (IDENTIFIER_GLOBAL_VALUE (overload_name))
-       if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST)
-         return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms);
+      if (fn && TREE_CODE (fn) == FUNCTION_DECL)
+       return build_function_call (DECL_MAIN_VARIANT (fn), parms);
     }
 
-  functions = IDENTIFIER_GLOBAL_VALUE (fnname);
+  functions = lookup_name_nonclass (fnname);
 
   if (functions == NULL_TREE)
     {
index 0807ce7cab85bd3b2752f604e412e7cc58584f0e..fe169ad3e37c42b7ead0dda277862d7080057995 100644 (file)
@@ -361,7 +361,7 @@ build_vtable_entry (delta, pfn)
       extern tree make_thunk ();
       if (idelta)
        {
-         pfn = build1 (ADDR_EXPR, ptr_type_node,
+         pfn = build1 (ADDR_EXPR, vtable_entry_type,
                        make_thunk (pfn, idelta));
          TREE_READONLY (pfn) = 1;
          TREE_CONSTANT (pfn) = 1;
@@ -782,7 +782,7 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
 {
   /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely
      convert to void *.  Make such a conversion here.  */
-  tree vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl);
+  tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
   TREE_CONSTANT (vfn) = 1;
 
 #ifndef DUMB_USER
@@ -2389,7 +2389,7 @@ override_one_vtable (binfo, old, t)
            if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
              CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
 
-           vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl);
+           vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
            TREE_CONSTANT (vfn) = 1;
            
            /* We can use integer_zero_node, as we will will core dump
@@ -2668,7 +2668,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
     }
 
   if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
-      && current_lang_name == lang_name_cplusplus && ! IS_SIGNATURE (t))
+      && ! IS_SIGNATURE (t))
     {
       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
       CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only;
@@ -3653,7 +3653,14 @@ finish_struct (t, list_of_fieldlists, warn_anon)
       last_x = tree_last (TYPE_FIELDS (t));
       while (x)
        {
+#if 0 /* What's wrong with using the decl the type already has? */
          tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
+         DECL_CONTEXT (tag) = t;
+#else
+         tree tag = TYPE_NAME (TREE_VALUE (x));
+#endif
+         DECL_CLASS_CONTEXT (tag) = t;
+
 #ifdef DWARF_DEBUGGING_INFO
          if (write_symbols == DWARF_DEBUG)
            {
@@ -3662,8 +3669,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
              DECL_IGNORED_P (tag) = 1;
            }
 #endif /* DWARF_DEBUGGING_INFO */
-         DECL_CONTEXT (tag) = t;
-         DECL_CLASS_CONTEXT (tag) = t;
+
+         TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
          x = TREE_CHAIN (x);
          last_x = chainon (last_x, tag);
        }
@@ -3691,16 +3698,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
   else if (TYPE_NEEDS_CONSTRUCTING (t))
     build_class_init_list (t);
 
-  if (current_lang_name == lang_name_cplusplus)
-    {
-      if (! CLASSTYPE_DECLARED_EXCEPTION (t)
-         && ! IS_SIGNATURE (t))
-       embrace_waiting_friends (t);
+  if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t))
+    embrace_waiting_friends (t);
 
-      /* Write out inline function definitions.  */
-      do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
-      CLASSTYPE_INLINE_FRIENDS (t) = 0;
-    }
+  /* Write out inline function definitions.  */
+  do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
+  CLASSTYPE_INLINE_FRIENDS (t) = 0;
 
   if (CLASSTYPE_VSIZE (t) != 0)
     {
@@ -4097,9 +4100,9 @@ pushclass (type, modify)
 }
  
 /* Get out of the current class scope. If we were in a class scope
-   previously, that is the one popped to.  The flag MODIFY tells
-   whether the current scope declarations needs to be modified
-   as a result of popping to the previous scope.  */
+   previously, that is the one popped to.  The flag MODIFY tells whether
+   the current scope declarations needs to be modified as a result of
+   popping to the previous scope.  0 is used for class definitions.  */
 void
 popclass (modify)
      int modify;
@@ -4116,7 +4119,7 @@ popclass (modify)
       /* This code can be seen as a cache miss.  When we've cached a
         class' scope's bindings and we can't use them, we need to reset
         them.  This is it!  */
-      for (t = previous_class_values; t; t = TREE_CHAIN(t))
+      for (t = previous_class_values; t; t = TREE_CHAIN (t))
        IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
       while (tags)
        {
@@ -4141,7 +4144,9 @@ popclass (modify)
        undo_template_name_overload (current_class_name, 0);
     }
 
-  poplevel_class ();
+  /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
+     since not all class decls make it there currently.  */
+  poplevel_class (! modify);
 
   /* Since poplevel_class does the popping of class decls nowadays,
      this really only frees the obstack used for these decls.
@@ -4540,10 +4545,11 @@ instantiate_type (lhstype, rhs, complain)
                return save_elem;
              }
            name = DECL_NAME (TREE_VALUE (rhs));
+#if 0
            if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
              {
                /* Try to instantiate from non-member functions.  */
-               rhs = IDENTIFIER_GLOBAL_VALUE (name);
+               rhs = lookup_name_nonclass (name);
                if (rhs && TREE_CODE (rhs) == TREE_LIST)
                  {
                    /* This code seems to be missing a `return'.  */
@@ -4551,6 +4557,7 @@ instantiate_type (lhstype, rhs, complain)
                    instantiate_type (lhstype, rhs, complain);
                  }
              }
+#endif
          }
        if (complain)
          error ("no static member functions named `%s'",
@@ -4655,7 +4662,9 @@ instantiate_type (lhstype, rhs, complain)
       return rhs;
       
     case ADDR_EXPR:
-      if (TREE_CODE (lhstype) != POINTER_TYPE)
+      if (TYPE_PTRMEMFUNC_P (lhstype))
+       lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
+      else if (TREE_CODE (lhstype) != POINTER_TYPE)
        {
          if (complain)
            error ("type for resolving address of overloaded function must be pointer type");
@@ -4663,7 +4672,8 @@ instantiate_type (lhstype, rhs, complain)
        }
       TREE_TYPE (rhs) = lhstype;
       lhstype = TREE_TYPE (lhstype);
-      TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
+      TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0),
+                                               complain);
       if (TREE_OPERAND (rhs, 0) == error_mark_node)
        return error_mark_node;
 
index 078b69e938f04f043e0b280f8ee52364742cb06c..1a82e0bc96dbf656a84a2a4b9ff62cb0b51bc099 100644 (file)
@@ -936,9 +936,8 @@ struct lang_decl_flags
   unsigned constructor_for_vbase_attr : 1;
   unsigned mutable_flag : 1;
   unsigned is_default_implementation : 1;
-  unsigned synthesized : 1;
   unsigned saved_inline : 1;
-  unsigned dummy : 9;
+  unsigned dummy : 10;
 
   tree access;
   tree context;
@@ -1000,6 +999,12 @@ struct lang_decl
    member function.  */
 #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function)
 
+/* Nonzero for a class member means that it is shared between all objects
+   of that class.  */
+#define SHARED_MEMBER_P(NODE) \
+  (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \
+   || TREE_CODE (NODE) == CONST_DECL)
+                               
 /* Nonzero for FUNCTION_DECL means that this decl is a member function
    (static or non-static).  */
 #define DECL_FUNCTION_MEMBER_P(NODE) \
@@ -1106,8 +1111,9 @@ struct lang_decl
 #define DECL_PUBLIC(NODE) (DECL_LANG_FLAG_7 (NODE))
 #endif
 
-/* This method was synthesized by cons_up_default_function.  */
-#define DECL_SYNTHESIZED(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.synthesized)
+/* This _DECL represents a compiler-generated entity.  */
+#define DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) == 0)
+#define SET_DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) = 0)
 
 /* Record whether a typedef for type `int' was actually `signed int'.  */
 #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp))
@@ -1327,7 +1333,6 @@ extern tree void_list_node;
 extern tree void_zero_node;
 extern tree default_function_type;
 extern tree vtable_entry_type;
-extern tree memptr_type;
 extern tree sigtable_entry_type;
 extern tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
 extern tree Type_info_type_node;
@@ -1347,6 +1352,11 @@ extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
 extern tree exception_type_node, unknown_type_node;
 extern tree opaque_type_node, signature_type_node;
 
+/* Node for "pointer to (virtual) function".
+   This may be distinct from ptr_type_node so gdb can distinuish them. */
+#define vfunc_ptr_type_node \
+  (flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
+
 /* Array type `(void *)[]' */
 extern tree vtbl_type_node;
 extern tree delta_type_node;
@@ -1812,7 +1822,7 @@ extern void insert_block                  PROTO((tree));
 extern void add_block_current_level            PROTO((tree));
 extern void set_block                          PROTO((tree));
 extern void pushlevel_class                    PROTO((void));
-extern tree poplevel_class                     PROTO((void));
+extern tree poplevel_class                     PROTO((int));
 /* skip print_other_binding_stack and print_binding_level */
 extern void print_binding_stack                        PROTO((void));
 extern void push_to_top_level                  PROTO((void));
@@ -1906,6 +1916,7 @@ extern tree reparse_absdcl_as_expr                PROTO((tree, tree));
 extern tree reparse_absdcl_as_casts            PROTO((tree, tree));
 extern tree reparse_decl_as_expr               PROTO((tree, tree));
 extern tree finish_decl_parsing                        PROTO((tree));
+extern tree lookup_name_nonclass               PROTO((tree));
 
 /* in edsel.c */
 
index bcf21c12f9f682bc4c684d163bd560ff0e5893e9..b1604129ca5b6e39f4477c0c593f569eeeddfa3f 100644 (file)
@@ -1539,7 +1539,11 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
       && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
          > TREE_READONLY (TREE_TYPE (xtype))))
     warning ("user-defined conversion casting away `const'");
-  return convert (xtype, rval);
+  rval = convert_for_initialization (NULL_TREE, xtype, rval, flags,
+                                    "conversion", NULL_TREE, 0);
+  if (rval == error_mark_node)
+    return NULL_TREE;
+  return rval;
 }
 
 /* Convert an aggregate EXPR to type XTYPE.  If a conversion
index 5af301bc68de3d83e3c59e7c2132869dbce46b1b..1533f95620c0d3c685a2e3f3e6d7400b7e0b46d4 100644 (file)
@@ -224,7 +224,7 @@ tree sizet_ftype_string;
 tree int_ftype_cptr_cptr_sizet;
 
 /* C++ extensions */
-tree memptr_type, vtable_entry_type;
+tree vtable_entry_type;
 tree delta_type_node;
 tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
 tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
@@ -531,9 +531,6 @@ struct binding_level
     /* Same, for IDENTIFIER_TYPE_VALUE.  */
     tree type_shadowed;
 
-    /* Same, for IDENTIFIER_GLOBAL_VALUE for overloaded functions.  */
-    tree overloads_shadowed;
-
     /* For each level (except not the global one),
        a chain of BLOCK nodes for all the levels
        that were entered and exited one level down.  */
@@ -1025,9 +1022,6 @@ poplevel (keep, reverse, functionbody)
   for (link = current_binding_level->type_shadowed;
        link; link = TREE_CHAIN (link))
     IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-  for (link = current_binding_level->overloads_shadowed;
-       link; link = TREE_CHAIN (link))
-    IDENTIFIER_GLOBAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
 
   /* If the level being exited is the top level of a function,
      check over all the labels.  */
@@ -1232,9 +1226,11 @@ pushlevel_class ()
   while (current_binding_level->parm_flag == 2);
 }
 
-/* ...and a poplevel for class declarations.  */
+/* ...and a poplevel for class declarations.  FORCE is used to force
+   clearing out of CLASS_VALUEs after a class definition.  */
 tree
-poplevel_class ()
+poplevel_class (force)
+     int force;
 {
   register struct binding_level *level = class_binding_level;
   tree block = NULL_TREE;
@@ -1250,7 +1246,7 @@ poplevel_class ()
      shouldn't even be used when current_class_type isn't set, and second,
      if we don't touch it here, we're able to use the caching effect if the
      next time we're entering a class scope, it is the same class.  */
-  if (current_class_depth != 1)
+  if (current_class_depth != 1 || force)
     for (shadowed = level->class_shadowed;
         shadowed;
         shadowed = TREE_CHAIN (shadowed))
@@ -1779,10 +1775,7 @@ pushtag (name, type, globalize)
          if (b->parm_flag != 2
              || TYPE_SIZE (current_class_type) != NULL_TREE)
            {
-             if (current_lang_name == lang_name_cplusplus)
-               d = lookup_nested_type (type, cdecl);
-             else
-               d = NULL_TREE;
+             d = lookup_nested_type (type, cdecl);
 
              if (d == NULL_TREE)
                {
@@ -1854,7 +1847,7 @@ pushtag (name, type, globalize)
            }
          TYPE_NAME (type) = d;
 
-         if (context == NULL_TREE || current_lang_name != lang_name_cplusplus)
+         if (context == NULL_TREE)
            /* Non-nested class.  */
            DECL_NESTED_TYPENAME (d) = name;
          else if (context && TREE_CODE (context) == FUNCTION_DECL)
@@ -1980,10 +1973,10 @@ decls_match (newdecl, olddecl)
         is METHOD_TYPE.  Change that to FUNCTION_TYPE, and
         proceed.  */
       if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))
-       revert_static_member_fn (&f1, &newdecl, &p1);
+       revert_static_member_fn (&newdecl, &f1, &p1);
       else if (TREE_CODE (f2) == METHOD_TYPE
               && DECL_STATIC_FUNCTION_P (newdecl))
-       revert_static_member_fn (&f2, &olddecl, &p2);
+       revert_static_member_fn (&olddecl, &f2, &p2);
 
       /* Here we must take care of the case where new default
         parameters are specified.  Also, warn if an old
@@ -2154,29 +2147,29 @@ duplicate_decls (newdecl, olddecl)
   else if (TREE_CODE (olddecl) == FUNCTION_DECL
           && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))
           && DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl))
+    /* Redeclaring a builtin as another function is handled in
+       push_overloaded_decl.  */
     {
       /* If you declare a built-in or predefined function name as static,
         the old definition is overridden,
         but optionally warn this was a bad choice of name.  */
       if (! TREE_PUBLIC (newdecl))
-       {
-         if (warn_shadow)
-           cp_warning ("shadowing %s function `%#D'",
-                       DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                       newdecl);
-         /* Discard the old built-in function.  */
-       }
-      else if (! types_match)
+       if (warn_shadow)
+         cp_warning ("shadowing %s function `%#D'",
+                     DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+                     newdecl);
+      /* Likewise, if the built-in is not ansi, then programs can override
+         it even globally without an error.  */
+      else if (! DECL_BUILT_IN (olddecl))
+       cp_warning ("library function `%#D' redeclared as non-function `%#D'",
+                   olddecl, newdecl);
+      else
        {
          cp_warning ("declaration of `%#D'", newdecl);
          cp_warning ("conflicts with built-in declaration `%#D'",
                      olddecl);
        }
-      if (TREE_CODE (newdecl) != FUNCTION_DECL)
-       return 0;
-
-      if (! types_match)
-       TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+      return 0;
     }
   else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
     {
@@ -2211,8 +2204,15 @@ duplicate_decls (newdecl, olddecl)
                        newdecl);
              cp_error_at ("previous declaration `%#D' here", olddecl);
            }
-         
-         return 0;
+
+         if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+                        TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2))
+           {
+             cp_error ("new declaration `%#D'", newdecl);
+             cp_error_at ("ambiguates old declaration `%#D'", olddecl);
+           }
+         else
+           return 0;
        }
 
       /* Already complained about this, so don't do so again.  */
@@ -2333,7 +2333,7 @@ duplicate_decls (newdecl, olddecl)
   /* Optionally warn about more than one declaration for the same name,
      but don't warn about a function declaration followed by a definition.  */
   if (warn_redundant_decls
-      && DECL_SOURCE_LINE (olddecl) != 0
+      && ! DECL_ARTIFICIAL (olddecl)
       && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
       /* Don't warn about extern decl followed by (tentative) definition.  */
       && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
@@ -2490,6 +2490,14 @@ duplicate_decls (newdecl, olddecl)
 
   if (TREE_CODE (newdecl) == FUNCTION_DECL)
     {
+      if (! types_match)
+       {
+         DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
+         DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl);
+         DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
+         DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
+         DECL_RTL (olddecl) = DECL_RTL (newdecl);
+       }
       if (new_defines_function)
        /* If defining a function declared with other language
           linkage, use the previously declared language linkage.  */
@@ -2630,10 +2638,9 @@ pushdecl (x)
     nglobals = len;
 #endif
 
-  /* Don't change DECL_CONTEXT of virtual methods.  */
   if (x != current_function_decl
-      && (TREE_CODE (x) != FUNCTION_DECL
-         || !DECL_VIRTUAL_P (x))
+      /* Don't change DECL_CONTEXT of virtual methods.  */
+      && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
       && ! DECL_CONTEXT (x))
     DECL_CONTEXT (x) = current_function_decl;
   /* A local declaration for a function doesn't constitute nesting.  */
@@ -2660,10 +2667,7 @@ pushdecl (x)
       char *file;
       int line;
 
-      if (DECL_EXTERNAL (x))
-       t = lookup_name (name, 0);
-      else
-       t = lookup_name_current_level (name);
+      t = lookup_name_current_level (name);
       if (t == error_mark_node)
        {
          /* error_mark_node is 0 for a while during initialization!  */
@@ -2956,7 +2960,7 @@ pushdecl (x)
          /* Maybe warn if shadowing something else.  */
          else if (warn_shadow && !DECL_EXTERNAL (x)
                   /* No shadow warnings for internally generated vars.  */
-                  && DECL_SOURCE_LINE (x) != 0
+                  && ! DECL_ARTIFICIAL (x)
                   /* No shadow warnings for vars made for inlining.  */
                   && ! DECL_FROM_INLINE (x))
            {
@@ -2997,7 +3001,7 @@ pushdecl (x)
     {
       if (current_class_name)
        {
-         if (!DECL_NESTED_TYPENAME (x))
+         if (!DECL_NESTED_TYPENAME (TYPE_NAME (TREE_TYPE (x))))
            set_nested_typename (x, current_class_name, DECL_NAME (x),
                                 TREE_TYPE (x));
        }
@@ -3173,10 +3177,10 @@ overloaded_globals_p (list)
   return 0;
 }
 
-/* DECL is a FUNCTION_DECL which may have other definitions already in place.
-   We get around this by making IDENTIFIER_GLOBAL_VALUE (DECL_NAME (DECL))
-   point to a list of all the things that want to be referenced by that name.
-   It is then up to the users of that name to decide what to do with that
+/* DECL is a FUNCTION_DECL which may have other definitions already in
+   place.  We get around this by making the value of the identifier point
+   to a list of all the things that want to be referenced by that name.  It
+   is then up to the users of that name to decide what to do with that
    list.
 
    DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT
@@ -3191,80 +3195,89 @@ push_overloaded_decl (decl, forgettable)
      int forgettable;
 {
   tree orig_name = DECL_NAME (decl);
-  tree glob = IDENTIFIER_GLOBAL_VALUE (orig_name);
+  tree old;
+  int doing_global = (global_bindings_p () || ! forgettable
+                     || flag_traditional || pseudo_global_level_p ());
+
+  if (doing_global)
+    {
+      old = IDENTIFIER_GLOBAL_VALUE (orig_name);
+      if (old && TREE_CODE (old) == FUNCTION_DECL
+         && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
+       {
+         if (! decls_match (decl, old)
+             && (DECL_LANGUAGE (decl) == lang_c
+                 || compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
+                               TYPE_ARG_TYPES (TREE_TYPE (old)), 2)))
+           {
+             cp_warning ("declaration of `%#D'", decl);
+             cp_warning ("conflicts with built-in declaration `%#D'", old);
+           }
+         old = NULL_TREE;
+       }
+    }
+  else
+    {
+      old = IDENTIFIER_LOCAL_VALUE (orig_name);
+      
+      if (! purpose_member (orig_name, current_binding_level->shadowed))
+       {
+         current_binding_level->shadowed
+           = tree_cons (orig_name, old, current_binding_level->shadowed);
+         old = NULL_TREE;
+       }
+    }
 
-  if (glob)
+  if (old)
     {
+#if 0
       /* We cache the value of builtin functions as ADDR_EXPRs
         in the name space.  Convert it to some kind of _DECL after
         remembering what to forget.  */
-      if (TREE_CODE (glob) == ADDR_EXPR)
-       glob = TREE_OPERAND (glob, 0);
-
-      else if (TREE_CODE (decl) == TEMPLATE_DECL)
-       {
-         tree tmp;
-
-         for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp))
-           if (decl == tmp || duplicate_decls (decl, tmp))
-             return decl;
-       }
-      else if (TREE_CODE (glob) == VAR_DECL)
+      if (TREE_CODE (old) == ADDR_EXPR)
+       old = TREE_OPERAND (old, 0);
+      else
+#endif
+      if (TREE_CODE (old) == VAR_DECL)
        {
-         cp_error_at ("previous non-function declaration `%#D'", glob);
+         cp_error_at ("previous non-function declaration `%#D'", old);
          cp_error ("conflicts with function declaration `%#D'", decl);
          return error_mark_node;
        }
-      else if (TREE_CODE (glob) == TYPE_DECL)
+      else if (TREE_CODE (old) == TYPE_DECL)
        {
-         tree t = TREE_TYPE (glob);
+         tree t = TREE_TYPE (old);
          if (IS_AGGR_TYPE (t) && warn_shadow)
            cp_warning ("`%#D' hides constructor for `%#T'", decl, t);
        }
-      else if (is_overloaded_fn (glob))
+      else if (is_overloaded_fn (old))
         {
           tree tmp;
          
-         for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp))
-           {
-             if (decl == tmp || duplicate_decls (decl, tmp))
-               return tmp;
-             /* Avoid doing things about built-ins, since duplicate_decls
-                will have given warnings/errors for them.  */
-             if (!DECL_BUILT_IN (tmp) && !DECL_BUILT_IN_NONANSI (tmp)
-                 && compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
-                               TYPE_ARG_TYPES (TREE_TYPE (tmp)), 2))
-               {
-                 cp_error ("new declaration `%#D'", decl);
-                 cp_error_at ("ambiguates old declaration `%#D'", tmp);
-               }
-           }
+         for (tmp = get_first_fn (old); tmp; tmp = DECL_CHAIN (tmp))
+           if (decl == tmp || duplicate_decls (decl, tmp))
+             return tmp;
        }
     }
 
-  if (forgettable
-      && ! flag_traditional
-      && (glob == NULL_TREE || TREE_PERMANENT (glob) == 1)
-      && !global_bindings_p ()
-      && !pseudo_global_level_p ())
-    current_binding_level->overloads_shadowed
-      = tree_cons (orig_name, glob,
-                  current_binding_level->overloads_shadowed);
-
-  if (glob || TREE_CODE (decl) == TEMPLATE_DECL)
+  if (old || TREE_CODE (decl) == TEMPLATE_DECL)
     {
-      if (glob && is_overloaded_fn (glob))
-       DECL_CHAIN (decl) = get_first_fn (glob);
+      if (old && is_overloaded_fn (old))
+       DECL_CHAIN (decl) = get_first_fn (old);
       else
        DECL_CHAIN (decl) = NULL_TREE;
-      glob = tree_cons (orig_name, decl, NULL_TREE);
-      TREE_TYPE (glob) = unknown_type_node;
+      old = tree_cons (orig_name, decl, NULL_TREE);
+      TREE_TYPE (old) = unknown_type_node;
     }
   else
     /* orig_name is not ambiguous.  */
-    glob = decl;
-  
-  IDENTIFIER_GLOBAL_VALUE (orig_name) = glob;
+    old = decl;
+
+  if (doing_global)
+    IDENTIFIER_GLOBAL_VALUE (orig_name) = old;
+  else
+    IDENTIFIER_LOCAL_VALUE (orig_name) = old;
+
   return decl;
 }
 \f
@@ -3530,7 +3543,7 @@ define_label (filename, line, name)
                           of internal entities.  They can't be accessed,
                           and they should be cleaned up
                           by the time we get to the label.  */
-                       && DECL_SOURCE_LINE (new_decls) != 0
+                       && ! DECL_ARTIFICIAL (new_decls)
                        && ((DECL_INITIAL (new_decls) != NULL_TREE
                             && DECL_INITIAL (new_decls) != error_mark_node)
                            || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
@@ -3849,9 +3862,9 @@ lookup_nested_type (type, context)
    Otherwise we prefer non-TYPE_DECLs.  */
 
 tree
-lookup_name (name, prefer_type)
+lookup_name_real (name, prefer_type, nonclass)
      tree name;
-     int prefer_type;
+     int prefer_type, nonclass;
 {
   register tree val;
   int yylex = 0;
@@ -3879,10 +3892,29 @@ lookup_name (name, prefer_type)
          else if (! IS_AGGR_TYPE (got_scope))
            /* Someone else will give an error about this if needed. */
            val = NULL_TREE;
+         else if (TYPE_BEING_DEFINED (got_scope))
+           {
+             val = IDENTIFIER_CLASS_VALUE (name);
+             if (val && DECL_CONTEXT (val) != got_scope)
+               {
+                 struct binding_level *b = class_binding_level;
+                 for (val = NULL_TREE; b; b = b->level_chain)
+                   {
+                     tree t = purpose_member (name, b->class_shadowed);
+                     if (t && TREE_VALUE (t)
+                         && DECL_CONTEXT (TREE_VALUE (t)) == got_scope)
+                       {
+                         val = TREE_VALUE (t);
+                         break;
+                       }
+                   }
+               }
+             if (val == NULL_TREE
+                 && CLASSTYPE_LOCAL_TYPEDECLS (got_scope))
+               val = lookup_field (got_scope, name, 0, 1);
+           }
          else if (got_scope == current_class_type)
            val = IDENTIFIER_CLASS_VALUE (name);
-         else if (TYPE_BEING_DEFINED (got_scope))
-           val = lookup_nested_tag (got_scope, name);
          else
            val = lookup_field (got_scope, name, 0, 0);
 
@@ -3895,21 +3927,19 @@ lookup_name (name, prefer_type)
     val = IDENTIFIER_LOCAL_VALUE (name);
   /* In C++ class fields are between local and global scope,
      just before the global scope.  */
-  else if (current_class_type)
+  else if (current_class_type && ! nonclass)
     {
       val = IDENTIFIER_CLASS_VALUE (name);
       if (val == NULL_TREE
-         && TYPE_SIZE (current_class_type) == NULL_TREE
+         && TYPE_BEING_DEFINED (current_class_type)
          && CLASSTYPE_LOCAL_TYPEDECLS (current_class_type))
+       /* Try to find values from base classes if we are presently
+          defining a type.  We are presently only interested in
+          TYPE_DECLs.  */
        {
-         /* Try to find values from base classes
-            if we are presently defining a type.
-            We are presently only interested in TYPE_DECLs.  */
          val = lookup_field (current_class_type, name, 0, 1);
-         if (val == error_mark_node)
-           return val;
-         if (val && TREE_CODE (val) != TYPE_DECL)
-           val = NULL_TREE;
+         if (val)
+           pushdecl_class_level (val);
        }
 
       /* yylex() calls this with -2, since we should never start digging for
@@ -3948,6 +3978,21 @@ lookup_name (name, prefer_type)
   return val;
 }
 
+tree
+lookup_name_nonclass (name)
+     tree name;
+{
+  return lookup_name_real (name, 0, 1);
+}
+
+tree
+lookup_name (name, prefer_type)
+     tree name;
+     int prefer_type;
+{
+  return lookup_name_real (name, prefer_type, 0);
+}
+
 /* Similar to `lookup_name' but look only at current binding level.  */
 
 tree
@@ -4654,34 +4699,40 @@ init_decl_processing ()
       pushdecl (lookup_name (get_identifier ("__gc_main"), 0));
     }
 
-  /* Simplify life by making a "memptr_type".  Give its
-     fields names so that the debugger can use them.  */
-
-  memptr_type = make_lang_type (RECORD_TYPE);
-  fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
-                                    delta_type_node);
-  fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
-                                    delta_type_node);
-  fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
-                                    ptr_type_node);
-  finish_builtin_type (memptr_type, VTBL_PTR_TYPE, fields, 2,
-                      double_type_node);
-
-  /* Make this part of an invisible union.  */
-  fields[3] = copy_node (fields[2]);
-  TREE_TYPE (fields[3]) = delta_type_node;
-  DECL_NAME (fields[3]) = delta2_identifier;
-  DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
-  DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
-  TREE_UNSIGNED (fields[3]) = 0;
-  TREE_CHAIN (fields[2]) = fields[3];
-  memptr_type = build_type_variant (memptr_type, 1, 0);
-  record_builtin_type (RID_MAX, VTBL_PTR_TYPE, memptr_type);
-
   if (flag_vtable_thunks)
-    vtable_entry_type = ptr_type_node;
+    {
+      /* Make sure we get a unique function type, so we can give
+        its pointer type a name.  (This wins for gdb.) */
+      tree vfunc_type = make_node (FUNCTION_TYPE);
+      TREE_TYPE (vfunc_type) = integer_type_node;
+      TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
+      layout_type (vfunc_type);
+
+      vtable_entry_type = build_pointer_type (vfunc_type);
+    }
   else
-    vtable_entry_type = memptr_type;
+    {
+      vtable_entry_type = make_lang_type (RECORD_TYPE);
+      fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
+                                        delta_type_node);
+      fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
+                                        delta_type_node);
+      fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
+                                        ptr_type_node);
+      finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2,
+                          double_type_node);
+
+      /* Make this part of an invisible union.  */
+      fields[3] = copy_node (fields[2]);
+      TREE_TYPE (fields[3]) = delta_type_node;
+      DECL_NAME (fields[3]) = delta2_identifier;
+      DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
+      DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
+      TREE_UNSIGNED (fields[3]) = 0;
+      TREE_CHAIN (fields[2]) = fields[3];
+      vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0);
+    }
+  record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
 
   vtbl_type_node
     = build_array_type (vtable_entry_type, NULL_TREE);
@@ -6625,7 +6676,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
       grok_ctor_properties (ctype, decl);
       if (check == 0 && ! current_function_decl)
        {
-         /* FIXME: this should only need to look at IDENTIFIER_GLOBAL_VALUE.  */
+         /* FIXME: this should only need to look at
+             IDENTIFIER_GLOBAL_VALUE.  */
          tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
          if (tmp == NULL_TREE)
            IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
@@ -9515,8 +9567,7 @@ grok_op_properties (decl, virtualp, friendp)
       /* When the compiler encounters the definition of A::operator new, it
         doesn't look at the class declaration to find out if it's static.  */
       if (methodp)
-       revert_static_member_fn (&TREE_TYPE (decl), &decl,
-                                &TYPE_ARG_TYPES (TREE_TYPE (decl)));
+       revert_static_member_fn (&decl, NULL, NULL);
      
       /* Take care of function decl if we had syntax errors.  */
       if (argtypes == NULL_TREE)
@@ -9531,8 +9582,7 @@ grok_op_properties (decl, virtualp, friendp)
           || name == ansi_opname[(int) VEC_DELETE_EXPR])
     {
       if (methodp)
-       revert_static_member_fn (&TREE_TYPE (decl), &decl,
-                                &TYPE_ARG_TYPES (TREE_TYPE (decl)));
+       revert_static_member_fn (&decl, NULL, NULL);
      
       if (argtypes == NULL_TREE)
        TREE_TYPE (decl) =
@@ -9554,7 +9604,7 @@ grok_op_properties (decl, virtualp, friendp)
       /* An operator function must either be a non-static member function
         or have at least one parameter of a class, a reference to a class,
         an enumeration, or a reference to an enumeration.  13.4.0.6 */
-      if (! methodp)
+      if (! methodp || DECL_STATIC_FUNCTION_P (decl))
        {
          if (OPERATOR_TYPENAME_P (name)
              || name == ansi_opname[(int) CALL_EXPR]
@@ -9566,6 +9616,9 @@ grok_op_properties (decl, virtualp, friendp)
            {
              tree p = argtypes;
 
+             if (DECL_STATIC_FUNCTION_P (decl))
+               cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
+
              if (p)
                for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p))
                  {
@@ -12119,20 +12172,30 @@ deactivate_exception_cleanups ()
 }
 
 /* Change a static member function definition into a FUNCTION_TYPE, instead
-   of the METHOD_TYPE that we create when it's originally parsed.  */
+   of the METHOD_TYPE that we create when it's originally parsed.
+
+   WARNING: DO NOT pass &TREE_TYPE (decl) to FN or &TYPE_ARG_TYPES
+   (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of
+   other decls.  Either pass the addresses of local variables or NULL.  */
+
 void
-revert_static_member_fn (fn, decl, argtypes)
-     tree *fn, *decl, *argtypes;
+revert_static_member_fn (decl, fn, argtypes)
+     tree *decl, *fn, *argtypes;
 {
-  tree tmp, function = *fn;
+  tree tmp;
+  tree function = fn ? *fn : TREE_TYPE (*decl);
+  tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function);
 
-  *argtypes = TREE_CHAIN (*argtypes);
-  tmp = build_function_type (TREE_TYPE (function), *argtypes);
+  args = TREE_CHAIN (args);
+  tmp = build_function_type (TREE_TYPE (function), args);
   tmp = build_type_variant (tmp, TYPE_READONLY (function),
                            TYPE_VOLATILE (function));
   tmp = build_exception_variant (TYPE_METHOD_BASETYPE (function), tmp,
                                 TYPE_RAISES_EXCEPTIONS (function));
   TREE_TYPE (*decl) = tmp;
-  *fn = tmp;
   DECL_STATIC_FUNCTION_P (*decl) = 1;
+  if (fn)
+    *fn = tmp;
+  if (argtypes)
+    *argtypes = args;
 }
index b910b6731ad55e15548d21fa963b61ddd166bffc..34b7499fcecb92c360d2bfb683a2ba1e9bc674db 100644 (file)
@@ -781,6 +781,7 @@ grokclassfn (ctype, cname, function, flags, quals)
   tree fn_name = DECL_NAME (function);
   tree arg_types;
   tree parm;
+  tree qualtype;
 
   if (fn_name == NULL_TREE)
     {
@@ -790,7 +791,9 @@ grokclassfn (ctype, cname, function, flags, quals)
     }
 
   if (quals)
-    ctype = grok_method_quals (ctype, function, quals);
+    qualtype = grok_method_quals (ctype, function, quals);
+  else
+    qualtype = ctype;
 
   arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
   if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
@@ -812,7 +815,7 @@ grokclassfn (ctype, cname, function, flags, quals)
                 of virtual baseclasses or not.  */
              parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);
              /* Mark the artificial `__in_chrg' parameter as "artificial".  */
-             DECL_SOURCE_LINE (parm) = 0;
+             SET_DECL_ARTIFICIAL (parm);
              DECL_ARG_TYPE (parm) = integer_type_node;
              DECL_REGISTER (parm) = 1;
              TREE_CHAIN (parm) = last_function_parms;
@@ -822,7 +825,7 @@ grokclassfn (ctype, cname, function, flags, quals)
 
       parm = build_decl (PARM_DECL, this_identifier, type);
       /* Mark the artificial `this' parameter as "artificial".  */
-      DECL_SOURCE_LINE (parm) = 0;
+      SET_DECL_ARTIFICIAL (parm);
       DECL_ARG_TYPE (parm) = type;
       /* We can make this a register, so long as we don't
         accidentally complain if someone tries to take its address.  */
@@ -865,7 +868,7 @@ grokclassfn (ctype, cname, function, flags, quals)
       DECL_ASSEMBLER_NAME (function) = get_identifier (buf);
       parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type);
       /* Mark the artificial `__in_chrg' parameter as "artificial".  */
-      DECL_SOURCE_LINE (parm) = 0;
+      SET_DECL_ARTIFICIAL (parm);
       TREE_USED (parm) = 1;
 #if 0
       /* We don't need to mark the __in_chrg parameter itself as `const'
@@ -878,7 +881,7 @@ grokclassfn (ctype, cname, function, flags, quals)
       /* This is the same chain as DECL_ARGUMENTS (...).  */
       TREE_CHAIN (last_function_parms) = parm;
 
-      TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node,
+      TREE_TYPE (function) = build_cplus_method_type (qualtype, void_type_node,
                                                      arg_types);
       TYPE_HAS_DESTRUCTOR (ctype) = 1;
     }
@@ -891,7 +894,7 @@ grokclassfn (ctype, cname, function, flags, quals)
          arg_types = hash_tree_chain (integer_type_node,
                                       TREE_CHAIN (arg_types));
          TREE_TYPE (function)
-           = build_cplus_method_type (ctype,
+           = build_cplus_method_type (qualtype,
                                       TREE_TYPE (TREE_TYPE (function)),
                                       arg_types);
          arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
@@ -901,7 +904,8 @@ grokclassfn (ctype, cname, function, flags, quals)
 
       if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
        /* Only true for static member functions.  */
-       these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types);
+       these_arg_types = hash_tree_chain (TYPE_POINTER_TO (qualtype),
+                                          arg_types);
 
       DECL_ASSEMBLER_NAME (function)
        = build_decl_overload (fn_name, these_arg_types,
@@ -1211,6 +1215,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
   if (TREE_CODE (value) == TYPE_DECL)
     {
       DECL_NONLOCAL (value) = 1;
+      DECL_CONTEXT (value) = current_class_type;
+      DECL_CLASS_CONTEXT (value) = current_class_type;
       CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
       pushdecl_class_level (value);
       return value;
@@ -2739,7 +2745,7 @@ finish_file ()
   vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node);
 #endif
   DECL_IGNORED_P (vars) = 1;
-  DECL_SOURCE_LINE (vars) = 0;
+  SET_DECL_ARTIFICIAL (vars);
   pushdecl (vars);
 #endif
 
index 1fbf21aa14e511e8a84e0a69836d527d745fc8db..66f12669b084250b753f5c9718e72ab39756633f 100644 (file)
@@ -500,7 +500,7 @@ tree
 ident_fndecl (t)
      tree t;
 {
-  tree n = IDENTIFIER_GLOBAL_VALUE (t);
+  tree n = lookup_name (t, 0);
 
   if (TREE_CODE (n) == FUNCTION_DECL)
     return n;
index 07de74c3d119f0606990f3e3844930a8047edc9e..8a81db9ef5cf92ebdd057c2578ec0e938488a061 100644 (file)
@@ -2791,7 +2791,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
     {
       /* @@ Should be able to ingest later definitions of this function
         before use.  */
-      tree decl = IDENTIFIER_GLOBAL_VALUE (declarator);
+      tree decl = lookup_name_nonclass (declarator);
       if (decl == NULL_TREE)
        {
          warning ("implicitly declaring `%s' as struct",
@@ -3676,6 +3676,26 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
     {
       tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0));
       tree basetypes = TYPE_BINFO (type);
+      tree passed_auto_delete;
+      tree do_delete = NULL_TREE;
+
+      if (use_global_delete)
+       {
+         tree cond = fold (build (BIT_AND_EXPR, integer_type_node,
+                                  auto_delete, integer_one_node));
+         tree call = build_builtin_call
+           (void_type_node, BID, build_tree_list (NULL_TREE, addr));
+
+         cond = fold (build (COND_EXPR, void_type_node, cond,
+                             call, void_zero_node));
+         if (cond != void_zero_node)
+           do_delete = cond;
+
+         passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node,
+                                           auto_delete, integer_two_node));
+       }
+      else
+       passed_auto_delete = auto_delete;
 
       if (flags & LOOKUP_PROTECT)
        {
@@ -3723,8 +3743,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
          if (function == error_mark_node)
            return error_mark_node;
          TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
-         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete);
+         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
          expr = build_function_call (function, parms);
+         if (do_delete)
+           expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
          if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
            {
              /* Handle the case where a virtual destructor is
@@ -3761,8 +3783,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
             but that's now obsolete.  */
          my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
 
-         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete);
+         TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
          expr = build_function_call (dtor, parms);
+         if (do_delete)
+           expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
 
          if (ifexp != integer_one_node)
            expr = build (COND_EXPR, void_type_node,
index ec26d83ca23444b5c765c655f0b47670d9938bf7..51cb77238e24741ca5f9081ab5cc6062453f4691 100644 (file)
@@ -1836,14 +1836,10 @@ cons_up_default_function (type, name, fields, kind)
   }
 #endif /* DEBUG_DEFAULT_FUNCTIONS */
 
-  DECL_CLASS_CONTEXT (fn) = type;
+  DECL_CLASS_CONTEXT (fn) = TYPE_MAIN_VARIANT (type);
 
   /* Show that this function was generated by the compiler.  */
-#if 0
-  DECL_SOURCE_LINE (fn) = 0;
-#else
-  DECL_SYNTHESIZED (fn) = 1;
-#endif
+  SET_DECL_ARTIFICIAL (fn);
   
   return fn;
 }
@@ -1956,7 +1952,6 @@ default_assign_ref_body (bufp, lenp, type, fields)
 
          btype = BINFO_TYPE (binfo);
          name = TYPE_NESTED_NAME (btype);
-          if (!name) name = DECL_NAME(TYPE_NAME(btype));
          s = IDENTIFIER_POINTER (name);
 
          tneed = (2 * strlen (s)) + 33;
@@ -2122,7 +2117,6 @@ default_copy_constructor_body (bufp, lenp, type, fields)
 
          btype = BINFO_TYPE (binfo);
          name = TYPE_NESTED_NAME (btype);
-         if (!name) name = DECL_NAME(TYPE_NAME(btype));
          s = IDENTIFIER_POINTER (name);
 
          tneed = (2 * strlen (s)) + 30;
index c61bf487deba825c6e6340b4de6c62a0d6fb1aee..d4ce558abb98f66a3713280984201a23a41e38df 100644 (file)
@@ -135,7 +135,8 @@ do_inline_function_hair (type, friend_list)
            }
 
          /* Allow this decl to be seen in global scope */
-         IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
+         if (! current_function_decl)
+           IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
        }
 
       friend_list = TREE_CHAIN (friend_list);
@@ -1242,7 +1243,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
   else
     fnname = ansi_opname[(int) code];
 
-  global_fn = IDENTIFIER_GLOBAL_VALUE (fnname);
+  global_fn = lookup_name_nonclass (fnname);
 
   /* This is the last point where we will accept failure.  This
      may be too eager if we wish an overloaded operator not to match,
@@ -1682,7 +1683,7 @@ make_thunk (function, delta)
   thunk = build_decl (THUNK_DECL, get_identifier (buffer),
                      TREE_TYPE (func_decl));
   DECL_RESULT (thunk)
-    = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+    = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type));
   make_function_rtl (thunk);
   DECL_INITIAL (thunk) = function;
   THUNK_DELTA (thunk) = delta;
@@ -1824,7 +1825,7 @@ emit_thunk (thunk_fndecl)
     emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));
 
   expand_end_bindings (NULL, 1, 0);
-  poplevel (0, 0, 1);
+  poplevel (0, 0, 0);
 
   TREE_ASM_WRITTEN (thunk_fndecl) = 1;
 
index ed57b7f1c92b67c2a18d45d65c5f5125e2ba65e6..32c5e524fd99e1f791219fe05251f2735efd323e 100644 (file)
@@ -80,6 +80,8 @@ void yyerror ();
    error message if the user supplies an empty conditional expression.  */
 static char *cond_stmt_keyword;
 
+static int doing_explicit;
+
 /* Nonzero if we have an `extern "C"' acting as an extern specifier.  */
 int have_extern_spec;
 int used_extern_spec;
@@ -262,7 +264,7 @@ empty_parms ()
 %type <ttype> qualified_type_name complete_type_name notype_identifier
 %type <ttype> complex_type_name nested_name_specifier_1
 %type <itype> nomods_initdecls nomods_initdcl0
-%type <ttype> new_initializer new_placement
+%type <ttype> new_initializer new_placement specialization
 
 /* in order to recognize aggr tags as defining and thus shadowing. */
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
@@ -542,6 +544,7 @@ datadef:
         | declmods ';'
          { pedwarn ("empty declaration"); }
        | explicit_instantiation ';'
+               { doing_explicit = 0; }
        | typed_declspecs ';'
          {
            tree t = $<ttype>$;
@@ -778,11 +781,16 @@ identifier_defn:
        | PTYPENAME_DEFN
        ;
 
+do_explicit: TEMPLATE %prec EMPTY
+       { doing_explicit = 1; }
+       ;
+
 explicit_instantiation:
-         TEMPLATE aggr template_type
-               { do_type_instantiation ($3); }
-       | TEMPLATE typed_declspecs declarator
+         do_explicit specialization template_instantiation
+               { do_type_instantiation ($3 ? $3 : $2); }
+       | do_explicit typed_declspecs declarator
                { do_function_instantiation ($2, $3); }
+       | do_explicit error
        ;
 
 template_type:
@@ -797,8 +805,8 @@ template_type_name:
                { $$ = lookup_template_class ($$, $3, NULL_TREE); }
        ;
 
-tmpl.2: %prec EMPTY
-       /* Always do expansion if it hasn't been done already. */
+tmpl.2: 
+         /* empty */ %prec EMPTY
                { $$ = instantiate_class_template ($<ttype>0, 1); }
        ;
 
@@ -2212,6 +2220,15 @@ aggr:      AGGR
                { error ("no body nor ';' separates two class, struct or union declarations"); }
        ;
 
+specialization:
+         aggr template_type_name ';'
+               { 
+                 yyungetc (';', 1); current_aggr = $$; $$ = $2; 
+                 if (doing_explicit)
+                   instantiate_class_template ($$, 1);
+               }
+       ;
+
 named_class_head_sans_basetype:
          aggr identifier
                { current_aggr = $$; $$ = $2; }
@@ -2227,6 +2244,7 @@ named_class_head_sans_basetype:
                  overload_template_name ($$, 0); }
        | aggr template_type_name ':'
                { yyungetc (':', 1); goto aggr2; }
+       | specialization
        ;
 
 named_class_head_sans_basetype_defn:
@@ -4137,7 +4155,7 @@ operator_name:
                { $$ = ansi_opname[VEC_NEW_EXPR]; }
        | operator DELETE '[' ']'
                { $$ = ansi_opname[VEC_DELETE_EXPR]; }
-       /* Should we be pushing into class scope to parse this?  */
+       /* Names here should be looked up in class scope ALSO.  */
        | operator typed_typespecs conversion_declarator
                { $$ = grokoptypename ($2, $3); }
        | operator error
index 3bea33d118134b396e8c9618afdebea5d4f75833..377d4a7a7e3c705c3639656945d3322452e1268e 100644 (file)
@@ -1314,7 +1314,7 @@ tsubst (t, args, nargs, in_decl)
              tree decls;
              int got_it = 0;
 
-             decls = IDENTIFIER_GLOBAL_VALUE (r);
+             decls = lookup_name (r, 0);
              if (decls == NULL_TREE)
                /* no match */;
              else if (TREE_CODE (decls) == TREE_LIST)
@@ -1624,8 +1624,7 @@ instantiate_template (tmpl, targ_ptr)
       && DECL_STATIC_FUNCTION_P (fndecl))
     {
       tree olddecl = DECL_RESULT (tmpl);
-      revert_static_member_fn (&TREE_TYPE (olddecl), &DECL_RESULT (tmpl),
-                              &TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
+      revert_static_member_fn (&DECL_RESULT (tmpl), NULL, NULL);
       /* Chop off the this pointer that grokclassfn so kindly added
         for us (it didn't know yet if the fn was static or not).  */
       DECL_ARGUMENTS (olddecl) = TREE_CHAIN (DECL_ARGUMENTS (olddecl));
index b601075821c8dafe9a2c8ff431f946f0d36c00c1..946763c4aaa9892e8e795cd97cbab4d712cbb254 100644 (file)
@@ -813,7 +813,7 @@ compute_access (basetype_path, field)
     PUBLIC_RETURN;
 
   /* Member found immediately within object.  */
-  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE || static_mem)
+  if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
     {
       /* Are we (or an enclosing scope) friends with the class that has
          FIELD? */
@@ -847,7 +847,8 @@ compute_access (basetype_path, field)
   types = basetype_path;
   via_protected = 0;
   access = access_default;
-  protected_ok = 0;
+  protected_ok = static_mem && current_class_type
+    && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
 
   while (1)
     {
@@ -1024,7 +1025,6 @@ lookup_field (xbasetype, name, protect, want_type)
      we know that binfo of a virtual base class will always == itself when
      found along any line.  (mrs)  */
 
-  /* Things for memoization.  */
   char *errstr = 0;
 
   /* Set this to nonzero if we don't know how to compute
@@ -1209,7 +1209,11 @@ lookup_field (xbasetype, name, protect, want_type)
 
       if (nval || lookup_fnfields_here (type, name)>=0)
        {
-         if (rval_binfo && hides (rval_binfo_h, binfo_h))
+         if (nval && nval == rval && SHARED_MEMBER_P (nval))
+           {
+             /* This is ok, the member found is the same [class.ambig] */
+           }
+         else if (rval_binfo && hides (rval_binfo_h, binfo_h))
            {
              /* This is ok, the member found is in rval_binfo, not
                 here (binfo). */
@@ -1476,7 +1480,6 @@ lookup_fnfields (basetype_path, name, complain)
   /* For now, don't try this.  */
   int protect = complain;
 
-  /* Things for memoization.  */
   char *errstr = 0;
 
   /* Set this to nonzero if we don't know how to compute
@@ -1578,11 +1581,6 @@ lookup_fnfields (basetype_path, name, complain)
          TREE_TYPE (entry) = NULL_TREE;
        }
 
-      if (errstr && protect)
-       {
-         error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
-         return error_mark_node;
-       }
       return rvals;
     }
   rval = NULL_TREE;
@@ -1697,7 +1695,7 @@ lookup_fnfields (basetype_path, name, complain)
          else
            {
              /* This is ambiguous. */
-             errstr = "request for member `%s' is ambiguous";
+             errstr = "request for method `%D' is ambiguous";
              rvals = error_mark_node;
              break;
            }
@@ -1733,7 +1731,7 @@ lookup_fnfields (basetype_path, name, complain)
 
   if (errstr && protect)
     {
-      error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
+      cp_error (errstr, name);
       rvals = error_mark_node;
     }
 
@@ -1946,7 +1944,8 @@ get_matching_virtual (binfo, fndecl, dtorp)
                  if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
                      && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
                    {
-                     cp_error ("conflicting return type specified for virtual function `%D'", fndecl);
+                     cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
+                     cp_error ("overriding definition as `%#D'", tmp);
                      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
                    }
                  break;
@@ -2368,7 +2367,7 @@ dfs_debug_mark (binfo)
   /* We cannot rely on some alien method to solve our problems,
      so we must write out the debug info ourselves.  */
   if (write_symbols != DWARF_DEBUG)
-    DECL_IGNORED_P (TYPE_NAME (t)) = 0;
+    TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
   if (! TREE_ASM_WRITTEN (TYPE_NAME (t)))
     rest_of_type_compilation (t, global_bindings_p ());
 }
@@ -3175,27 +3174,3 @@ reinit_search_statistics ()
   n_outer_fields_searched = 0;
   n_contexts_saved = 0;
 }
-
-tree
-lookup_nested_tag (type, name)
-     tree type, name;
-{
-  tree tags = CLASSTYPE_TAGS (type);
-
-  for (; tags; tags = TREE_CHAIN (tags))
-    {
-      /* The TREE_PURPOSE of an enum tag (which becomes a member of the
-        enclosing class) is set to the name for the enum type.  So, if
-        name is `bar', and we strike `baz' for `enum bar { baz }', then
-        this test will be true.  */
-      if (TREE_PURPOSE (tags) == name)
-       break;
-    }
-  if (tags)
-    return TYPE_NAME (TREE_VALUE (tags));
-
-  if (TYPE_CONTEXT (type))
-    return lookup_nested_tag (TYPE_CONTEXT (type), name);
-
-  return NULL_TREE;
-}
index 9ea4408e12dae77522f03fa95a8778c89f17e244..55f5f86f3c377139a7f52304bd718c96059036d9 100644 (file)
@@ -2114,28 +2114,35 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
        return instance;
 
       vtbl = convert_pointer_to (ptr_type_node, instance);
-      vtbl = build (PLUS_EXPR,
-                   build_pointer_type (build_pointer_type (memptr_type)),
-                   vtbl, convert (sizetype, delta2));
+      vtbl
+       = build (PLUS_EXPR,
+                build_pointer_type (build_pointer_type (vtable_entry_type)),
+                vtbl, convert (sizetype, delta2));
       vtbl = build_indirect_ref (vtbl, NULL_PTR);
       aref = build_array_ref (vtbl, size_binop (MINUS_EXPR,
                                                index,
                                                integer_one_node));
-      aref = save_expr (aref);
+      if (! flag_vtable_thunks)
+       {
+         aref = save_expr (aref);
 
-      /* Save the intermediate result in a SAVE_EXPR so we don't have to
-        compute each component of the virtual function pointer twice.  */ 
-     if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF)
-       TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
+         /* Save the intermediate result in a SAVE_EXPR so we don't have to
+            compute each component of the virtual function pointer twice.  */ 
+         if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF)
+           TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
       
-      delta = build (PLUS_EXPR, integer_type_node,
-                    build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node),
-                    delta);
+         delta = build (PLUS_EXPR, integer_type_node,
+                        build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node),
+                        delta);
+       }
 
       *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (*instance_ptrptr),
                                *instance_ptrptr,
                                convert (integer_type_node, delta));
-      e2 = build_component_ref (aref, pfn_identifier, 0, 0);
+      if (flag_vtable_thunks)
+       e2 = aref;
+      else
+       e2 = build_component_ref (aref, pfn_identifier, 0, 0);
 
       e3 = PFN_FROM_PTRMEMFUNC (function);
       TREE_TYPE (e2) = TREE_TYPE (e3);
@@ -5502,10 +5509,16 @@ build_modify_expr (lhs, modifycode, rhs)
   /* check to see if there is an assignment to `this' */
   if (lhs == current_class_decl)
     {
-      if (flag_this_is_variable > 0
-         && DECL_NAME (current_function_decl) != NULL_TREE
-         && current_class_name != DECL_NAME (current_function_decl))
-       warning ("assignment to `this' not in constructor or destructor");
+      if (DECL_NAME (current_function_decl) != NULL_TREE)
+       {
+         /* ARM 18.3.3 and draft standard section C.11 say that assigning
+            something to this is an anachronism.  */
+         if (pedantic)
+           warning ("anachronistic assignment to `this' pointer");
+         else if (flag_this_is_variable > 0
+                  && current_class_name != DECL_NAME (current_function_decl))
+           warning ("assignment to `this' not in constructor or destructor");
+       }
       current_function_just_assigned_this = 1;
     }
 
@@ -5670,7 +5683,7 @@ build_modify_expr (lhs, modifycode, rhs)
     {
       /* Allow array assignment in compiler-generated code.  */
       if ((pedantic || flag_ansi)
-         && ! DECL_SYNTHESIZED (current_function_decl))
+         && ! DECL_ARTIFICIAL (current_function_decl))
        pedwarn ("ANSI C++ forbids assignment between arrays");
 
       /* Have to wrap this in RTL_EXPR for two cases:
@@ -6600,7 +6613,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
            {
              tree init = build_method_call (exp, constructor_name_full (type),
                                             build_tree_list (NULL_TREE, rhs),
-                                            NULL_TREE, LOOKUP_NORMAL);
+                                            TYPE_BINFO (type), LOOKUP_NORMAL);
 
              if (init == error_mark_node)
                return error_mark_node;
index fd426a4cd9e39fd5989e4dac702fe3c29253df8b..53106b2e44d8644203b869e950a1c1b089338d5d 100644 (file)
@@ -1362,10 +1362,9 @@ build_m_component_ref (datum, component)
 
 /* Return a tree node for the expression TYPENAME '(' PARMS ')'.
 
-   Because we cannot tell whether this construct is really
-   a function call or a call to a constructor or a request for
-   a type conversion, we try all three, and report any ambiguities
-   we find.  */
+   Because we cannot tell whether this construct is really a call to a
+   constructor or a request for a type conversion, we try both, and
+   report any ambiguities we find.  */
 tree
 build_functional_cast (exp, parms)
      tree exp;
@@ -1375,8 +1374,6 @@ build_functional_cast (exp, parms)
      or a C cast in C++'s `functional' notation.  */
   tree type, name = NULL_TREE;
   tree expr_as_ctor = NULL_TREE;
-  tree expr_as_method = NULL_TREE;
-  tree expr_as_fncall = NULL_TREE;
   tree expr_as_conversion = NULL_TREE;
 
   if (exp == error_mark_node || parms == error_mark_node)
@@ -1423,50 +1420,16 @@ build_functional_cast (exp, parms)
        name = DECL_NAME (name);
     }
 
-  /* Try evaluating as a call to a function.  */
-  if (IDENTIFIER_CLASS_VALUE (name)
-      && (TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == TREE_LIST
-         || TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == FUNCTION_DECL))
-    {
-      expr_as_method = build_method_call (current_class_decl, name, parms,
-                                         NULL_TREE, LOOKUP_SPECULATIVELY);
-      if (expr_as_method == error_mark_node)
-       expr_as_method = NULL_TREE;
-    }
-
-  if (IDENTIFIER_GLOBAL_VALUE (name)
-      && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TREE_LIST
-         || TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL))
-    {
-      expr_as_fncall = build_overload_call (name, parms, 0,
-                                           (struct candidate *)0);
-      if (expr_as_fncall == NULL_TREE)
-       expr_as_fncall = error_mark_node;
-    }
-
   if (! IS_AGGR_TYPE (type))
     {
       /* this must build a C cast */
       if (parms == NULL_TREE)
-       {
-         if (expr_as_method || expr_as_fncall)
-           goto return_function;
-
-         return build1 (NOP_EXPR, type, integer_zero_node);
-       }
-      if (expr_as_method
-         || (expr_as_fncall && expr_as_fncall != error_mark_node))
-       {
-         cp_error ("ambiguity between cast to `%#T' and function call", type);
-         return error_mark_node;
-       }
+       return build1 (NOP_EXPR, type, integer_zero_node);
       return build_c_cast (type, build_compound_expr (parms));
     }
 
   if (TYPE_SIZE (type) == NULL_TREE)
     {
-      if (expr_as_method || expr_as_fncall)
-       goto return_function;
       cp_error ("type `%T' is not yet defined", type);
       return error_mark_node;
     }
@@ -1475,7 +1438,7 @@ build_functional_cast (exp, parms)
     expr_as_conversion
       = build_type_conversion (CONVERT_EXPR, type, TREE_VALUE (parms), 0);
     
-  if (! TYPE_NEEDS_CONSTRUCTING (type) && parms != NULL_TREE)
+  if (! TYPE_HAS_CONSTRUCTOR (type) && parms != NULL_TREE)
     {
       char *msg = 0;
 
@@ -1488,71 +1451,13 @@ build_functional_cast (exp, parms)
        }
       else msg = "type `%T' does not have a constructor";
 
-      if ((expr_as_method || expr_as_fncall) && expr_as_conversion)
-       msg = "ambiguity between conversion to `%T' and function call";
-      else if (expr_as_method || expr_as_fncall)
-       goto return_function;
-      else if (expr_as_conversion)
+      if (expr_as_conversion)
        return expr_as_conversion;
 
       cp_error (msg, type);
       return error_mark_node;
     }
 
-#if 0
-  /* Constructors are not inherited...  --jason */
-  if (! TYPE_HAS_CONSTRUCTOR (type))
-    {
-      if (expr_as_method || expr_as_fncall)
-       goto return_function;
-      if (expr_as_conversion)
-       return expr_as_conversion;
-
-      /* Look through this type until we find the
-        base type which has a constructor.  */
-      do
-       {
-         tree binfos = TYPE_BINFO_BASETYPES (type);
-         int i, index = 0;
-
-         while (binfos && TREE_VEC_LENGTH (binfos) == 1
-                && ! TYPE_HAS_CONSTRUCTOR (type))
-           {
-             type = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
-             binfos = TYPE_BINFO_BASETYPES (type);
-           }
-         if (TYPE_HAS_CONSTRUCTOR (type))
-           break;
-         /* Hack for MI.  */
-         i = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-         if (i == 0) break;        
-         while (--i > 0)
-           {
-             if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (TREE_VEC_ELT (binfos, i))))
-               {
-                 if (index == 0)
-                   index = i;
-                 else
-                   {
-                     error ("multiple base classes with constructor, ambiguous");
-                     type = 0;
-                     break;
-                   }
-               }
-           }
-         if (type == 0)
-           break;
-       } while (! TYPE_HAS_CONSTRUCTOR (type));
-      if (type == 0)
-       return error_mark_node;
-    }
-  name = TYPE_NAME (type);
-  if (TREE_CODE (name) == TYPE_DECL)
-    name = DECL_NAME (name);
-
-  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 321);
-#endif
-
   {
     int flags = LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN;
 
@@ -1565,20 +1470,7 @@ build_functional_cast (exp, parms)
 
     if (expr_as_ctor && expr_as_ctor != error_mark_node)
       {
-#if 0
-       /* mrs Mar 12, 1992 I claim that if it is a constructor, it is
-          impossible to be an expr_as_method, without being a
-          constructor call. */
-       if (expr_as_method
-           || (expr_as_fncall && expr_as_fncall != error_mark_node))
-#else
-       if (expr_as_fncall && expr_as_fncall != error_mark_node)
-#endif
-         {
-           cp_warning ("function hides constructor for class `%T'", type);
-           return expr_as_fncall;
-         }
-       else if (expr_as_conversion && expr_as_conversion != error_mark_node)
+       if (expr_as_conversion && expr_as_conversion != error_mark_node)
          {
            /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */
            cp_error ("ambiguity between conversion to `%T' and constructor",
@@ -1632,23 +1524,8 @@ build_functional_cast (exp, parms)
       }
 
     if (expr_as_conversion)
-      {
-       if (expr_as_method || expr_as_fncall)
-         {
-           cp_error ("ambiguity between conversion to `%T' and function call",
-                     type);
-           return error_mark_node;
-         }
-       return expr_as_conversion;
-      }
-  return_function:
-    if (expr_as_method)
-      return build_method_call (current_class_decl, name, parms,
-                               NULL_TREE, LOOKUP_NORMAL);
-    if (expr_as_fncall)
-      return expr_as_fncall == error_mark_node
-       ? build_overload_call (name, parms, LOOKUP_COMPLAIN, (struct candidate *)0)
-         : expr_as_fncall;
+      return expr_as_conversion;
+
     cp_error ("no suitable conversion to `%T' exists", type);
     return error_mark_node;
   }