Jason,

Please ignore the previous patch, where I have introduced an
unintentional modification for PR c++/30195 in search.c, here is a new
one, sorry about that.

-- 
Fabien
Index: gcc/testsuite/g++.old-deja/g++.other/using1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/using1.C       (revision 178088)
+++ gcc/testsuite/g++.old-deja/g++.other/using1.C       (working copy)
@@ -16,12 +16,12 @@ public:
   using B::b;
 };
 
-class D2 : public B { // { dg-error "" } conflicting access specifications
+class D2 : public B {
 public:
   using B::a;
-  using B::b;
+  using B::b; // { dg-message "" } conflicting declaration
 
 private:
-  using B::b; 
+  using B::b; // { dg-error "" } conflicts
 };
  
Index: gcc/testsuite/g++.dg/debug/using4.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using4.C (revision 0)
+++ gcc/testsuite/g++.dg/debug/using4.C (revision 0)
@@ -0,0 +1,24 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    typedef char type;
+};
+
+struct B
+{
+    typedef int type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type f (type);
+};
+
+C::type C::f( type ) 
+{
+    type c = 'e';
+    return c;
+}
Index: gcc/testsuite/g++.dg/debug/using5.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using5.C (revision 0)
+++ gcc/testsuite/g++.dg/debug/using5.C (revision 0)
@@ -0,0 +1,23 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    int i;
+};
+
+struct B
+{
+    int i;
+};
+
+struct C : A, B
+{
+    using B::i;
+    int f ();
+};
+
+int C::f() 
+{
+    return i;
+}
Index: gcc/testsuite/g++.dg/lookup/using36.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using36.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using36.C       (revision 0)
@@ -0,0 +1,31 @@
+// PR c++/25994
+// { dg-do run }
+
+struct B1
+{
+  void f (char) {}
+  void f (double) { __builtin_abort(); }
+};
+
+struct B2
+{
+  void f (double) { __builtin_abort(); }
+  void f (int) {}
+};
+
+struct D : public B1, public B2
+{
+  using B1::f;
+  using B2::f;
+  void g ()
+  {
+    f ('a');           // should call B1::f(char)
+    f (33);            // should call B2::f(int)
+  }
+};
+
+int main()
+{
+  D d;
+  d.g();
+}
Index: gcc/testsuite/g++.dg/lookup/using24.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using24.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using24.C       (revision 0)
@@ -0,0 +1,12 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A { int next; };
+struct B { int next; };
+struct C : B { using B::next; };
+
+struct D : A, C
+{
+   using C::next;
+   void f() { next = 1; }
+};
Index: gcc/testsuite/g++.dg/lookup/using28.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using28.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using28.C       (revision 0)
@@ -0,0 +1,11 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A { int f; };
+struct B { int f; };
+struct C : A, B { using B::f; };
+
+struct D : C
+{
+    void g() { f = 1; }
+};
Index: gcc/testsuite/g++.dg/lookup/using33.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using33.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using33.C       (revision 0)
@@ -0,0 +1,26 @@
+// { dg-do run }
+
+template <class T>
+struct Foo 
+{
+  int k (float) {return 0;}
+};
+
+template <class T>
+struct Baz 
+{
+  int k (int) {return 1;}
+};
+
+template <class T>
+struct Bar : Foo<T> , Baz<T>
+{
+  using Foo<T>::k;
+  using Baz<T>::k;
+};
+
+int main()
+{
+  Bar<int> bar;
+  return bar.k( 1.0f );
+}
Index: gcc/testsuite/g++.dg/lookup/using25.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using25.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using25.C       (revision 0)
@@ -0,0 +1,28 @@
+// PR c++/26256
+// { dg-do run }
+
+struct A 
+{
+    int next; 
+};
+
+struct B 
+{
+    int next; 
+};
+
+struct C : public A, public B 
+{
+    using A::next; 
+};
+
+void foo(C& c) { c.next = 42; }
+
+int main()
+{
+    C c;
+    foo (c);
+    c.B::next = 12;
+    if (c.next != 42 || c.A::next != 42 || c.B::next != 12)
+       __builtin_abort();
+}
Index: gcc/testsuite/g++.dg/lookup/using29.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using29.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using29.C       (revision 0)
@@ -0,0 +1,81 @@
+// { dg-do compile }
+
+struct A 
+{
+  int i;
+};
+
+struct B
+{
+  int i;
+};
+
+struct C : A, B
+{
+  using A::i; // { dg-error "conflicts with previous" }
+  using B::i; // { dg-error "declaration" }
+};
+
+struct E
+{
+  typedef int type;
+};
+
+struct F
+{
+  typedef int type;
+};
+
+struct G : E, F
+{
+  using E::type; // { dg-error "conflicts with previous" }
+  using F::type; // { dg-error "declaration" }
+};
+
+struct H
+{
+  typedef int type;
+};
+
+struct I : H
+{
+  typedef int type; // { dg-error "conflicts with previous" }
+  using H::type; // { dg-error "declaration" }
+};
+
+struct I2 : H
+{
+  using H::type; // { dg-error "conflicts with previous" }
+  typedef int type; // { dg-error "declaration" }
+};
+
+struct J
+{
+  struct type {};
+};
+
+struct K : J
+{
+  struct type {}; // { dg-error "conflicts with previous" }
+  using J::type; // { dg-error "declaration" }
+};
+
+struct L : J
+{
+  using J::type; // { dg-error "conflicts with previous" }
+  struct type {}; // { dg-error "declaration" }
+};
+
+struct M
+{
+  typedef int type;
+  struct type2 {};
+};
+
+struct N : M
+{
+  using M::type; // { dg-error "conflicts with previous" }
+  using M::type; // { dg-error "declaration" }
+  using M::type2; // { dg-error "conflicts with previous" }
+  using M::type2; // { dg-error "declaration" }
+};
Index: gcc/testsuite/g++.dg/lookup/using30.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using30.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using30.C       (revision 0)
@@ -0,0 +1,8 @@
+// { dg-do compile }
+
+struct H { typedef int type; };
+struct J : H
+{
+  struct type {}; // { dg-error "conflicts with previous" }
+  using H::type; // { dg-error "declaration" }
+};
Index: gcc/testsuite/g++.dg/lookup/using34.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using34.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using34.C       (revision 0)
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+struct A { int f (); };
+struct B : A 
+{
+  using A::f;
+  struct f {};
+  void g() { f(); struct f ff; }
+  struct f ff;
+};
Index: gcc/testsuite/g++.dg/lookup/using26.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using26.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using26.C       (revision 0)
@@ -0,0 +1,27 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A 
+{
+    double next; 
+};
+
+struct B 
+{
+private:
+    int next; // { dg-error "private" }
+};
+
+struct C
+{
+    int next;
+};
+
+struct D : A, B, C // { dg-error "context" }
+{
+    using B::next;
+    void f()
+    {
+       next = 12;
+    }
+};
Index: gcc/testsuite/g++.dg/lookup/using31.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using31.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using31.C       (revision 0)
@@ -0,0 +1,8 @@
+// { dg-do compile }
+
+struct H2 { int f (); };
+struct J2 : H2
+{
+  struct f {};
+  using H2::f;
+};
Index: gcc/testsuite/g++.dg/lookup/using35.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using35.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using35.C       (revision 0)
@@ -0,0 +1,11 @@
+// { dg-do compile }
+
+struct A { typedef int type; };
+struct B { typedef int type; };
+struct C : B { using B::type; };
+
+struct D : A, C
+{
+  using C::type;
+  void f() { type t = 0;}
+};
Index: gcc/testsuite/g++.dg/lookup/using23.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using23.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using23.C       (revision 0)
@@ -0,0 +1,19 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+private:
+    typedef int type; // { dg-error "private" }
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B // { dg-error "context" }
+{
+    using A::type; 
+    type d;
+};
Index: gcc/testsuite/g++.dg/lookup/using27.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using27.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using27.C       (revision 0)
@@ -0,0 +1,48 @@
+// PR c++/26256
+// { dg-do run }
+
+struct A
+{
+    typedef int type;
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type d;
+
+    void f()
+    {
+       type e;
+       if (sizeof (type) != sizeof (A::type))
+           __builtin_abort();
+    }
+
+    void g();
+};
+
+void C::g()
+{
+    type x;
+    if (sizeof (type) != sizeof (A::type))
+       __builtin_abort();
+}
+
+int main ()
+{
+    if (sizeof (C::type) != sizeof (A::type))
+       __builtin_abort();
+
+    if (sizeof (C::d) != sizeof (A::type))
+       __builtin_abort();
+
+    C::type x;
+    C c;
+    c.f();
+    c.g();
+}
Index: gcc/testsuite/g++.dg/lookup/using32.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using32.C       (revision 0)
+++ gcc/testsuite/g++.dg/lookup/using32.C       (revision 0)
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+struct T { struct type {}; };
+struct T2 : T { using T::type; };
+struct T3 : T2
+{
+  struct type {};
+  type t;
+};
Index: gcc/testsuite/g++.dg/cpp0x/forw_enum10.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/forw_enum10.C    (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/forw_enum10.C    (revision 0)
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+//This error is diagnosed at instantiation time
+template<typename T> struct S1
+{
+    enum E : T;   // { dg-error "previous definition" }
+    enum E : int;     // { dg-error "different underlying type" }
+};
+template struct S1<short>; // { dg-message "required from here" }
+
+template<typename T> struct S2
+{
+    enum E : T;
+    enum E : T;
+};
+template struct S2<short>;
+
+template<typename T1, typename T2> struct S3
+{
+    enum E : T1;
+    enum E : T2;
+};
+template struct S3<short,short>;
+
+template<typename T1, typename T2> struct S4
+{
+    enum E : T1; // { dg-error "previous definition" }
+    enum E : T2; // { dg-error "different underlying type" }
+};
+template struct S4<short,char>; // { dg-message "required from here" }
+
Index: gcc/testsuite/g++.dg/template/using2.C
===================================================================
--- gcc/testsuite/g++.dg/template/using2.C      (revision 178088)
+++ gcc/testsuite/g++.dg/template/using2.C      (working copy)
@@ -7,24 +7,25 @@
 
 template <class T>
 struct Foo {
-  int i; // { dg-error "Foo" }
+  int i;
 };
 
 struct Baz 
 {
-  int i; // { dg-error "Baz" }
+  int i;
 };
 
 template <class T>
-struct Bar : public Foo<T>, Baz {
-  using Foo<T>::i;
-  using Baz::i;
+struct Bar : public Foo<T>, Baz 
+{
+  using Foo<T>::i; // { dg-message "conflicts with previous" } 
+  using Baz::i; // { dg-error "declaration" } 
 
-  int foo () { return i; } // { dg-error "request for member" }
+  int foo () { return i; }
 };
 
 void foo (Bar<int> &bar)
 {
-  bar.foo(); // { dg-message "required" }
+  bar.foo();
 }
 
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c     (revision 178088)
+++ gcc/cp/typeck.c     (working copy)
@@ -2109,6 +2109,7 @@ build_class_member_access_expr (tree obj
   tree object_type;
   tree member_scope;
   tree result = NULL_TREE;
+  tree using_decl = NULL_TREE;
 
   if (error_operand_p (object) || error_operand_p (member))
     return error_mark_node;
@@ -2329,6 +2330,11 @@ build_class_member_access_expr (tree obj
        result = build2 (COMPOUND_EXPR, TREE_TYPE (result),
                         object, result);
     }
+  else if ((using_decl = strip_using_decl (member)) != member)
+    result = build_class_member_access_expr (object,
+                                            using_decl,
+                                            access_path, preserve_reference,
+                                            complain);
   else
     {
       if (complain & tf_error)
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c      (revision 178088)
+++ gcc/cp/class.c      (working copy)
@@ -1053,9 +1053,6 @@ add_method (tree type, tree method, tree
                return false;
              if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
                error ("repeated using declaration %q+D", using_decl);
-             else
-               error ("using declaration %q+D conflicts with a previous using 
declaration",
-                      using_decl);
            }
          else
            {
@@ -3016,15 +3013,8 @@ check_field_decls (tree t, tree *access_
 
       if (TREE_CODE (x) == USING_DECL)
        {
-         /* Prune the access declaration from the list of fields.  */
-         *field = DECL_CHAIN (x);
-
          /* Save the access declarations for our caller.  */
          *access_decls = tree_cons (NULL_TREE, x, *access_decls);
-
-         /* Since we've reset *FIELD there's no reason to skip to the
-            next field.  */
-         next = field;
          continue;
        }
 
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c       (revision 178088)
+++ gcc/cp/decl.c       (working copy)
@@ -11937,8 +11937,20 @@ start_enum (tree name, tree enumtype, tr
            *is_new = true;
        }
       prevtype = enumtype;
-      enumtype = cxx_make_type (ENUMERAL_TYPE);
-      enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
+
+      /* do not push the decl more than once */
+      if (!enumtype
+         || (underlying_type
+             && dependent_type_p (underlying_type))
+         || (ENUM_UNDERLYING_TYPE (enumtype)
+             && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))))
+       {
+         enumtype = cxx_make_type (ENUMERAL_TYPE);
+         enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
+       }
+      else
+         enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current, 
false);
+
       if (enumtype == error_mark_node)
        return error_mark_node;
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c  (revision 178088)
+++ gcc/cp/semantics.c  (working copy)
@@ -2670,8 +2670,7 @@ finish_member_declaration (tree decl)
        }
     }
   /* Enter the DECL into the scope of the class.  */
-  else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
-          || pushdecl_class_level (decl))
+  else if (pushdecl_class_level (decl))
     {
       /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
         go at the beginning.  The reason is that lookup_field_1
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c     (revision 178088)
+++ gcc/cp/parser.c     (working copy)
@@ -13046,6 +13046,9 @@ cp_parser_nonclass_name (cp_parser* pars
   /* Look up the type-name.  */
   type_decl = cp_parser_lookup_name_simple (parser, identifier, 
token->location);
 
+  /* If it is a using decl, use its underlying decl.  */
+  type_decl = strip_using_decl (type_decl);
+
   if (TREE_CODE (type_decl) != TYPE_DECL
       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
     {
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h    (revision 178088)
+++ gcc/cp/cp-tree.h    (working copy)
@@ -5776,7 +5776,8 @@ extern void cxx_omp_finish_clause         (tree
 extern bool cxx_omp_privatize_by_reference     (const_tree);
 
 /* in name-lookup.c */
-extern void suggest_alternatives_for (location_t, tree);
+extern void suggest_alternatives_for            (location_t, tree);
+extern tree strip_using_decl                    (tree);
 
 /* -- end of C++ */
 
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c     (revision 178088)
+++ gcc/cp/search.c     (working copy)
@@ -1,7 +1,7 @@
 /* Breadth-first and depth-first routines for
    searching multiple-inheritance lattice for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiem...@cygnus.com)
 
@@ -449,6 +449,8 @@ lookup_field_1 (tree type, tree name, bo
 #endif /* GATHER_STATISTICS */
   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
     {
+      tree decl = field;
+
 #ifdef GATHER_STATISTICS
       n_fields_searched++;
 #endif /* GATHER_STATISTICS */
@@ -460,26 +462,19 @@ lookup_field_1 (tree type, tree name, bo
          if (temp)
            return temp;
        }
-      if (TREE_CODE (field) == USING_DECL)
+      
+      if (TREE_CODE (decl) == USING_DECL)
        {
-         /* We generally treat class-scope using-declarations as
-            ARM-style access specifications, because support for the
-            ISO semantics has not been implemented.  So, in general,
-            there's no reason to return a USING_DECL, and the rest of
-            the compiler cannot handle that.  Once the class is
-            defined, USING_DECLs are purged from TYPE_FIELDS; see
-            handle_using_decl.  However, we make special efforts to
-            make using-declarations in class templates and class
-            template partial specializations work correctly.  */
-         if (!DECL_DEPENDENT_P (field))
+         decl = strip_using_decl (decl);
+         if (is_overloaded_fn (decl))
            continue;
        }
 
-      if (DECL_NAME (field) == name
+      if (DECL_NAME (decl) == name
          && (!want_type
-             || TREE_CODE (field) == TYPE_DECL
-             || DECL_CLASS_TEMPLATE_P (field)))
-       return field;
+             || TREE_CODE (decl) == TYPE_DECL
+             || DECL_CLASS_TEMPLATE_P (decl)))
+       return decl;
     }
   /* Not found.  */
   if (name == vptr_identifier)
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c        (revision 178088)
+++ gcc/cp/name-lookup.c        (working copy)
@@ -394,6 +394,16 @@ pop_binding (tree id, tree decl)
     }
 }
 
+/* Strip non dependent using declarations.  */
+
+tree
+strip_using_decl (tree decl)
+{
+  while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
+    decl = USING_DECL_DECLS (decl);
+  return decl;
+}
+
 /* BINDING records an existing declaration for a name in the current scope.
    But, DECL is another declaration for that same identifier in the
    same scope.  This is the `struct stat' hack whereby a non-typedef
@@ -417,29 +427,45 @@ supplement_binding_1 (cxx_binding *bindi
 {
   tree bval = binding->value;
   bool ok = true;
+  tree target_bval = strip_using_decl (bval);
+  tree target_decl = strip_using_decl (decl);
 
-  if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
+  if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
+      && target_decl != target_bval
+      && (TREE_CODE (target_bval) != TYPE_DECL
+         /* We allow pushing an enum multiple times in a class
+          * template in order to handle late matching of underlying
+          * type on an opaque-enum-declaration followed by an
+          * enum-specifier.  */
+         || (TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
+             && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
+             && (dependent_type_p (ENUM_UNDERLYING_TYPE
+                                   (TREE_TYPE (target_decl)))
+                 || dependent_type_p (ENUM_UNDERLYING_TYPE
+                                      (TREE_TYPE (target_bval))))
+              )))
     /* The new name is the type name.  */
     binding->type = decl;
-  else if (/* BVAL is null when push_class_level_binding moves an
+  else if (/* TARGET_BVAL is null when push_class_level_binding moves an
              inherited type-binding out of the way to make room for a
              new value binding.  */
-          !bval
-          /* BVAL is error_mark_node when DECL's name has been used
+          !target_bval
+          /* TARGET_BVAL is error_mark_node when TARGET_DECL's name has been 
used
              in a non-class scope prior declaration.  In that case,
              we should have already issued a diagnostic; for graceful
              error recovery purpose, pretend this was the intended
              declaration for that name.  */
-          || bval == error_mark_node
-          /* If BVAL is anticipated but has not yet been declared,
+          || target_bval == error_mark_node
+          /* If TARGET_BVAL is anticipated but has not yet been declared,
              pretend it is not there at all.  */
-          || (TREE_CODE (bval) == FUNCTION_DECL
-              && DECL_ANTICIPATED (bval)
-              && !DECL_HIDDEN_FRIEND_P (bval)))
+          || (TREE_CODE (target_bval) == FUNCTION_DECL
+              && DECL_ANTICIPATED (target_bval)
+              && !DECL_HIDDEN_FRIEND_P (target_bval)))
     binding->value = decl;
-  else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-          && (TREE_CODE (decl) != TYPE_DECL
-              || same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))))
+  else if (TREE_CODE (target_bval) == TYPE_DECL && DECL_ARTIFICIAL 
(target_bval)
+          && target_decl != target_bval
+          && (TREE_CODE (target_decl) != TYPE_DECL
+              || same_type_p (TREE_TYPE (target_decl), TREE_TYPE 
(target_bval))))
     {
       /* The old binding was a type name.  It was placed in
         VALUE field because it was thought, at the point it was
@@ -450,15 +476,15 @@ supplement_binding_1 (cxx_binding *bindi
       binding->value = decl;
       binding->value_is_inherited = false;
     }
-  else if (TREE_CODE (bval) == TYPE_DECL
-          && TREE_CODE (decl) == TYPE_DECL
-          && DECL_NAME (decl) == DECL_NAME (bval)
+  else if (TREE_CODE (target_bval) == TYPE_DECL
+          && TREE_CODE (target_decl) == TYPE_DECL
+          && DECL_NAME (target_decl) == DECL_NAME (target_bval)
           && binding->scope->kind != sk_class
-          && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
+          && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
               /* If either type involves template parameters, we must
                  wait until instantiation.  */
-              || uses_template_parms (TREE_TYPE (decl))
-              || uses_template_parms (TREE_TYPE (bval))))
+              || uses_template_parms (TREE_TYPE (target_decl))
+              || uses_template_parms (TREE_TYPE (target_bval))))
     /* We have two typedef-names, both naming the same type to have
        the same name.  In general, this is OK because of:
 
@@ -480,9 +506,9 @@ supplement_binding_1 (cxx_binding *bindi
 
        A member shall not be declared twice in the
        member-specification.  */
-  else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
-          && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
-          && !DECL_CLASS_SCOPE_P (decl))
+  else if (TREE_CODE (target_decl) == VAR_DECL && TREE_CODE (target_bval) == 
VAR_DECL
+          && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
+          && !DECL_CLASS_SCOPE_P (target_decl))
     {
       duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
       ok = false;
@@ -3018,6 +3044,8 @@ push_class_level_binding_1 (tree name, t
     {
       tree bval = binding->value;
       tree old_decl = NULL_TREE;
+      tree target_decl = strip_using_decl (decl);
+      tree target_bval = strip_using_decl (bval);
 
       if (INHERITED_VALUE_BINDING_P (binding))
        {
@@ -3025,8 +3053,8 @@ push_class_level_binding_1 (tree name, t
             tag name, slide it over to make room for the new binding.
             The old binding is still visible if explicitly qualified
             with a class-key.  */
-         if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
-             && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+         if (TREE_CODE (target_bval) == TYPE_DECL && DECL_ARTIFICIAL 
(target_bval)
+             && !(TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL 
(target_decl)))
            {
              old_decl = binding->type;
              binding->type = bval;
@@ -3038,18 +3066,21 @@ push_class_level_binding_1 (tree name, t
              old_decl = bval;
              /* Any inherited type declaration is hidden by the type
                 declaration in the derived class.  */
-             if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
+             if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL 
(target_decl))
                binding->type = NULL_TREE;
            }
        }
-      else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
-       old_decl = bval;
-      else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
-       return true;
-      else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
+      else if (TREE_CODE (target_decl) == OVERLOAD && is_overloaded_fn 
(target_bval))
        old_decl = bval;
-      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
+      else if (TREE_CODE (decl) == USING_DECL
+              && DECL_DEPENDENT_P (decl)
+              && TREE_CODE (bval) == USING_DECL
+              && DECL_DEPENDENT_P (bval))
        return true;
+      else if (TREE_CODE (decl) == USING_DECL && is_overloaded_fn 
(target_bval))
+       old_decl = bval;
+      else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn 
(target_decl))
+       return true;
 
       if (old_decl && binding->scope == class_binding_level)
        {
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c        (revision 178088)
+++ gcc/dbxout.c        (working copy)
@@ -1518,6 +1518,8 @@ dbxout_type_fields (tree type)
       if (TREE_CODE (tem) == TYPE_DECL
          /* Omit here the nameless fields that are used to skip bits.  */
          || DECL_IGNORED_P (tem)
+         /* Omit USING_DECL */
+         || TREE_CODE (tem) >= LAST_AND_UNUSED_TREE_CODE
          /* Omit fields whose position or size are variable or too large to
             represent.  */
          || (TREE_CODE (tem) == FIELD_DECL

Reply via email to