Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -std=c++11 -verify %s -fms-extensions -triple x86_64-apple-darwin9.0.0
      2 
      3 using size_t = decltype(sizeof(int));
      4 enum class LitKind {
      5   Char, WideChar, Char16, Char32,
      6   CharStr, WideStr, Char16Str, Char32Str,
      7   Integer, Floating, Raw, Template
      8 };
      9 constexpr LitKind operator"" _kind(char p) { return LitKind::Char; }
     10 constexpr LitKind operator"" _kind(wchar_t p) { return LitKind::WideChar; }
     11 constexpr LitKind operator"" _kind(char16_t p) { return LitKind::Char16; }
     12 constexpr LitKind operator"" _kind(char32_t p) { return LitKind::Char32; }
     13 constexpr LitKind operator"" _kind(const char *p, size_t n) { return LitKind::CharStr; }
     14 constexpr LitKind operator"" _kind(const wchar_t *p, size_t n) { return LitKind::WideStr; }
     15 constexpr LitKind operator"" _kind(const char16_t *p, size_t n) { return LitKind::Char16Str; }
     16 constexpr LitKind operator"" _kind(const char32_t *p, size_t n) { return LitKind::Char32Str; }
     17 constexpr LitKind operator"" _kind(unsigned long long n) { return LitKind::Integer; }
     18 constexpr LitKind operator"" _kind(long double n) { return LitKind::Floating; }
     19 constexpr LitKind operator"" _kind2(const char *p) { return LitKind::Raw; }
     20 template<char ...Cs> constexpr LitKind operator"" _kind3() { return LitKind::Template; }
     21 
     22 static_assert('x'_kind == LitKind::Char, "");
     23 static_assert(L'x'_kind == LitKind::WideChar, "");
     24 static_assert(u'x'_kind == LitKind::Char16, "");
     25 static_assert(U'x'_kind == LitKind::Char32, "");
     26 static_assert("foo"_kind == LitKind::CharStr, "");
     27 static_assert(u8"foo"_kind == LitKind::CharStr, "");
     28 static_assert(L"foo"_kind == LitKind::WideStr, "");
     29 static_assert(u"foo"_kind == LitKind::Char16Str, "");
     30 static_assert(U"foo"_kind == LitKind::Char32Str, "");
     31 static_assert(194_kind == LitKind::Integer, "");
     32 static_assert(0377_kind == LitKind::Integer, "");
     33 static_assert(0x5ffc_kind == LitKind::Integer, "");
     34 static_assert(.5954_kind == LitKind::Floating, "");
     35 static_assert(1._kind == LitKind::Floating, "");
     36 static_assert(1.e-2_kind == LitKind::Floating, "");
     37 static_assert(4e6_kind == LitKind::Floating, "");
     38 static_assert(4e6_kind2 == LitKind::Raw, "");
     39 static_assert(4e6_kind3 == LitKind::Template, "");
     40 
     41 constexpr const char *fractional_digits_impl(const char *p) {
     42   return *p == '.' ? p + 1 : *p ? fractional_digits_impl(p + 1) : 0;
     43 }
     44 constexpr const char *operator"" _fractional_digits(const char *p) {
     45   return fractional_digits_impl(p) ?: p;
     46 }
     47 constexpr bool streq(const char *p, const char *q) {
     48   return *p == *q && (!*p || streq(p+1, q+1));
     49 }
     50 
     51 static_assert(streq(143.97_fractional_digits, "97"), "");
     52 static_assert(streq(0x786_fractional_digits, "0x786"), "");
     53 static_assert(streq(.4_fractional_digits, "4"), "");
     54 static_assert(streq(4._fractional_digits, ""), "");
     55 static_assert(streq(1e+97_fractional_digits, "1e+97"), "");
     56 static_assert(streq(0377_fractional_digits, "0377"), "");
     57 static_assert(streq(0377.5_fractional_digits, "5"), "");
     58 
     59 int operator"" _ambiguous(char); // expected-note {{candidate}}
     60 namespace N {
     61   void *operator"" _ambiguous(char); // expected-note {{candidate}}
     62 }
     63 using namespace N;
     64 int k = 'x'_ambiguous; // expected-error {{ambiguous}}
     65 
     66 int operator"" _deleted(unsigned long long) = delete; // expected-note {{here}}
     67 int m = 42_deleted; // expected-error {{attempt to use a deleted}}
     68 
     69 namespace Using {
     70   namespace M {
     71     int operator"" _using(char);
     72   }
     73   int k1 = 'x'_using; // expected-error {{no matching literal operator for call to 'operator""_using'}}
     74 
     75   using M::operator "" _using;
     76   int k2 = 'x'_using;
     77 }
     78 
     79 namespace AmbiguousRawTemplate {
     80   int operator"" _ambig1(const char *); // expected-note {{candidate}}
     81   template<char...> int operator"" _ambig1(); // expected-note {{candidate}}
     82 
     83   int k1 = 123_ambig1; // expected-error {{call to 'operator""_ambig1' is ambiguous}}
     84 
     85   namespace Inner {
     86     template<char...> int operator"" _ambig2(); // expected-note 3{{candidate}}
     87   }
     88   int operator"" _ambig2(const char *); // expected-note 3{{candidate}}
     89   using Inner::operator"" _ambig2;
     90 
     91   int k2 = 123_ambig2; // expected-error {{call to 'operator""_ambig2' is ambiguous}}
     92 
     93   namespace N {
     94     using Inner::operator"" _ambig2;
     95 
     96     int k3 = 123_ambig2; // ok
     97 
     98     using AmbiguousRawTemplate::operator"" _ambig2;
     99 
    100     int k4 = 123_ambig2; // expected-error {{ambiguous}}
    101 
    102     namespace M {
    103 
    104       template<char...> int operator"" _ambig2();
    105 
    106       int k5 = 123_ambig2; // ok
    107     }
    108 
    109     int operator"" _ambig2(unsigned long long);
    110 
    111     int k6 = 123_ambig2; // ok
    112     int k7 = 123._ambig2; // expected-error {{ambiguous}}
    113   }
    114 }
    115 
    116 constexpr unsigned mash(unsigned a) {
    117  return 0x93ae27b5 * ((a >> 13) | a << 19);
    118 }
    119 template<typename=void> constexpr unsigned hash(unsigned a) { return a; }
    120 template<char C, char...Cs> constexpr unsigned hash(unsigned a) {
    121  return hash<Cs...>(mash(a ^ mash(C)));
    122 }
    123 template<typename T, T v> struct constant { constexpr static T value = v; };
    124 template<char...Cs> constexpr unsigned operator"" _hash() {
    125   return constant<unsigned, hash<Cs...>(0)>::value;
    126 }
    127 static_assert(0x1234_hash == 0x103eff5e, "");
    128 static_assert(hash<'0', 'x', '1', '2', '3', '4'>(0) == 0x103eff5e, "");
    129 
    130 // Functions and literal suffixes go in separate namespaces.
    131 namespace Namespace {
    132   template<char...> int operator"" _x();
    133   int k = _x(); // expected-error {{undeclared identifier '_x'}}
    134 
    135   int _y(unsigned long long);
    136   int k2 = 123_y; // expected-error {{no matching literal operator for call to 'operator""_y'}}
    137 }
    138 
    139 namespace PR14950 {
    140   template<...> // expected-error {{expected template parameter}}
    141   int operator"" _b(); // expected-error {{no function template matches function template specialization}}
    142   int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator""_b'}}
    143 }
    144 
    145 namespace bad_names {
    146   template<char...> int operator""_x();
    147 
    148   template<typename T> void f() {
    149     class T:: // expected-error {{anonymous class}} expected-warning {{does not declare anything}}
    150         operator // expected-error {{expected identifier}}
    151             ""_q<'a'>;
    152 
    153     T::template operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
    154     T::template operator""_q<'a'>::X; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
    155     T::operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
    156     typename T::template operator""_q<'a'> a; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
    157     typename T::operator""_q(""); // expected-error +{{}} expected-note {{to match}}
    158     T::operator""_q(""); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}}
    159 
    160     bad_names::operator""_x<'a', 'b', 'c'>();
    161   };
    162 
    163   struct S {};
    164   void g() {
    165     S::operator""_q(); // expected-error {{non-namespace scope 'S::' cannot have a literal operator member}}
    166   }
    167 }
    168