diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-23 23:06:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-23 23:06:20 +0000 |
commit | f4f296de01568857bec625f2983f60638afbcc0e (patch) | |
tree | c9bcca6c32c490a0633be94d8747b3d95dc4c197 /clang/test/SemaTemplate/instantiate-method.cpp | |
parent | 7fe1b0f50fc9255e545427693a6a3020aeb3fc37 (diff) | |
download | bcm5719-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.cpp | 43 |
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}} +} |