Implement code completion within a function call, triggered after the
opening parentheses and after each comma. We gather the set of visible
overloaded functions, perform "partial" overloading based on the set
of arguments that we have thus far, and return the still-viable
results sorted by the likelihood that they will be the best candidate.

Most of the changes in this patch are a refactoring of the overloading
routines for a function call, since we needed to separate out the
notion of building an overload set (common to code-completion and
normal semantic analysis) and then what to do with that overload
set. As part of this change, I've pushed explicit template arguments
into a few more subroutines.

There is still much more work to do in this area. Function templates
won't be handled well (unless we happen to deduce all of the template
arguments before we hit the completion point), nor will overloaded
function-call operators or calls to member functions.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82549 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 06213dd..df85dfe 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -2239,6 +2239,18 @@
   /// \brief S the scope in which the case statement occurs.
   virtual void CodeCompleteCase(Scope *S) { }
   
+  /// \brief Code completion for a call.
+  ///
+  /// \brief S the scope in which the call occurs.
+  ///
+  /// \param Fn the expression describing the function being called.
+  ///
+  /// \param Args the arguments to the function call (so far).
+  ///
+  /// \param NumArgs the number of arguments in \p Args.
+  virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+                                ExprTy **Args, unsigned NumArgs) { }
+                                
   /// \brief Code completion for a C++ nested-name-specifier that precedes a
   /// qualified-id of some form.
   ///
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index e1a6e7a..b9b17d2 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -745,7 +745,11 @@
   typedef llvm::SmallVector<SourceLocation, ExprListSize> CommaLocsTy;
 
   /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-  bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs);
+  bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
+                           void (Action::*Completer)(Scope *S, void *Data,
+                                                     ExprTy **Args,
+                                                     unsigned NumArgs) = 0,
+                           void *Data = 0);
 
   /// ParenParseOption - Control what ParseParenExpression will parse.
   enum ParenParseOption {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 156c848..d10e38c 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -899,8 +899,14 @@
 
       Loc = ConsumeParen();
 
+      if (Tok.is(tok::code_completion)) {
+        Actions.CodeCompleteCall(CurScope, LHS.get(), 0, 0);
+        ConsumeToken();
+      }
+      
       if (Tok.isNot(tok::r_paren)) {
-        if (ParseExpressionList(ArgExprs, CommaLocs)) {
+        if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall,
+                                LHS.get())) {
           SkipUntil(tok::r_paren);
           return ExprError();
         }
@@ -1508,8 +1514,19 @@
 /// [C++]   assignment-expression
 /// [C++]   expression-list , assignment-expression
 ///
-bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
+bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs,
+                                 void (Action::*Completer)(Scope *S, 
+                                                           void *Data,
+                                                           ExprTy **Args,
+                                                           unsigned NumArgs),
+                                 void *Data) {
   while (1) {
+    if (Tok.is(tok::code_completion)) {
+      if (Completer)
+        (Actions.*Completer)(CurScope, Data, Exprs.data(), Exprs.size());
+      ConsumeToken();
+    }
+    
     OwningExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid())
       return true;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 7fa5462..4d8fd8d 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -835,7 +835,8 @@
                             Expr **Args, unsigned NumArgs,
                             OverloadCandidateSet& CandidateSet,
                             bool SuppressUserConversions = false,
-                            bool ForceRValue = false);
+                            bool ForceRValue = false,
+                            bool PartialOverloading = false);
   void AddFunctionCandidates(const FunctionSet &Functions,
                              Expr **Args, unsigned NumArgs,
                              OverloadCandidateSet& CandidateSet,
@@ -891,7 +892,11 @@
                                     OverloadCandidateSet& CandidateSet);
   void AddArgumentDependentLookupCandidates(DeclarationName Name,
                                             Expr **Args, unsigned NumArgs,
-                                            OverloadCandidateSet& CandidateSet);
+                                            bool HasExplicitTemplateArgs,
+                                  const TemplateArgument *ExplicitTemplateArgs,
+                                            unsigned NumExplicitTemplateArgs,                                            
+                                            OverloadCandidateSet& CandidateSet,
+                                            bool PartialOverloading = false);
   bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
                                  const OverloadCandidate& Cand2);
   OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
@@ -904,6 +909,16 @@
                                                    bool Complain);
   void FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
 
+  void AddOverloadedCallCandidates(NamedDecl *Callee,
+                                   DeclarationName &UnqualifiedName,
+                                   bool &ArgumentDependentLookup,
+                                   bool HasExplicitTemplateArgs,
+                                   const TemplateArgument *ExplicitTemplateArgs,
+                                   unsigned NumExplicitTemplateArgs,
+                                   Expr **Args, unsigned NumArgs,
+                                   OverloadCandidateSet &CandidateSet,
+                                   bool PartialOverloading = false);
+    
   FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
                                         DeclarationName UnqualifiedName,
                                         bool HasExplicitTemplateArgs,
@@ -1670,6 +1685,16 @@
                                  unsigned NumInitializers
                                  );
 
+  void DeconstructCallFunction(Expr *FnExpr,
+                               NamedDecl *&Function,
+                               DeclarationName &Name,
+                               NestedNameSpecifier *&Qualifier,
+                               SourceRange &QualifierRange,
+                               bool &ArgumentDependentLookup,
+                               bool &HasExplicitTemplateArguments,
+                               const TemplateArgument *&ExplicitTemplateArgs,
+                               unsigned &NumExplicitTemplateArgs);
+    
   /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
   /// This provides the location of the left/right parens and a list of comma
   /// locations.
@@ -3635,6 +3660,8 @@
                                                bool IsArrow);
   virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
   virtual void CodeCompleteCase(Scope *S);
+  virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
+                                ExprTy **Args, unsigned NumArgs);
   virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
                                        bool EnteringContext);
   virtual void CodeCompleteUsing(Scope *S);
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 52e7d0e..757bb62 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1070,6 +1070,78 @@
   HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size());  
 }
 
+namespace {
+  struct IsBetterOverloadCandidate {
+    Sema &S;
+    
+  public:
+    explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
+    
+    bool 
+    operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
+      return S.isBetterOverloadCandidate(X, Y);
+    }
+  };
+}
+
+void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
+                            ExprTy **ArgsIn, unsigned NumArgs) {
+  if (!CodeCompleter)
+    return;
+  
+  Expr *Fn = (Expr *)FnIn;
+  Expr **Args = (Expr **)ArgsIn;
+  
+  // Ignore type-dependent call expressions entirely.
+  if (Fn->isTypeDependent() || 
+      Expr::hasAnyTypeDependentArguments(Args, NumArgs))
+    return;
+  
+  NamedDecl *Function;
+  DeclarationName UnqualifiedName;
+  NestedNameSpecifier *Qualifier;
+  SourceRange QualifierRange;
+  bool ArgumentDependentLookup;
+  bool HasExplicitTemplateArgs;
+  const TemplateArgument *ExplicitTemplateArgs;
+  unsigned NumExplicitTemplateArgs;
+  
+  DeconstructCallFunction(Fn,
+                          Function, UnqualifiedName, Qualifier, QualifierRange,
+                          ArgumentDependentLookup, HasExplicitTemplateArgs,
+                          ExplicitTemplateArgs, NumExplicitTemplateArgs);
+
+  
+  // FIXME: What if we're calling something that isn't a function declaration?
+  // FIXME: What if we're calling a pseudo-destructor?
+  // FIXME: What if we're calling a member function?
+  
+  // Build an overload candidate set based on the functions we find.
+  OverloadCandidateSet CandidateSet;
+  AddOverloadedCallCandidates(Function, UnqualifiedName, 
+                              ArgumentDependentLookup, HasExplicitTemplateArgs,
+                              ExplicitTemplateArgs, NumExplicitTemplateArgs,
+                              Args, NumArgs,
+                              CandidateSet,
+                              /*PartialOverloading=*/true);
+  
+  // Sort the overload candidate set by placing the best overloads first.
+  std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
+                   IsBetterOverloadCandidate(*this));
+  
+  // Add the remaining viable overload candidates as code-completion reslults.  
+  typedef CodeCompleteConsumer::Result Result;
+  ResultBuilder Results(*this);
+  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
+                                   CandEnd = CandidateSet.end();
+       Cand != CandEnd; ++Cand) {
+    if (Cand->Viable)
+      Results.MaybeAddResult(Result(Cand->Function, 0), 0);
+  }
+  
+  HandleCodeCompleteResults(CodeCompleter, Results.data(), Results.size());
+}
+
 void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
                                    bool EnteringContext) {
   if (!SS.getScopeRep() || !CodeCompleter)
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 333cd35..3eed4fc 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2734,6 +2734,96 @@
   return Invalid;
 }
 
+/// \brief "Deconstruct" the function argument of a call expression to find 
+/// the underlying declaration (if any), the name of the called function, 
+/// whether argument-dependent lookup is available, whether it has explicit
+/// template arguments, etc.
+void Sema::DeconstructCallFunction(Expr *FnExpr,
+                                   NamedDecl *&Function,
+                                   DeclarationName &Name,
+                                   NestedNameSpecifier *&Qualifier,
+                                   SourceRange &QualifierRange,
+                                   bool &ArgumentDependentLookup,
+                                   bool &HasExplicitTemplateArguments,
+                                 const TemplateArgument *&ExplicitTemplateArgs,
+                                   unsigned &NumExplicitTemplateArgs) {
+  // Set defaults for all of the output parameters.
+  Function = 0;
+  Name = DeclarationName();
+  Qualifier = 0;
+  QualifierRange = SourceRange();
+  ArgumentDependentLookup = getLangOptions().CPlusPlus;
+  HasExplicitTemplateArguments = false;
+  
+  // 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.
+  while (true) {
+    if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr))
+      FnExpr = IcExpr->getSubExpr();
+    else if (ParenExpr *PExpr = dyn_cast<ParenExpr>(FnExpr)) {
+      // Parentheses around a function disable ADL
+      // (C++0x [basic.lookup.argdep]p1).
+      ArgumentDependentLookup = false;
+      FnExpr = PExpr->getSubExpr();
+    } else if (isa<UnaryOperator>(FnExpr) &&
+               cast<UnaryOperator>(FnExpr)->getOpcode()
+               == UnaryOperator::AddrOf) {
+      FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
+    } else if (QualifiedDeclRefExpr *QDRExpr 
+                 = dyn_cast<QualifiedDeclRefExpr>(FnExpr)) {
+      // Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
+      ArgumentDependentLookup = false;
+      Qualifier = QDRExpr->getQualifier();
+      QualifierRange = QDRExpr->getQualifierRange();
+      Function = dyn_cast<NamedDecl>(QDRExpr->getDecl());
+      break;
+    } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
+      Function = dyn_cast<NamedDecl>(DRExpr->getDecl());
+      break;
+    } else if (UnresolvedFunctionNameExpr *DepName
+               = dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
+      Name = DepName->getName();
+      break;
+    } else if (TemplateIdRefExpr *TemplateIdRef
+               = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
+      Function = TemplateIdRef->getTemplateName().getAsTemplateDecl();
+      if (!Function)
+        Function = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
+      HasExplicitTemplateArguments = true;
+      ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
+      NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
+      
+      // C++ [temp.arg.explicit]p6:
+      //   [Note: For simple function names, argument dependent lookup (3.4.2)
+      //   applies even when the function name is not visible within the
+      //   scope of the call. This is because the call still has the syntactic
+      //   form of a function call (3.4.1). But when a function template with
+      //   explicit template arguments is used, the call does not have the
+      //   correct syntactic form unless there is a function template with
+      //   that name visible at the point of the call. If no such name is
+      //   visible, the call is not syntactically well-formed and
+      //   argument-dependent lookup does not apply. If some such name is
+      //   visible, argument dependent lookup applies and additional function
+      //   templates may be found in other namespaces.
+      //
+      // The summary of this paragraph is that, if we get to this point and the
+      // template-id was not a qualified name, then argument-dependent lookup
+      // is still possible.
+      if ((Qualifier = TemplateIdRef->getQualifier())) {
+        ArgumentDependentLookup = false;
+        QualifierRange = TemplateIdRef->getQualifierRange();
+      }
+      break;
+    } else {
+      // Any kind of name that does not refer to a declaration (or
+      // set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3).
+      ArgumentDependentLookup = false;
+      break;
+    }
+  }
+}
+
 /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
 /// This provides the location of the left/right parens and a list of comma
 /// locations.
@@ -2808,67 +2898,15 @@
   // 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.
-  Expr *FnExpr = Fn;
   bool ADL = true;
   bool HasExplicitTemplateArgs = 0;
   const TemplateArgument *ExplicitTemplateArgs = 0;
   unsigned NumExplicitTemplateArgs = 0;
-  while (true) {
-    if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr))
-      FnExpr = IcExpr->getSubExpr();
-    else if (ParenExpr *PExpr = dyn_cast<ParenExpr>(FnExpr)) {
-      // Parentheses around a function disable ADL
-      // (C++0x [basic.lookup.argdep]p1).
-      ADL = false;
-      FnExpr = PExpr->getSubExpr();
-    } else if (isa<UnaryOperator>(FnExpr) &&
-               cast<UnaryOperator>(FnExpr)->getOpcode()
-                 == UnaryOperator::AddrOf) {
-      FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
-    } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
-      // Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
-      ADL &= !isa<QualifiedDeclRefExpr>(DRExpr);
-      NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
-      break;
-    } else if (UnresolvedFunctionNameExpr *DepName
-                 = dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
-      UnqualifiedName = DepName->getName();
-      break;
-    } else if (TemplateIdRefExpr *TemplateIdRef
-                 = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
-      NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl();
-      if (!NDecl)
-        NDecl = TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
-      HasExplicitTemplateArgs = true;
-      ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
-      NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
-
-      // C++ [temp.arg.explicit]p6:
-      //   [Note: For simple function names, argument dependent lookup (3.4.2)
-      //   applies even when the function name is not visible within the
-      //   scope of the call. This is because the call still has the syntactic
-      //   form of a function call (3.4.1). But when a function template with
-      //   explicit template arguments is used, the call does not have the
-      //   correct syntactic form unless there is a function template with
-      //   that name visible at the point of the call. If no such name is
-      //   visible, the call is not syntactically well-formed and
-      //   argument-dependent lookup does not apply. If some such name is
-      //   visible, argument dependent lookup applies and additional function
-      //   templates may be found in other namespaces.
-      //
-      // The summary of this paragraph is that, if we get to this point and the
-      // template-id was not a qualified name, then argument-dependent lookup
-      // is still possible.
-      if (TemplateIdRef->getQualifier())
-        ADL = false;
-      break;
-    } else {
-      // Any kind of name that does not refer to a declaration (or
-      // set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3).
-      ADL = false;
-      break;
-    }
-  }
+  NestedNameSpecifier *Qualifier = 0;
+  SourceRange QualifierRange;
+  DeconstructCallFunction(Fn, NDecl, UnqualifiedName, Qualifier, QualifierRange,
+                          ADL,HasExplicitTemplateArgs, ExplicitTemplateArgs,
+                          NumExplicitTemplateArgs);
 
   OverloadedFunctionDecl *Ovl = 0;
   FunctionTemplateDecl *FunctionTemplate = 0;
@@ -2903,16 +2941,15 @@
 
       // Update Fn to refer to the actual function selected.
       Expr *NewFn = 0;
-      if (QualifiedDeclRefExpr *QDRExpr
-            = dyn_cast<QualifiedDeclRefExpr>(FnExpr))
+      if (Qualifier)
         NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(),
-                                                   QDRExpr->getLocation(),
+                                                   Fn->getLocStart(),
                                                    false, false,
-                                                 QDRExpr->getQualifierRange(),
-                                                   QDRExpr->getQualifier());
+                                                   QualifierRange,
+                                                   Qualifier);
       else
         NewFn = new (Context) DeclRefExpr(FDecl, FDecl->getType(),
-                                          Fn->getSourceRange().getBegin());
+                                          Fn->getLocStart());
       Fn->Destroy(Context);
       Fn = NewFn;
     }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 2ff0c05..063b387 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2122,12 +2122,17 @@
 /// If @p ForceRValue, treat all arguments as rvalues. This is a slightly
 /// hacky way to implement the overloading rules for elidable copy
 /// initialization in C++0x (C++0x 12.8p15).
+///
+/// \para PartialOverloading true if we are performing "partial" overloading
+/// based on an incomplete set of function arguments. This feature is used by
+/// code completion.
 void
 Sema::AddOverloadCandidate(FunctionDecl *Function,
                            Expr **Args, unsigned NumArgs,
                            OverloadCandidateSet& CandidateSet,
                            bool SuppressUserConversions,
-                           bool ForceRValue) {
+                           bool ForceRValue,
+                           bool PartialOverloading) {
   const FunctionProtoType* Proto
     = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
   assert(Proto && "Functions without a prototype cannot be overloaded");
@@ -2177,7 +2182,7 @@
   // parameter list is truncated on the right, so that there are
   // exactly m parameters.
   unsigned MinRequiredArgs = Function->getMinRequiredArguments();
-  if (NumArgs < MinRequiredArgs) {
+  if (NumArgs < MinRequiredArgs && !PartialOverloading) {
     // Not enough arguments.
     Candidate.Viable = false;
     return;
@@ -3615,9 +3620,15 @@
 void
 Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
                                            Expr **Args, unsigned NumArgs,
-                                           OverloadCandidateSet& CandidateSet) {
+                                           bool HasExplicitTemplateArgs,
+                                const TemplateArgument *ExplicitTemplateArgs,
+                                           unsigned NumExplicitTemplateArgs,                                            
+                                           OverloadCandidateSet& CandidateSet,
+                                           bool PartialOverloading) {
   FunctionSet Functions;
 
+  // FIXME: Should we be trafficking in canonical function decls throughout?
+  
   // Record all of the function candidates that we've already
   // added to the overload set, so that we don't add those same
   // candidates a second time.
@@ -3630,6 +3641,7 @@
         Functions.insert(FunTmpl);
     }
 
+  // FIXME: Pass in the explicit template arguments?
   ArgumentDependentLookup(Name, Args, NumArgs, Functions);
 
   // Erase all of the candidates we already knew about.
@@ -3648,11 +3660,17 @@
   for (FunctionSet::iterator Func = Functions.begin(),
                           FuncEnd = Functions.end();
        Func != FuncEnd; ++Func) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
-      AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
-    else
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) {
+      if (HasExplicitTemplateArgs)
+        continue;
+      
+      AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+                           false, false, PartialOverloading);
+    } else
       AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
-                                   /*FIXME: explicit args */false, 0, 0,
+                                   HasExplicitTemplateArgs,
+                                   ExplicitTemplateArgs,
+                                   NumExplicitTemplateArgs,
                                    Args, NumArgs, CandidateSet);
   }
 }
@@ -4100,6 +4118,101 @@
   return 0;
 }
 
+/// \brief Add a single candidate to the overload set.
+static void AddOverloadedCallCandidate(Sema &S,
+                                       AnyFunctionDecl Callee,
+                                       bool &ArgumentDependentLookup,
+                                       bool HasExplicitTemplateArgs,
+                                 const TemplateArgument *ExplicitTemplateArgs,
+                                       unsigned NumExplicitTemplateArgs,
+                                       Expr **Args, unsigned NumArgs,
+                                       OverloadCandidateSet &CandidateSet,
+                                       bool PartialOverloading) {
+  if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
+    assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
+    S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false,
+                           PartialOverloading);
+  
+    if (Func->getDeclContext()->isRecord() ||
+        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;
+}
+  
+/// \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,
+                                       DeclarationName &UnqualifiedName,
+                                       bool &ArgumentDependentLookup,
+                                       bool HasExplicitTemplateArgs,
+                                  const TemplateArgument *ExplicitTemplateArgs,
+                                       unsigned NumExplicitTemplateArgs,
+                                       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:
+  //
+  // 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
+  //
+  //     -- a declaration of a class member, or
+  //
+  //     -- a block-scope function declaration that is not a
+  //        using-declaration (FIXME: check for 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,
+                               HasExplicitTemplateArgs,
+                               ExplicitTemplateArgs, NumExplicitTemplateArgs,
+                               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,
+                                         ExplicitTemplateArgs,
+                                         NumExplicitTemplateArgs,
+                                         CandidateSet,
+                                         PartialOverloading);  
+}
+  
 /// ResolveOverloadedCallFn - Given the call expression that calls Fn
 /// (which eventually refers to the declaration Func) and the call
 /// arguments Args/NumArgs, attempt to resolve the function call down
@@ -4120,74 +4233,11 @@
   OverloadCandidateSet CandidateSet;
 
   // 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:
-  //
-  // 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
-  //
-  //     -- a declaration of a class member, or
-  //
-  //     -- a block-scope function declaration that is not a
-  //        using-declaration, or
-  //
-  //     -- a declaration that is neither a function or a function
-  //        template
-  //
-  //   then Y is empty.
-  if (OverloadedFunctionDecl *Ovl
-        = dyn_cast_or_null<OverloadedFunctionDecl>(Callee)) {
-    for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
-                                                FuncEnd = Ovl->function_end();
-         Func != FuncEnd; ++Func) {
-      DeclContext *Ctx = 0;
-      if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Func)) {
-        if (HasExplicitTemplateArgs)
-          continue;
-
-        AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
-        Ctx = FunDecl->getDeclContext();
-      } else {
-        FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*Func);
-        AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs,
-                                     ExplicitTemplateArgs,
-                                     NumExplicitTemplateArgs,
-                                     Args, NumArgs, CandidateSet);
-        Ctx = FunTmpl->getDeclContext();
-      }
-
-
-      if (Ctx->isRecord() || Ctx->isFunctionOrMethod())
-        ArgumentDependentLookup = false;
-    }
-  } else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) {
-    assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
-    AddOverloadCandidate(Func, Args, NumArgs, CandidateSet);
-
-    if (Func->getDeclContext()->isRecord() ||
-        Func->getDeclContext()->isFunctionOrMethod())
-      ArgumentDependentLookup = false;
-  } else if (FunctionTemplateDecl *FuncTemplate
-               = dyn_cast_or_null<FunctionTemplateDecl>(Callee)) {
-    AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
-                                 ExplicitTemplateArgs,
-                                 NumExplicitTemplateArgs,
-                                 Args, NumArgs, CandidateSet);
-
-    if (FuncTemplate->getDeclContext()->isRecord())
-      ArgumentDependentLookup = false;
-  }
-
-  if (Callee)
-    UnqualifiedName = Callee->getDeclName();
-
-  // FIXME: Pass explicit template arguments through for ADL
-  if (ArgumentDependentLookup)
-    AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
-                                         CandidateSet);
-
+  // functions. 
+  AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup,
+                              HasExplicitTemplateArgs, ExplicitTemplateArgs,
+                              NumExplicitTemplateArgs, Args, NumArgs, 
+                              CandidateSet);
   OverloadCandidateSet::iterator Best;
   switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
   case OR_Success:
@@ -4877,7 +4927,6 @@
   //   for a class object x of type T if T::operator->() exists and if
   //   the operator is selected as the best match function by the
   //   overload resolution mechanism (13.3).
-  // FIXME: look in base classes.
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
   OverloadCandidateSet CandidateSet;
   const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp
new file mode 100644
index 0000000..4faff15
--- /dev/null
+++ b/test/CodeCompletion/call.cpp
@@ -0,0 +1,22 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+void f(float x, float y);
+void f(int i, int j, int k);
+struct X { };
+void f(X);
+namespace N {
+  struct Y { 
+    Y(int = 0); 
+    
+    operator int() const;
+  };
+  void f(Y y);
+}
+typedef N::Y Y;
+void f();
+
+void test() {
+  // CHECK-CC1: f : 0 : f(<#struct N::Y y#>)
+  // CHECK-NEXT-CC1: f : 0 : f(<#int i#>, <#int j#>, <#int k#>)
+  // CHECK-NEXT-CC1: f : 0 : f(<#float x#>, <#float y#>)
+  f(Y(),