[cfe-commits] r90939 - in /cfe/trunk/lib/Sema: Sema.h SemaDecl.cpp SemaOverload.cpp
John McCall
rjmccall at apple.com
Tue Dec 8 19:35:25 PST 2009
Author: rjmccall
Date: Tue Dec 8 21:35:25 2009
New Revision: 90939
URL: http://llvm.org/viewvc/llvm-project?rev=90939&view=rev
Log:
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.
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=90939&r1=90938&r2=90939&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Dec 8 21:35:25 2009
@@ -832,8 +832,22 @@
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
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=90939&r1=90938&r2=90939&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec 8 21:35:25 2009
@@ -3165,34 +3165,44 @@
// 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;
+ NamedDecl *OldDecl = 0;
+ if (!AllowOverloadingOfFunction(Previous, Context)) {
+ Redeclaration = true;
+ OldDecl = Previous.getFoundDecl();
+ } else {
+ if (!getLangOptions().CPlusPlus) {
+ OverloadableAttrRequired = 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();
+ // 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)) {
+ 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;
- OldDecl = Previous.getFoundDecl();
- } else if (!IsOverload(NewFD, Previous, OldDecl)) {
- if (!isUsingDecl(OldDecl))
- Redeclaration = true;
+ break;
+
+ case Ovl_Overload:
+ Redeclaration = false;
+ break;
}
}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=90939&r1=90938&r2=90939&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Dec 8 21:35:25 2009
@@ -262,9 +262,9 @@
// 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 @@
// 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) {
More information about the cfe-commits
mailing list