2015-10-08 08:17:59 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
2010-01-13 17:01:02 +08:00
# include <stddef.h>
2010-08-31 01:47:05 +08:00
struct tag {
2015-10-08 08:17:59 +08:00
void operator " " _tag_bad ( const char * ) ; // expected-error {{literal operator 'operator""_tag_bad' must be in a namespace or global scope}}
2011-08-31 06:40:35 +08:00
friend void operator " " _tag_good ( const char * ) ;
2010-01-13 17:01:02 +08:00
} ;
2011-08-31 06:40:35 +08:00
namespace ns { void operator " " _ns_good ( const char * ) ; }
2010-08-31 01:47:05 +08:00
// Check extern "C++" declarations
2011-08-31 06:40:35 +08:00
extern " C++ " void operator " " _extern_good ( const char * ) ;
extern " C++ " { void operator " " _extern_good ( const char * ) ; }
2010-08-31 01:47:05 +08:00
2012-03-11 06:18:57 +08:00
void fn ( ) { void operator " " _fn_good ( const char * ) ; }
2010-08-31 01:47:05 +08:00
// One-param declarations (const char * was already checked)
2011-08-31 06:40:35 +08:00
void operator " " _good ( char ) ;
void operator " " _good ( wchar_t ) ;
void operator " " _good ( char16_t ) ;
void operator " " _good ( char32_t ) ;
void operator " " _good ( unsigned long long ) ;
void operator " " _good ( long double ) ;
2010-01-13 17:01:02 +08:00
2010-08-31 01:47:05 +08:00
// Two-param declarations
2011-08-31 06:40:35 +08:00
void operator " " _good ( const char * , size_t ) ;
void operator " " _good ( const wchar_t * , size_t ) ;
void operator " " _good ( const char16_t * , size_t ) ;
void operator " " _good ( const char32_t * , size_t ) ;
2010-01-13 17:01:02 +08:00
2010-08-31 01:47:05 +08:00
// Check typedef and array equivalences
2011-08-31 06:40:35 +08:00
void operator " " _good ( const char [ ] ) ;
2010-08-31 01:47:05 +08:00
typedef const char c ;
2011-08-31 06:40:35 +08:00
void operator " " _good ( c * ) ;
2010-01-13 17:01:02 +08:00
2010-08-31 01:47:05 +08:00
// Check extra cv-qualifiers
2016-02-17 08:04:04 +08:00
void operator " " _cv_good ( volatile const char * , const size_t ) ; // expected-error {{invalid literal operator parameter type 'const volatile char *', did you mean 'const char *'?}}
2010-01-13 17:01:02 +08:00
2012-03-04 17:41:16 +08:00
// Template declaration
template < char . . . > void operator " " _good ( ) ;
2010-01-13 17:01:02 +08:00
2016-02-17 08:04:04 +08:00
template < typename . . . > void operator " " _invalid ( ) ; // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}}
template < wchar_t . . . > void operator " " _invalid ( ) ; // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}}
template < unsigned long long . . . > void operator " " _invalid ( ) ; // expected-error {{template parameter list for literal operator must be either 'char...' or 'typename T, T...'}}
2015-10-08 08:17:59 +08:00
_Complex float operator " " if ( long double ) ; // expected-warning {{reserved}}
_Complex float test_if_1 ( ) { return 2.0f + 1.5 if ; } ;
void test_if_2 ( ) { " foo " if ; } // expected-error {{no matching literal operator for call to 'operator""if'}}
2020-03-28 11:59:49 +08:00
template < typename T > void dependent_member_template ( ) {
T ( ) . template operator " " _foo < int > ( ) ; // expected-error {{'operator""_foo' following the 'template' keyword cannot refer to a dependent template}}
}