summaryrefslogtreecommitdiffstats
path: root/test/Parser/cxx-template-argument.cpp
blob: 963356eaaba328fc35dfd1d72fc28a5bd301c7af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -fdelayed-template-parsing
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fdelayed-template-parsing

template<typename T> struct A {};

// Check for template argument lists followed by junk
// FIXME: The diagnostics here aren't great...
A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
A<int x; // expected-error {{expected '>'}}

// PR8912
template <bool> struct S {};
S<bool(2 > 1)> s;

// Test behavior when a template-id is ended by a token which starts with '>'.
namespace greatergreater {
  template<typename T> struct S { S(); S(T); };
  void f(S<int>=0); // expected-error {{a space is required between a right angle bracket and an equals sign (use '> =')}}
  void f(S<S<int>>=S<int>()); // expected-error {{use '> >'}} expected-error {{use '> ='}}
  template<typename T> void t();
  void g() {
    void (*p)() = &t<int>;
    (void)(&t<int>==p); // expected-error {{use '> ='}}
    (void)(&t<int>>=p); // expected-error {{use '> >'}}
    (void)(&t<S<int>>>=p);
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
    (void)(&t<S<int>>==p); // expected-error {{use '> >'}} expected-error {{use '> ='}}
  }
}

namespace PR5925 {
  template <typename x>
  class foo { // expected-note {{here}}
  };
  void bar(foo *X) { // expected-error {{requires template arguments}}
  }
}

namespace PR13210 {
  template <class T>
  class C {}; // expected-note {{here}}

  void f() {
    new C(); // expected-error {{requires template arguments}}
  }
}

// Don't emit spurious messages
namespace pr16225add {

  template<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}}
  template<class T1, typename T2> struct X;
  template<class T1, typename T2> struct ABC; // expected-note {{template is declared here}}
  template<int N1, int N2> struct ABC2 {};

  template<class T1, typename T2> struct foo :
    UnknownBase<T1,T2> // expected-error {{unknown template name 'UnknownBase'}}
  { };

  template<class T1, typename T2> struct foo2 :
    UnknownBase<T1,T2>, // expected-error {{unknown template name 'UnknownBase'}}
    Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
  { };

  template<class T1, typename T2> struct foo3 :
    UnknownBase<T1,T2,ABC<T2,T1> > // expected-error {{unknown template name 'UnknownBase'}}
  { };

  template<class T1, typename T2> struct foo4 :
    UnknownBase<T1,ABC<T2> >, // expected-error {{unknown template name 'UnknownBase'}} \
                              // expected-error {{too few template arguments for class template 'ABC'}}
    Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
  { };

  template<class T1, typename T2> struct foo5 :
    UnknownBase<T1,T2,ABC<T2,T1>> // expected-error {{unknown template name 'UnknownBase'}}
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
  { };

  template<class T1, typename T2> struct foo6 :
    UnknownBase<T1,ABC<T2,T1>>, // expected-error {{unknown template name 'UnknownBase'}}
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
    Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
  { };

  template<class T1, typename T2, int N> struct foo7 :
    UnknownBase<T1,T2,(N>1)> // expected-error {{unknown template name 'UnknownBase'}}
  { };

  template<class T1, typename T2> struct foo8 :
    UnknownBase<X<int,int>,X<int,int>> // expected-error {{unknown template name 'UnknownBase'}}
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
  { };

  template<class T1, typename T2> struct foo9 :
    UnknownBase<Known<int,int>,X<int,int>> // expected-error {{unknown template name 'UnknownBase'}}
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
  { };

  template<class T1, typename T2> struct foo10 :
    UnknownBase<Known<int,int>,X<int,X<int,int>>> // expected-error {{unknown template name 'UnknownBase'}}
#if __cplusplus <= 199711L
    // expected-error@-2 {{use '> >'}}
#endif
  { };

  template<int N1, int N2> struct foo11 :
    UnknownBase<2<N1,N2<4> // expected-error {{unknown template name 'UnknownBase'}}
  { };

}

namespace PR18793 {
  template<typename T, T> struct S {};
  template<typename T> int g(S<T, (T())> *);
}