Clang Project

clang_source_code/test/Modules/template-default-args.cpp
1// RUN: rm -rf %t
2// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN= -DEND=
3// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN="namespace N {" -DEND="}"
4
5BEGIN
6template<typename T> struct A;
7template<typename T> struct B;
8template<typename T> struct C;
9template<typename T = int> struct D;
10template<typename T = int> struct E {};
11template<typename T> struct H {};
12template<typename T = int, typename U = int> struct I {};
13END
14
15#include "b.h"
16#include "d.h"
17
18BEGIN
19template<typename T = int> struct A {};
20template<typename T> struct B {};
21template<typename T = int> struct B;
22template<typename T = int> struct C;
23template<typename T> struct D {};
24template<typename T> struct F {};
25template<typename T> struct G {};
26template<typename T> struct J {};
27template<typename T = int> struct J;
28struct K : J<> {};
29END
30
31#include "c.h"
32
33BEGIN
34A<> a;
35B<> b;
36extern C<> c;
37D<> d;
38E<> e;
39F<> f;
40G<> g; // expected-error {{default argument of 'G' must be imported from module 'X.A' before it is required}}
41// expected-note@a.h:7 {{default argument declared here}}
42H<> h; // expected-error {{default argument of 'H' must be imported from module 'X.A' before it is required}}
43// expected-note@a.h:8 {{default argument declared here}}
44I<> i;
45L<> *l;
46END
47
48namespace DeferredLookup {
49  template<typename T, typename U = T> using X = U;
50  template<typename T> void f() { (void) X<T>(); }
51  template<typename T> int n = X<T>(); // expected-warning {{extension}}
52  template<typename T> struct S { X<T> xt; enum E : int; };
53  template<typename T> enum S<T>::E : int { a = X<T>() };
54
55  void test() {
56    f<int>();
57    n<int> = 1;
58    S<int> s;
59    S<int>::E e = S<int>::E::a;
60
61    Indirect::B<int>::C<int> indirect;
62  }
63}
64