[cfe-commits] r89570 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/Sema/Lookup.h lib/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateInstantiate.cpp
John McCall
rjmccall at apple.com
Sat Nov 21 16:44:52 PST 2009
Author: rjmccall
Date: Sat Nov 21 18:44:51 2009
New Revision: 89570
URL: http://llvm.org/viewvc/llvm-project?rev=89570&view=rev
Log:
Consider a FunctionTemplate to be an overload all on its lonesome. Track
this information through lookup rather than rederiving it.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/Sema/Lookup.h
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sat Nov 21 18:44:51 2009
@@ -1050,13 +1050,17 @@
/// call.
bool RequiresADL;
+ /// True if these lookup results are overloaded. This is pretty
+ /// trivially rederivable if we urgently need to kill this field.
+ bool Overloaded;
+
UnresolvedLookupExpr(QualType T,
NestedNameSpecifier *Qualifier, SourceRange QRange,
DeclarationName Name, SourceLocation NameLoc,
- bool RequiresADL)
+ bool RequiresADL, bool Overloaded)
: Expr(UnresolvedLookupExprClass, T, false, false),
Name(Name), Qualifier(Qualifier), QualifierRange(QRange),
- NameLoc(NameLoc), RequiresADL(RequiresADL)
+ NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded)
{}
public:
@@ -1065,9 +1069,9 @@
SourceRange QualifierRange,
DeclarationName Name,
SourceLocation NameLoc,
- bool ADL) {
+ bool ADL, bool Overloaded) {
return new(C) UnresolvedLookupExpr(C.OverloadTy, Qualifier, QualifierRange,
- Name, NameLoc, ADL);
+ Name, NameLoc, ADL, Overloaded);
}
void addDecl(NamedDecl *Decl) {
@@ -1082,6 +1086,9 @@
/// argument-dependent lookup.
bool requiresADL() const { return RequiresADL; }
+ /// True if this lookup is overloaded.
+ bool isOverloaded() const { return Overloaded; }
+
/// Fetches the name looked up.
DeclarationName getName() const { return Name; }
Modified: cfe/trunk/lib/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Lookup.h?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Sat Nov 21 18:44:51 2009
@@ -208,6 +208,11 @@
return getResultKind() == Found;
}
+ /// Determines if the results are overloaded.
+ bool isOverloadedResult() const {
+ return getResultKind() == FoundOverloaded;
+ }
+
LookupResultKind getResultKind() const {
sanity();
return ResultKind;
@@ -444,15 +449,24 @@
void sanity() const {
assert(ResultKind != NotFound || Decls.size() == 0);
assert(ResultKind != Found || Decls.size() == 1);
- assert(ResultKind == NotFound || ResultKind == Found ||
- ResultKind == FoundUnresolvedValue ||
- (ResultKind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects)
- || Decls.size() > 1);
+ assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
+ (Decls.size() == 1 && isa<FunctionTemplateDecl>(Decls[0])));
+ assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
+ assert(ResultKind != Ambiguous || Decls.size() > 1 ||
+ (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
assert((Paths != NULL) == (ResultKind == Ambiguous &&
(Ambiguity == AmbiguousBaseSubobjectTypes ||
Ambiguity == AmbiguousBaseSubobjects)));
}
+ bool sanityCheckUnresolved() const {
+ for (DeclsTy::const_iterator I = Decls.begin(), E = Decls.end();
+ I != E; ++I)
+ if (isa<UnresolvedUsingValueDecl>(*I))
+ return true;
+ return false;
+ }
+
static void deletePaths(CXXBasePaths *);
// Results.
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Nov 21 18:44:51 2009
@@ -1423,6 +1423,7 @@
SourceLocation Loc,
DeclarationName Name,
bool NeedsADL,
+ bool IsOverloaded,
NamedDecl * const *Decls,
unsigned NumDecls);
OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
@@ -1531,6 +1532,7 @@
NestedNameSpecifier *&Qualifier,
SourceRange &QualifierRange,
bool &ArgumentDependentLookup,
+ bool &Overloaded,
bool &HasExplicitTemplateArguments,
const TemplateArgumentLoc *&ExplicitTemplateArgs,
unsigned &NumExplicitTemplateArgs);
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Sat Nov 21 18:44:51 2009
@@ -1472,13 +1472,15 @@
NestedNameSpecifier *Qualifier;
SourceRange QualifierRange;
bool ArgumentDependentLookup;
+ bool Overloaded;
bool HasExplicitTemplateArgs;
const TemplateArgumentLoc *ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs;
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
- ArgumentDependentLookup, HasExplicitTemplateArgs,
- ExplicitTemplateArgs, NumExplicitTemplateArgs);
+ ArgumentDependentLookup, Overloaded,
+ HasExplicitTemplateArgs, ExplicitTemplateArgs,
+ NumExplicitTemplateArgs);
// FIXME: What if we're calling something that isn't a function declaration?
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 21 18:44:51 2009
@@ -954,7 +954,7 @@
}
return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
- /*ADL*/ false,
+ /*ADL*/ false, R.isOverloadedResult(),
R.begin(), R.end() - R.begin());
}
@@ -1042,7 +1042,8 @@
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());
}
@@ -1074,23 +1075,24 @@
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]);
@@ -1103,16 +1105,13 @@
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
@@ -2689,6 +2688,7 @@
NestedNameSpecifier *&Qualifier,
SourceRange &QualifierRange,
bool &ArgumentDependentLookup,
+ bool &Overloaded,
bool &HasExplicitTemplateArguments,
const TemplateArgumentLoc *&ExplicitTemplateArgs,
unsigned &NumExplicitTemplateArgs) {
@@ -2697,7 +2697,12 @@
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
@@ -2725,19 +2730,24 @@
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();
@@ -2875,52 +2885,66 @@
// 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);
+ ADL, Overloaded, 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);
- }
+ NamedDecl *NDecl; // the specific declaration we're calling, if applicable
+ FunctionDecl *FDecl; // same, if it's known to be a function
- 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 || 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 (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);
}
}
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sat Nov 21 18:44:51 2009
@@ -242,6 +242,7 @@
delete Paths;
}
+/// Resolves the result kind of this lookup.
void LookupResult::resolveKind() {
unsigned N = Decls.size();
@@ -251,8 +252,12 @@
return;
}
+ // If there's a single decl, we need to examine it to decide what
+ // kind of lookup this is.
if (N == 1) {
- if (isa<UnresolvedUsingValueDecl>(Decls[0]))
+ if (isa<FunctionTemplateDecl>(Decls[0]))
+ ResultKind = FoundOverloaded;
+ else if (isa<UnresolvedUsingValueDecl>(Decls[0]))
ResultKind = FoundUnresolvedValue;
return;
}
@@ -264,7 +269,7 @@
bool Ambiguous = false;
bool HasTag = false, HasFunction = false, HasNonFunction = false;
- bool HasUnresolved = false;
+ bool HasFunctionTemplate = false, HasUnresolved = false;
unsigned UniqueTagIndex = 0;
@@ -290,7 +295,10 @@
Ambiguous = true;
UniqueTagIndex = I;
HasTag = true;
- } else if (D->isFunctionOrFunctionTemplate()) {
+ } else if (isa<FunctionTemplateDecl>(D)) {
+ HasFunction = true;
+ HasFunctionTemplate = true;
+ } else if (isa<FunctionDecl>(D)) {
HasFunction = true;
} else {
if (HasNonFunction)
@@ -323,7 +331,7 @@
setAmbiguous(LookupResult::AmbiguousReference);
else if (HasUnresolved)
ResultKind = LookupResult::FoundUnresolvedValue;
- else if (N > 1)
+ else if (N > 1 || HasFunctionTemplate)
ResultKind = LookupResult::FoundOverloaded;
else
ResultKind = LookupResult::Found;
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Nov 21 18:44:51 2009
@@ -4656,6 +4656,11 @@
return 0;
}
+static bool IsOverloaded(const Sema::FunctionSet &Functions) {
+ return Functions.size() > 1 ||
+ (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
+}
+
/// \brief Create a unary operation that may resolve to an overloaded
/// operator.
///
@@ -4699,7 +4704,7 @@
if (Input->isTypeDependent()) {
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
- /*ADL*/ true);
+ /*ADL*/ true, IsOverloaded(Functions));
for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
Func != FuncEnd; ++Func)
@@ -4855,7 +4860,7 @@
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, OpLoc,
- /* ADL */ true);
+ /* ADL */ true, IsOverloaded(Functions));
for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
@@ -5020,7 +5025,7 @@
UnresolvedLookupExpr *Fn
= UnresolvedLookupExpr::Create(Context, 0, SourceRange(), OpName, LLoc,
- /*ADL*/ true);
+ /*ADL*/ true, /*Overloaded*/ false);
// Can't add an actual overloads yet
Base.release();
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=89570&r1=89569&r2=89570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Nov 21 18:44:51 2009
@@ -701,30 +701,20 @@
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);
- }
+ // The lookup values can never instantiate to a UsingDecl, because
+ // only UnresolvedUsingValueDecls do that, and those can never
+ // appear in UnresolvedLookupExprs (only UnresolvedMemberLookupExprs).
+ assert(!isa<UsingDecl>(InstD));
- continue;
- }
+ // Analogously.
+ assert(!isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl()));
- if (isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl()))
- HasUnresolved = true;
InstDecls.push_back(InstD);
}
@@ -742,6 +732,7 @@
return SemaRef.BuildDeclarationNameExpr(&SS, Old->getNameLoc(),
Old->getName(), Old->requiresADL(),
+ Old->isOverloaded(),
InstDecls.data(), InstDecls.size());
}
More information about the cfe-commits
mailing list