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
diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp
index eaca56c..4b4d435 100644
--- a/clang/test/SemaCXX/nested-name-spec.cpp
+++ b/clang/test/SemaCXX/nested-name-spec.cpp
@@ -101,8 +101,7 @@
 
 int A2::RC::x; // expected-error{{non-static data member defined out-of-line}}
 
-void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member must be a definition}} \
-     //  expected-error{{out-of-line declaration of a member must be a definition}}
+void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member must be a definition}}
 
 
 namespace E {
diff --git a/clang/test/SemaTemplate/instantiate-method.cpp b/clang/test/SemaTemplate/instantiate-method.cpp
new file mode 100644
index 0000000..2eb2b7a
--- /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}}
+}