Implement access control for overloaded functions.  Suppress access control
diagnostics in "early" lookups, such as during typename checks and when building
unresolved lookup expressions.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94647 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index a6574ef..475dcf2 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -116,6 +116,7 @@
 // UnresolvedLookupExpr
 UnresolvedLookupExpr *
 UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
+                             CXXRecordDecl *NamingClass,
                              NestedNameSpecifier *Qualifier,
                              SourceRange QualifierRange, DeclarationName Name,
                              SourceLocation NameLoc, bool ADL,
@@ -125,7 +126,8 @@
                          ExplicitTemplateArgumentList::sizeFor(Args));
   UnresolvedLookupExpr *ULE
     = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
-                                     Dependent, Qualifier, QualifierRange,
+                                     Dependent, NamingClass,
+                                     Qualifier, QualifierRange,
                                      Name, NameLoc, ADL,
                                      /*Overload*/ true,
                                      /*ExplicitTemplateArgs*/ true);
@@ -651,6 +653,35 @@
                              Member, MemberLoc, TemplateArgs);
 }
 
+CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
+  // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
+
+  // If there was a nested name specifier, it names the naming class.
+  // It can't be dependent: after all, we were actually able to do the
+  // lookup.
+  const RecordType *RT;
+  if (Qualifier) {
+    Type *T = Qualifier->getAsType();
+    assert(T && "qualifier in member expression does not name type");
+    RT = T->getAs<RecordType>();
+    assert(RT && "qualifier in member expression does not name record");
+
+  // Otherwise the naming class must have been the base class.
+  } else {
+    QualType BaseType = getBaseType().getNonReferenceType();
+    if (isArrow()) {
+      const PointerType *PT = BaseType->getAs<PointerType>();
+      assert(PT && "base of arrow member access is not pointer");
+      BaseType = PT->getPointeeType();
+    }
+    
+    RT = BaseType->getAs<RecordType>();
+    assert(RT && "base of member expression does not name record");
+  }
+  
+  return cast<CXXRecordDecl>(RT->getDecl());
+}
+
 Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
   return child_iterator(&Base);
 }