/// \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.
///
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 {
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();
}
/// [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;
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,
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,
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,
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.
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);
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)
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.
// 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;
// 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;
}
/// 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");
// 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;
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.
Functions.insert(FunTmpl);
}
+ // FIXME: Pass in the explicit template arguments?
ArgumentDependentLookup(Name, Args, NumArgs, Functions);
// Erase all of the candidates we already knew about.
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);
}
}
return 0;
}
-/// 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
-/// to a specific function. If overload resolution succeeds, returns
-/// 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,
- DeclarationName UnqualifiedName,
- bool HasExplicitTemplateArgs,
+/// \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,
- SourceLocation LParenLoc,
- Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc,
- bool &ArgumentDependentLookup) {
- OverloadCandidateSet CandidateSet;
-
+ 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:
// -- a declaration of a class member, or
//
// -- a block-scope function declaration that is not a
- // using-declaration, or
+ // using-declaration (FIXME: check for 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)) {
+ 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) {
- 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;
- }
-
+ 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();
-
- // FIXME: Pass explicit template arguments through for ADL
+
if (ArgumentDependentLookup)
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
- CandidateSet);
+ 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
+/// to a specific function. If overload resolution succeeds, returns
+/// 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,
+ DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation LParenLoc,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc,
+ bool &ArgumentDependentLookup) {
+ OverloadCandidateSet CandidateSet;
+ // Add the functions denoted by Callee to the set of candidate
+ // functions.
+ AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup,
+ HasExplicitTemplateArgs, ExplicitTemplateArgs,
+ NumExplicitTemplateArgs, Args, NumArgs,
+ CandidateSet);
OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
case OR_Success:
// 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>();
--- /dev/null
+// 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(),