13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only %s
20760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char one_byte;
30760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&two_bytes)[2];
40760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&four_bytes)[4];
50760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&eight_bytes)[8];
60760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
70760636d458c860beeb77a63049e91e614b4be31Douglas Gregortemplate<int N> struct A { };
80760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
90760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N1 {
100760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  struct X { };
110760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
120760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
130760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N2 {
140760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  struct Y { };
150760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
160760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  two_bytes operator+(Y, Y);
170760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
180760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
190760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N3 {
200760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  struct Z { };
210760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
220760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  eight_bytes operator+(Z, Z);
230760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
240760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
250760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N4 {
260760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  one_byte operator+(N1::X, N2::Y);
270760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
280760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  template<typename T, typename U>
290760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  struct BinOpOverload {
300760636d458c860beeb77a63049e91e614b4be31Douglas Gregor    typedef A<sizeof(T() + U())> type;
310760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  };
320760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
330760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
340760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N1 {
350760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  four_bytes operator+(X, X);
360760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
370760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
380760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N3 {
390760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  eight_bytes operator+(Z, Z); // redeclaration
400760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
410760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
420760636d458c860beeb77a63049e91e614b4be31Douglas Gregorvoid test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
430760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
440760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  XY *xy = a1;
450760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
460760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  XX *xx = a4;
470760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
480760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  YY *yy = a2;
490760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
500760636d458c860beeb77a63049e91e614b4be31Douglas Gregor  ZZ *zz = a8;
510760636d458c860beeb77a63049e91e614b4be31Douglas Gregor}
520760636d458c860beeb77a63049e91e614b4be31Douglas Gregor
53c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregornamespace N3 {
54c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  eight_bytes operator-(::N3::Z);
55c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor}
56c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor
57c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregornamespace N4 {
58c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  template<typename T>
59c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  struct UnaryOpOverload {
60c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor    typedef A<sizeof(-T())> type;
61c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  };
62c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor}
63c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor
64c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregorvoid test_unary_op_overload(A<8> *a8) {
65c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  typedef N4::UnaryOpOverload<N3::Z>::type UZ;
66c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor  UZ *uz = a8;
67c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor}
688a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
698a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif/*
708a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greifnamespace N5 {
718a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  template<int I>
728a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  struct Lookup {
738a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif    enum { val = I, more = val + 1 };
748a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  };
758a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
768a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  template<bool B>
778a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  struct Cond {
788a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif    enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
798a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  };
808a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
818a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  enum { resultT = Cond<true>::is,
828a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif         resultF = Cond<false>::is };
838a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif}
848a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif*/
858a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
868a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greifnamespace N6 {
87b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  // non-typedependent
888a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  template<int I>
89b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  struct Lookup {};
908a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
918a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  template<bool B, typename T, typename E>
928a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  struct Cond {
938a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif    typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
948a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif    typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
958a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  };
968a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
978a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif  typedef Cond<true, int, char>::True True;
9876368bbd3f5a8433a863798727e41af9afbf598dGabor Greif  typedef Cond<true, int, char>::False False;
9976368bbd3f5a8433a863798727e41af9afbf598dGabor Greif
10076368bbd3f5a8433a863798727e41af9afbf598dGabor Greif  // check that we have the right types
10176368bbd3f5a8433a863798727e41af9afbf598dGabor Greif  Lookup<1> const &L1(False());
10276368bbd3f5a8433a863798727e41af9afbf598dGabor Greif  Lookup<sizeof(int)> const &L2(True());
1038a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif}
1048a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
1058a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif
106b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greifnamespace N7 {
107b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  // type dependent
108b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  template<int I>
109b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  struct Lookup {};
110b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif
111b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  template<bool B, typename T, typename E>
112b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  struct Cond {
113b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif    T foo() { return B ? T() : E(); }
114b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif    typedef Lookup<sizeof(B ? T() : E())> Type;
115b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  };
116b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif
117b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  //Cond<true, int*, double> C; // Errors
118b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  //int V(C.foo()); // Errors
1195f62c5e91eeee5847b637b9820d5b3009d035dc1Douglas Gregor  //typedef Cond<true, int*, double>::Type Type; // Errors
120b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif  typedef Cond<true, int, double>::Type Type;
121b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif}
122b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif
123260059cab5bab4960880bc9155b32618201d7994Douglas Gregortemplate<typename T, unsigned long N> struct IntegralConstant { };
124260059cab5bab4960880bc9155b32618201d7994Douglas Gregor
125260059cab5bab4960880bc9155b32618201d7994Douglas Gregortemplate<typename T>
126260059cab5bab4960880bc9155b32618201d7994Douglas Gregorstruct X0 {
127260059cab5bab4960880bc9155b32618201d7994Douglas Gregor  void f(T x, IntegralConstant<T, sizeof(x)>);
128260059cab5bab4960880bc9155b32618201d7994Douglas Gregor};
129260059cab5bab4960880bc9155b32618201d7994Douglas Gregor
130260059cab5bab4960880bc9155b32618201d7994Douglas Gregorvoid test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
1315f62c5e91eeee5847b637b9820d5b3009d035dc1Douglas Gregor  x.f(5,ic);
132260059cab5bab4960880bc9155b32618201d7994Douglas Gregor}
1333b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor
1343b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregornamespace N8 {
1353b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  struct X {
1363b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor    X operator+(const X&) const;
1373b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  };
1383b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor
1393b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  template<typename T>
1403b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  T test_plus(const T* xp, const T& x, const T& y) {
1413b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor    x.operator+(y);
1423b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor    return xp->operator+(y);
1433b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  }
1443b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor
1453b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  void test_test_plus(X x) {
1463b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor    test_plus(&x, x, x);
1473b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor  }
1483b4dc7c723dd16a3c02a73f40204da6953dc0094Douglas Gregor}
14923026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor
15023026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregornamespace N9 {
15123026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor  struct A {
15223026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor    bool operator==(int value);
15323026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor  };
15423026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor
15523026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor  template<typename T> struct B {
15623026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor    bool f(A a) {
15723026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor      return a == 1;
15823026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor    }
15923026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor  };
16023026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor
16123026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor  template struct B<int>;
16223026c84139c97017f9eaa148a39ff346fc0e42dDouglas Gregor}
163464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor
164464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregornamespace N10 {
165464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  template <typename T>
166464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  class A {
167464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor    struct X { };
168464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor
169464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  public:
170464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor    ~A() {
171464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor      f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0));
172464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor    }
173464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor
174464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  private:
175464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor    void f(X *);
176464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor    void f(X *, X *);
177464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  };
178464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor
179464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor  template class A<int>;
180464fa061a15708f985cb83c59ea0dae86d7cf240Douglas Gregor}
1818dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor
1828dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregornamespace N12 {
1838dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  // PR5224
1848dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  template<typename T>
1858dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  struct A { typedef int t0; };
1868dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor
1878dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  struct C  {
1888dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor    C(int);
1898dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor
1908dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor    template<typename T>
1918dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor    static C *f0(T a0) {return new C((typename A<T>::t0) 1);   }
1928dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  };
1938dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor
1948dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor  void f0(int **a) { C::f0(a); }
1958dca9d5ab574d0a2ce3d16546eaff0e5f3dfe2d1Douglas Gregor}
196fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor
1976d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregornamespace PR7202 {
1986d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  template<typename U, typename T>
1996d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  struct meta {
2006d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    typedef T type;
2016d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  };
2026d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2036d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  struct X {
2046d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    struct dummy;
2056d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2066d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    template<typename T>
2076d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    X(T, typename meta<T, dummy*>::type = 0);
2086d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2096d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    template<typename T, typename A>
2106d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    X(T, A);
2116d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  };
2126d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2136d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  template<typename T>
2146d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  struct Z { };
2156d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2166d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  template<typename T> Z<T> g(T);
2176d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2186d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  struct Y {
2196d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    template<typename T>
2206d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    void f(T t) {
2216d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor      new X(g(*this));
2226d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor    }
2236d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  };
2246d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
2256d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor  template void Y::f(int);
2266d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor}
2276d10a8a246505c4ebe05f7693cda74480f0ab05bDouglas Gregor
228fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregornamespace N13 {
229fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  class A{
230fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor    A(const A&);
231fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor
232fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  public:
233fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor    ~A();
234fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor    A(int);
235fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor    template<typename T> A &operator<<(const T&);
236fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  };
237fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor
238fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  template<typename T>
239fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  void f(T t) {
240fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor    A(17) << t;
241fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  }
242fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor
243fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor  template void f(int);
244fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor
245fe891e194e27f77ff564c5a19abf09b6e03afdbaDouglas Gregor}
246