summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate/instantiate-method.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-23 23:06:20 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-23 23:06:20 +0000
commitf4f296de01568857bec625f2983f60638afbcc0e (patch)
treec9bcca6c32c490a0633be94d8747b3d95dc4c197 /clang/test/SemaTemplate/instantiate-method.cpp
parent7fe1b0f50fc9255e545427693a6a3020aeb3fc37 (diff)
downloadbcm5719-llvm-f4f296de01568857bec625f2983f60638afbcc0e.tar.gz
bcm5719-llvm-f4f296de01568857bec625f2983f60638afbcc0e.zip
Template instantiation for the declarations of member functions within
a class template. At present, we can only instantiation normal methods, but not constructors, destructors, or conversion operators. As ever, this contains a bit of refactoring in Sema's type-checking. In particular: - Split ActOnFunctionDeclarator into ActOnFunctionDeclarator (handling the declarator itself) and CheckFunctionDeclaration (checking for the the function declaration), the latter of which is also used by template instantiation. - We were performing the adjustment of function parameter types in three places; collect those into a single new routine. - When the type of a parameter is adjusted, allocate an OriginalParmVarDecl to keep track of the type as it was written. - Eliminate a redundant check for out-of-line declarations of member functions; hide more C++-specific checks on function declarations behind if(getLangOptions().CPlusPlus). llvm-svn: 67575
Diffstat (limited to 'clang/test/SemaTemplate/instantiate-method.cpp')
-rw-r--r--clang/test/SemaTemplate/instantiate-method.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/instantiate-method.cpp b/clang/test/SemaTemplate/instantiate-method.cpp
new file mode 100644
index 00000000000..2eb2b7a88cd
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-method.cpp
@@ -0,0 +1,43 @@
+// RUN: clang -fsyntax-only -verify %s
+
+template<typename T>
+class X {
+public:
+ void f(T); // expected-error{{argument may not have 'void' type}}
+ // FIXME: source location isn't very good, because we're
+ // instantiating the type. Could we do better?
+ void g(T*);
+
+ static int h(T, T); // expected-error 2{{argument may not have 'void' type}}
+};
+
+int identity(int x) { return x; }
+
+void test(X<int> *xi, int *ip, X<int(int)> *xf) {
+ xi->f(17);
+ xi->g(ip);
+ xf->f(&identity);
+ xf->g(identity);
+ X<int>::h(17, 25);
+ X<int(int)>::h(identity, &identity);
+}
+
+void test_bad() {
+ X<void> xv; // expected-note{{in instantiation of template class 'class X<void>' requested here}}
+}
+
+template<typename T, typename U>
+class Overloading {
+public:
+ int& f(T, T); // expected-note{{previous declaration is here}}
+ float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void test_ovl(Overloading<int, long> *oil, int i, long l) {
+ int &ir = oil->f(i, i);
+ float &fr = oil->f(i, l);
+}
+
+void test_ovl_bad() {
+ Overloading<float, float> off; // expected-note{{in instantiation of template class 'class Overloading<float, float>' requested here}}
+}
OpenPOWER on IntegriCloud