aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-25 20:25:43 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-25 20:25:43 +0000
commit6bf356fb8f769575d5e6e54a3bf81436ddec106a (patch)
tree43d6539c649c6d1b4b4342b907c0e8cd732d5347
parentd7d5bb1e0ccf0b6d73b6d2a21b5eae788a02b0a1 (diff)
When performing name lookup for an operator name, be sure to look
through using declarations. Fixes ~18 tests in Boost.Fusion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102311 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaLookup.cpp9
-rw-r--r--test/SemaCXX/overloaded-operator.cpp21
2 files changed, 26 insertions, 4 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 0609eef3c9..558bd4eb96 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1824,16 +1824,17 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
Op != OpEnd; ++Op) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
+ NamedDecl *Found = (*Op)->getUnderlyingDecl();
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
- Functions.addDecl(FD, Op.getAccess()); // FIXME: canonical FD
+ Functions.addDecl(*Op, Op.getAccess()); // FIXME: canonical FD
} else if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(*Op)) {
+ = dyn_cast<FunctionTemplateDecl>(Found)) {
// FIXME: friend operators?
// FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
// later?
if (!FunTmpl->getDeclContext()->isRecord())
- Functions.addDecl(FunTmpl, Op.getAccess());
+ Functions.addDecl(*Op, Op.getAccess());
}
}
}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index f9d341f3d1..3d737f4d30 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -356,3 +356,24 @@ namespace pr5900 {
x(); // expected-error {{does not provide a call operator}}
}
}
+
+// Operator lookup through using declarations.
+namespace N {
+ struct X2 { };
+}
+
+namespace N2 {
+ namespace M {
+ namespace Inner {
+ template<typename T>
+ N::X2 &operator<<(N::X2&, const T&);
+ }
+ using Inner::operator<<;
+ }
+}
+
+void test_lookup_through_using() {
+ using namespace N2::M;
+ N::X2 x;
+ x << 17;
+}