<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hello everyone,<div><br></div><div>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.</div><div><br></div><div>The feature is fairly simple in appearance, here is the syntax: __weak_capture(variableName);</div><div>You can only write that inside a Block ^{ } and the feature is only available under ARC.</div><div>I am done with the whole Sema part, all the errors and warnings are managed:</div><div>- Error: used outside of a block</div><div>- Error: referencing a non-local variable</div><div>- Error: referencing a non-ObjC object variable</div><div>- Error: referencing a __block variable</div><div>- Error: referencing a class that does not support __weak references</div><div>- Warning: __weak_capture() duplicate statements in the same block (the second one is ignored)</div><div>- Warning: __weak_capture() a variable that is not actually used in the block (the whole statement is removed)</div><div><br></div><div>When writing __weak_capture(var); inside a block, the variable "var" is captured in the block structure as if it was __weak.</div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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?</div><div><br></div><div>I have no idea how to detect the last use though, I know ARC already does that, but where?</div><div><br></div><div>Here is an example of how it would look with and without the use of that feature:</div><div><br></div><div>With the feature:</div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; "><span style="color: #063ff4">@interface</span> MyClass : NSObject <span style="color: #063ff4">@end</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; "><span style="color: #063ff4">@implementation</span> MyClass { <span style="color: #063ff4">id</span> obj; }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">- (<span style="color: #063ff4">void</span>)method</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    <span style="color: #063ff4">void</span> (^someBlock)(<span style="color: #063ff4">void</span>) =</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    ^{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        __weak_capture(<span style="color: #063ff4">self</span>);</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; min-height: 16.0px">        <br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        <span style="color: #063ff4">if</span>(<span style="color: #063ff4">self</span> == <span style="color: #063ff4">nil</span>) <span style="color: #063ff4">return</span>;</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; min-height: 16.0px">        <br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; color: rgb(0, 164, 51); "><span style="color: #000000">        </span>// obj referes to the weakly captured "self"</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        NSlog(<span style="color: #797ca6">@"%@"</span>, obj);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    };</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; color: rgb(6, 63, 244); ">@end</div></div><div><br></div><div>Without the feature:</div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; "><span style="color: #063ff4">@interface</span> MyClass : NSObject <span style="color: #063ff4">@end</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; "><span style="color: #063ff4">@implementation</span> MyClass { <span style="color: #063ff4">id</span> obj; }</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">- (<span style="color: #063ff4">void</span>)method</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    <span style="color: #063ff4">__weak</span> MyClass *weakSelf = <span style="color: #063ff4">self</span>;</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; min-height: 16.0px">    <br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    <span style="color: #063ff4">void</span> (^someBlock)(<span style="color: #063ff4">void</span>) =</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    ^{</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        MyClass *<span style="color: #063ff4">self</span> = weakSelf;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        <span style="color: #063ff4">if</span>(<span style="color: #063ff4">self</span> == <span style="color: #063ff4">nil</span>) <span style="color: #063ff4">return</span>;</div><p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; min-height: 16.0px">        <br class="webkit-block-placeholder"></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; color: rgb(0, 164, 51); "><span style="color: #000000">        </span>// obj referes to the weakly captured "self"</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">        NSlog(<span style="color: #797ca6">@"%@"</span>, obj);</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">    };</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; ">}</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 14px/normal Menlo; color: rgb(6, 63, 244); ">@end</div><div apple-content-edited="true">
<div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="orphans: 2; text-indent: 0px; widows: 2; -webkit-text-decorations-in-effect: none; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div><div style="border-collapse: separate; color: rgb(0, 0, 0); font-variant: normal; letter-spacing: normal; line-height: normal; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">____________________________________</div><div style="border-collapse: separate; color: rgb(0, 0, 0); font-variant: normal; letter-spacing: normal; line-height: normal; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">Remy "Psy" Demarest</div><div style="border-collapse: separate; color: rgb(0, 0, 0); font-variant: normal; letter-spacing: normal; line-height: normal; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><a href="mailto:remy.demarest@gmail.com">remy.demarest@gmail.com</a></div><div style="border-collapse: separate; color: rgb(0, 0, 0); font-variant: normal; letter-spacing: normal; line-height: normal; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">+1 (647) 862-1779</div></div></div></span></div></div>
</div>
<br></div></body></html>