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/using24.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
@@ -0,0 +1,24 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct ListDProto {
+    unsigned length();
+    bool empty();
+    void clear();
+    void first();
+    void next();
+    enum Action { NORMAL, REMOVE_CURRENT };
+};
+struct SetLD: ListDProto {
+    void remove()
+    {ListDProto::Action a = this->NORMAL;}
+    ListDProto::length;
+    ListDProto::empty;
+    ListDProto::clear;
+    ListDProto::first;
+    ListDProto::next;
+
+    using ListDProto::NORMAL;
+    using ListDProto::REMOVE_CURRENT;
+};
+
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/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/using23.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
@@ -0,0 +1,21 @@
+// 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; // { dg-error "context" }
+};
+
+
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,49 @@
+// 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/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 158572)
+++ gcc/cp/class.c	(working copy)
@@ -2704,6 +2704,8 @@ count_fields (tree fields)
   int n_fields = 0;
   for (x = fields; x; x = TREE_CHAIN (x))
     {
+      if (TREE_CODE (x) == USING_DECL)
+	continue;
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
 	n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
       else
@@ -2721,6 +2723,9 @@ add_fields_to_record_type (tree fields, 
   tree x;
   for (x = fields; x; x = TREE_CHAIN (x))
     {
+      if (TREE_CODE (x) == USING_DECL)
+	continue;
+
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
 	idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
       else
@@ -2935,15 +2940,8 @@ check_field_decls (tree t, tree *access_
 
       if (TREE_CODE (x) == USING_DECL)
 	{
-	  /* Prune the access declaration from the list of fields.  */
-	  *field = TREE_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/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 158572)
+++ gcc/cp/parser.c	(working copy)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -18121,6 +18121,9 @@ cp_parser_lookup_name (cp_parser *parser
   if (is_template)
     decl = maybe_get_template_decl_from_type_decl (decl);
 
+  /* Handle using decls. */
+  decl = disambiguate_with_using_decl (decl, parser->qualifying_scope);
+
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   if (TREE_CODE (decl) == TREE_LIST)
     {
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 158572)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4648,6 +4648,7 @@ extern tree check_for_out_of_scope_varia
 extern void print_other_binding_stack		(struct cp_binding_level *);
 extern tree maybe_push_decl			(tree);
 extern tree current_decl_namespace		(void);
+extern tree disambiguate_with_using_decl        (tree, tree);
 
 /* decl.c */
 extern tree poplevel				(int, int, int);
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c	(revision 158572)
+++ 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
+   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -1225,6 +1225,17 @@ lookup_member (tree xbasetype, tree name
 	protect = 0;
     }
 
+  if (protect == 1 && lfi.ambiguous)
+    {
+      tree disamb = disambiguate_with_using_decl (lfi.ambiguous, 
+						  TREE_TYPE (basetype_path));
+      if (TREE_CODE (disamb) != TREE_LIST)
+	{
+	  rval = disamb;
+	  errstr = 0;
+	}
+    }
+
   /* [class.access]
 
      In the case of overloaded function names, access control is
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 158572)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -5509,4 +5509,60 @@ cp_emit_debug_info_for_using (tree t, tr
       }
 }
 
+/* Try to disambiguate an ambiguous DECL, with using
+   declarations. Returns DECL if DECL cannot be disambiguated,
+   otherwise returns the selected candidate (not a TREE_LIST). The
+   lookup is done in SCOPE if it is not a NULL_TREE, otherwise, in
+   current_class_type if it is not a NULL_TREE. */
+tree
+disambiguate_with_using_decl (tree decl, tree scope)
+{
+  int candidates = 0;
+  tree decl_after_using = NULL_TREE;
+  tree field = NULL_TREE;
+  tree decl_scope = NULL_TREE;
+
+  if (TREE_CODE (decl) != TREE_LIST)
+    return decl;
+      
+  if (scope)
+    decl_scope = scope;
+  else if (current_class_type)
+    decl_scope = current_class_type;
+  /* else if (object_scope) */
+  /*   decl_scope = TREE_TYPE (object_scope); */
+
+  if (decl_scope == NULL_TREE
+      || !CLASS_TYPE_P (decl_scope))
+    return decl;
+
+  for (field = TYPE_FIELDS (decl_scope);
+       field;
+       field = TREE_CHAIN (field))
+    {
+      if (TREE_CODE (field) == USING_DECL)
+	{
+	  tree using_decl = USING_DECL_DECLS (field);
+	  tree fn;
+	  for (fn = decl; fn != NULL_TREE; fn = TREE_CHAIN (fn))
+	    {
+	      if (same_type_p ( TREE_TYPE (TREE_VALUE (fn)),
+				TREE_TYPE (using_decl)))
+		{
+		  decl_after_using = tree_cons (NULL_TREE,
+						using_decl,
+						decl_after_using);
+		  ++ candidates;
+		  break;
+		}
+	    }
+	}
+    }
+
+  if (candidates == 1)
+      decl = TREE_VALUE (decl_after_using);
+  return decl;
+}
+
+
 #include "gt-cp-name-lookup.h"
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 158572)
+++ gcc/dbxout.c	(working copy)
@@ -1,6 +1,6 @@
 /* Output dbx-format symbol table information from GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1431,6 +1431,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) == USING_DECL
 	  /* Omit fields whose position or size are variable or too large to
 	     represent.  */
 	  || (TREE_CODE (tem) == FIELD_DECL
