aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-15 07:48:03 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-15 07:48:03 +0000
commit593564ba94ff854b7a410a4ca17ad34a90c5b761 (patch)
tree0a2a43654cb0bffb85bedd8fe402fdda63c52d85
parent539e9b18e64479e1092e0cd52efdb2ad41b4d07d (diff)
When looking for operator() to type-check a call to an object of class
type, use full qualified name lookup rather than the poking the declaration context directly. This makes sure that we see operator()'s in superclasses. Also, move the complete-type check before this name lookup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88842 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaOverload.cpp16
-rw-r--r--test/SemaCXX/overloaded-operator.cpp9
2 files changed, 17 insertions, 8 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index b324068ea8..56a878b694 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5255,8 +5255,15 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// (E).operator().
OverloadCandidateSet CandidateSet;
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
+
+ if (RequireCompleteType(LParenLoc, Object->getType(),
+ PartialDiagnostic(diag::err_incomplete_object_call)
+ << Object->getSourceRange()))
+ return true;
+
+ LookupResult R;
+ LookupQualifiedName(R, Record->getDecl(), OpName, LookupOrdinaryName, false);
+ for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Oper)) {
AddMethodTemplateCandidate(FunTmpl, false, 0, 0, Object, Args, NumArgs,
@@ -5268,11 +5275,6 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
}
-
- if (RequireCompleteType(LParenLoc, Object->getType(),
- PartialDiagnostic(diag::err_incomplete_object_call)
- << Object->getSourceRange()))
- return true;
// C++ [over.call.object]p2:
// In addition, for each conversion function declared in T of the
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 750038d4ab..7762667d1a 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -164,7 +164,11 @@ struct Callable2 {
double& operator()(...) const;
};
-void test_callable(Callable c, Callable2 c2, const Callable2& c2c) {
+struct DerivesCallable : public Callable {
+};
+
+void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
+ DerivesCallable dc) {
int &ir = c(1);
float &fr = c(1, 3.14159, 17, 42);
@@ -175,6 +179,9 @@ void test_callable(Callable c, Callable2 c2, const Callable2& c2c) {
int &ir2 = c2();
int &ir3 = c2(1);
double &fr2 = c2c();
+
+ int &ir4 = dc(17);
+ double &fr3 = dc(3.14159f);
}
typedef float FLOAT;