Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
      2 
      3 // MSVC should compile this file without errors.
      4 
      5 namespace test_basic {
      6 template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
      7 struct Foo { T x; };
      8 typedef int Baz;
      9 template struct Foo<>;
     10 }
     11 
     12 namespace test_namespace {
     13 namespace nested {
     14 template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
     15 struct Foo {
     16   static_assert(sizeof(T) == 4, "should get int, not double");
     17 };
     18 typedef int Baz;
     19 }
     20 typedef double Baz;
     21 template struct nested::Foo<>;
     22 }
     23 
     24 namespace test_inner_class_template {
     25 struct Outer {
     26   template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
     27   struct Foo {
     28     static_assert(sizeof(T) == 4, "should get int, not double");
     29   };
     30   typedef int Baz;
     31 };
     32 typedef double Baz;
     33 template struct Outer::Foo<>;
     34 }
     35 
     36 namespace test_nontype_param {
     37 template <typename T> struct Bar { T x; };
     38 typedef int Qux;
     39 template <Bar<Qux> *P>
     40 struct Foo {
     41 };
     42 Bar<int> g;
     43 template struct Foo<&g>;
     44 }
     45 
     46 // MSVC accepts this, but Clang doesn't.
     47 namespace test_template_instantiation_arg {
     48 template <typename T> struct Bar { T x; };
     49 template <typename T = Bar<Weber>>  // expected-error {{use of undeclared identifier 'Weber'}}
     50 struct Foo {
     51   static_assert(sizeof(T) == 4, "Bar should have gotten int");
     52   // FIXME: These diagnostics are bad.
     53 }; // expected-error {{expected ',' or '>' in template-parameter-list}}
     54 // expected-warning@-1 {{does not declare anything}}
     55 typedef int Weber;
     56 }
     57 
     58 // MSVC accepts this, but Clang doesn't.
     59 namespace test_scope_spec {
     60 template <typename T = ns::Bar>  // expected-error {{use of undeclared identifier 'ns'}}
     61 struct Foo {
     62   static_assert(sizeof(T) == 4, "Bar should have gotten int");
     63 };
     64 namespace ns { typedef int Bar; }
     65 }
     66 
     67 #ifdef __clang__
     68 // These are negative test cases that MSVC doesn't compile either.  Try to use
     69 // unique undeclared identifiers so typo correction doesn't find types declared
     70 // above.
     71 
     72 namespace test_undeclared_nontype_parm_type {
     73 template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
     74 struct Foo { int x[N]; };
     75 typedef int Zargon;
     76 template struct Foo<4>;
     77 }
     78 
     79 namespace test_undeclared_nontype_parm_type_no_name {
     80 template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
     81 struct Foo { T x; };
     82 template struct Foo<int, 0>;
     83 }
     84 
     85 namespace test_undeclared_type_arg {
     86 template <typename T>
     87 struct Foo { T x; };
     88 template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
     89 }
     90 
     91 namespace test_undeclared_nontype_parm_arg {
     92 // Bury an undeclared type as a template argument to the type of a non-type
     93 // template parameter.
     94 template <typename T> struct Bar { T x; };
     95 
     96 template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
     97 // expected-note@-1 {{template parameter is declared here}}
     98 struct Foo { };
     99 
    100 typedef int Xylophone;
    101 Bar<Xylophone> g;
    102 template struct Foo<&g>; // expected-error {{cannot be converted}}
    103 }
    104 
    105 #endif
    106