================================================================================ Blocks: declaration ================================================================================ NSObject* (^blockName)(NSObject *); -------------------------------------------------------------------------------- (translation_unit (declaration type: (type_identifier) declarator: (pointer_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (abstract_pointer_declarator))))))) ================================================================================ Blocks: As a local variable ================================================================================ int (^blockName)() = ^int() {return -1;}; int (^blockName)(int) = ^int(int a) {return -1;}; int (^blockName)(int, NSObject *) = ^int(int a, NSObject *object) {return -1;}; NSString * _Nullable(^blockName)(NSString * _Nonnull) = ^NSString * _Nullable(NSString * _Nonnull key) { return nil; }; -------------------------------------------------------------------------------- (translation_unit (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list)) value: (block_expression declarator: (type_descriptor type: (primitive_type) declarator: (abstract_function_declarator parameters: (parameter_list))) (compound_statement (return_statement (number_literal)))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)))) value: (block_expression declarator: (type_descriptor type: (primitive_type) declarator: (abstract_function_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (identifier))))) (compound_statement (return_statement (number_literal)))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (type_identifier) declarator: (abstract_pointer_declarator)))) value: (block_expression declarator: (type_descriptor type: (primitive_type) declarator: (abstract_function_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (identifier)) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier)))))) (compound_statement (return_statement (number_literal)))))) (declaration type: (type_identifier) declarator: (init_declarator declarator: (pointer_declarator (type_qualifier) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (abstract_pointer_declarator (type_qualifier)))))) value: (block_expression declarator: (type_descriptor type: (type_identifier) declarator: (abstract_pointer_declarator (type_qualifier) declarator: (abstract_function_declarator parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))))))) (compound_statement (return_statement (nil))))))) ================================================================================ Blocks: As a typedef ================================================================================ typedef void(^blockName)(void); typedef void(^blockName)(NSObject *object); typedef void(^blockName)(NSObject * _Nullable object); typedef void(^blockName)(NSUInteger val1, NSUInteger val2); typedef void (^blockName)(NSMutableOrderedSet * _Nullable objects, NSInteger val1, NSBlock_declaration * _Nullable block_declaration); typedef void (^blockName)(__kindof UIView * _Nonnull view); typedef NSURLResponse * _Nullable (^blockName)(NSURLResponse * _Nonnull val1, NSBundle * _Nullable val2); // type qualifier in block definition typedef id _Nullable (^blockName)(NSString *name, NSBundle * _Nullable bundle); -------------------------------------------------------------------------------- (translation_unit (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type))))) (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier)))))) (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))))) (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (identifier)) (parameter_declaration type: (type_identifier) declarator: (identifier))))) (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (generic_type_specifier class_name: (type_identifier) type_reference: (generic_type_references (type_descriptor type: (type_identifier) declarator: (abstract_pointer_declarator)))) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))) (parameter_declaration type: (type_identifier) declarator: (identifier)) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))))) (type_definition type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration (type_qualifier) type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))))) (type_definition type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))))))) (comment) (type_definition type: (id) (type_qualifier) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier))) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))))))) ================================================================================ Blocks: As a method parameter ================================================================================ @interface Block - (void)loginWithCompletion:(nullable NSNumber *(^)(BOOL success, NSString *name, id object))completion; @end @implementation Block - (void)loginWithCompletion:(nullable void(_Nonnull ^)(BOOL success, id object))completion { [self registerHandler:^(UIView * _Nonnull view, NSString * _Nonnull name, NSDictionary * _Nullable params, void (^ _Nonnull callback)(int, id _Nullable)) { if (handler) { handler(params, callback); } } forMethod:method]; } - (void)URLSession:(NSURLSession *)session completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { } @end -------------------------------------------------------------------------------- (translation_unit (class_interface name: (identifier) (method_declaration scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (nullable) type: (type_identifier) declarator: (abstract_pointer_declarator declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (BOOL) declarator: (identifier)) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier))) (parameter_declaration type: (id) declarator: (identifier))))) name: (identifier))))) (class_implementation name: (identifier) (method_definition scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (nullable) type: (primitive_type) declarator: (block_abstract_declarator (type_qualifier) parameters: (parameter_list (parameter_declaration type: (BOOL) declarator: (identifier)) (parameter_declaration type: (id) declarator: (identifier)))) name: (identifier))) body: (compound_statement (expression_statement (message_expression receiver: (self) selector: (keyword_argument_list (keyword_argument keyword: (identifier) argument: (block_expression parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier))) (parameter_declaration type: (primitive_type) declarator: (block_declarator (type_qualifier) declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (id) (type_qualifier)))))) (compound_statement (if_statement condition: (parenthesized_expression (identifier)) consequence: (compound_statement (expression_statement (call_expression function: (identifier) arguments: (argument_list (identifier) (identifier))))))))) (keyword_argument keyword: (identifier) argument: (identifier))))))) (method_definition scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (type_identifier) declarator: (abstract_pointer_declarator) name: (identifier)) (keyword_declarator keyword: (identifier) type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (identifier)))) name: (identifier))) body: (compound_statement)))) ================================================================================ Blocks: As a property ================================================================================ @interface Block @property (nonatomic, copy) int (^blockName)(int, int); @property (nonatomic, copy) int (^blockName)(int a, int b); @property (nonatomic, copy) NSObject * (^blockName)(int, int); @property (nonatomic, copy) id (^blockName)(int, int, UIImage * _Nonnull frame); @property (nonatomic, strong) NSMutableDictionary *tasks; @end -------------------------------------------------------------------------------- (translation_unit (class_interface name: (identifier) (property_declaration (property_attributes (nonatomic) (copy)) type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (primitive_type))))) (property_declaration (property_attributes (nonatomic) (copy)) type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (identifier)) (parameter_declaration type: (primitive_type) declarator: (identifier))))) (property_declaration (property_attributes (nonatomic) (copy)) type: (type_identifier) declarator: (pointer_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (primitive_type)))))) (property_declaration (property_attributes (nonatomic) (copy)) type: (id) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (primitive_type)) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))))) (property_declaration (property_attributes (nonatomic) (strong)) type: (generic_type_specifier class_name: (type_identifier) type_reference: (generic_type_references (type_descriptor type: (type_identifier) declarator: (abstract_pointer_declarator)) (type_descriptor type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (abstract_pointer_declarator (type_qualifier))) (parameter_declaration type: (type_identifier))))))) declarator: (pointer_declarator declarator: (identifier))))) ================================================================================ Blocks: As a argument to a method call ================================================================================ [someObject someMethodThatTakesABlock:^(id _Nullable observer, id _Nonnull object, NSDictionary * _Nonnull change) { int (^blockName)() = ^int() {return -1;}; }]; -------------------------------------------------------------------------------- (translation_unit (expression_statement (message_expression receiver: (type_identifier) selector: (keyword_argument_list (keyword_argument keyword: (identifier) argument: (block_expression parameters: (parameter_list (parameter_declaration type: (id) (type_qualifier) declarator: (identifier)) (parameter_declaration type: (id) (type_qualifier) declarator: (identifier)) (parameter_declaration type: (generic_type_specifier class_name: (type_identifier) type_reference: (generic_type_references (type_descriptor type: (type_identifier) declarator: (abstract_pointer_declarator)) (type_descriptor type: (id)))) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))) (compound_statement (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list)) value: (block_expression declarator: (type_descriptor type: (primitive_type) declarator: (abstract_function_declarator parameters: (parameter_list))) (compound_statement (return_statement (number_literal))))))))))))) ================================================================================ Blocks: As a C function call, as _field_declarator ================================================================================ void SomeFunctionThatTakesABlock(returnType (^blockName)(int)); -------------------------------------------------------------------------------- (translation_unit (declaration type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type))))))))) ================================================================================ Blocks: As a cast type specifier ================================================================================ (returnType (^)(int, id))anotherBlock; -------------------------------------------------------------------------------- (translation_unit (expression_statement (cast_expression type: (type_descriptor type: (type_identifier) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type)) (parameter_declaration type: (id))))) value: (identifier)))) ================================================================================ Blocks: block type in block declaration parameter_list ================================================================================ void(^blockName1)(void(^blockName2)(void)); @interface Block - (void)someMethodThatTakesABlock:(void(^)(void(^)(void)))block; @end -------------------------------------------------------------------------------- (translation_unit (declaration type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)))))))) (class_interface name: (identifier) (method_declaration scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type))))))) name: (identifier)))))) ================================================================================ Blocks: block type in block declaration parameter_list ================================================================================ void (^blockName)(void); void (^(^blockName)(void (^)(void)))(void); void(^(^blockName)(NSDictionary *params))(UIImage *image) = ^(NSDictionary *params) { return ^(UIImage * image) { }; }; -------------------------------------------------------------------------------- (translation_unit (declaration type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type))))) (declaration type: (primitive_type) declarator: (block_declarator return_type: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type))))))) parameters: (parameter_list (parameter_declaration type: (primitive_type))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator return_type: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier))))) parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier))))) value: (block_expression parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier)))) (compound_statement (return_statement (block_expression parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier)))) (compound_statement)))))))) ================================================================================ Blocks: block_type_specifier in cast expression parameter_list ================================================================================ ((id(*)(id, SEL, id, id, id, id, void(^)(NSURLRequest *)))objc_msgSend)( slf, swizzledSelector, session, task, response, newRequest, completionHandler ); -------------------------------------------------------------------------------- (translation_unit (expression_statement (call_expression function: (parenthesized_expression (cast_expression type: (type_descriptor type: (id) declarator: (abstract_function_declarator declarator: (abstract_parenthesized_declarator (abstract_pointer_declarator)) parameters: (parameter_list (parameter_declaration type: (id)) (parameter_declaration type: (SEL)) (parameter_declaration type: (id)) (parameter_declaration type: (id)) (parameter_declaration type: (id)) (parameter_declaration type: (id)) (parameter_declaration type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (type_identifier) declarator: (abstract_pointer_declarator)))))))) value: (identifier))) arguments: (argument_list (identifier) (identifier) (identifier) (identifier) (identifier) (identifier) (identifier))))) ================================================================================ Blocks: expression ================================================================================ [self.KVOController observe:imageView keyPaths:@[NSStringFromSelector(@selector(currentFrameIndex)), NSStringFromSelector(@selector(currentLoopCount))] options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary * _Nonnull change) { }]; -------------------------------------------------------------------------------- (translation_unit (expression_statement (message_expression receiver: (field_expression argument: (self) field: (field_identifier)) selector: (keyword_argument_list (keyword_argument keyword: (identifier) argument: (identifier)) (keyword_argument keyword: (identifier) argument: (array_expression (call_expression function: (identifier) arguments: (argument_list (selector_expression name: (identifier)))) (call_expression function: (identifier) arguments: (argument_list (selector_expression name: (identifier)))))) (keyword_argument keyword: (identifier) argument: (identifier)) (keyword_argument keyword: (identifier) argument: (block_expression parameters: (parameter_list (parameter_declaration type: (id) (type_qualifier) declarator: (identifier)) (parameter_declaration type: (id) (type_qualifier) declarator: (identifier)) (parameter_declaration type: (generic_type_specifier class_name: (type_identifier) type_reference: (generic_type_references (type_descriptor type: (type_identifier) declarator: (abstract_pointer_declarator)) (type_descriptor type: (id)))) declarator: (pointer_declarator (type_qualifier) declarator: (identifier)))) (compound_statement))))))) ================================================================================ Blocks: as a instance variable ================================================================================ @interface FLEXVariableEditorViewController : UIViewController { @protected void (^_Nullable _commitHandler)(); } @end -------------------------------------------------------------------------------- (translation_unit (class_interface name: (identifier) (superclass_reference name: (identifier)) (protected) (field_declaration type: (primitive_type) declarator: (block_declarator (type_qualifier) declarator: (identifier) parameters: (parameter_list))))) ================================================================================ Blocks: unknown [FIXME] ================================================================================ extern void use(id); extern void use_block(void (^)(void)); void use_block(int (^block_t)(void)) { block_t(); return; } void test7(void) { use_block(^{return 1;}); } // int (^square(int x))(void) { // return ^{ return x * x; }; // } void test8(void) { int (^square_block)(void) = square(4); int i = square_block(); NSLog(@"%d", i); } void (^simpleBlock)() = ^ _Nonnull { //expected-warning {{attribute '_Nonnull' ignored, because it cannot be applied to omitted return type}} return; }; void (^simpleBlock6)() = ^ const (void) { //expected-warning {{'const' qualifier on omitted return type '' has no effect}} return; }; -------------------------------------------------------------------------------- (translation_unit (declaration (storage_class_specifier) type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (id))))) (declaration (storage_class_specifier) type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (block_abstract_declarator parameters: (parameter_list (parameter_declaration type: (primitive_type)))))))) (function_definition type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type) declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type))))))) body: (compound_statement (expression_statement (call_expression function: (identifier) arguments: (argument_list))) (return_statement))) (function_definition type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)))) body: (compound_statement (expression_statement (call_expression function: (identifier) arguments: (argument_list (block_expression (compound_statement (return_statement (number_literal))))))))) (comment) (comment) (comment) (function_definition type: (primitive_type) declarator: (function_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)))) body: (compound_statement (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list (parameter_declaration type: (primitive_type)))) value: (call_expression function: (identifier) arguments: (argument_list (number_literal))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (call_expression function: (identifier) arguments: (argument_list)))) (expression_statement (call_expression function: (identifier) arguments: (argument_list (string_expression) (identifier)))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list)) value: (block_expression declarator: (type_qualifier) (compound_statement (comment) (return_statement))))) (declaration type: (primitive_type) declarator: (init_declarator declarator: (block_declarator declarator: (identifier) parameters: (parameter_list)) value: (block_expression declarator: (type_qualifier) parameters: (parameter_list (parameter_declaration type: (primitive_type))) (compound_statement (comment) (return_statement)))))) ================================================================================ IMP: type definition and cast expression ================================================================================ // id (*IMP)(id, SEL, ...) typedef NSObject * (* typedefIMP)(id thisSelf, SEL selector, NSString *filePath); CGFloat (* msgSendIMP)(id, SEL, id, CGFloat) = (CGFloat (*)(id, SEL, id, CGFloat))objc_msgSend; @interface NSMutableArray : NSObject - (void)sortWithFunction:(int (*)(T, T))function; - (void)getObjects:(T __strong *)objects length:(unsigned*)length; @end -------------------------------------------------------------------------------- (translation_unit (comment) (type_definition type: (type_identifier) declarator: (pointer_declarator declarator: (function_declarator declarator: (parenthesized_declarator (pointer_declarator declarator: (type_identifier))) parameters: (parameter_list (parameter_declaration type: (id) declarator: (identifier)) (parameter_declaration type: (SEL) declarator: (identifier)) (parameter_declaration type: (type_identifier) declarator: (pointer_declarator declarator: (identifier))))))) (expression_statement (assignment_expression left: (call_expression function: (call_expression function: (identifier) arguments: (argument_list (pointer_expression argument: (identifier)))) arguments: (argument_list (identifier) (identifier) (identifier) (identifier))) right: (cast_expression type: (type_descriptor type: (type_identifier) declarator: (abstract_function_declarator declarator: (abstract_parenthesized_declarator (abstract_pointer_declarator)) parameters: (parameter_list (parameter_declaration type: (id)) (parameter_declaration type: (SEL)) (parameter_declaration type: (id)) (parameter_declaration type: (type_identifier))))) value: (identifier)))) (class_interface name: (identifier) (protocol_qualifiers (protocol_identifier)) (superclass_reference name: (identifier) type_reference: (generic_type_references (type_descriptor type: (type_identifier)))) (method_declaration scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (primitive_type) declarator: (abstract_function_declarator declarator: (abstract_parenthesized_declarator (abstract_pointer_declarator)) parameters: (parameter_list (parameter_declaration type: (type_identifier)) (parameter_declaration type: (type_identifier)))) name: (identifier)))) (method_declaration scope: (instance_scope) type: (primitive_type) selector: (keyword_selector (keyword_declarator keyword: (identifier) type: (type_identifier) type: (type_qualifier) declarator: (abstract_pointer_declarator) name: (identifier)) (keyword_declarator keyword: (identifier) type: (sized_type_specifier) declarator: (abstract_pointer_declarator) name: (identifier)))))) ================================================================================ Blocks: block type in block declaration parameter_list ================================================================================ // void (^GlobalBlockName())(NSIndexPath *indexPath, BOOL isOn) { // return ^(NSIndexPath * _Nonnull indexPath, BOOL isOn) { // }; // } // void (^GlobalBlockName(NSString *event, NSString *type))(NSIndexPath *indexPath, BOOL isOn) { // return ^(NSIndexPath * _Nonnull indexPath, BOOL isOn) { // }; // } -------------------------------------------------------------------------------- (translation_unit (comment) (comment) (comment) (comment) (comment) (comment) (comment) (comment))