Home | History | Annotate | Download | only in PCH
      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 
     10 #ifndef ERROR
     11 // expected-no-diagnostics
     12 #endif
     13 
     14 #ifdef NONPCH
     15 #if !defined(HEADER1)
     16 #define HEADER1
     17 #undef HEADER2
     18 #undef HEADERUSE
     19 #elif !defined(HEADER2)
     20 #define HEADER2
     21 #undef HEADERUSE
     22 #else
     23 #define HEADERUSE
     24 #undef HEADER1
     25 #undef HEADER2
     26 #endif
     27 #endif
     28 
     29 
     30 // *** HEADER1: First header file
     31 #if defined(HEADER1) && !defined(HEADER2) && !defined(HEADERUSE)
     32 
     33 template<typename T> T var0a = T();
     34 template<typename T> extern T var0b;
     35 
     36 namespace join {
     37   template<typename T> T va = T(100);
     38   template<typename T> extern T vb;
     39 
     40   namespace diff_types {
     41 #ifdef ERROR
     42     template<typename T> extern float err0;
     43     template<typename T> extern T err1;
     44 #endif
     45     template<typename T> extern T def;
     46   }
     47 
     48 }
     49 
     50 namespace spec {
     51   template<typename T> constexpr T va = T(10);
     52   template<> constexpr float va<float> = 1.5;
     53   template constexpr int va<int>;
     54 
     55   template<typename T> T vb = T();
     56   template<> constexpr float vb<float> = 1.5;
     57 
     58   template<typename T> T vc = T();
     59 
     60   template<typename T> constexpr T vd = T(10);
     61   template<typename T> T* vd<T*> = new T();
     62 }
     63 
     64 namespace spec_join1 {
     65   template<typename T> T va = T(10);
     66   template<> extern float va<float>;
     67   extern template int va<int>;
     68 
     69   template<typename T> T vb = T(10);
     70   template<> extern float vb<float>;
     71 
     72   template<typename T> T vc = T(10);
     73 
     74   template<typename T> T vd = T(10);
     75   template<typename T> extern T* vd<T*>;
     76 }
     77 
     78 #endif
     79 
     80 
     81 // *** HEADER2: Second header file -- including HEADER1
     82 #if defined(HEADER2) && !defined(HEADERUSE)
     83 
     84 namespace join {
     85   template<typename T> extern T va;
     86   template<> constexpr float va<float> = 2.5;
     87 
     88   template<typename T> T vb = T(100);
     89 
     90   namespace diff_types {
     91 #ifdef ERROR
     92     template<typename T> extern T err0; // expected-error {{redefinition of 'err0' with a different type: 'T' vs 'float'}}  // expected-note@42 {{previous definition is here}}
     93     template<typename T> extern float err1; // expected-error {{redefinition of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous definition is here}}
     94 #endif
     95     template<typename T> extern T def;
     96   }
     97 }
     98 
     99 namespace spec_join1 {
    100   template<typename T> extern T va;
    101   template<> float va<float> = 1.5;
    102   extern template int va<int>;
    103 
    104   template<> float vb<float> = 1.5;
    105   template int vb<int>;
    106 
    107   template<> float vc<float> = 1.5;
    108   template int vc<int>;
    109 
    110   template<typename T> extern T vd;
    111   template<typename T> T* vd<T*> = new T();
    112 }
    113 
    114 #endif
    115 
    116 // *** HEADERUSE: File using both header files -- including HEADER2
    117 #ifdef HEADERUSE
    118 
    119 template int var0a<int>;
    120 float fvara = var0a<float>;
    121 
    122 template<typename T> extern T var0a;
    123 
    124 template<typename T> T var0b = T();
    125 template int var0b<int>;
    126 float fvarb = var0b<float>;
    127 
    128 namespace join {
    129   template const int va<const int>;
    130   template<> const int va<int> = 50;
    131   static_assert(va<float> == 2.5, "");
    132   static_assert(va<int> == 50, "");
    133 
    134   template<> constexpr float vb<float> = 2.5;
    135   template const int vb<const int>;
    136   static_assert(vb<float> == 2.5, "");
    137   static_assert(vb<const int> == 100, "");
    138 
    139   namespace diff_types {
    140     template<typename T> T def = T();
    141   }
    142 
    143 }
    144 
    145 namespace spec {
    146   static_assert(va<float> == 1.5, "");
    147   static_assert(va<int> == 10, "");
    148 
    149   template<typename T> T* vb<T*> = new T();
    150   int* intpb = vb<int*>;
    151   static_assert(vb<float> == 1.5, "");
    152 
    153   template<typename T> T* vc<T*> = new T();
    154   template<> constexpr float vc<float> = 1.5;
    155   int* intpc = vc<int*>;
    156   static_assert(vc<float> == 1.5, "");
    157 
    158   char* intpd = vd<char*>;
    159 }
    160 
    161 namespace spec_join1 {
    162   template int va<int>;
    163   int a = va<int>;
    164 
    165   template<typename T> extern T vb;
    166   int b = vb<int>;
    167 
    168   int* intpb = vd<int*>;
    169 }
    170 
    171 #endif
    172