Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 172709)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2968,6 +2968,7 @@
   BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
                                            SourceLocation nameLoc,
                                            IndirectFieldDecl *indirectField,
+                                           LookupResult *R = 0,
                                            Expr *baseObjectExpr = 0,
                                       SourceLocation opLoc = SourceLocation());
   ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
Index: lib/Sema/SemaExprMember.cpp
===================================================================
--- lib/Sema/SemaExprMember.cpp	(revision 172709)
+++ lib/Sema/SemaExprMember.cpp	(working copy)
@@ -669,6 +669,7 @@
 Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
                                                SourceLocation loc,
                                                IndirectFieldDecl *indirectField,
+                                               LookupResult *R,
                                                Expr *baseObjectExpr,
                                                SourceLocation opLoc) {
   // First, build the expression that refers to the base object.
@@ -734,6 +735,7 @@
       = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true);
     baseObjectIsPointer = true;
     baseQuals = ThisTy->castAs<PointerType>()->getPointeeType().getQualifiers();
+    R->setBaseObjectType(ThisTy->castAs<PointerType>()->getPointeeType());
   }
   
   // Build the implicit member references to the field of the
@@ -746,8 +748,9 @@
   if (!baseVariable) {
     FieldDecl *field = cast<FieldDecl>(*FI);
     
-    // FIXME: use the real found-decl info!
-    DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
+    assert(R->getResultKind() == LookupResult::Found);
+    NamedDecl *ND = *R->begin();
+    DeclAccessPair foundDecl = DeclAccessPair::make(ND, ND->getAccess());
     
     // Make a nameInfo that properly uses the anonymous name.
     DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
@@ -938,7 +941,7 @@
   if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
     // We may have found a field within an anonymous union or struct
     // (C++ [class.union]).
-    return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
+    return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD, &R,
                                                     BaseExpr, OpLoc);
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
@@ -1649,7 +1652,7 @@
   // (C++ [class.union]).
   // FIXME: template-ids inside anonymous structs?
   if (IndirectFieldDecl *FD = R.getAsSingle<IndirectFieldDecl>())
-    return BuildAnonymousStructUnionMemberReference(SS, R.getNameLoc(), FD);
+    return BuildAnonymousStructUnionMemberReference(SS, R.getNameLoc(), FD, &R);
   
   // If this is known to be an instance access, go ahead and build an
   // implicit 'this' expression now.
Index: test/CXX/class.access/class.access.base/p1.cpp
===================================================================
--- test/CXX/class.access/class.access.base/p1.cpp	(revision 172709)
+++ test/CXX/class.access/class.access.base/p1.cpp	(working copy)
@@ -1,155 +1,169 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-// C++0x [class.access.base]p1(a):
-//   If a class is declared to be a base class for another class using
-//   the public access specifier, the public members of the base class
-//   are accessible as public members of the derived class and protected
-//   members of the base class are accessible as protected members of
-//   the derived class.
-namespace test0 {
-  class Base {
-  public: int pub; static int spub;
-  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
-  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
-  };
-
-  class Test : public Base {
-    void test() {
-      pub++;
-      spub++;
-      prot++;
-      sprot++;
-      priv++; // expected-error {{private member}}
-      spriv++; // expected-error {{private member}}
-
-      Base::pub++;
-      Base::spub++;
-      Base::prot++;
-      Base::sprot++;
-      Base::priv++; // expected-error {{private member}}
-      Base::spriv++; // expected-error {{private member}}
-    }
-  };
-
-  void test(Test *t) {
-    t->pub++;
-    t->spub++;
-    t->prot++; // expected-error {{protected member}}
-    t->sprot++; // expected-error {{protected member}}
-    t->priv++; // expected-error {{private member}}
-    t->spriv++; // expected-error {{private member}}
-
-    t->Base::pub++;
-    t->Base::spub++;
-    t->Base::prot++; // expected-error {{protected member}}
-    t->Base::sprot++; // expected-error {{protected member}}
-    t->Base::priv++; // expected-error {{private member}}
-    t->Base::spriv++; // expected-error {{private member}}
-  }
-}
-
-// C++0x [class.access.base]p1(b):
-//   If a class is declared to be a base class for another class using
-//   the protected access specifier, the public and protected members
-//   of the base class are accessible as protected members of the
-//   derived class.
-namespace test1 {
-  class Base { // expected-note 6{{member is declared here}}
-  public: 
-    int pub; // expected-note{{member is declared here}}
-    static int spub; // expected-note{{member is declared here}}
-  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
-  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
-  };
-
-  class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
-    void test() {
-      pub++;
-      spub++;
-      prot++;
-      sprot++;
-      priv++; // expected-error {{private member}}
-      spriv++; // expected-error {{private member}}
-
-      Base::pub++;
-      Base::spub++;
-      Base::prot++;
-      Base::sprot++;
-      Base::priv++; // expected-error {{private member}}
-      Base::spriv++; // expected-error {{private member}}
-    }
-  };
-
-  void test(Test *t) {
-    t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
-    t->spub++; // expected-error {{protected member}}
-    t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
-    t->sprot++; // expected-error {{protected member}}
-    t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
-    t->spriv++; // expected-error {{private member}}
-
-    // Two possible errors here: one for Base, one for the member
-    t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
-    t->Base::spub++; // expected-error {{protected member}}
-    t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
-    t->Base::sprot++; // expected-error 2 {{protected member}}
-    t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
-    t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
-  }
-}
-
-// C++0x [class.access.base]p1(b):
-//   If a class is declared to be a base class for another class using
-//   the private access specifier, the public and protected members of
-//   the base class are accessible as private members of the derived
-//   class.
-namespace test2 {
-  class Base { // expected-note 6{{member is declared here}}
-  public:
-    int pub; // expected-note{{member is declared here}}
-    static int spub; // expected-note{{member is declared here}}
-  protected:
-    int prot; // expected-note {{declared protected here}} \
-    // expected-note{{member is declared here}}
-    static int sprot; // expected-note {{declared protected here}} \
-    // expected-note{{member is declared here}}
-  private:
-    int priv; // expected-note 4 {{declared private here}}
-    static int spriv; // expected-note 4 {{declared private here}}
-  };
-
-  class Test : private Base { // expected-note 6 {{declared private here}} \
-                              // expected-note 10 {{constrained by private inheritance here}}
-    void test() {
-      pub++;
-      spub++;
-      prot++;
-      sprot++;
-      priv++; // expected-error {{private member}}
-      spriv++; // expected-error {{private member}}
-
-      Base::pub++;
-      Base::spub++;
-      Base::prot++;
-      Base::sprot++;
-      Base::priv++; // expected-error {{private member}}
-      Base::spriv++; // expected-error {{private member}}
-    }
-  };
-
-  void test(Test *t) {
-    t->pub++; // expected-error {{private member}} expected-error {{private base class}}
-    t->spub++; // expected-error {{private member}}
-    t->prot++; // expected-error {{private member}} expected-error {{private base class}}
-    t->sprot++; // expected-error {{private member}}
-    t->priv++; // expected-error {{private member}} expected-error {{private base class}}
-    t->spriv++; // expected-error {{private member}}
-
-    t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
-    t->Base::spub++; // expected-error {{private member}}
-    t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
-    t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
-    t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
-    t->Base::spriv++; // expected-error 2 {{private member}}
-  }
-}
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.access.base]p1(a):
+//   If a class is declared to be a base class for another class using
+//   the public access specifier, the public members of the base class
+//   are accessible as public members of the derived class and protected
+//   members of the base class are accessible as protected members of
+//   the derived class.
+namespace test0 {
+  class Base {
+  public: int pub; static int spub;
+  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
+  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
+  };
+
+  class Test : public Base {
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++;
+    t->spub++;
+    t->prot++; // expected-error {{protected member}}
+    t->sprot++; // expected-error {{protected member}}
+    t->priv++; // expected-error {{private member}}
+    t->spriv++; // expected-error {{private member}}
+
+    t->Base::pub++;
+    t->Base::spub++;
+    t->Base::prot++; // expected-error {{protected member}}
+    t->Base::sprot++; // expected-error {{protected member}}
+    t->Base::priv++; // expected-error {{private member}}
+    t->Base::spriv++; // expected-error {{private member}}
+  }
+}
+
+// C++0x [class.access.base]p1(b):
+//   If a class is declared to be a base class for another class using
+//   the protected access specifier, the public and protected members
+//   of the base class are accessible as protected members of the
+//   derived class.
+namespace test1 {
+  class Base { // expected-note 6{{member is declared here}}
+  public: 
+    int pub; // expected-note{{member is declared here}}
+    static int spub; // expected-note{{member is declared here}}
+  protected: int prot; static int sprot; // expected-note 4 {{declared protected here}}
+  private: int priv; static int spriv; // expected-note 8 {{declared private here}}
+  };
+
+  class Test : protected Base { // expected-note 6 {{declared protected here}} expected-note 8 {{constrained by protected inheritance here}}
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->spub++; // expected-error {{protected member}}
+    t->prot++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->sprot++; // expected-error {{protected member}}
+    t->priv++; // expected-error {{private member}} expected-error {{protected base class}}
+    t->spriv++; // expected-error {{private member}}
+
+    // Two possible errors here: one for Base, one for the member
+    t->Base::pub++; // expected-error {{protected member}} expected-error {{protected base class}}
+    t->Base::spub++; // expected-error {{protected member}}
+    t->Base::prot++; // expected-error 2 {{protected member}} expected-error {{protected base class}}
+    t->Base::sprot++; // expected-error 2 {{protected member}}
+    t->Base::priv++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{protected base class}}
+    t->Base::spriv++; // expected-error {{protected member}} expected-error {{private member}}
+  }
+}
+
+// C++0x [class.access.base]p1(b):
+//   If a class is declared to be a base class for another class using
+//   the private access specifier, the public and protected members of
+//   the base class are accessible as private members of the derived
+//   class.
+namespace test2 {
+  class Base { // expected-note 6{{member is declared here}}
+  public:
+    int pub; // expected-note{{member is declared here}}
+    static int spub; // expected-note{{member is declared here}}
+  protected:
+    int prot; // expected-note {{declared protected here}} \
+    // expected-note{{member is declared here}}
+    static int sprot; // expected-note {{declared protected here}} \
+    // expected-note{{member is declared here}}
+  private:
+    int priv; // expected-note 4 {{declared private here}}
+    static int spriv; // expected-note 4 {{declared private here}}
+  };
+
+  class Test : private Base { // expected-note 6 {{declared private here}} \
+                              // expected-note 10 {{constrained by private inheritance here}}
+    void test() {
+      pub++;
+      spub++;
+      prot++;
+      sprot++;
+      priv++; // expected-error {{private member}}
+      spriv++; // expected-error {{private member}}
+
+      Base::pub++;
+      Base::spub++;
+      Base::prot++;
+      Base::sprot++;
+      Base::priv++; // expected-error {{private member}}
+      Base::spriv++; // expected-error {{private member}}
+    }
+  };
+
+  void test(Test *t) {
+    t->pub++; // expected-error {{private member}} expected-error {{private base class}}
+    t->spub++; // expected-error {{private member}}
+    t->prot++; // expected-error {{private member}} expected-error {{private base class}}
+    t->sprot++; // expected-error {{private member}}
+    t->priv++; // expected-error {{private member}} expected-error {{private base class}}
+    t->spriv++; // expected-error {{private member}}
+
+    t->Base::pub++; // expected-error {{private member}} expected-error {{private base class}}
+    t->Base::spub++; // expected-error {{private member}}
+    t->Base::prot++; // expected-error {{protected member}} expected-error {{private member}} expected-error {{private base class}}
+    t->Base::sprot++; // expected-error {{protected member}} expected-error {{private member}}
+    t->Base::priv++; // expected-error 2 {{private member}} expected-error {{private base class}}
+    t->Base::spriv++; // expected-error 2 {{private member}}
+  }
+}
+
+namespace PR12788 {
+  class Base {
+  protected:
+    struct { int x; };
+  };
+  
+  class Test : public Base {
+    void mem() {
+      x++;
+      Base::x++;
+    }
+  };
+}
