1f03cb005SDoug Wyatt // RUN: %clang_cc1 %s -ast-dump -fblocks | FileCheck %s 2f03cb005SDoug Wyatt 3f03cb005SDoug Wyatt // Make sure that the attribute gets parsed and attached to the correct AST elements. 4f03cb005SDoug Wyatt 5f03cb005SDoug Wyatt #pragma clang diagnostic ignored "-Wunused-variable" 6*7fe43adaSDoug Wyatt #pragma clang diagnostic ignored "-Wperf-constraint-implies-noexcept" 7f03cb005SDoug Wyatt 8f03cb005SDoug Wyatt // ========================================================================================= 9f03cb005SDoug Wyatt // Square brackets, true 10f03cb005SDoug Wyatt 11f03cb005SDoug Wyatt namespace square_brackets { 12f03cb005SDoug Wyatt 13f03cb005SDoug Wyatt // 1. On the type of the FunctionDecl 14f03cb005SDoug Wyatt void nl_function() [[clang::nonblocking]]; 15f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))' 16f03cb005SDoug Wyatt 17f03cb005SDoug Wyatt // 2. On the type of the VarDecl holding a function pointer 18f03cb005SDoug Wyatt void (*nl_func_a)() [[clang::nonblocking]]; 19f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_func_a 'void (*)() __attribute__((nonblocking))' 20f03cb005SDoug Wyatt 21f03cb005SDoug Wyatt // 3. On the type of the ParmVarDecl of a function parameter 22f03cb005SDoug Wyatt static void nlReceiver(void (*nl_func)() [[clang::nonblocking]]); 23f03cb005SDoug Wyatt // CHECK: ParmVarDecl {{.*}} nl_func 'void (*)() __attribute__((nonblocking))' 24f03cb005SDoug Wyatt 25f03cb005SDoug Wyatt // 4. As an AttributedType within the nested types of a typedef 26f03cb005SDoug Wyatt typedef void (*nl_fp_type)() [[clang::nonblocking]]; 27f03cb005SDoug Wyatt // CHECK: TypedefDecl {{.*}} nl_fp_type 'void (*)() __attribute__((nonblocking))' 28f03cb005SDoug Wyatt using nl_fp_talias = void (*)() [[clang::nonblocking]]; 29f03cb005SDoug Wyatt // CHECK: TypeAliasDecl {{.*}} nl_fp_talias 'void (*)() __attribute__((nonblocking))' 30f03cb005SDoug Wyatt 31f03cb005SDoug Wyatt // 5. From a typedef or typealias, on a VarDecl 32f03cb005SDoug Wyatt nl_fp_type nl_fp_var1; 33f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_fp_var1 'nl_fp_type':'void (*)() __attribute__((nonblocking))' 34f03cb005SDoug Wyatt nl_fp_talias nl_fp_var2; 35f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_fp_var2 'nl_fp_talias':'void (*)() __attribute__((nonblocking))' 36f03cb005SDoug Wyatt 37f03cb005SDoug Wyatt // 6. On type of a FieldDecl 38f03cb005SDoug Wyatt struct Struct { 39f03cb005SDoug Wyatt void (*nl_func_field)() [[clang::nonblocking]]; 40f03cb005SDoug Wyatt // CHECK: FieldDecl {{.*}} nl_func_field 'void (*)() __attribute__((nonblocking))' 41f03cb005SDoug Wyatt }; 42f03cb005SDoug Wyatt 43f03cb005SDoug Wyatt // nonallocating should NOT be subsumed into nonblocking 44f03cb005SDoug Wyatt void nl1() [[clang::nonblocking]] [[clang::nonallocating]]; 45f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl1 'void () __attribute__((nonblocking)) __attribute__((nonallocating))' 46f03cb005SDoug Wyatt 47f03cb005SDoug Wyatt void nl2() [[clang::nonallocating]] [[clang::nonblocking]]; 48f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl2 'void () __attribute__((nonblocking)) __attribute__((nonallocating))' 49f03cb005SDoug Wyatt 50f03cb005SDoug Wyatt decltype(nl1) nl3; 51f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl3 'decltype(nl1)':'void () __attribute__((nonblocking)) __attribute__((nonallocating))' 52f03cb005SDoug Wyatt 53f03cb005SDoug Wyatt // Attribute propagates from base class virtual method to overrides. 54f03cb005SDoug Wyatt struct Base { 55f03cb005SDoug Wyatt virtual void nb_method() [[clang::nonblocking]]; 56f03cb005SDoug Wyatt }; 57f03cb005SDoug Wyatt struct Derived : public Base { 58f03cb005SDoug Wyatt void nb_method() override; 59f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((nonblocking))' 60f03cb005SDoug Wyatt }; 61f03cb005SDoug Wyatt 62f03cb005SDoug Wyatt // Dependent expression 63f03cb005SDoug Wyatt template <bool V> 64f03cb005SDoug Wyatt struct Dependent { 65f03cb005SDoug Wyatt void nb_method2() [[clang::nonblocking(V)]]; 66f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} nb_method2 'void () __attribute__((nonblocking(V)))' 67f03cb005SDoug Wyatt }; 68f03cb005SDoug Wyatt 69f03cb005SDoug Wyatt // --- Blocks --- 70f03cb005SDoug Wyatt 71f03cb005SDoug Wyatt // On the type of the VarDecl holding a BlockDecl 72f03cb005SDoug Wyatt void (^nl_block1)() [[clang::nonblocking]] = ^() [[clang::nonblocking]] {}; 73f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_block1 'void (^)() __attribute__((nonblocking))' 74f03cb005SDoug Wyatt 75f03cb005SDoug Wyatt int (^nl_block2)() [[clang::nonblocking]] = ^() [[clang::nonblocking]] { return 0; }; 76f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_block2 'int (^)() __attribute__((nonblocking))' 77f03cb005SDoug Wyatt 78f03cb005SDoug Wyatt // The operand of the CallExpr is an ImplicitCastExpr of a DeclRefExpr -> nl_block which hold the attribute 79f03cb005SDoug Wyatt static void blockCaller() { nl_block1(); } 80f03cb005SDoug Wyatt // CHECK: DeclRefExpr {{.*}} 'nl_block1' 'void (^)() __attribute__((nonblocking))' 81f03cb005SDoug Wyatt 82f03cb005SDoug Wyatt // --- Lambdas --- 83f03cb005SDoug Wyatt 84f03cb005SDoug Wyatt // On the operator() of a lambda's CXXMethodDecl 85f03cb005SDoug Wyatt auto nl_lambda = []() [[clang::nonblocking]] {}; 86f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} operator() 'void () const __attribute__((nonblocking))' inline 87f03cb005SDoug Wyatt 88f03cb005SDoug Wyatt // ========================================================================================= 89f03cb005SDoug Wyatt // Square brackets, false 90f03cb005SDoug Wyatt 91f03cb005SDoug Wyatt void nl_func_false() [[clang::blocking]]; 92f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl_func_false 'void () __attribute__((blocking))' 93f03cb005SDoug Wyatt 94f03cb005SDoug Wyatt auto nl_lambda_false = []() [[clang::blocking]] {}; 95f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} operator() 'void () const __attribute__((blocking))' 96f03cb005SDoug Wyatt 97f03cb005SDoug Wyatt } // namespace square_brackets 98f03cb005SDoug Wyatt 99f03cb005SDoug Wyatt // ========================================================================================= 100f03cb005SDoug Wyatt // GNU-style attribute, true 101f03cb005SDoug Wyatt 102f03cb005SDoug Wyatt namespace gnu_style { 103f03cb005SDoug Wyatt 104f03cb005SDoug Wyatt // 1. On the type of the FunctionDecl 105f03cb005SDoug Wyatt void nl_function() __attribute__((nonblocking)); 106f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))' 107f03cb005SDoug Wyatt 108f03cb005SDoug Wyatt // 1a. Alternate placement on the FunctionDecl 109f03cb005SDoug Wyatt __attribute__((nonblocking)) void nl_function(); 110f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} nl_function 'void () __attribute__((nonblocking))' 111f03cb005SDoug Wyatt 112f03cb005SDoug Wyatt // 2. On the type of the VarDecl holding a function pointer 113f03cb005SDoug Wyatt void (*nl_func_a)() __attribute__((nonblocking)); 114f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_func_a 'void (*)() __attribute__((nonblocking))' 115f03cb005SDoug Wyatt 116f03cb005SDoug Wyatt // 2a. Alternate attribute placement on VarDecl 117f03cb005SDoug Wyatt __attribute__((nonblocking)) void (*nl_func_b)(); 118f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_func_b 'void (*)() __attribute__((nonblocking))' 119f03cb005SDoug Wyatt 120f03cb005SDoug Wyatt // 3. On the type of the ParmVarDecl of a function parameter 121f03cb005SDoug Wyatt static void nlReceiver(void (*nl_func)() __attribute__((nonblocking))); 122f03cb005SDoug Wyatt // CHECK: ParmVarDecl {{.*}} nl_func 'void (*)() __attribute__((nonblocking))' 123f03cb005SDoug Wyatt 124f03cb005SDoug Wyatt // 4. As an AttributedType within the nested types of a typedef 125f03cb005SDoug Wyatt // Note different placement from square brackets for the typealias. 126f03cb005SDoug Wyatt typedef void (*nl_fp_type)() __attribute__((nonblocking)); 127f03cb005SDoug Wyatt // CHECK: TypedefDecl {{.*}} nl_fp_type 'void (*)() __attribute__((nonblocking))' 128f03cb005SDoug Wyatt using nl_fp_talias = __attribute__((nonblocking)) void (*)(); 129f03cb005SDoug Wyatt // CHECK: TypeAliasDecl {{.*}} nl_fp_talias 'void (*)() __attribute__((nonblocking))' 130f03cb005SDoug Wyatt 131f03cb005SDoug Wyatt // 5. From a typedef or typealias, on a VarDecl 132f03cb005SDoug Wyatt nl_fp_type nl_fp_var1; 133f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_fp_var1 'nl_fp_type':'void (*)() __attribute__((nonblocking))' 134f03cb005SDoug Wyatt nl_fp_talias nl_fp_var2; 135f03cb005SDoug Wyatt // CHECK: VarDecl {{.*}} nl_fp_var2 'nl_fp_talias':'void (*)() __attribute__((nonblocking))' 136f03cb005SDoug Wyatt 137f03cb005SDoug Wyatt // 6. On type of a FieldDecl 138f03cb005SDoug Wyatt struct Struct { 139f03cb005SDoug Wyatt void (*nl_func_field)() __attribute__((nonblocking)); 140f03cb005SDoug Wyatt // CHECK: FieldDecl {{.*}} nl_func_field 'void (*)() __attribute__((nonblocking))' 141f03cb005SDoug Wyatt }; 142f03cb005SDoug Wyatt 143f03cb005SDoug Wyatt } // namespace gnu_style 144f03cb005SDoug Wyatt 145f03cb005SDoug Wyatt // ========================================================================================= 146f03cb005SDoug Wyatt // nonallocating and allocating - quick checks because the code paths are generally 147f03cb005SDoug Wyatt // identical after parsing. 148f03cb005SDoug Wyatt 149f03cb005SDoug Wyatt void na_function() [[clang::nonallocating]]; 150f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} na_function 'void () __attribute__((nonallocating))' 151f03cb005SDoug Wyatt 152f03cb005SDoug Wyatt void na_true_function() [[clang::nonallocating(true)]]; 153f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} na_true_function 'void () __attribute__((nonallocating))' 154f03cb005SDoug Wyatt 155f03cb005SDoug Wyatt void na_false_function() [[clang::nonallocating(false)]]; 156f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} na_false_function 'void () __attribute__((allocating))' 157f03cb005SDoug Wyatt 158f03cb005SDoug Wyatt void alloc_function() [[clang::allocating]]; 159f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} alloc_function 'void () __attribute__((allocating))' 160f03cb005SDoug Wyatt 161f03cb005SDoug Wyatt 162f03cb005SDoug Wyatt // ========================================================================================= 163f03cb005SDoug Wyatt // Non-blocking with an expression parameter 164f03cb005SDoug Wyatt 165f03cb005SDoug Wyatt void t0() [[clang::nonblocking(1 - 1)]]; 166f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} t0 'void () __attribute__((blocking))' 167f03cb005SDoug Wyatt void t1() [[clang::nonblocking(1 + 1)]]; 168f03cb005SDoug Wyatt // CHECK: FunctionDecl {{.*}} t1 'void () __attribute__((nonblocking))' 169f03cb005SDoug Wyatt 170f03cb005SDoug Wyatt template <bool V> 171f03cb005SDoug Wyatt struct ValueDependent { 172f03cb005SDoug Wyatt void nb_method() [[clang::nonblocking(V)]]; 173f03cb005SDoug Wyatt }; 174f03cb005SDoug Wyatt 175f03cb005SDoug Wyatt void t3() [[clang::nonblocking]] 176f03cb005SDoug Wyatt { 177f03cb005SDoug Wyatt ValueDependent<false> x1; 178f03cb005SDoug Wyatt x1.nb_method(); 179f03cb005SDoug Wyatt // CHECK: ClassTemplateSpecializationDecl {{.*}} ValueDependent 180f03cb005SDoug Wyatt // CHECK: TemplateArgument integral 'false' 181f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((blocking))' 182f03cb005SDoug Wyatt 183f03cb005SDoug Wyatt ValueDependent<true> x2; 184f03cb005SDoug Wyatt x2.nb_method(); 185f03cb005SDoug Wyatt // CHECK: ClassTemplateSpecializationDecl {{.*}} ValueDependent 186f03cb005SDoug Wyatt // CHECK: TemplateArgument integral 'true' 187f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} nb_method 'void () __attribute__((nonblocking))' 188f03cb005SDoug Wyatt } 189f03cb005SDoug Wyatt 190f03cb005SDoug Wyatt template <typename X> 191f03cb005SDoug Wyatt struct TypeDependent { 192f03cb005SDoug Wyatt void td_method() [[clang::nonblocking(X::is_nb)]]; 193f03cb005SDoug Wyatt }; 194f03cb005SDoug Wyatt 195f03cb005SDoug Wyatt struct NBPolicyTrue { 196f03cb005SDoug Wyatt static constexpr bool is_nb = true; 197f03cb005SDoug Wyatt }; 198f03cb005SDoug Wyatt 199f03cb005SDoug Wyatt struct NBPolicyFalse { 200f03cb005SDoug Wyatt static constexpr bool is_nb = false; 201f03cb005SDoug Wyatt }; 202f03cb005SDoug Wyatt 203f03cb005SDoug Wyatt void t4() 204f03cb005SDoug Wyatt { 205f03cb005SDoug Wyatt TypeDependent<NBPolicyFalse> x1; 206f03cb005SDoug Wyatt x1.td_method(); 207f03cb005SDoug Wyatt // CHECK: ClassTemplateSpecializationDecl {{.*}} TypeDependent 208f03cb005SDoug Wyatt // CHECK: TemplateArgument type 'NBPolicyFalse' 209f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} td_method 'void () __attribute__((blocking))' 210f03cb005SDoug Wyatt 211f03cb005SDoug Wyatt TypeDependent<NBPolicyTrue> x2; 212f03cb005SDoug Wyatt x2.td_method(); 213f03cb005SDoug Wyatt // CHECK: ClassTemplateSpecializationDecl {{.*}} TypeDependent 214f03cb005SDoug Wyatt // CHECK: TemplateArgument type 'NBPolicyTrue' 215f03cb005SDoug Wyatt // CHECK: CXXMethodDecl {{.*}} td_method 'void () __attribute__((nonblocking))' 216f03cb005SDoug Wyatt } 217f03cb005SDoug Wyatt 218