forked from OSchip/llvm-project
Rename Sema::IsOverload to Sema::CheckOverload. Teach it to ignore unresolved
using value decls; we optimistically assume they won't turn into conflicts. Teach it to tell the caller *why* the function doesn't overload with the returned decl; this will be useful for using hiding. llvm-svn: 90939
This commit is contained in:
parent
31c7e88667
commit
daa3d6bb50
|
@ -832,8 +832,22 @@ public:
|
|||
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
|
||||
|
||||
/// C++ Overloading.
|
||||
bool IsOverload(FunctionDecl *New, LookupResult &OldDecls,
|
||||
NamedDecl *&OldDecl);
|
||||
enum OverloadKind {
|
||||
/// This is a legitimate overload: the existing declarations are
|
||||
/// functions or function templates with different signatures.
|
||||
Ovl_Overload,
|
||||
|
||||
/// This is not an overload because the signature exactly matches
|
||||
/// an existing declaration.
|
||||
Ovl_Match,
|
||||
|
||||
/// This is not an overload because the lookup results contain a
|
||||
/// non-function.
|
||||
Ovl_NonFunction
|
||||
};
|
||||
OverloadKind CheckOverload(FunctionDecl *New,
|
||||
LookupResult &OldDecls,
|
||||
NamedDecl *&OldDecl);
|
||||
bool IsOverload(FunctionDecl *New, FunctionDecl *Old);
|
||||
|
||||
ImplicitConversionSequence
|
||||
|
|
|
@ -3165,34 +3165,44 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD,
|
|||
// there's no more work to do here; we'll just add the new
|
||||
// function to the scope.
|
||||
|
||||
if (!getLangOptions().CPlusPlus &&
|
||||
AllowOverloadingOfFunction(Previous, Context)) {
|
||||
OverloadableAttrRequired = true;
|
||||
|
||||
// Functions marked "overloadable" must have a prototype (that
|
||||
// we can't get through declaration merging).
|
||||
if (!NewFD->getType()->getAs<FunctionProtoType>()) {
|
||||
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype)
|
||||
<< NewFD;
|
||||
Redeclaration = true;
|
||||
|
||||
// Turn this into a variadic function with no parameters.
|
||||
QualType R = Context.getFunctionType(
|
||||
NewFD->getType()->getAs<FunctionType>()->getResultType(),
|
||||
0, 0, true, 0);
|
||||
NewFD->setType(R);
|
||||
return NewFD->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
|
||||
NamedDecl *OldDecl = 0;
|
||||
if (!Previous.empty()) {
|
||||
if (!AllowOverloadingOfFunction(Previous, Context)) {
|
||||
Redeclaration = true;
|
||||
OldDecl = Previous.getFoundDecl();
|
||||
} else if (!IsOverload(NewFD, Previous, OldDecl)) {
|
||||
if (!isUsingDecl(OldDecl))
|
||||
if (!AllowOverloadingOfFunction(Previous, Context)) {
|
||||
Redeclaration = true;
|
||||
OldDecl = Previous.getFoundDecl();
|
||||
} else {
|
||||
if (!getLangOptions().CPlusPlus) {
|
||||
OverloadableAttrRequired = true;
|
||||
|
||||
// Functions marked "overloadable" must have a prototype (that
|
||||
// we can't get through declaration merging).
|
||||
if (!NewFD->getType()->getAs<FunctionProtoType>()) {
|
||||
Diag(NewFD->getLocation(),
|
||||
diag::err_attribute_overloadable_no_prototype)
|
||||
<< NewFD;
|
||||
Redeclaration = true;
|
||||
|
||||
// Turn this into a variadic function with no parameters.
|
||||
QualType R = Context.getFunctionType(
|
||||
NewFD->getType()->getAs<FunctionType>()->getResultType(),
|
||||
0, 0, true, 0);
|
||||
NewFD->setType(R);
|
||||
return NewFD->setInvalidDecl();
|
||||
}
|
||||
}
|
||||
|
||||
switch (CheckOverload(NewFD, Previous, OldDecl)) {
|
||||
case Ovl_Match:
|
||||
// FIXME: hide or conflict with using shadow decls as appropriate
|
||||
Redeclaration = !isa<UsingShadowDecl>(OldDecl);
|
||||
break;
|
||||
|
||||
case Ovl_NonFunction:
|
||||
Redeclaration = true;
|
||||
break;
|
||||
|
||||
case Ovl_Overload:
|
||||
Redeclaration = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,9 +262,9 @@ void ImplicitConversionSequence::DebugPrint() const {
|
|||
// New and Old cannot be overloaded, e.g., if New has the same
|
||||
// signature as some function in Old (C++ 1.3.10) or if the Old
|
||||
// declarations aren't functions (or function templates) at all. When
|
||||
// it does return false and Old is an overload set, MatchedDecl will
|
||||
// be set to point to the FunctionDecl that New cannot be overloaded
|
||||
// with.
|
||||
// it does return false, MatchedDecl will point to the decl that New
|
||||
// cannot be overloaded with. This decl may be a UsingShadowDecl on
|
||||
// top of the underlying declaration.
|
||||
//
|
||||
// Example: Given the following input:
|
||||
//
|
||||
|
@ -286,31 +286,33 @@ void ImplicitConversionSequence::DebugPrint() const {
|
|||
// identical (return types of functions are not part of the
|
||||
// signature), IsOverload returns false and MatchedDecl will be set to
|
||||
// point to the FunctionDecl for #2.
|
||||
bool
|
||||
Sema::IsOverload(FunctionDecl *New, LookupResult &Old, NamedDecl *&Match) {
|
||||
Sema::OverloadKind
|
||||
Sema::CheckOverload(FunctionDecl *New, LookupResult &Old, NamedDecl *&Match) {
|
||||
for (LookupResult::iterator I = Old.begin(), E = Old.end();
|
||||
I != E; ++I) {
|
||||
NamedDecl *OldD = (*I)->getUnderlyingDecl();
|
||||
if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
|
||||
if (!IsOverload(New, OldT->getTemplatedDecl())) {
|
||||
Match = OldT;
|
||||
return false;
|
||||
Match = *I;
|
||||
return Ovl_Match;
|
||||
}
|
||||
} else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
|
||||
if (!IsOverload(New, OldF)) {
|
||||
Match = OldF;
|
||||
return false;
|
||||
Match = *I;
|
||||
return Ovl_Match;
|
||||
}
|
||||
} else {
|
||||
} else if (!isa<UnresolvedUsingValueDecl>(OldD)) {
|
||||
// (C++ 13p1):
|
||||
// Only function declarations can be overloaded; object and type
|
||||
// declarations cannot be overloaded.
|
||||
Match = OldD;
|
||||
return false;
|
||||
// But we permit unresolved using value decls and diagnose the error
|
||||
// during template instantiation.
|
||||
Match = *I;
|
||||
return Ovl_NonFunction;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return Ovl_Overload;
|
||||
}
|
||||
|
||||
bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
|
||||
|
|
Loading…
Reference in New Issue