// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
// RUN: not %clang_cc1 -std=gnu++11 -ast-dump %s | FileCheck %s
namespace attribute_aligned {
template<int N>
struct X {
char c[1] __attribute__((__aligned__((N)))); // expected-error {{alignment is not a power of 2}}
};
template <bool X> struct check {
int check_failed[X ? 1 : -1]; // expected-error {{array with a negative size}}
};
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;
template<unsigned Size, unsigned Align>
class my_aligned_storage
{
__attribute__((aligned(Align))) char storage[Size];
};
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;
}
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); }
}
namespace attribute_annotate {
// CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
// CHECK: FunctionDecl {{.*}} HasAnnotations
// CHECK: TemplateArgument type 'int'
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
void UseAnnotations() { HasAnnotations<int>(); }
// CHECK: FunctionTemplateDecl {{.*}} HasPackAnnotations
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: FunctionDecl {{.*}} HasPackAnnotations 'void ()'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BAZ"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: FunctionDecl {{.*}} used HasPackAnnotations 'void ()'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BAZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 2
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 3
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
template <int... Is> [[clang::annotate("ANNOTATE_BAZ", Is...)]] void HasPackAnnotations();
void UsePackAnnotations() { HasPackAnnotations<1, 2, 3>(); }
template <int... Is> [[clang::annotate(Is...)]] void HasOnlyPackAnnotation() {} // expected-error {{expected string literal as argument of 'annotate' attribute}}
void UseOnlyPackAnnotations() {
HasOnlyPackAnnotation<>();
HasOnlyPackAnnotation<1>();
}
// CHECK: ClassTemplateDecl {{.*}} AnnotatedPackTemplateStruct
// CHECK-NEXT: TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 1 ... Is
// CHECK-NEXT: CXXRecordDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOO"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 2
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 3
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 5
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 6
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument type 'bool'
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: TemplateArgument{{.*}} integral '8'
// CHECK-NEXT: TemplateArgument{{.*}} integral '9'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 7
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 1 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 7
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 8
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 1 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 9
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 1 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 9
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument type 'char'
// CHECK-NEXT: BuiltinType {{.*}} 'char'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'char'
// CHECK-NEXT: BuiltinType {{.*}} 'char'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplatePartialSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} expr
// CHECK-NEXT: PackExpansionExpr {{.*}} 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOO"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplatePartialSpecializationDecl {{.*}} struct AnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} expr
// CHECK-NEXT: PackExpansionExpr {{.*}} 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 5
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 6
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct AnnotatedPackTemplateStruct
template <typename T, int... Is> struct [[clang::annotate("ANNOTATE_FOZ", Is...)]] AnnotatedPackTemplateStruct{};
template <int... Is> struct [[clang::annotate("ANNOTATE_BOO", Is...)]] AnnotatedPackTemplateStruct<int, Is...>{};
template <int... Is> struct [[clang::annotate("ANNOTATE_FOZ", 4, 5, 6)]] AnnotatedPackTemplateStruct<float, Is...>{};
template <int... Is> struct [[clang::annotate(Is...)]] AnnotatedPackTemplateStruct<char, Is...>{}; // expected-error {{expected string literal as argument of 'annotate' attribute}}
void UseAnnotatedPackTemplateStructSpecializations() {
AnnotatedPackTemplateStruct<int, 1, 2, 3> Instance1{};
AnnotatedPackTemplateStruct<float, 3, 2, 1> Instance2{};
AnnotatedPackTemplateStruct<bool, 7, 8, 9> Instance3{};
AnnotatedPackTemplateStruct<char, 1, 2, 3> Instance4{};
AnnotatedPackTemplateStruct<char> Instance5{};
}
// CHECK: ClassTemplateDecl {{.*}} InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} 'int' depth 0 index 1 ... Is
// CHECK-NEXT: CXXRecordDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecialization {{.*}} 'InvalidAnnotatedPackTemplateStruct'
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BIR"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 2
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 3
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'bool'
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: TemplateArgument{{.*}} integral '8'
// CHECK-NEXT: TemplateArgument{{.*}} integral '9'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'bool'
// CHECK-NEXT: BuiltinType {{.*}} 'bool'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplatePartialSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'int'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} expr
// CHECK-NEXT: PackExpansionExpr {{.*}} 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BIR"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplatePartialSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'float'
// CHECK-NEXT: BuiltinType {{.*}} 'float'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} expr
// CHECK-NEXT: PackExpansionExpr {{.*}} 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
// CHECK-NEXT: ClassTemplateSpecializationDecl {{.*}} struct InvalidAnnotatedPackTemplateStruct definition
// CHECK-NEXT: DefinitionData
// CHECK-NEXT: DefaultConstructor
// CHECK-NEXT: CopyConstructor
// CHECK-NEXT: MoveConstructor
// CHECK-NEXT: CopyAssignment
// CHECK-NEXT: MoveAssignment
// CHECK-NEXT: Destructor
// CHECK-NEXT: TemplateArgument{{.*}} type 'char'
// CHECK-NEXT: BuiltinType {{.*}} 'char'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '5'
// CHECK-NEXT: TemplateArgument{{.*}} integral '6'
// CHECK-NEXT: TemplateArgument{{.*}} integral '7'
// CHECK-NEXT: CXXRecordDecl {{.*}} implicit struct InvalidAnnotatedPackTemplateStruct
template <typename T, int... Is> struct InvalidAnnotatedPackTemplateStruct{};
template <int... Is> struct [[clang::annotate("ANNOTATE_BIR", Is...)]] InvalidAnnotatedPackTemplateStruct<int, Is...>{};
template <int... Is> struct InvalidAnnotatedPackTemplateStruct<float, Is...> {};
template <> struct InvalidAnnotatedPackTemplateStruct<char, 5, 6, 7> {};
void UseInvalidAnnotatedPackTemplateStruct() {
InvalidAnnotatedPackTemplateStruct<int, 1, 2, 3> Instance1{};
InvalidAnnotatedPackTemplateStruct<float, 3, 2, 1> Instance2{};
InvalidAnnotatedPackTemplateStruct<char, 5, 6, 7> Instance3{};
InvalidAnnotatedPackTemplateStruct<bool, 7, 8, 9> Instance4{};
InvalidAnnotatedPackTemplateStruct<bool> Instance5{};
}
// CHECK: FunctionTemplateDecl {{.*}} RedeclaredAnnotatedFunc
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: FunctionDecl {{.*}} RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FAR"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: FunctionDecl {{.*}} used RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: TemplateArgument{{.*}} pack
// CHECK-NEXT: TemplateArgument{{.*}} integral '1'
// CHECK-NEXT: TemplateArgument{{.*}} integral '2'
// CHECK-NEXT: TemplateArgument{{.*}} integral '3'
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FAR"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 1
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 2
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 3
// CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} 'int'
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FIZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 5
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 6
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
// CHECK-NEXT: FunctionTemplateDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} referenced 'int' depth 0 index 0 ... Is
// CHECK-NEXT: FunctionDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: AnnotateAttr {{.*}} Inherited "ANNOTATE_FAR"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOZ"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: Function {{.*}} 'RedeclaredAnnotatedFunc' 'void ()'
// CHECK-NEXT: FunctionTemplateDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} 'int' depth 0 index 0 ... Is
// CHECK-NEXT: FunctionDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: AnnotateAttr {{.*}} Inherited "ANNOTATE_FAR"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: AnnotateAttr {{.*}} Inherited "ANNOTATE_BOZ"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_FIZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 5
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
// CHECK-NEXT: Function {{.*}} 'RedeclaredAnnotatedFunc' 'void ()'
// CHECK-NEXT: FunctionTemplateDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} 'int' depth 0 index 0 ... Is
// CHECK-NEXT: FunctionDecl {{.*}} prev {{.*}} RedeclaredAnnotatedFunc 'void ()'
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: AnnotateAttr {{.*}} Inherited "ANNOTATE_FAR"
// CHECK-NEXT: PackExpansionExpr {{.*}} '<dependent type>'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' NonTypeTemplateParm {{.*}} 'Is' 'int'
// CHECK-NEXT: AnnotateAttr {{.*}} Inherited "ANNOTATE_FIZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 4
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 5
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
// CHECK-NEXT: AnnotateAttr {{.*}} "ANNOTATE_BOZ"
// CHECK-NEXT: ConstantExpr {{.*}} 'int'
// CHECK-NEXT: value: Int 6
// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
// CHECK-NEXT: Function {{.*}} 'RedeclaredAnnotatedFunc' 'void ()'
// CHECK-NEXT: EmptyDecl
template <int... Is> [[clang::annotate("ANNOTATE_FAR", Is...)]] void RedeclaredAnnotatedFunc();
template <int... Is> [[clang::annotate("ANNOTATE_BOZ", Is...)]] void RedeclaredAnnotatedFunc();
template <int... Is> [[clang::annotate("ANNOTATE_FIZ", 4, 5)]] void RedeclaredAnnotatedFunc();
template <int... Is> [[clang::annotate("ANNOTATE_BOZ", 6)]] void RedeclaredAnnotatedFunc(){};
void UseRedeclaredAnnotatedFunc() {
RedeclaredAnnotatedFunc<1, 2, 3>();
}
} // namespace attribute_annotate
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 X'}}
template<typename T> struct [[clang::preferred_name(Z)]] C; // expected-error {{argument '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 {{.*}} X
// CHECK-NOT: PreferredNameAttr
// CHECK: CXXRecordDecl
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
// CHECK: TemplateArgument type 'float'
// CHECK-NOT: PreferredNameAttr
// CHECK: PreferredNameAttr {{.*}} 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 {};
};
template<typename T> T desugar(T);
auto it = desugar(MemberTemplate<int>::Iter<const int>());
int n = it; // expected-error {{no viable conversion from 'preferred_name::MemberTemplate<int>::const_iterator' to 'int'}}
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>'}}
}
::preferred_name::Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}