"Incremental" progress on using expressions, by which I mean totally ripping
into pretty much everything about overload resolution in order to wean
BuildDeclarationNameExpr off LookupResult::getAsSingleDecl().  Replace  
UnresolvedFunctionNameExpr with UnresolvedLookupExpr, which generalizes the
idea of a non-member lookup that we haven't totally resolved yet, whether by
overloading, argument-dependent lookup, or (eventually) the presence of   
a function template in the lookup results.  

Incidentally fixes a problem with argument-dependent lookup where we were 
still performing ADL even when the lookup results contained something from
a block scope.  

Incidentally improves a diagnostic when using an ObjC ivar from a class method.
This just fell out from rewriting BuildDeclarationNameExpr's interaction with
lookup, and I'm too apathetic to break it out.

The only remaining uses of OverloadedFunctionDecl that I know of are in
TemplateName and MemberExpr.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89544 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 10cc818..6366a4c 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -280,6 +280,12 @@
   /// ambiguous and overloaded lookups.
   NamedDecl *getAsSingleDecl(ASTContext &Context) const;
 
+  template <class DeclClass>
+  DeclClass *getAsSingle() const {
+    if (getResultKind() != Found) return 0;
+    return dyn_cast<DeclClass>(getFoundDecl());
+  }
+
   /// \brief Fetch the unique decl found by this lookup.  Asserts
   /// that one was found.
   ///
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index e0c3f13..e26df11 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -959,7 +959,7 @@
                                                    bool Complain);
   Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
 
-  void AddOverloadedCallCandidates(NamedDecl *Callee,
+  void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees,
                                    DeclarationName &UnqualifiedName,
                                    bool &ArgumentDependentLookup,
                                    bool HasExplicitTemplateArgs,
@@ -969,7 +969,8 @@
                                    OverloadCandidateSet &CandidateSet,
                                    bool PartialOverloading = false);
     
-  FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
+  FunctionDecl *ResolveOverloadedCallFn(Expr *Fn,
+                                        llvm::SmallVectorImpl<NamedDecl*> &Fns,
                                         DeclarationName UnqualifiedName,
                                         bool HasExplicitTemplateArgs,
                              const TemplateArgumentLoc *ExplicitTemplateArgs,
@@ -1415,10 +1416,18 @@
                                             bool HasTrailingLParen,
                                             const CXXScopeSpec *SS,
                                             bool isAddressOfOperand = false);
-  OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
-                                            bool HasTrailingLParen,
-                                            const CXXScopeSpec *SS,
+  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                                            LookupResult &R, bool ADL,
                                             bool isAddressOfOperand);
+  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                                            SourceLocation Loc,
+                                            DeclarationName Name,
+                                            bool NeedsADL,
+                                            NamedDecl * const *Decls,
+                                            unsigned NumDecls);
+  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                                            SourceLocation Loc,
+                                            NamedDecl *D);
 
   virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
                                                tok::TokenKind Kind);
@@ -1517,7 +1526,7 @@
                                SourceLocation RParenLoc);
 
   void DeconstructCallFunction(Expr *FnExpr,
-                               NamedDecl *&Function,
+                               llvm::SmallVectorImpl<NamedDecl*>& Fns,
                                DeclarationName &Name,
                                NestedNameSpecifier *&Qualifier,
                                SourceRange &QualifierRange,
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 6dbb442..203b421 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1467,7 +1467,7 @@
       Expr::hasAnyTypeDependentArguments(Args, NumArgs))
     return;
   
-  NamedDecl *Function;
+  llvm::SmallVector<NamedDecl*,8> Fns;
   DeclarationName UnqualifiedName;
   NestedNameSpecifier *Qualifier;
   SourceRange QualifierRange;
@@ -1476,8 +1476,7 @@
   const TemplateArgumentLoc *ExplicitTemplateArgs;
   unsigned NumExplicitTemplateArgs;
   
-  DeconstructCallFunction(Fn,
-                          Function, UnqualifiedName, Qualifier, QualifierRange,
+  DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
                           ArgumentDependentLookup, HasExplicitTemplateArgs,
                           ExplicitTemplateArgs, NumExplicitTemplateArgs);
 
@@ -1488,7 +1487,7 @@
   
   // Build an overload candidate set based on the functions we find.
   OverloadCandidateSet CandidateSet;
-  AddOverloadedCallCandidates(Function, UnqualifiedName, 
+  AddOverloadedCallCandidates(Fns, UnqualifiedName, 
                               ArgumentDependentLookup, HasExplicitTemplateArgs,
                               ExplicitTemplateArgs, NumExplicitTemplateArgs,
                               Args, NumArgs,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 45870a1..95a5743 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2601,16 +2601,8 @@
     if (FunctionTemplateDecl *ConversionTemplate
           = Conversion->getDescribedFunctionTemplate())
       ExpectedPrevDecl = ConversionTemplate->getPreviousDeclaration();
-    OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
-    for (OverloadedFunctionDecl::function_iterator
-           Conv = Conversions->function_begin(),
-           ConvEnd = Conversions->function_end();
-         Conv != ConvEnd; ++Conv) {
-      if (*Conv == ExpectedPrevDecl) {
-        *Conv = Conversion;
-        return DeclPtrTy::make(Conversion);
-      }
-    }
+    if (ClassDecl->replaceConversion(ExpectedPrevDecl, Conversion))
+      return DeclPtrTy::make(Conversion);
     assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
   } else if (FunctionTemplateDecl *ConversionTemplate
                = Conversion->getDescribedFunctionTemplate())
@@ -3895,18 +3887,17 @@
       = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
 
     OverloadCandidateSet CandidateSet;
-    OverloadedFunctionDecl *Conversions
+    const UnresolvedSet *Conversions
       = T2RecordDecl->getVisibleConversionFunctions();
-    for (OverloadedFunctionDecl::function_iterator Func
-           = Conversions->function_begin();
-         Func != Conversions->function_end(); ++Func) {
+    for (UnresolvedSet::iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
       FunctionTemplateDecl *ConvTemplate
-        = dyn_cast<FunctionTemplateDecl>(*Func);
+        = dyn_cast<FunctionTemplateDecl>(*I);
       CXXConversionDecl *Conv;
       if (ConvTemplate)
         Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
       else
-        Conv = cast<CXXConversionDecl>(*Func);
+        Conv = cast<CXXConversionDecl>(*I);
       
       // If the conversion function doesn't return a reference type,
       // it can't be considered for this conversion.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7895193..12e0c59 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -417,6 +417,8 @@
 Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
                        bool TypeDependent, bool ValueDependent,
                        const CXXScopeSpec *SS) {
+  assert(!isa<OverloadedFunctionDecl>(D));
+
   if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
     Diag(Loc,
          diag::err_auto_variable_cannot_appear_in_own_initializer)
@@ -688,8 +690,6 @@
   if (Lookup.isAmbiguous())
     return ExprError();
 
-  NamedDecl *D = Lookup.getAsSingleDecl(Context);
-
   // If this reference is in an Objective-C method, then ivar lookup happens as
   // well.
   IdentifierInfo *II = Name.getAsIdentifierInfo();
@@ -699,44 +699,58 @@
     // found a decl, but that decl is outside the current instance method (i.e.
     // a global variable).  In these two cases, we do a lookup for an ivar with
     // this name, if the lookup sucedes, we replace it our current decl.
-    if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
+
+    // FIXME:  we should change lookup to do this.
+
+    // If we're in a class method, we don't normally want to look for
+    // ivars.  But if we don't find anything else, and there's an
+    // ivar, that's an error.
+    bool IsClassMethod = getCurMethodDecl()->isClassMethod();
+
+    bool LookForIvars;
+    if (Lookup.empty())
+      LookForIvars = true;
+    else if (IsClassMethod)
+      LookForIvars = false;
+    else
+      LookForIvars = (Lookup.isSingleResult() &&
+                      Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+
+    if (LookForIvars) {
       ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
       ObjCInterfaceDecl *ClassDeclared;
       if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
-        // Check if referencing a field with __attribute__((deprecated)).
-        if (DiagnoseUseOfDecl(IV, Loc))
-          return ExprError();
+        // Diagnose using an ivar in a class method.
+        if (IsClassMethod)
+           return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
+                            << IV->getDeclName());
 
         // If we're referencing an invalid decl, just return this as a silent
         // error node.  The error diagnostic was already emitted on the decl.
         if (IV->isInvalidDecl())
           return ExprError();
 
-        bool IsClsMethod = getCurMethodDecl()->isClassMethod();
-        // If a class method attemps to use a free standing ivar, this is
-        // an error.
-        if (IsClsMethod && D && !D->isDefinedOutsideFunctionOrMethod())
-           return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method)
-                           << IV->getDeclName());
-        // If a class method uses a global variable, even if an ivar with
-        // same name exists, use the global.
-        if (!IsClsMethod) {
-          if (IV->getAccessControl() == ObjCIvarDecl::Private &&
-              ClassDeclared != IFace)
-           Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
-          // FIXME: This should use a new expr for a direct reference, don't
-          // turn this into Self->ivar, just return a BareIVarExpr or something.
-          IdentifierInfo &II = Context.Idents.get("self");
-          UnqualifiedId SelfName;
-          SelfName.setIdentifier(&II, SourceLocation());          
-          CXXScopeSpec SelfScopeSpec;
-          OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
-                                                        SelfName, false, false);
-          MarkDeclarationReferenced(Loc, IV);
-          return Owned(new (Context)
-                       ObjCIvarRefExpr(IV, IV->getType(), Loc,
-                                       SelfExpr.takeAs<Expr>(), true, true));
-        }
+        // Check if referencing a field with __attribute__((deprecated)).
+        if (DiagnoseUseOfDecl(IV, Loc))
+          return ExprError();
+
+        // Diagnose the use of an ivar outside of the declaring class.
+        if (IV->getAccessControl() == ObjCIvarDecl::Private &&
+            ClassDeclared != IFace)
+          Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName();
+
+        // FIXME: This should use a new expr for a direct reference, don't
+        // turn this into Self->ivar, just return a BareIVarExpr or something.
+        IdentifierInfo &II = Context.Idents.get("self");
+        UnqualifiedId SelfName;
+        SelfName.setIdentifier(&II, SourceLocation());          
+        CXXScopeSpec SelfScopeSpec;
+        OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+                                                      SelfName, false, false);
+        MarkDeclarationReferenced(Loc, IV);
+        return Owned(new (Context)
+                     ObjCIvarRefExpr(IV, IV->getType(), Loc,
+                                     SelfExpr.takeAs<Expr>(), true, true));
       }
     } else if (getCurMethodDecl()->isInstanceMethod()) {
       // We should warn if a local variable hides an ivar.
@@ -749,7 +763,7 @@
       }
     }
     // Needed to implement property "super.method" notation.
-    if (D == 0 && II->isStr("super")) {
+    if (Lookup.empty() && II->isStr("super")) {
       QualType T;
 
       if (getCurMethodDecl()->isInstanceMethod())
@@ -766,26 +780,14 @@
   bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
              HasTrailingLParen;
 
-  if (ADL && D == 0) {
-    // We've seen something of the form
-    //
-    //   identifier(
-    //
-    // and we did not find any entity by the name
-    // "identifier". However, this identifier is still subject to
-    // argument-dependent lookup, so keep track of the name.
-    return Owned(new (Context) UnresolvedFunctionNameExpr(Name,
-                                                          Context.OverloadTy,
-                                                          Loc));
-  }
-
-  if (D == 0) {
+  if (Lookup.empty() && !ADL) {
     // Otherwise, this could be an implicitly declared function reference (legal
     // in C90, extension in C99).
     if (HasTrailingLParen && II &&
-        !getLangOptions().CPlusPlus) // Not in C++.
-      D = ImplicitlyDefineFunction(Loc, *II, S);
-    else {
+        !getLangOptions().CPlusPlus) { // Not in C++.
+      NamedDecl *D = ImplicitlyDefineFunction(Loc, *II, S);
+      if (D) Lookup.addDecl(D);
+    } else {
       // If this name wasn't predeclared and if this is not a function call,
       // diagnose the problem.
       if (SS && !SS->isEmpty())
@@ -801,7 +803,7 @@
     }
   }
 
-  if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+  if (VarDecl *Var = Lookup.getAsSingle<VarDecl>()) {
     // Warn about constructs like:
     //   if (void *X = foo()) { ... } else { X }.
     // In the else block, the pointer is always false.
@@ -824,7 +826,7 @@
         CheckS = CheckS->getParent();
       }
     }
-  } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
+  } else if (FunctionDecl *Func = Lookup.getAsSingle<FunctionDecl>()) {
     if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
       // C99 DR 316 says that, if a function type comes from a
       // function definition (without a prototype), that type is only
@@ -842,8 +844,10 @@
     }
   }
 
-  return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand);
+  return BuildDeclarationNameExpr(SS, Lookup, HasTrailingLParen,
+                                  isAddressOfOperand);
 }
+
 /// \brief Cast member's object to its own class if necessary.
 bool
 Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) {
@@ -887,53 +891,28 @@
   return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
 }
 
-/// \brief Complete semantic analysis for a reference to the given declaration.
-Sema::OwningExprResult
-Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
-                               bool HasTrailingLParen,
-                               const CXXScopeSpec *SS,
-                               bool isAddressOfOperand) {
-  assert(D && "Cannot refer to a NULL declaration");
-  DeclarationName Name = D->getDeclName();
-
-  // If this is an expression of the form &Class::member, don't build an
-  // implicit member ref, because we want a pointer to the member in general,
-  // not any specific instance's member.
-  if (isAddressOfOperand && SS && !SS->isEmpty() && !HasTrailingLParen) {
-    DeclContext *DC = computeDeclContext(*SS);
-    if (D && isa<CXXRecordDecl>(DC)) {
-      QualType DType;
-      if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-        DType = FD->getType().getNonReferenceType();
-      } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
-        DType = Method->getType();
-      } else if (isa<OverloadedFunctionDecl>(D)) {
-        DType = Context.OverloadTy;
-      }
-      // Could be an inner type. That's diagnosed below, so ignore it here.
-      if (!DType.isNull()) {
-        // The pointer is type- and value-dependent if it points into something
-        // dependent.
-        bool Dependent = DC->isDependentContext();
-        return BuildDeclRefExpr(D, DType, Loc, Dependent, Dependent, SS);
-      }
-    }
-  }
+/// Builds an implicit member access expression from the given
+/// unqualified lookup set, which is known to contain only class
+/// members.
+Sema::OwningExprResult BuildImplicitMemberExpr(Sema &S, LookupResult &R,
+                                               const CXXScopeSpec *SS) {
+  NamedDecl *D = R.getAsSingleDecl(S.Context);
+  SourceLocation Loc = R.getNameLoc();
 
   // We may have found a field within an anonymous union or struct
   // (C++ [class.union]).
   // FIXME: This needs to happen post-isImplicitMemberReference?
   if (FieldDecl *FD = dyn_cast<FieldDecl>(D))
     if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
-      return BuildAnonymousStructUnionMemberReference(Loc, FD);
+      return S.BuildAnonymousStructUnionMemberReference(Loc, FD);
 
-  // Cope with an implicit member access in a C++ non-static member function.
-  QualType ThisType, MemberType;
-  if (isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
-    Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
-    MarkDeclarationReferenced(Loc, D);
-    if (PerformObjectMemberConversion(This, D))
-      return ExprError();
+  QualType ThisType;
+  QualType MemberType;
+  if (S.isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
+    Expr *This = new (S.Context) CXXThisExpr(SourceLocation(), ThisType);
+    S.MarkDeclarationReferenced(Loc, D);
+    if (S.PerformObjectMemberConversion(This, D))
+      return S.ExprError();
 
     bool ShouldCheckUse = true;
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
@@ -943,45 +922,196 @@
         ShouldCheckUse = false;
     }
 
-    if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
-      return ExprError();
-    return Owned(BuildMemberExpr(Context, This, true, SS, D,
-                                 Loc, MemberType));
+    if (ShouldCheckUse && S.DiagnoseUseOfDecl(D, Loc))
+      return S.ExprError();
+    return S.Owned(BuildMemberExpr(S.Context, This, true, SS, D,
+                                   Loc, MemberType));
   }
 
-  if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
-    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
-      if (MD->isStatic())
+  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+    if (!Method->isStatic()) {
+      S.Diag(Loc, diag::err_member_call_without_object);
+      return S.ExprError();
+    }
+  }
+
+  if (isa<FieldDecl>(D)) {
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S.CurContext)) {
+      if (MD->isStatic()) {
         // "invalid use of member 'x' in static member function"
-        return ExprError(Diag(Loc,diag::err_invalid_member_use_in_static_method)
-          << FD->getDeclName());
+        S.Diag(Loc,diag::err_invalid_member_use_in_static_method)
+          << D->getDeclName();
+        return S.ExprError();
+      }
     }
 
     // Any other ways we could have found the field in a well-formed
     // program would have been turned into implicit member expressions
     // above.
-    return ExprError(Diag(Loc, diag::err_invalid_non_static_member_use)
-      << FD->getDeclName());
+    S.Diag(Loc, diag::err_invalid_non_static_member_use)
+      << D->getDeclName();
+    return S.ExprError();
   }
 
-  if (isa<TypedefDecl>(D))
-    return ExprError(Diag(Loc, diag::err_unexpected_typedef) << Name);
-  if (isa<ObjCInterfaceDecl>(D))
-    return ExprError(Diag(Loc, diag::err_unexpected_interface) << Name);
-  if (isa<NamespaceDecl>(D))
-    return ExprError(Diag(Loc, diag::err_unexpected_namespace) << Name);
+  return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
+                                    /*ADL*/ false,
+                                    R.begin(), R.end() - R.begin());
+}
+
+static bool UseArgumentDependentLookup(Sema &SemaRef,
+                                       const CXXScopeSpec *SS,
+                                       bool HasTrailingLParen,
+                                       const LookupResult &R) {
+  // Only when used directly as the postfix-expression of a call.
+  if (!HasTrailingLParen)
+    return false;
+
+  // Never if a scope specifier was provided.
+  if (SS && SS->isSet())
+    return false;
+
+  // Only in C++ or ObjC++.
+  if (!SemaRef.getLangOptions().CPlusPlus)
+    return false;
+
+  // Turn off ADL when we find certain kinds of declarations during
+  // normal lookup:
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
+    NamedDecl *D = *I;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a declaration of a class member
+    // Since using decls preserve this property, we check this on the
+    // original decl.
+    if (D->getDeclContext()->isRecord())
+      return false;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a block-scope function declaration that is not a
+    //        using-declaration
+    // NOTE: we also trigger this for function templates (in fact, we
+    // don't check the decl type at all, since all other decl types
+    // turn off ADL anyway).
+    if (isa<UsingShadowDecl>(D))
+      D = cast<UsingShadowDecl>(D)->getTargetDecl();
+    else if (D->getDeclContext()->isFunctionOrMethod())
+      return false;
+
+    // C++0x [basic.lookup.argdep]p3:
+    //     -- a declaration that is neither a function or a function
+    //        template
+    // And also for builtin functions.
+    if (isa<FunctionDecl>(D)) {
+      FunctionDecl *FDecl = cast<FunctionDecl>(D);
+
+      // But also builtin functions.
+      if (FDecl->getBuiltinID() && FDecl->isImplicit())
+        return false;
+    } else if (!isa<FunctionTemplateDecl>(D))
+      return false;
+  }
+
+  return true;
+}
+
+
+/// \brief Complete semantic analysis for a reference to the given
+/// lookup results.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                               LookupResult &R,
+                               bool HasTrailingLParen,
+                               bool isAddressOfOperand) {
+  assert(!R.isAmbiguous() && "results are ambiguous");
+
+  // &SomeClass::foo is an abstract member reference, regardless of
+  // the nature of foo, but &SomeClass::foo(...) is not.
+  bool isAbstractMemberPointer = 
+    (isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty());
+
+  // If we're *not* an abstract member reference, and any of the
+  // results are class members (i.e. they're all class members), then
+  // we make an implicit member reference instead.
+  if (!isAbstractMemberPointer && !R.empty() &&
+      isa<CXXRecordDecl>((*R.begin())->getDeclContext())) {
+    return BuildImplicitMemberExpr(*this, R, SS);
+  }
+
+  assert(R.getResultKind() != LookupResult::FoundUnresolvedValue &&
+         "found UnresolvedUsingValueDecl in non-class scope");
+
+  bool ADL = UseArgumentDependentLookup(*this, SS, HasTrailingLParen, R);
+
+  return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(), ADL,
+                                  R.begin(), R.end() - R.begin());
+}
+
+/// Diagnoses obvious problems with the use of the given declaration
+/// as an expression.  This is only actually called for lookups that
+/// were not overloaded, and it doesn't promise that the declaration
+/// will in fact be used.
+static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
+  if (isa<TypedefDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_typedef) << D->getDeclName();
+    return true;
+  }
+
+  if (isa<ObjCInterfaceDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_interface) << D->getDeclName();
+    return true;
+  }
+
+  if (isa<NamespaceDecl>(D)) {
+    S.Diag(Loc, diag::err_unexpected_namespace) << D->getDeclName();
+    return true;
+  }
+
+  return false;
+}
+
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                               SourceLocation Loc,
+                               DeclarationName Name,
+                               bool NeedsADL,
+                               NamedDecl * const *Decls,
+                               unsigned NumDecls) {
+  if (!NeedsADL && NumDecls == 1)
+    return BuildDeclarationNameExpr(SS, Loc, Decls[0]->getUnderlyingDecl());
+
+  // We only need to check the declaration if there's exactly one
+  // result, because in the overloaded case the results can only be
+  // functions and function templates.
+  if (NumDecls == 1 &&
+      CheckDeclInExpr(*this, Loc, Decls[0]->getUnderlyingDecl()))
+    return ExprError();
+
+  UnresolvedLookupExpr *ULE
+    = UnresolvedLookupExpr::Create(Context,
+                    SS ? (NestedNameSpecifier *)SS->getScopeRep() : 0,
+                                   SS ? SS->getRange() : SourceRange(), 
+                                   Name, Loc, NeedsADL);
+  for (unsigned I = 0; I != NumDecls; ++I)
+    ULE->addDecl(Decls[I]);
+
+  return Owned(ULE);
+}
+                               
+
+/// \brief Complete semantic analysis for a reference to the given declaration.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
+                               SourceLocation Loc, NamedDecl *D) {
+  assert(D && "Cannot refer to a NULL declaration");
+  DeclarationName Name = D->getDeclName();
+
+  if (CheckDeclInExpr(*this, Loc, D))
+    return ExprError();
 
   // Make the DeclRefExpr or BlockDeclRefExpr for the decl.
-  if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
-    return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc,
-                           false, false, SS);
-  else if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
+  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
     return BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
                             false, false, SS);
-  else if (UnresolvedUsingValueDecl *UD = dyn_cast<UnresolvedUsingValueDecl>(D))
-    return BuildDeclRefExpr(UD, Context.DependentTy, Loc,
-                            /*TypeDependent=*/true,
-                            /*ValueDependent=*/true, SS);
 
   ValueDecl *VD = cast<ValueDecl>(D);
 
@@ -989,9 +1119,7 @@
   // this check when we're going to perform argument-dependent lookup
   // on this function name, because this might not be the function
   // that overload resolution actually selects.
-  bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
-             HasTrailingLParen;
-  if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
+  if (DiagnoseUseOfDecl(VD, Loc))
     return ExprError();
 
   // Only create DeclRefExpr's for valid Decl's.
@@ -1038,9 +1166,8 @@
       TypeDependent = true;
     //     - a nested-name-specifier that contains a class-name that
     //       names a dependent type.
-    else if (SS && !SS->isEmpty()) {
-      for (DeclContext *DC = computeDeclContext(*SS);
-           DC; DC = DC->getParent()) {
+    else {
+      for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
         // FIXME: could stop early at namespace scope.
         if (DC->isRecord()) {
           CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
@@ -2557,7 +2684,7 @@
 /// whether argument-dependent lookup is available, whether it has explicit
 /// template arguments, etc.
 void Sema::DeconstructCallFunction(Expr *FnExpr,
-                                   NamedDecl *&Function,
+                                   llvm::SmallVectorImpl<NamedDecl*> &Fns,
                                    DeclarationName &Name,
                                    NestedNameSpecifier *&Qualifier,
                                    SourceRange &QualifierRange,
@@ -2566,7 +2693,6 @@
                            const TemplateArgumentLoc *&ExplicitTemplateArgs,
                                    unsigned &NumExplicitTemplateArgs) {
   // Set defaults for all of the output parameters.
-  Function = 0;
   Name = DeclarationName();
   Qualifier = 0;
   QualifierRange = SourceRange();
@@ -2589,21 +2715,29 @@
                == UnaryOperator::AddrOf) {
       FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
     } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
-      Function = dyn_cast<NamedDecl>(DRExpr->getDecl());
-      if ((Qualifier = DRExpr->getQualifier())) {
-        ArgumentDependentLookup = false;
+      Fns.push_back(cast<NamedDecl>(DRExpr->getDecl()));
+      ArgumentDependentLookup = false;
+      if ((Qualifier = DRExpr->getQualifier()))
         QualifierRange = DRExpr->getQualifierRange();
-      }      
       break;
-    } else if (UnresolvedFunctionNameExpr *DepName
-               = dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
-      Name = DepName->getName();
+    } else if (UnresolvedLookupExpr *UnresLookup
+               = dyn_cast<UnresolvedLookupExpr>(FnExpr)) {
+      Name = UnresLookup->getName();
+      Fns.append(UnresLookup->decls_begin(), UnresLookup->decls_end());
+      ArgumentDependentLookup = UnresLookup->requiresADL();
+      if ((Qualifier = UnresLookup->getQualifier()))
+        QualifierRange = UnresLookup->getQualifierRange();
       break;
     } else if (TemplateIdRefExpr *TemplateIdRef
                = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
-      Function = TemplateIdRef->getTemplateName().getAsTemplateDecl();
-      if (!Function)
-        Function = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
+      if (NamedDecl *Function
+          = TemplateIdRef->getTemplateName().getAsTemplateDecl())
+        Fns.push_back(Function);
+      else {
+        OverloadedFunctionDecl *Overload
+          = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
+        Fns.append(Overload->function_begin(), Overload->function_end());
+      }
       HasExplicitTemplateArguments = true;
       ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
       NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
@@ -2653,9 +2787,6 @@
   Expr *Fn = fn.takeAs<Expr>();
   Expr **Args = reinterpret_cast<Expr**>(args.release());
   assert(Fn && "no function call expression");
-  FunctionDecl *FDecl = NULL;
-  NamedDecl *NDecl = NULL;
-  DeclarationName UnqualifiedName;
 
   if (getLangOptions().CPlusPlus) {
     // If this is a pseudo-destructor expression, build the call immediately.
@@ -2742,39 +2873,43 @@
   // If we're directly calling a function, get the appropriate declaration.
   // Also, in C++, keep track of whether we should perform argument-dependent
   // lookup and whether there were any explicitly-specified template arguments.
+  llvm::SmallVector<NamedDecl*,8> Fns;
+  DeclarationName UnqualifiedName;
   bool ADL = true;
   bool HasExplicitTemplateArgs = 0;
   const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
   unsigned NumExplicitTemplateArgs = 0;
   NestedNameSpecifier *Qualifier = 0;
   SourceRange QualifierRange;
-  DeconstructCallFunction(Fn, NDecl, UnqualifiedName, Qualifier, QualifierRange,
+  DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
                           ADL,HasExplicitTemplateArgs, ExplicitTemplateArgs,
                           NumExplicitTemplateArgs);
 
-  OverloadedFunctionDecl *Ovl = 0;
+  NamedDecl *NDecl = 0; // the specific declaration we're calling, if applicable
+  FunctionDecl *FDecl = 0; // same, if it's a function or function template
   FunctionTemplateDecl *FunctionTemplate = 0;
-  if (NDecl) {
+
+  if (Fns.size() == 1) {
+    NDecl = Fns[0];
     FDecl = dyn_cast<FunctionDecl>(NDecl);
     if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
       FDecl = FunctionTemplate->getTemplatedDecl();
     else
       FDecl = dyn_cast<FunctionDecl>(NDecl);
-    Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl);
   }
 
-  if (Ovl || FunctionTemplate ||
+  if (Fns.size() > 1 || FunctionTemplate ||
       (getLangOptions().CPlusPlus && (FDecl || UnqualifiedName))) {
     // We don't perform ADL for implicit declarations of builtins.
     if (FDecl && FDecl->getBuiltinID() && FDecl->isImplicit())
-      ADL = false;
+      assert(!ADL); // this should be guaranteed earlier
 
     // We don't perform ADL in C.
     if (!getLangOptions().CPlusPlus)
-      ADL = false;
+      assert(!ADL); // ditto
 
-    if (Ovl || FunctionTemplate || ADL) {
-      FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName,
+    if (Fns.size() > 1 || FunctionTemplate || ADL) {
+      FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName,
                                       HasExplicitTemplateArgs,
                                       ExplicitTemplateArgs,
                                       NumExplicitTemplateArgs,
@@ -2784,6 +2919,8 @@
         return ExprError();
 
       Fn = FixOverloadedFunctionReference(Fn, FDecl);
+
+      NDecl = FDecl;
     }
   }
 
@@ -5123,6 +5260,8 @@
     // FIXME: Can LHS ever be null here?
     if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
       return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
+  } else if (isa<UnresolvedLookupExpr>(op)) {
+    return Context.OverloadTy;
   } else if (dcl) { // C99 6.5.3.2p1
     // We have an lvalue with a decl. Make sure the decl is not declared
     // with the register storage-class specifier.
@@ -5132,8 +5271,7 @@
           << "register variable" << op->getSourceRange();
         return QualType();
       }
-    } else if (isa<OverloadedFunctionDecl>(dcl) ||
-               isa<FunctionTemplateDecl>(dcl)) {
+    } else if (isa<FunctionTemplateDecl>(dcl)) {
       return Context.OverloadTy;
     } else if (FieldDecl *FD = dyn_cast<FieldDecl>(dcl)) {
       // Okay: we can take the address of a field.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index be9375c..790c849 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -855,18 +855,15 @@
     if (const RecordType *Record = Type->getAs<RecordType>()) {
       llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
-      OverloadedFunctionDecl *Conversions = 
-        RD->getVisibleConversionFunctions();
+      const UnresolvedSet *Conversions = RD->getVisibleConversionFunctions();
       
-      for (OverloadedFunctionDecl::function_iterator
-             Func = Conversions->function_begin(),
-             FuncEnd = Conversions->function_end();
-           Func != FuncEnd; ++Func) {
+      for (UnresolvedSet::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
         // Skip over templated conversion functions; they aren't considered.
-        if (isa<FunctionTemplateDecl>(*Func))
+        if (isa<FunctionTemplateDecl>(*I))
           continue;
         
-        CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
+        CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
         
         QualType ConvType = Conv->getConversionType().getNonReferenceType();
         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
@@ -2310,6 +2307,9 @@
       MemberType
         = Context.getQualifiedType(MemberType,
                            Qualifiers::fromCVRMask(MD->getTypeQualifiers()));
+  } else if (isa<UnresolvedUsingValueDecl>(D)) {
+    Ctx = D->getDeclContext();
+    MemberType = Context.DependentTy;
   } else {
     for (OverloadIterator Ovl(D), OvlEnd; Ovl != OvlEnd; ++Ovl) {
       CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 1957d7f..99f9f55 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1525,33 +1525,29 @@
     // in which the function or function template is defined and the
     // classes and namespaces associated with its (non-dependent)
     // parameter types and return type.
-    DeclRefExpr *DRE = 0;
-    TemplateIdRefExpr *TIRE = 0;
     Arg = Arg->IgnoreParens();
-    if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) {
-      if (unaryOp->getOpcode() == UnaryOperator::AddrOf) {
-        DRE = dyn_cast<DeclRefExpr>(unaryOp->getSubExpr());
-        TIRE = dyn_cast<TemplateIdRefExpr>(unaryOp->getSubExpr());
-      }
-    } else {
-      DRE = dyn_cast<DeclRefExpr>(Arg);
-      TIRE = dyn_cast<TemplateIdRefExpr>(Arg);
-    }
+    if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
+      if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+        Arg = unaryOp->getSubExpr();
 
-    OverloadedFunctionDecl *Ovl = 0;
-    if (DRE)
-      Ovl = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
-    else if (TIRE)
-      Ovl = TIRE->getTemplateName().getAsOverloadedFunctionDecl();
-    if (!Ovl)
+    // TODO: avoid the copies.  This should be easy when the cases
+    // share a storage implementation.
+    llvm::SmallVector<NamedDecl*, 8> Functions;
+
+    if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg))
+      Functions.append(ULE->decls_begin(), ULE->decls_end());
+    else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(Arg)) {
+      TemplateName TName = TIRE->getTemplateName();
+      OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl();
+      Functions.append(Ovl->function_begin(), Ovl->function_end());
+    } else
       continue;
 
-    for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
-                                                FuncEnd = Ovl->function_end();
-         Func != FuncEnd; ++Func) {
-      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*Func);
+    for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(),
+           E = Functions.end(); I != E; ++I) {
+      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I);
       if (!FDecl)
-        FDecl = cast<FunctionTemplateDecl>(*Func)->getTemplatedDecl();
+        FDecl = cast<FunctionTemplateDecl>(*I)->getTemplatedDecl();
 
       // Add the namespace in which this function was defined. Note
       // that, if this is a member function, we do *not* consider the
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8d47960..4572911 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1353,18 +1353,6 @@
   return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
 }
 
-/// \brief Given a function template or function, extract the function template
-/// declaration (if any) and the underlying function declaration.
-template<typename T>
-static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function,
-                                   FunctionTemplateDecl *&FunctionTemplate) {
-  FunctionTemplate = dyn_cast<FunctionTemplateDecl>(Orig);
-  if (FunctionTemplate)
-    Function = cast<T>(FunctionTemplate->getTemplatedDecl());
-  else
-    Function = cast<T>(Orig);
-}
-
 /// Determines whether there is a user-defined conversion sequence
 /// (C++ [over.ics.user]) that converts expression From to the type
 /// ToType. If such a conversion exists, User will contain the
@@ -1455,18 +1443,16 @@
     if (CXXRecordDecl *FromRecordDecl
          = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
       // Add all of the conversion functions as candidates.
-      OverloadedFunctionDecl *Conversions
+      const UnresolvedSet *Conversions
         = FromRecordDecl->getVisibleConversionFunctions();
-      for (OverloadedFunctionDecl::function_iterator Func
-             = Conversions->function_begin();
-           Func != Conversions->function_end(); ++Func) {
+      for (UnresolvedSet::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
         CXXConversionDecl *Conv;
         FunctionTemplateDecl *ConvTemplate;
-        GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
-        if (ConvTemplate)
+        if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(*I)))
           Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
         else
-          Conv = dyn_cast<CXXConversionDecl>(*Func);
+          Conv = dyn_cast<CXXConversionDecl>(*I);
 
         if (AllowExplicit || !Conv->isExplicit()) {
           if (ConvTemplate)
@@ -3144,20 +3130,17 @@
       }
 
       CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
-      OverloadedFunctionDecl *Conversions
+      const UnresolvedSet *Conversions
         = ClassDecl->getVisibleConversionFunctions();
-      for (OverloadedFunctionDecl::function_iterator Func
-             = Conversions->function_begin();
-           Func != Conversions->function_end(); ++Func) {
-        CXXConversionDecl *Conv;
-        FunctionTemplateDecl *ConvTemplate;
-        GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
+      for (UnresolvedSet::iterator I = Conversions->begin(),
+             E = Conversions->end(); I != E; ++I) {
 
         // Skip conversion function templates; they don't tell us anything
         // about which builtin types we can convert to.
-        if (ConvTemplate)
+        if (isa<FunctionTemplateDecl>(*I))
           continue;
 
+        CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
         if (AllowExplicitConversions || !Conv->isExplicit()) {
           AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false, 
                                 VisibleQuals);
@@ -3211,13 +3194,12 @@
     }
     
     CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
-    OverloadedFunctionDecl *Conversions =
+    const UnresolvedSet *Conversions =
       ClassDecl->getVisibleConversionFunctions();
     
-    for (OverloadedFunctionDecl::function_iterator Func
-         = Conversions->function_begin();
-         Func != Conversions->function_end(); ++Func) {
-      if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*Func)) {
+    for (UnresolvedSet::iterator I = Conversions->begin(),
+           E = Conversions->end(); I != E; ++I) {
+      if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
         QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
         if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>())
           CanTy = ResTypeRef->getPointeeType();
@@ -4336,7 +4318,6 @@
     return 0;
 
   // Find the actual overloaded function declaration.
-  OverloadedFunctionDecl *Ovl = 0;
 
   // C++ [over.over]p1:
   //   [...] [Note: any redundant set of parentheses surrounding the
@@ -4354,15 +4335,21 @@
   bool HasExplicitTemplateArgs = false;
   const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
   unsigned NumExplicitTemplateArgs = 0;
+
+  llvm::SmallVector<NamedDecl*,8> Fns;
   
   // Try to dig out the overloaded function.
+  OverloadedFunctionDecl *Ovl = 0;
   FunctionTemplateDecl *FunctionTemplate = 0;
   if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr)) {
-    Ovl = dyn_cast<OverloadedFunctionDecl>(DR->getDecl());
+    assert(!isa<OverloadedFunctionDecl>(DR->getDecl()));
     FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl());
     HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList();
     ExplicitTemplateArgs = DR->getTemplateArgs();
     NumExplicitTemplateArgs = DR->getNumTemplateArgs();
+  } else if (UnresolvedLookupExpr *UL
+               = dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
+    Fns.append(UL->decls_begin(), UL->decls_end());
   } else if (MemberExpr *ME = dyn_cast<MemberExpr>(OvlExpr)) {
     Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl());
     FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl());
@@ -4379,23 +4366,20 @@
     ExplicitTemplateArgs = TIRE->getTemplateArgs();
     NumExplicitTemplateArgs = TIRE->getNumTemplateArgs();
   }
-  
-  // If there's no overloaded function declaration or function template,
-  // we're done.
-  if (!Ovl && !FunctionTemplate)
-    return 0;
 
-  OverloadIterator Fun;
-  if (Ovl)
-    Fun = Ovl;
-  else
-    Fun = FunctionTemplate;
+  if (Ovl) Fns.append(Ovl->function_begin(), Ovl->function_end());
+  if (FunctionTemplate) Fns.push_back(FunctionTemplate);
+
+  // If we didn't actually find anything, we're done.
+  if (Fns.empty())
+    return 0;
 
   // Look through all of the overloaded functions, searching for one
   // whose type matches exactly.
   llvm::SmallPtrSet<FunctionDecl *, 4> Matches;
   bool FoundNonTemplateFunction = false;
-  for (OverloadIterator FunEnd; Fun != FunEnd; ++Fun) {
+  for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
+         E = Fns.end(); I != E; ++I) {
     // C++ [over.over]p3:
     //   Non-member functions and static member functions match
     //   targets of type "pointer-to-function" or "reference-to-function."
@@ -4404,7 +4388,7 @@
     // Note that according to DR 247, the containing class does not matter.
 
     if (FunctionTemplateDecl *FunctionTemplate
-          = dyn_cast<FunctionTemplateDecl>(*Fun)) {
+          = dyn_cast<FunctionTemplateDecl>(*I)) {
       if (CXXMethodDecl *Method
             = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
         // Skip non-static function templates when converting to pointer, and
@@ -4438,9 +4422,11 @@
         Matches.insert(
                 cast<FunctionDecl>(Specialization->getCanonicalDecl()));
       }
+
+      continue;
     }
 
-    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Fun)) {
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) {
       // Skip non-static functions when converting to pointer, and static
       // when converting to member pointer.
       if (Method->isStatic() == IsMember)
@@ -4452,9 +4438,9 @@
     } else if (IsMember)
       continue;
 
-    if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Fun)) {
+    if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*I)) {
       if (FunctionType == Context.getCanonicalType(FunDecl->getType())) {
-        Matches.insert(cast<FunctionDecl>(Fun->getCanonicalDecl()));
+        Matches.insert(cast<FunctionDecl>(FunDecl->getCanonicalDecl()));
         FoundNonTemplateFunction = true;
       }
     }
@@ -4522,7 +4508,7 @@
 
 /// \brief Add a single candidate to the overload set.
 static void AddOverloadedCallCandidate(Sema &S,
-                                       AnyFunctionDecl Callee,
+                                       NamedDecl *Callee,
                                        bool &ArgumentDependentLookup,
                                        bool HasExplicitTemplateArgs,
                              const TemplateArgumentLoc *ExplicitTemplateArgs,
@@ -4530,6 +4516,9 @@
                                        Expr **Args, unsigned NumArgs,
                                        OverloadCandidateSet &CandidateSet,
                                        bool PartialOverloading) {
+  if (isa<UsingShadowDecl>(Callee))
+    Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
+
   if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
     assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
     S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false,
@@ -4539,21 +4528,28 @@
         Func->getDeclContext()->isFunctionOrMethod())
       ArgumentDependentLookup = false;
     return;
-  }  
-  
-  FunctionTemplateDecl *FuncTemplate = cast<FunctionTemplateDecl>(Callee);
-  S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
-                                 ExplicitTemplateArgs,
-                                 NumExplicitTemplateArgs,
-                                 Args, NumArgs, CandidateSet);
-  
-  if (FuncTemplate->getDeclContext()->isRecord())
-    ArgumentDependentLookup = false;
+  }
+
+  if (FunctionTemplateDecl *FuncTemplate
+      = dyn_cast<FunctionTemplateDecl>(Callee)) {
+    S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
+                                   ExplicitTemplateArgs,
+                                   NumExplicitTemplateArgs,
+                                   Args, NumArgs, CandidateSet);
+
+    if (FuncTemplate->getDeclContext()->isRecord())
+      ArgumentDependentLookup = false;
+    return;
+  }
+
+  assert(false && "unhandled case in overloaded call candidate");
+
+  // do nothing?
 }
   
 /// \brief Add the overload candidates named by callee and/or found by argument
 /// dependent lookup to the given overload set.
-void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
+void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns,
                                        DeclarationName &UnqualifiedName,
                                        bool &ArgumentDependentLookup,
                                        bool HasExplicitTemplateArgs,
@@ -4562,11 +4558,11 @@
                                        Expr **Args, unsigned NumArgs,
                                        OverloadCandidateSet &CandidateSet,
                                        bool PartialOverloading) {
-  // Add the functions denoted by Callee to the set of candidate
-  // functions. While we're doing so, track whether argument-dependent
-  // lookup still applies, per:
+
+#ifndef NDEBUG
+  // Verify that ArgumentDependentLookup is consistent with the rules
+  // in C++0x [basic.lookup.argdep]p3:
   //
-  // C++0x [basic.lookup.argdep]p3:
   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
   //   and let Y be the lookup set produced by argument dependent
   //   lookup (defined as follows). If X contains
@@ -4574,38 +4570,31 @@
   //     -- a declaration of a class member, or
   //
   //     -- a block-scope function declaration that is not a
-  //        using-declaration (FIXME: check for using declaration), or
+  //        using-declaration, or
   //
   //     -- a declaration that is neither a function or a function
   //        template
   //
   //   then Y is empty.
-  if (!Callee) {
-    // Nothing to do.
-  } else if (OverloadedFunctionDecl *Ovl
-               = dyn_cast<OverloadedFunctionDecl>(Callee)) {
-    for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
-                                                FuncEnd = Ovl->function_end();
-         Func != FuncEnd; ++Func)
-      AddOverloadedCallCandidate(*this, *Func, ArgumentDependentLookup,
-                                 HasExplicitTemplateArgs,
-                                 ExplicitTemplateArgs, NumExplicitTemplateArgs,
-                                 Args, NumArgs, CandidateSet, 
-                                 PartialOverloading);
-  } else if (isa<FunctionDecl>(Callee) || isa<FunctionTemplateDecl>(Callee))
-    AddOverloadedCallCandidate(*this, 
-                               AnyFunctionDecl::getFromNamedDecl(Callee),
-                               ArgumentDependentLookup,
+
+  if (ArgumentDependentLookup) {
+    for (unsigned I = 0; I < Fns.size(); ++I) {
+      assert(!Fns[I]->getDeclContext()->isRecord());
+      assert(isa<UsingShadowDecl>(Fns[I]) ||
+             !Fns[I]->getDeclContext()->isFunctionOrMethod());
+      assert(Fns[I]->getUnderlyingDecl()->isFunctionOrFunctionTemplate());
+    }
+  }
+#endif
+
+  for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
+         E = Fns.end(); I != E; ++I)
+    AddOverloadedCallCandidate(*this, *I, ArgumentDependentLookup,
                                HasExplicitTemplateArgs,
                                ExplicitTemplateArgs, NumExplicitTemplateArgs,
-                               Args, NumArgs, CandidateSet,
+                               Args, NumArgs, CandidateSet, 
                                PartialOverloading);
-  // FIXME: assert isa<FunctionDecl> || isa<FunctionTemplateDecl> rather than
-  // checking dynamically.
-  
-  if (Callee)
-    UnqualifiedName = Callee->getDeclName();
-  
+
   if (ArgumentDependentLookup)
     AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
                                          HasExplicitTemplateArgs,
@@ -4622,7 +4611,8 @@
 /// the function declaration produced by overload
 /// resolution. Otherwise, emits diagnostics, deletes all of the
 /// arguments and Fn, and returns NULL.
-FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
+FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn,
+                                     llvm::SmallVectorImpl<NamedDecl*> &Fns,
                                             DeclarationName UnqualifiedName,
                                             bool HasExplicitTemplateArgs,
                              const TemplateArgumentLoc *ExplicitTemplateArgs,
@@ -4636,7 +4626,7 @@
 
   // Add the functions denoted by Callee to the set of candidate
   // functions. 
-  AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup,
+  AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup,
                               HasExplicitTemplateArgs, ExplicitTemplateArgs,
                               NumExplicitTemplateArgs, Args, NumArgs, 
                               CandidateSet);
@@ -4716,15 +4706,13 @@
   }
 
   if (Input->isTypeDependent()) {
-    OverloadedFunctionDecl *Overloads
-      = OverloadedFunctionDecl::Create(Context, CurContext, OpName);
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
+                                     /*ADL*/ true);
     for (FunctionSet::iterator Func = Functions.begin(),
                             FuncEnd = Functions.end();
          Func != FuncEnd; ++Func)
-      Overloads->addOverload(*Func);
-
-    DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
-                                                OpLoc, false, false);
+      Fn->addDecl(*Func);
 
     input.release();
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
@@ -4874,15 +4862,14 @@
                                                         OpLoc));
     }
     
-    OverloadedFunctionDecl *Overloads
-      = OverloadedFunctionDecl::Create(Context, CurContext, OpName);
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
+                                     /* ADL */ true);
+                                     
     for (FunctionSet::iterator Func = Functions.begin(),
                             FuncEnd = Functions.end();
          Func != FuncEnd; ++Func)
-      Overloads->addOverload(*Func);
-
-    DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
-                                                OpLoc, false, false);
+      Fn->addDecl(*Func);
 
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
                                                    Args, 2,
@@ -5040,11 +5027,10 @@
   // expression.
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
 
-    OverloadedFunctionDecl *Overloads
-      = OverloadedFunctionDecl::Create(Context, CurContext, OpName);
-
-    DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
-                                                LLoc, false, false);
+    UnresolvedLookupExpr *Fn
+      = UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, LLoc,
+                                     /*ADL*/ true);
+    // Can't add an actual overloads yet
 
     Base.release();
     Idx.release();
@@ -5334,21 +5320,17 @@
   //   accessible base class provided the function is not hidden
   //   within T by another intervening declaration.
   // FIXME: Look in base classes for more conversion operators!
-  OverloadedFunctionDecl *Conversions
+  const UnresolvedSet *Conversions
     = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
-  for (OverloadedFunctionDecl::function_iterator
-         Func = Conversions->function_begin(),
-         FuncEnd = Conversions->function_end();
-       Func != FuncEnd; ++Func) {
-    CXXConversionDecl *Conv;
-    FunctionTemplateDecl *ConvTemplate;
-    GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
-
+  for (UnresolvedSet::iterator I = Conversions->begin(),
+         E = Conversions->end(); I != E; ++I) {
     // Skip over templated conversion functions; they aren't
     // surrogates.
-    if (ConvTemplate)
+    if (isa<FunctionTemplateDecl>(*I))
       continue;
 
+    CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
+
     // Strip the reference type (if any) and then the pointer type (if
     // any) to get down to what might be a function type.
     QualType ConvType = Conv->getConversionType().getNonReferenceType();
@@ -5637,38 +5619,32 @@
       if (Method->isStatic()) {
         // Do nothing: static member functions aren't any different
         // from non-member functions.
-      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr())) {
-        if (DRE->getQualifier()) {
-          // We have taken the address of a pointer to member
-          // function. Perform the computation here so that we get the
-          // appropriate pointer to member type.
-          QualType ClassType
-            = Context.getTypeDeclType(
-                                  cast<RecordDecl>(Method->getDeclContext()));
-          QualType MemPtrType
-            = Context.getMemberPointerType(Fn->getType(), 
-                                           ClassType.getTypePtr());
+      } else {
+        // Fix the sub expression, which really has to be one of:
+        //   * a DeclRefExpr holding a member function template
+        //   * a TemplateIdRefExpr, also holding a member function template
+        //   * an UnresolvedLookupExpr holding an overloaded member function
+        Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
+        if (SubExpr == UnOp->getSubExpr())
+          return UnOp->Retain();
 
-          DeclRefExpr *NewDRE 
-            = DeclRefExpr::Create(Context,
-                                  DRE->getQualifier(),
-                                  DRE->getQualifierRange(),
-                                  Fn,
-                                  DRE->getLocation(),
-                                  DRE->hasExplicitTemplateArgumentList(),
-                                  DRE->getLAngleLoc(),
-                                  DRE->getTemplateArgs(),
-                                  DRE->getNumTemplateArgs(),
-                                  DRE->getRAngleLoc(),
-                                  Fn->getType(),
-                                  DRE->isTypeDependent(),
-                                  DRE->isValueDependent());
-          
-          return new (Context) UnaryOperator(NewDRE, UnaryOperator::AddrOf,
-                                             MemPtrType,
-                                             UnOp->getOperatorLoc());
-        }
+        assert(isa<DeclRefExpr>(SubExpr)
+               && "fixed to something other than a decl ref");
+        assert(cast<DeclRefExpr>(SubExpr)->getQualifier()
+               && "fixed to a member ref with no nested name qualifier");
+
+        // We have taken the address of a pointer to member
+        // function. Perform the computation here so that we get the
+        // appropriate pointer to member type.
+        QualType ClassType
+          = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
+        QualType MemPtrType
+          = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
+
+        return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+                                           MemPtrType, UnOp->getOperatorLoc());
       }
+
       // FIXME: TemplateIdRefExpr referring to a member function template
       // specialization!
     }
@@ -5682,8 +5658,7 @@
   }
   
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-    assert((isa<OverloadedFunctionDecl>(DRE->getDecl()) ||
-            isa<FunctionTemplateDecl>(DRE->getDecl()) ||
+    assert((isa<FunctionTemplateDecl>(DRE->getDecl()) ||
             isa<FunctionDecl>(DRE->getDecl())) &&
            "Expected function or function template");
     return DeclRefExpr::Create(Context,
@@ -5700,6 +5675,18 @@
                                DRE->isTypeDependent(),
                                DRE->isValueDependent());
   } 
+
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
+    return DeclRefExpr::Create(Context,
+                               ULE->getQualifier(),
+                               ULE->getQualifierRange(),
+                               Fn,
+                               ULE->getNameLoc(),
+                               Fn->getType(),
+                               Fn->getType()->isDependentType(),
+                               false);
+  }
+
   
   if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {
     assert((isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) ||
@@ -5736,13 +5723,6 @@
                                /*FIXME?*/false, /*FIXME?*/false);    
   } 
   
-  if (isa<UnresolvedFunctionNameExpr>(E))
-    return DeclRefExpr::Create(Context, 
-                               /*Qualifier=*/0,
-                               /*QualifierRange=*/SourceRange(),
-                               Fn, E->getLocStart(),
-                               Fn->getType(), false, false);
-  
   assert(false && "Invalid reference to overloaded function");
   return E->Retain();
 }
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 58fe59e..c61481f 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -556,6 +556,9 @@
                                                    bool isAddressOfOperand);
     Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E,
                                                 bool isAddressOfOperand);
+    Sema::OwningExprResult TransformUnresolvedLookupExpr(
+                                                UnresolvedLookupExpr *E,
+                                                bool isAddressOfOperand);
 
     Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
                                                       bool isAddressOfOperand);
@@ -694,6 +697,55 @@
 }
 
 Sema::OwningExprResult
+TemplateInstantiator::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
+                                                    bool isAddressOfOperand) {
+  llvm::SmallVector<NamedDecl*, 16> InstDecls;
+
+  bool HasUnresolved = false;
+
+  for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
+         E = Old->decls_end(); I != E; ++I) {
+    NamedDecl *InstD = SemaRef.FindInstantiatedDecl(*I, TemplateArgs);
+    if (!InstD)
+      return SemaRef.ExprError();
+
+    // Expand using declarations.
+    if (isa<UsingDecl>(InstD)) {
+      UsingDecl *UD = cast<UsingDecl>(InstD);
+      for (UsingDecl::shadow_iterator UI = UD->shadow_begin(),
+             UE = UD->shadow_end(); UI != UE; ++UI) {
+        UsingShadowDecl *Shadow = *UI;
+        if (isa<UnresolvedUsingValueDecl>(Shadow->getUnderlyingDecl()))
+          HasUnresolved = true;
+        InstDecls.push_back(Shadow);
+      }
+
+      continue;
+    }
+
+    if (isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl()))
+      HasUnresolved = true;
+    InstDecls.push_back(InstD);
+  }
+
+  CXXScopeSpec SS;
+  NestedNameSpecifier *Qualifier = 0;
+  if (Old->getQualifier()) {
+    Qualifier = TransformNestedNameSpecifier(Old->getQualifier(),
+                                             Old->getQualifierRange());
+    if (!Qualifier)
+      return SemaRef.ExprError();
+    
+    SS.setScopeRep(Qualifier);
+    SS.setRange(Old->getQualifierRange());
+  }
+
+  return SemaRef.BuildDeclarationNameExpr(&SS, Old->getNameLoc(),
+                                          Old->getName(), Old->requiresADL(),
+                                          InstDecls.data(), InstDecls.size());
+}
+
+Sema::OwningExprResult
 TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E,
                                            bool isAddressOfOperand) {
   // FIXME: Clean this up a bit
@@ -788,46 +840,7 @@
   if (!InstD)
     return SemaRef.ExprError();
 
-  // Flatten using declarations into their shadow declarations.
-  if (isa<UsingDecl>(InstD)) {
-    UsingDecl *UD = cast<UsingDecl>(InstD);
-
-    bool HasNonFunction = false;
-
-    llvm::SmallVector<NamedDecl*, 8> Decls;
-    for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
-                                    E = UD->shadow_end(); I != E; ++I) {
-      NamedDecl *TD = (*I)->getTargetDecl();
-      if (!TD->isFunctionOrFunctionTemplate())
-        HasNonFunction = true;
-
-      Decls.push_back(TD);
-    }
-
-    if (Decls.empty())
-      return SemaRef.ExprError();
-
-    if (Decls.size() == 1)
-      InstD = Decls[0];
-    else if (!HasNonFunction) {
-      OverloadedFunctionDecl *OFD
-        = OverloadedFunctionDecl::Create(SemaRef.Context,
-                                         UD->getDeclContext(),
-                                         UD->getDeclName());
-      for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Decls.begin(),
-                                                E = Decls.end(); I != E; ++I)
-        if (isa<FunctionDecl>(*I))
-          OFD->addOverload(cast<FunctionDecl>(*I));
-        else
-          OFD->addOverload(cast<FunctionTemplateDecl>(*I));
-
-      InstD = OFD;
-    } else {
-      // FIXME
-      assert(false && "using declaration resolved to mixed set");
-      return SemaRef.ExprError();
-    }
-  }
+  assert(!isa<UsingDecl>(InstD) && "decl ref instantiated to UsingDecl");
 
   CXXScopeSpec SS;
   NestedNameSpecifier *Qualifier = 0;
@@ -841,10 +854,7 @@
     SS.setRange(E->getQualifierRange());
   }
   
-  return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD,
-                                          /*FIXME:*/false,
-                                          &SS,
-                                          isAddressOfOperand);
+  return SemaRef.BuildDeclarationNameExpr(&SS, E->getLocation(), InstD);
 }
 
 Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 5018b15..101690a 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -4558,10 +4558,10 @@
 
 template<typename Derived>
 Sema::OwningExprResult
-TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
-                                                  UnresolvedFunctionNameExpr *E,
+TreeTransform<Derived>::TransformUnresolvedLookupExpr(
+                                                  UnresolvedLookupExpr *E,
                                                   bool isAddressOfOperand) {
-  // There is no transformation we can apply to an unresolved function name.
+  // There is no transformation we can apply to an unresolved lookup.
   return SemaRef.Owned(E->Retain());
 }
 
@@ -5384,8 +5384,7 @@
                                                    ExprArg Second) {
   Expr *FirstExpr = (Expr *)First.get();
   Expr *SecondExpr = (Expr *)Second.get();
-  DeclRefExpr *DRE
-    = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
+  Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
   bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
   // Determine whether this should be a builtin operation.
@@ -5393,7 +5392,7 @@
     if (!FirstExpr->getType()->isOverloadableType() &&
         !SecondExpr->getType()->isOverloadableType())
       return getSema().CreateBuiltinArraySubscriptExpr(move(First),
-                                                       DRE->getLocStart(),
+                                                 CalleeExpr->getLocStart(),
                                                        move(Second), OpLoc);
   } else if (Op == OO_Arrow) {
     // -> is never a builtin operation.
@@ -5428,10 +5427,18 @@
   // used during overload resolution.
   Sema::FunctionSet Functions;
 
-  // FIXME: Do we have to check
-  // IsAcceptableNonMemberOperatorCandidate for each of these?
-  for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
-    Functions.insert(*F);
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
+    assert(ULE->requiresADL());
+
+    // FIXME: Do we have to check
+    // IsAcceptableNonMemberOperatorCandidate for each of these?
+    for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
+           E = ULE->decls_end(); I != E; ++I)
+      Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
+  } else {
+    Functions.insert(AnyFunctionDecl::getFromNamedDecl(
+                        cast<DeclRefExpr>(CalleeExpr)->getDecl()));
+  }
 
   // Add any functions found via argument-dependent lookup.
   Expr *Args[2] = { FirstExpr, SecondExpr };
@@ -5449,8 +5456,10 @@
   }
 
   if (Op == OO_Subscript)
-    return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
-                                                      move(First),move(Second));
+    return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
+                                                      OpLoc,
+                                                      move(First),
+                                                      move(Second));
 
   // Create the overloaded operator invocation for binary operators.
   BinaryOperator::Opcode Opc =