[cfe-dev] CodeGen help for a new feature in ObjC

Remy Demarest remy.demarest at gmail.com
Tue Dec 20 06:58:29 PST 2011


Hello everyone,

I'm currently implementing a new feature for ObjC and ARC in Clang, and would like some advice regarding an idea to implement the code generation of that feature.

The feature is fairly simple in appearance, here is the syntax: __weak_capture(variableName);
You can only write that inside a Block ^{ } and the feature is only available under ARC.
I am done with the whole Sema part, all the errors and warnings are managed:
- Error: used outside of a block
- Error: referencing a non-local variable
- Error: referencing a non-ObjC object variable
- Error: referencing a __block variable
- Error: referencing a class that does not support __weak references
- Warning: __weak_capture() duplicate statements in the same block (the second one is ignored)
- Warning: __weak_capture() a variable that is not actually used in the block (the whole statement is removed)

When writing __weak_capture(var); inside a block, the variable "var" is captured in the block structure as if it was __weak.
However, when the block is executed, the captured object is loaded and retained (as if it was moved inside a __strong local variable) for as long as the object is used inside the block. When the variable is not used anymore, it is released like any other __strong variable in a local scope.

So, my actual problem is in CodeGen. I've god the weak capture itself working, the compiler generates the objc_loadWeak() to store the captured variable in the block structure as a weak. What I'm missing is the retain and release inside the code and there I'm not sure how to work it out.

I was thinking about adding a map in the CodeGenFunction that would indicate which variables are captured weakly and when it's time to retain it (on first use) check the map, emit an objc_retain(), and after the last use emit the objc_release. What do you think about that idea?

I have no idea how to detect the last use though, I know ARC already does that, but where?

Here is an example of how it would look with and without the use of that feature:

With the feature:
@interface MyClass : NSObject @end
@implementation MyClass { id obj; }
- (void)method
{
    void (^someBlock)(void) =
    ^{
        __weak_capture(self);
        
        if(self == nil) return;
        
        // obj referes to the weakly captured "self"
        NSlog(@"%@", obj);
    };
}
@end

Without the feature:
@interface MyClass : NSObject @end
@implementation MyClass { id obj; }
- (void)method
{
    __weak MyClass *weakSelf = self;
    
    void (^someBlock)(void) =
    ^{
        MyClass *self = weakSelf;
        if(self == nil) return;
        
        // obj referes to the weakly captured "self"
        NSlog(@"%@", obj);
    };
}
@end

____________________________________
Remy "Psy" Demarest
remy.demarest at gmail.com
+1 (647) 862-1779

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20111220/37fccda1/attachment.html>


More information about the cfe-dev mailing list