cxx1y-variable-templates.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // No PCH:
  2. // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH
  3. // RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH -DERROR
  4. //
  5. // With PCH:
  6. // RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t.a -DHEADER1
  7. // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b -DHEADER2
  8. // RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE
  9. #ifndef ERROR
  10. // expected-no-diagnostics
  11. #endif
  12. #ifdef NONPCH
  13. #if !defined(HEADER1)
  14. #define HEADER1
  15. #undef HEADER2
  16. #undef HEADERUSE
  17. #elif !defined(HEADER2)
  18. #define HEADER2
  19. #undef HEADERUSE
  20. #else
  21. #define HEADERUSE
  22. #undef HEADER1
  23. #undef HEADER2
  24. #endif
  25. #endif
  26. // *** HEADER1: First header file
  27. #if defined(HEADER1) && !defined(HEADER2) && !defined(HEADERUSE)
  28. template<typename T> T var0a = T();
  29. template<typename T> extern T var0b;
  30. namespace join {
  31. template<typename T> T va = T(100);
  32. template<typename T> extern T vb;
  33. namespace diff_types {
  34. #ifdef ERROR
  35. template<typename T> extern float err0;
  36. template<typename T> extern T err1;
  37. #endif
  38. template<typename T> extern T def;
  39. }
  40. }
  41. namespace spec {
  42. template<typename T> constexpr T va = T(10);
  43. template<> constexpr float va<float> = 1.5;
  44. template constexpr int va<int>;
  45. template<typename T> T vb = T();
  46. template<> constexpr float vb<float> = 1.5;
  47. template<typename T> T vc = T();
  48. template<typename T> constexpr T vd = T(10);
  49. template<typename T> T* vd<T*> = new T();
  50. }
  51. namespace spec_join1 {
  52. template<typename T> T va = T(10);
  53. template<> extern float va<float>;
  54. extern template int va<int>;
  55. template<typename T> T vb = T(10);
  56. template<> extern float vb<float>;
  57. template<typename T> T vc = T(10);
  58. template<typename T> T vd = T(10);
  59. template<typename T> extern T* vd<T*>;
  60. }
  61. #endif
  62. // *** HEADER2: Second header file -- including HEADER1
  63. #if defined(HEADER2) && !defined(HEADERUSE)
  64. namespace join {
  65. template<typename T> extern T va;
  66. template<> constexpr float va<float> = 2.5;
  67. template<typename T> T vb = T(100);
  68. namespace diff_types {
  69. #ifdef ERROR
  70. template<typename T> extern T err0; // expected-error {{redeclaration of 'err0' with a different type: 'T' vs 'float'}} // expected-note@42 {{previous declaration is here}}
  71. template<typename T> extern float err1; // expected-error {{redeclaration of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous declaration is here}}
  72. #endif
  73. template<typename T> extern T def;
  74. }
  75. }
  76. namespace spec_join1 {
  77. template<typename T> extern T va;
  78. template<> float va<float> = 1.5;
  79. extern template int va<int>;
  80. template<> float vb<float> = 1.5;
  81. template int vb<int>;
  82. template<> float vc<float> = 1.5;
  83. template int vc<int>;
  84. template<typename T> extern T vd;
  85. template<typename T> T* vd<T*> = new T();
  86. }
  87. #endif
  88. // *** HEADERUSE: File using both header files -- including HEADER2
  89. #ifdef HEADERUSE
  90. template int var0a<int>;
  91. float fvara = var0a<float>;
  92. template<typename T> extern T var0a;
  93. template<typename T> T var0b = T();
  94. template int var0b<int>;
  95. float fvarb = var0b<float>;
  96. namespace join {
  97. template const int va<const int>;
  98. template<> const int va<int> = 50;
  99. static_assert(va<float> == 2.5, "");
  100. static_assert(va<int> == 50, "");
  101. template<> constexpr float vb<float> = 2.5;
  102. template const int vb<const int>;
  103. static_assert(vb<float> == 2.5, "");
  104. static_assert(vb<const int> == 100, "");
  105. namespace diff_types {
  106. template<typename T> T def = T();
  107. }
  108. }
  109. namespace spec {
  110. static_assert(va<float> == 1.5, "");
  111. static_assert(va<int> == 10, "");
  112. template<typename T> T* vb<T*> = new T();
  113. int* intpb = vb<int*>;
  114. static_assert(vb<float> == 1.5, "");
  115. template<typename T> T* vc<T*> = new T();
  116. template<> constexpr float vc<float> = 1.5;
  117. int* intpc = vc<int*>;
  118. static_assert(vc<float> == 1.5, "");
  119. char* intpd = vd<char*>;
  120. }
  121. namespace spec_join1 {
  122. template int va<int>;
  123. int a = va<int>;
  124. template<typename T> extern T vb;
  125. int b = vb<int>;
  126. int* intpb = vd<int*>;
  127. }
  128. #endif