injected-class-name.cpp revision 762bb9d0ad20320b9f97a841dce57ba5e8e48b07
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3// Check for declaration matching with out-of-line declarations and
4// variadic templates, which involves proper computation of the
5// injected-class-name.
6template<typename T, typename ...Types>
7struct X0 {
8  typedef T type;
9
10  void f0(T);
11  type f1(T);
12};
13
14template<typename T, typename ...Types>
15void X0<T, Types...>::f0(T) { }
16
17template<typename T, typename ...Types>
18typename X0<T, Types...>::type X0<T, Types...>::f1(T) { }
19
20template<typename T, typename ...Types>
21struct X0<T, T, Types...> {
22  typedef T* result;
23  result f3();
24
25  template<typename... InnerTypes>
26  struct Inner;
27};
28
29template<typename T, typename ...Types>
30typename X0<T, T, Types...>::result X0<T, T, Types...>::f3() { return 0; }
31
32template<typename T, typename ...Types>
33template<typename ...InnerTypes>
34struct X0<T, T, Types...>::Inner {
35  template<typename ...ReallyInner> void f4();
36};
37
38template<typename T, typename ...Types>
39template<typename ...InnerTypes>
40template<typename ...ReallyInner>
41void X0<T, T, Types...>::Inner<InnerTypes...>::f4() { }
42
43namespace rdar8848837 {
44  // Out-of-line definitions that cause rebuilding in the current
45  // instantiation.
46  template<typename F> struct X;
47
48  template<typename R, typename ...ArgTypes>
49  struct X<R(ArgTypes...)> {
50    X<R(ArgTypes...)> f();
51  };
52
53  template<typename R, typename ...ArgTypes>
54  X<R(ArgTypes...)> X<R(ArgTypes...)>::f() { return *this; }
55
56
57  X<int(float, double)> xif;
58
59  template<unsigned> struct unsigned_c { };
60  template<typename ...ArgTypes> int g(ArgTypes...);
61
62  template<typename F> struct X1;
63
64  template<typename R, typename ...ArgTypes>
65  struct X1<R(ArgTypes...)> {
66    unsigned_c<sizeof(1 + g(ArgTypes()...))> f();
67  };
68
69  template<typename R, typename ...ArgTypes>
70  unsigned_c<sizeof(1 + g(ArgTypes()...))> X1<R(ArgTypes...)>::f() {
71    return unsigned_c<sizeof(int)>();
72  }
73
74  X1<int(float, double)> xif2;
75}
76