Propagate the "found declaration" (i.e. the using declaration instead of
the underlying/instantiated decl) through a lot of API, including "intermediate"
MemberExprs required for (e.g.) template instantiation.  This is necessary
because of the access semantics of member accesses to using declarations:
only the base class *containing the using decl* need be accessible from the
naming class.

This allows us to complete an access-controlled selfhost, if there are no
recent regressions.

llvm-svn: 99936
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 1e37bb0..fd30a53 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -437,32 +437,35 @@
                               << CondExpr->getSourceRange()))
     return true;
 
-  llvm::SmallVector<CXXConversionDecl *, 4> ViableConversions;
-  llvm::SmallVector<CXXConversionDecl *, 4> ExplicitConversions;
+  UnresolvedSet<4> ViableConversions;
+  UnresolvedSet<4> ExplicitConversions;
   if (const RecordType *RecordTy = CondType->getAs<RecordType>()) {
     const UnresolvedSetImpl *Conversions
       = cast<CXXRecordDecl>(RecordTy->getDecl())
                                              ->getVisibleConversionFunctions();
     for (UnresolvedSetImpl::iterator I = Conversions->begin(),
            E = Conversions->end(); I != E; ++I) {
-      if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(*I))
+      if (CXXConversionDecl *Conversion
+            = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl()))
         if (Conversion->getConversionType().getNonReferenceType()
               ->isIntegralType()) {
           if (Conversion->isExplicit())
-            ExplicitConversions.push_back(Conversion);
+            ExplicitConversions.addDecl(I.getDecl(), I.getAccess());
           else
-          ViableConversions.push_back(Conversion);
+            ViableConversions.addDecl(I.getDecl(), I.getAccess());
         }
     }
 
     switch (ViableConversions.size()) {
     case 0:
       if (ExplicitConversions.size() == 1) {
+        DeclAccessPair Found = ExplicitConversions[0];
+        CXXConversionDecl *Conversion =
+          cast<CXXConversionDecl>(Found->getUnderlyingDecl());
         // The user probably meant to invoke the given explicit
         // conversion; use it.
         QualType ConvTy
-          = ExplicitConversions[0]->getConversionType()
-                        .getNonReferenceType();
+          = Conversion->getConversionType().getNonReferenceType();
         std::string TypeStr;
         ConvTy.getAsStringInternal(TypeStr, S.Context.PrintingPolicy);
 
@@ -473,8 +476,7 @@
           << CodeModificationHint::CreateInsertion(
                             S.PP.getLocForEndOfToken(CondExpr->getLocEnd()),
                                ")");
-        S.Diag(ExplicitConversions[0]->getLocation(),
-             diag::note_switch_conversion)
+        S.Diag(Conversion->getLocation(), diag::note_switch_conversion)
           << ConvTy->isEnumeralType() << ConvTy;
 
         // If we aren't in a SFINAE context, build a call to the 
@@ -482,25 +484,32 @@
         if (S.isSFINAEContext())
           return true;
 
-        CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ExplicitConversions[0]);
+        S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+                                    CondExpr, 0, Found);
+        CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found, Conversion);
       }
 
       // We'll complain below about a non-integral condition type.
       break;
 
-    case 1:
+    case 1: {
       // Apply this conversion.
-      CondExpr = S.BuildCXXMemberCallExpr(CondExpr, ViableConversions[0]);
+      DeclAccessPair Found = ViableConversions[0];
+      S.CheckMemberOperatorAccess(CondExpr->getExprLoc(),
+                                  CondExpr, 0, Found);
+      CondExpr = S.BuildCXXMemberCallExpr(CondExpr, Found,
+                        cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
       break;
+    }
 
     default:
       S.Diag(SwitchLoc, diag::err_switch_multiple_conversions)
         << CondType << CondExpr->getSourceRange();
       for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
-        QualType ConvTy
-          = ViableConversions[I]->getConversionType().getNonReferenceType();
-        S.Diag(ViableConversions[I]->getLocation(),
-             diag::note_switch_conversion)
+        CXXConversionDecl *Conv
+          = cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
+        QualType ConvTy = Conv->getConversionType().getNonReferenceType();
+        S.Diag(Conv->getLocation(), diag::note_switch_conversion)
           << ConvTy->isEnumeralType() << ConvTy;
       }
       return true;