}
return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
- /*ADL*/ false,
+ /*ADL*/ false, R.isOverloadedResult(),
R.begin(), R.end() - R.begin());
}
bool ADL = UseArgumentDependentLookup(*this, SS, HasTrailingLParen, R);
- return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(), ADL,
+ return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
+ ADL, R.isOverloadedResult(),
R.begin(), R.end() - R.begin());
}
SourceLocation Loc,
DeclarationName Name,
bool NeedsADL,
+ bool IsOverloaded,
NamedDecl * const *Decls,
unsigned NumDecls) {
- if (!NeedsADL && NumDecls == 1)
+ if (!NeedsADL && !IsOverloaded)
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 &&
+ if (!IsOverloaded && 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);
+ SS ? SS->getRange() : SourceRange(),
+ Name, Loc, NeedsADL, IsOverloaded);
for (unsigned I = 0; I != NumDecls; ++I)
ULE->addDecl(Decls[I]);
Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
SourceLocation Loc, NamedDecl *D) {
assert(D && "Cannot refer to a NULL declaration");
+ assert(!isa<FunctionTemplateDecl>(D) &&
+ "Cannot refer unambiguously to a function template");
DeclarationName Name = D->getDeclName();
if (CheckDeclInExpr(*this, Loc, D))
return ExprError();
- // Make the DeclRefExpr or BlockDeclRefExpr for the decl.
- if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
- return BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
- false, false, SS);
-
ValueDecl *VD = cast<ValueDecl>(D);
// Check whether this declaration can be used. Note that we suppress
NestedNameSpecifier *&Qualifier,
SourceRange &QualifierRange,
bool &ArgumentDependentLookup,
+ bool &Overloaded,
bool &HasExplicitTemplateArguments,
const TemplateArgumentLoc *&ExplicitTemplateArgs,
unsigned &NumExplicitTemplateArgs) {
Qualifier = 0;
QualifierRange = SourceRange();
ArgumentDependentLookup = getLangOptions().CPlusPlus;
+ Overloaded = false;
HasExplicitTemplateArguments = false;
+
+ // Most of the explicit tracking of ArgumentDependentLookup in this
+ // function can disappear when we handle unresolved
+ // TemplateIdRefExprs properly.
// If we're directly calling a function, get the appropriate declaration.
// Also, in C++, keep track of whether we should perform argument-dependent
Name = UnresLookup->getName();
Fns.append(UnresLookup->decls_begin(), UnresLookup->decls_end());
ArgumentDependentLookup = UnresLookup->requiresADL();
+ Overloaded = UnresLookup->isOverloaded();
if ((Qualifier = UnresLookup->getQualifier()))
QualifierRange = UnresLookup->getQualifierRange();
break;
} else if (TemplateIdRefExpr *TemplateIdRef
= dyn_cast<TemplateIdRefExpr>(FnExpr)) {
if (NamedDecl *Function
- = TemplateIdRef->getTemplateName().getAsTemplateDecl())
+ = TemplateIdRef->getTemplateName().getAsTemplateDecl()) {
+ Name = Function->getDeclName();
Fns.push_back(Function);
+ }
else {
OverloadedFunctionDecl *Overload
= TemplateIdRef->getTemplateName().getAsOverloadedFunctionDecl();
+ Name = Overload->getDeclName();
Fns.append(Overload->function_begin(), Overload->function_end());
}
+ Overloaded = true;
HasExplicitTemplateArguments = true;
ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
// lookup and whether there were any explicitly-specified template arguments.
llvm::SmallVector<NamedDecl*,8> Fns;
DeclarationName UnqualifiedName;
- bool ADL = true;
+ bool Overloaded;
+ bool ADL;
bool HasExplicitTemplateArgs = 0;
const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
unsigned NumExplicitTemplateArgs = 0;
NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange;
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
- ADL,HasExplicitTemplateArgs, ExplicitTemplateArgs,
- NumExplicitTemplateArgs);
-
- 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 (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);
- }
+ ADL, Overloaded, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs);
+
+ NamedDecl *NDecl; // the specific declaration we're calling, if applicable
+ FunctionDecl *FDecl; // same, if it's known to be a function
+
+ if (Overloaded || ADL) {
+#ifndef NDEBUG
+ if (ADL) {
+ // To do ADL, we must have found an unqualified name.
+ assert(UnqualifiedName && "found no unqualified name for ADL");
+
+ // We don't perform ADL for implicit declarations of builtins.
+ // Verify that this was correctly set up.
+ if (Fns.size() == 1 && (FDecl = dyn_cast<FunctionDecl>(Fns[0])) &&
+ FDecl->getBuiltinID() && FDecl->isImplicit())
+ assert(0 && "performing ADL for builtin");
+
+ // We don't perform ADL in C.
+ assert(getLangOptions().CPlusPlus && "ADL enabled in C");
+ }
- 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())
- assert(!ADL); // this should be guaranteed earlier
-
- // We don't perform ADL in C.
- if (!getLangOptions().CPlusPlus)
- assert(!ADL); // ditto
-
- if (Fns.size() > 1 || FunctionTemplate || ADL) {
- FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName,
- HasExplicitTemplateArgs,
- ExplicitTemplateArgs,
- NumExplicitTemplateArgs,
- LParenLoc, Args, NumArgs, CommaLocs,
- RParenLoc, ADL);
- if (!FDecl)
- return ExprError();
+ if (Overloaded) {
+ // To be overloaded, we must either have multiple functions or
+ // at least one function template (which is effectively an
+ // infinite set of functions).
+ assert((Fns.size() > 1 ||
+ (Fns.size() == 1 &&
+ isa<FunctionTemplateDecl>(Fns[0]->getUnderlyingDecl())))
+ && "unrecognized overload situation");
+ }
+#endif
+
+ FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName,
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ LParenLoc, Args, NumArgs, CommaLocs,
+ RParenLoc, ADL);
+ if (!FDecl)
+ return ExprError();
- Fn = FixOverloadedFunctionReference(Fn, FDecl);
+ Fn = FixOverloadedFunctionReference(Fn, FDecl);
- NDecl = FDecl;
+ NDecl = FDecl;
+ } else {
+ assert(Fns.size() <= 1 && "overloaded without Overloaded flag");
+ if (Fns.empty())
+ NDecl = FDecl = 0;
+ else {
+ NDecl = Fns[0];
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
}
}