inspecting emitted blocks code

Why are blocks excluded when printing out the AST? Is it a bug?

$ cat foo.c
#include<stdio.h>
int main(int argc, char *argv[])
{
void (^hello)() = ^ { printf(“hello world\n”); };
hello();
return 0;
}

$ clang -cc1 -fblocks hello.c -ast-print

int main(int argc, char *argv[]) {
void (^hello)() = ^;
hello();
return 0;
}

In any case, is there a quick way to dump the blocks-specific generated code (__block_invoke_1, __block_literal_1 etc.)?
Finally, is there a way to reach a block’s imported variables without modifying the compiler?

Thanks,
Abhishek

Why are blocks excluded when printing out the AST? Is it a bug?

Yes.

In any case, is there a quick way to dump the blocks-specific generated code (__block_invoke_1, __block_literal_1 etc.)?

Blocks code is generated by directly synthesizing the appropriate LLVM IR, not by constructing a C-like syntax tree and then emitting that. The Objective-C rewriter is capable of doing that, although it doesn't make any guarantee of being perfectly consistent with the code that IR gen would emit.

Finally, is there a way to reach a block's imported variables without modifying the compiler?

If you have the AST, this is the block decl's "captures" list.

I don't know what you mean by "without modifying the compiler", but we strongly encourage people who are interested in analyzing C/C++ programs to work with our AST (or LLVM IR, as appropriate) instead of exporting the information into some other format which is pretty much inevitably going to be a lesser cousin to the AST.

John.

Why are blocks excluded when printing out the AST? Is it a bug?

Yes.

In any case, is there a quick way to dump the blocks-specific generated code (__block_invoke_1, __block_literal_1 etc.)?

Blocks code is generated by directly synthesizing the appropriate LLVM IR, not by constructing a C-like syntax tree and then emitting that. The Objective-C rewriter is capable of doing that, although it doesn’t make any guarantee of being perfectly consistent with the code that IR gen would emit.

Yes, I figured. But thanks, -rewrite-objc gives a good sense of what’s going on.

Finally, is there a way to reach a block’s imported variables without modifying the compiler?

If you have the AST, this is the block decl’s “captures” list.

I don’t know what you mean by “without modifying the compiler”, but we strongly encourage people who are interested in analyzing C/C++ programs to work with our AST (or LLVM IR, as appropriate) instead of exporting the information into some other format which is pretty much inevitably going to be a lesser cousin to the AST.

Sorry for not being clear – I meant to ask if there is a way to inspect the closure’s data at runtime. If I have the block pointer, can I get the values of the imported variables that the block encapsulates? I have been looking at the blocks runtime that comes with compiler-rt and it is not clear how the imported variables are laid out within the block’s descriptor.

Abhishek

There’s no reflection information because there aren’t any runtime reflection APIs which would consume it. The closest we get is that in ObjC GC mode, we do emit layout information indicating where the pointers are.

John.