Initial implementation of argument dependent lookup (a.k.a. ADL,
a.k.a. Koenig lookup) in C++. Most of the pieces are in place, but for
two:
- In an unqualified call g(x), even if the name does not refer to
anything in the current scope, we can still find functions named
"g" based on ADL. We don't yet have this ability.
- ADL will need updating for friend functions and templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63692 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/basic_lookup_argdep.cpp b/test/SemaCXX/basic_lookup_argdep.cpp
new file mode 100644
index 0000000..67f2b65
--- /dev/null
+++ b/test/SemaCXX/basic_lookup_argdep.cpp
@@ -0,0 +1,45 @@
+// RUN: clang -fsyntax-only -verify %s
+
+namespace N {
+ struct X { };
+
+ X operator+(X, X);
+
+ void f(X);
+ void g(X);
+
+ void test_multiadd(X x) {
+ (void)(x + x);
+ }
+}
+
+namespace M {
+ struct Y : N::X { };
+}
+
+void f();
+
+void test_operator_adl(N::X x, M::Y y) {
+ (void)(x + x);
+ (void)(y + y);
+}
+
+void test_func_adl(N::X x, M::Y y) {
+ f(x);
+ f(y);
+ (f)(x); // expected-error{{too many arguments to function call}}
+ ::f(x); // expected-error{{too many arguments to function call}}
+}
+
+namespace N {
+ void test_multiadd2(X x) {
+ (void)(x + x);
+ }
+}
+
+
+void test_func_adl_only(N::X x) {
+ // FIXME: here, despite the fact that the name lookup for 'g' fails,
+ // this is well-formed code. The fix will go into Sema::ActOnCallExpr.
+ // g(x);
+}
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index 1b57214..100267c 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -36,7 +36,7 @@
bool b3 = ctb || ecb;
}
-void accepts_bool(bool) { }
+void accepts_bool(bool) { } // expected-note{{candidate function}}
struct ExplicitConvToRef {
explicit operator int&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
@@ -45,7 +45,7 @@
void test_explicit_bool(ExplicitConvToBool ecb) {
bool b1(ecb); // okay
bool b2 = ecb; // expected-error{{incompatible type initializing 'struct ExplicitConvToBool', expected '_Bool'}}
- accepts_bool(ecb); // expected-error{{incompatible type passing 'struct ExplicitConvToBool', expected '_Bool'}}
+ accepts_bool(ecb); // expected-error{{no matching function for call to}}
}
void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
diff --git a/test/SemaCXX/converting-constructor.cpp b/test/SemaCXX/converting-constructor.cpp
index 0ab8d93..edded17 100644
--- a/test/SemaCXX/converting-constructor.cpp
+++ b/test/SemaCXX/converting-constructor.cpp
@@ -12,13 +12,13 @@
X(const Y&);
};
-void f(X);
+void f(X); // expected-note{{candidate function}}
void g(short s, Y y, Z z) {
f(s);
f(1.0f);
f(y);
- f(z); // expected-error{{incompatible type passing 'class Z', expected 'class X'}}
+ f(z); // expected-error{{no matching function}}
}
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index db84539..0cc9d7e 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -33,11 +33,11 @@
}
class C { };
-void fn(int(C)) { } // void fn(int(*fp)(C c)) { }
+void fn(int(C)) { } // void fn(int(*fp)(C c)) { } expected-note{{candidate function}}
// not: void fn(int C);
int g(C);
void foo() {
- fn(1); // expected-error {{incompatible type passing 'int', expected 'int (*)(class C)'}}
+ fn(1); // expected-error {{no matching function}}
fn(g); // OK
}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index e558faa..6c7a8d7 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -195,3 +195,18 @@
*this = *Base;
}
};
+
+namespace N {
+ struct X { };
+}
+
+namespace M {
+ N::X operator+(N::X, N::X);
+}
+
+namespace M {
+ void test_X(N::X x) {
+ // FIXME: this should work! See comment in Sema::AddOperatorCandidates.
+ // (void)(x + x);
+ }
+}
diff --git a/test/SemaCXX/qualification-conversion.cpp b/test/SemaCXX/qualification-conversion.cpp
index 1b818c3..689a7b3 100644
--- a/test/SemaCXX/qualification-conversion.cpp
+++ b/test/SemaCXX/qualification-conversion.cpp
@@ -1,23 +1,23 @@
// RUN: clang -fsyntax-only -pedantic -verify %s
int* quals1(int const * p);
int* quals2(int const * const * pp);
-int* quals3(int const * * const * ppp);
+int* quals3(int const * * const * ppp); // expected-note{{candidate function}}
void test_quals(int * p, int * * pp, int * * * ppp) {
int const * const * pp2 = pp;
quals1(p);
quals2(pp);
- quals3(ppp); // expected-error {{ incompatible type passing 'int ***', expected 'int const **const *' }}
+ quals3(ppp); // expected-error {{no matching}}
}
struct A {};
void mquals1(int const A::*p);
void mquals2(int const A::* const A::*pp);
-void mquals3(int const A::* A::* const A::*ppp);
+void mquals3(int const A::* A::* const A::*ppp); // expected-note{{candidate function}}
void test_mquals(int A::*p, int A::* A::*pp, int A::* A::* A::*ppp) {
int const A::* const A::* pp2 = pp;
mquals1(p);
mquals2(pp);
- mquals3(ppp); // expected-error {{ incompatible type passing 'int struct A::*struct A::*struct A::*', expected 'int const struct A::*struct A::*const struct A::*' }}
+ mquals3(ppp); // expected-error {{no matching}}
}
diff --git a/test/SemaCXX/type-dependent-exprs.cpp b/test/SemaCXX/type-dependent-exprs.cpp
index 15808c6..b3bfa8b 100644
--- a/test/SemaCXX/type-dependent-exprs.cpp
+++ b/test/SemaCXX/type-dependent-exprs.cpp
@@ -4,7 +4,7 @@
virtual int f();
};
-void g(int);
+void g(int); // expected-note{{candidate function}}
template<typename T>
T f(T x) {
@@ -18,7 +18,7 @@
(void)const_cast<int>(x);
return g(x);
h(x); // h is a dependent name
- g(1, 1); // expected-error{{too many arguments to function call}}
+ g(1, 1); // expected-error{{no matching function for call}}
h(1); // expected-error{{use of undeclared identifier 'h'}}
return 0;
}
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
index 8aee152..a792006 100644
--- a/test/SemaObjCXX/blocks.mm
+++ b/test/SemaObjCXX/blocks.mm
@@ -11,14 +11,14 @@
return bar2(objectCreationBlock); // expected-warning{{incompatible pointer types passing 'id (*)(void)', expected 'id<NSObject> (*)(void)'}}
}
-void bar3(id(*)());
+void bar3(id(*)()); // expected-note{{candidate function}}
void foo3(id (*objectCreationBlock)(int)) {
- return bar3(objectCreationBlock); // expected-error{{incompatible type passing 'id (*)(int)', expected 'id (*)(void)'}}
+ return bar3(objectCreationBlock); // expected-error{{no matching}}
}
-void bar4(id(^)());
+void bar4(id(^)()); // expected-note{{candidate function}}
void foo4(id (^objectCreationBlock)(int)) {
- return bar4(objectCreationBlock); // expected-error{{incompatible type passing 'id (^)(int)', expected 'id (^)(void)'}}
+ return bar4(objectCreationBlock); // expected-error{{no matching}}
}
void foo5(id (^x)(int)) {