2013-05-03 07:25:32 +08:00
// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
2018-01-05 07:42:29 +08:00
// RUN: not %clang_cc1 -std=gnu++11 -ast-dump %s | FileCheck %s
2010-05-19 07:01:22 +08:00
2010-06-25 11:22:07 +08:00
namespace attribute_aligned {
template < int N >
struct X {
char c [ 1 ] __attribute__ ( ( __aligned__ ( ( N ) ) ) ) ; // expected-error {{alignment is not a power of 2}}
} ;
2010-05-19 07:01:22 +08:00
2010-06-25 11:22:07 +08:00
template < bool X > struct check {
2011-01-04 12:44:35 +08:00
int check_failed [ X ? 1 : - 1 ] ; // expected-error {{array with a negative size}}
2010-06-25 11:22:07 +08:00
} ;
template < int N > struct check_alignment {
typedef check < N = = sizeof ( X < N > ) > t ; // expected-note {{in instantiation}}
} ;
check_alignment < 1 > : : t c1 ;
check_alignment < 2 > : : t c2 ;
check_alignment < 3 > : : t c3 ; // expected-note 2 {{in instantiation}}
check_alignment < 4 > : : t c4 ;
2013-05-03 07:25:32 +08:00
template < unsigned Size , unsigned Align >
class my_aligned_storage
{
2014-01-14 05:30:03 +08:00
__attribute__ ( ( aligned ( Align ) ) ) char storage [ Size ] ;
2013-05-03 07:25:32 +08:00
} ;
template < typename T >
class C {
public :
C ( ) {
static_assert ( sizeof ( t ) = = sizeof ( T ) , " my_aligned_storage size wrong " ) ;
static_assert ( alignof ( t ) = = alignof ( T ) , " my_aligned_storage align wrong " ) ; // expected-warning{{'alignof' applied to an expression is a GNU extension}}
}
private :
my_aligned_storage < sizeof ( T ) , alignof ( T ) > t ;
} ;
C < double > cd ;
2010-06-25 11:22:07 +08:00
}
2011-10-10 06:26:49 +08:00
namespace PR9049 {
extern const void * CFRetain ( const void * ref ) ;
template < typename T > __attribute__ ( ( cf_returns_retained ) )
inline T WBCFRetain ( T aValue ) { return aValue ? ( T ) CFRetain ( aValue ) : ( T ) 0 ; }
extern void CFRelease ( const void * ref ) ;
template < typename T >
inline void WBCFRelease ( __attribute__ ( ( cf_consumed ) ) T aValue ) { if ( aValue ) CFRelease ( aValue ) ; }
}
2018-01-05 07:42:29 +08:00
// CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
2018-06-26 04:06:13 +08:00
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
2018-08-03 09:21:16 +08:00
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
2018-01-05 07:42:29 +08:00
// CHECK: FunctionDecl {{.*}} HasAnnotations
// CHECK: TemplateArgument type 'int'
2018-06-26 04:06:13 +08:00
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
2018-08-03 09:21:16 +08:00
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
2018-01-05 07:42:29 +08:00
template < typename T > [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations ( ) ;
void UseAnnotations ( ) { HasAnnotations < int > ( ) ; }
2020-11-12 09:12:18 +08:00
namespace preferred_name {
int x [[clang::preferred_name("frank")]] ; // expected-error {{expected a type}}
int y [[clang::preferred_name(int)]] ; // expected-warning {{'preferred_name' attribute only applies to class templates}}
struct [[clang::preferred_name(int)]] A ; // expected-warning {{'preferred_name' attribute only applies to class templates}}
template < typename T > struct [[clang::preferred_name(int)]] B ; // expected-error {{argument 'int' to 'preferred_name' attribute is not a typedef for a specialization of 'B'}}
template < typename T > struct C ;
using X = C < int > ; // expected-note {{'X' declared here}}
typedef C < float > Y ;
using Z = const C < double > ; // expected-note {{'Z' declared here}}
template < typename T > struct [[clang::preferred_name(C<int>)]] C ; // expected-error {{argument 'C<int>' to 'preferred_name' attribute is not a typedef for a specialization of 'C'}}
template < typename T > struct [[clang::preferred_name(X), clang::preferred_name(Y)]] C ;
template < typename T > struct [[clang::preferred_name(const X)]] C ; // expected-error {{argument 'const preferred_name::X'}}
template < typename T > struct [[clang::preferred_name(Z)]] C ; // expected-error {{argument 'preferred_name::Z' (aka 'const C<double>')}}
template < typename T > struct C { } ;
// CHECK: ClassTemplateDecl {{.*}} <line:[[@LINE-10]]:{{.*}} C
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
// CHECK: TemplateArgument type 'int'
// CHECK-NOT: PreferredNameAttr
// CHECK: PreferredNameAttr {{.*}} preferred_name::X
// CHECK-NOT: PreferredNameAttr
// CHECK: CXXRecordDecl
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
// CHECK: TemplateArgument type 'float'
// CHECK-NOT: PreferredNameAttr
// CHECK: PreferredNameAttr {{.*}} preferred_name::Y
// CHECK-NOT: PreferredNameAttr
// CHECK: CXXRecordDecl
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
// CHECK: TemplateArgument type 'double'
// CHECK-NOT: PreferredNameAttr
// CHECK: CXXRecordDecl
// Check this doesn't cause us to instantiate the same attribute multiple times.
C < float > * cf1 ;
C < float > * cf2 ;
void f ( C < int > a , C < float > b , C < double > c ) {
auto p = a ;
auto q = b ;
auto r = c ;
p . f ( ) ; // expected-error {{no member named 'f' in 'preferred_name::X'}}
q . f ( ) ; // expected-error {{no member named 'f' in 'preferred_name::Y'}}
r . f ( ) ; // expected-error {{no member named 'f' in 'preferred_name::C<double>'}}
}
template < typename T > struct D ;
using DInt = D < int > ;
template < typename T > struct __attribute__ ( ( __preferred_name__ ( DInt ) ) ) D { } ;
template struct D < int > ;
int use_dint = D < int > ( ) . get ( ) ; // expected-error {{no member named 'get' in 'preferred_name::DInt'}}
template < typename T > struct MemberTemplate {
template < typename U > struct Iter ;
using iterator = Iter < T > ;
using const_iterator = Iter < const T > ;
template < typename U >
struct [ [ clang : : preferred_name ( iterator ) ,
clang : : preferred_name ( const_iterator ) ] ] Iter { } ;
} ;
auto it = MemberTemplate < int > : : Iter < const int > ( ) ;
int n = it ; // expected-error {{no viable conversion from 'preferred_name::MemberTemplate<int>::const_iterator' to 'int'}}
2021-01-06 07:32:44 +08:00
template < int A , int B , typename . . . T > struct Foo ;
template < typename . . . T > using Bar = Foo < 1 , 2 , T . . . > ;
template < int A , int B , typename . . . T > struct [[clang::preferred_name(::preferred_name::Bar<T...>)]] Foo { } ;
Foo < 1 , 2 , int , float > : : nosuch x ; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}
2020-11-12 09:12:18 +08:00
}
2021-01-06 07:32:44 +08:00
: : preferred_name : : Foo < 1 , 2 , int , float > : : nosuch x ; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}