1c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
2c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor
3c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor// PR6619
4c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate<bool C> struct if_c { };
5c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate<typename T1> struct if_ {
6ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregor  typedef if_c< static_cast<bool>(T1::value)> almost_type_; // expected-note 5{{in instantiation}}
7c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
8c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <class Model, void (Model::*)()> struct wrap_constraints { };
9c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <class Model>
10ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregorinline char has_constraints_(Model* ,  // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
11c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor                             // expected-note 3{{candidate template ignored}}
12ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregor                               wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 2{{in instantiation}}
13c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor
14c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <class Model> struct not_satisfied {
15c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}}
16c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
17c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <class ModelFn> struct requirement_;
18c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <void(*)()> struct instantiate {
19c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
20ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregortemplate <class Model> struct requirement_<void(*)(Model)>                           : if_<       not_satisfied<Model>         >::type { // expected-note 5{{in instantiation}}
21c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
22c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate <class Model> struct usage_requirements {
23c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
24c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregortemplate < typename TT > struct InputIterator                            {
25ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregor    typedef  instantiate< & requirement_<void(*)(usage_requirements<InputIterator> x)>::failed> boost_concept_check1; // expected-note {{in instantiation}}
26c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
27ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregortemplate < typename TT > struct ForwardIterator                              : InputIterator<TT>                              { // expected-note {{in instantiation}}
28ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregor  typedef instantiate< & requirement_<void(*)(usage_requirements<ForwardIterator> x)>::failed> boost_concept_check2; // expected-note {{in instantiation}}
29c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor
30c7e6fde0411680a8aac9abaab7a3c444929ecd3eDouglas Gregor};
31ccef51ab5ac0f0649edd899b5370e1b68cd0f3d4Douglas Gregortypedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX;// expected-note 3{{in instantiation}}
32443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor
33443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregortemplate<typename T> struct X0 { };
34443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregortemplate<typename R, typename A1> struct X0<R(A1 param)> { };
35443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor
36443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregortemplate<typename T, typename A1, typename A2>
37443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregorvoid instF0(X0<T(A1)> x0a, X0<T(A2)> x0b) {
38443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor  X0<T(A1)> x0c;
39443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor  X0<T(A2)> x0d;
40443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor}
41443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregor
42443c72eee72b317222989aa04739e3d63c8224e5Douglas Gregortemplate void instF0<int, int, float>(X0<int(int)>, X0<int(float)>);
43c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor
44c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregortemplate<typename R, typename A1, R (*ptr)(A1)> struct FuncPtr { };
45c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregortemplate<typename A1, int (*ptr)(A1)> struct FuncPtr<int, A1, ptr> { };
46c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor
47c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregortemplate<typename R, typename A1> R unary_func(A1);
48c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor
49c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregortemplate<typename R, typename A1, typename A2>
50c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregorvoid use_func_ptr() {
51c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor  FuncPtr<R, A1, &unary_func<R, A1> > fp1;
52c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor  FuncPtr<R, A2, &unary_func<R, A2> > fp2;
53c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor};
54c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregor
55c2ec761a5f63dc8638f688657053aa9048497bdeDouglas Gregortemplate void use_func_ptr<int, float, double>();
56cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor
57cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregornamespace PR6990 {
58cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  template < typename , typename = int, typename = int > struct X1;
59cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  template <typename >
60cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  struct X2;
61cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor
62cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  template <typename = int *, typename TokenT = int,
63cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor            typename = int( X2<TokenT> &)>
64cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  struct X3
65cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  {
66cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  };
67cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor
68cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  template <typename , typename P>
69cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  struct X3_base : X3< X1<int, P> >
70cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  {
71cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  protected: typedef X1< P> type;
72cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor    X3<type> e;
73cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  };
74cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor
75cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  struct r : X3_base<int, int>
76cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  {
77cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor  };
78cf6cc5410fafb0ac9b16499f335103c73c40bc27Douglas Gregor}
79070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor
80070700a777f857c65cec18d01405d2d240ba1914Douglas Gregornamespace InstantiateFunctionTypedef {
81070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor  template<typename T>
82070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor  struct X {
83070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor    typedef int functype(int, int);
84070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor    functype func;
85070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor  };
86070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor
87070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor  void f(X<int> x) {
88070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor    (void)x.func(1, 2);
89070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor  }
90070700a777f857c65cec18d01405d2d240ba1914Douglas Gregor}
91