<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>On 15/03/2013, at 17:11 , Jordan Rose <<a href="mailto:jordan_rose@apple.com">jordan_rose@apple.com</a>> wrote:</div><div><br class="Apple-interchange-newline"><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=windows-1252"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Mar 15, 2013, at 7:27 , Sebastian Hagedorn <<a href="mailto:hagi.dd@web.de">hagi.dd@web.de</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=windows-1252"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I'm currently working on a Clang modification that analyses the (iOS SDK) version in which certain symbols were introduced. Most of it is based on code that looks similar to this:<div><br></div><div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(195, 89, 0); "><span style="">decl-></span><span style="color: #587ea8">getAttr</span><span style=""><</span>AvailabilityAttr<span style="">>()</span><span style="">-></span><span style="color: rgb(88, 126, 168); ">getIntroduced</span><span style="">()</span><span style="">;</span></div></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(195, 89, 0); "><span style=""><br></span></div><div style="margin: 0px; ">So far, this works fine for ObjC methods, properties, classes, and C functions. One missing piece are enumerations, but I've found that they seem to lack availability information alltogether. Let's pick an example, I'm trying to use the <span style="font-family: Menlo; font-size: 11px; ">PKPassKitErrorCode</span> enum that was introduced in iOS 6. The framework header declares the following:</div><div style="margin: 0px; "><br></div><div style="margin: 0px; "><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #35568a">typedef</span> <span style="color: #777997">NS_ENUM</span>(NSInteger, PKPassKitErrorCode) {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKUnknownError = -<span style="color: #35568a">1</span>,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKInvalidDataError = <span style="color: #35568a">1</span>,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKUnsupportedVersionError,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKInvalidSignature,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(119, 121, 151); "><span style="">} </span>NS_ENUM_AVAILABLE_IOS<span style="">(</span><span style="color: #35568a">6</span><span style="">_0);</span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(119, 121, 151); "><span style=""><br></span></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(119, 121, 151); "><span style="font-family: Helvetica; font-size: medium; ">Obviously, availability information is provided using the usual macros. This is what the preprocessor generates:</span></div></div><div style="margin: 0px; "><br></div><div style="margin: 0px; "><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">typedef enum PKPassKitErrorCode : NSInteger PKPassKitErrorCode; enum PKPassKitErrorCode : NSInteger {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKUnknownError = -<span style="color: #35568a">1</span>,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKInvalidDataError = <span style="color: #35568a">1</span>,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKUnsupportedVersionError,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> PKInvalidSignature,</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">} __attribute__((availability(ios,introduced=<span style="color: #35568a">6.0</span>)));</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><br></div><div style="margin: 0px; ">Still looks ok to me, all the information I'm looking for is included. However, when I try to get the availability information during the compilation process (I'm modifying <span style="font-family: Menlo; font-size: 11px; color: rgb(195, 89, 0); ">Sema</span><span style="font-family: Menlo; font-size: 11px; ">::DiagnoseUseOfDecl()</span> in SemaExpr.cpp), there is none – <span style="font-family: Menlo; font-size: 11px; color: rgb(88, 126, 168); ">getAttr</span><span style="font-family: Menlo; font-size: 11px; "><</span><span style="color: rgb(195, 89, 0); font-family: Menlo; font-size: 11px; ">AvailabilityAttr</span><span style="font-family: Menlo; font-size: 11px; ">>()</span> returns NULL for EnumConstantDecls.</div><div style="margin: 0px; "><br></div><div style="margin: 0px; ">I have not started examining the parsing of the declaration, but wanted to ask first whether there's an obvious reason why the information is missing, or there's an obvious mistake/misassumption I'm making?</div></div></div></blockquote><br></div><div>The attribute here isn't <i>on</i> the EnumConstantDecls; it's on the EnumDecl as a whole. You'll also have to be careful about redeclarations; in this case I would guess that the first EnumDecl (inside the typedef) doesn't have the attribute, but the second one (where the enumerators are actually defined) does.</div><div><br></div><div>Jordan</div><br></div></blockquote></div><br><div>Thanks for your response!</div><div><br></div><div>Re:EnumConstantDecl vs. EnumDecl... my bad. I actually tested both though, and neither the constants nor the declaration have availability information.</div><div><br></div><div>Re:Redeclarations: How is this handled in Clang? After looking at the EnumDecl class and the TagDecl class specifically, I assumed Clang keeps all the (re)declarations it finds and makes them accessible via iterators. So I tried to acces the most recent declaration (which should be the one with the constants defined), but also go through all previous declarations and always test whether there's an availability attribute. Looks like this...</div><div><br></div><div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: #c35900">EnumDecl</span> *enumD = <span style="color: #587ea8">dyn_cast_or_null</span><<span style="color: #c35900">EnumDecl</span>>(decl);</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><div style="margin: 0px; color: rgb(53, 86, 138); ">bool<span style="color: #000000"> hit = </span>false<span style="color: #000000">;</span></div></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="color: rgb(53, 86, 138); ">if</span> (enumD) {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: rgb(195, 89, 0); ">EnumDecl</span> *prev = enumD-><span style="color: rgb(88, 126, 168); ">getMostRecentDecl</span>();</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #35568a">while</span> (prev) {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> <span style="color: #35568a">if</span> (prev-><span style="color: #587ea8">getAttr</span><<span style="color: #c35900">AvailabilityAttr</span>>()) {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> hit = <span style="color: rgb(53, 86, 138); ">true</span>;</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; min-height: 13px; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> prev = prev-><span style="color: #587ea8">getPreviousDecl</span>();</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "> }</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; ">}</div></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><br></div><div style="margin: 0px; font-size: 11px; font-family: Menlo; "><span style="font-family: Helvetica; font-size: medium; ">Unfortunately, </span>prev-><span style="color: rgb(88, 126, 168); ">getPreviousDecl</span>()<span style="font-family: Helvetica; font-size: medium; "> always returns NULL, so the while loop executes only once. And it does not find availability information for the most recent declaration.</span></div><div><br></div><div>Is there another way to check all (re)declarations?</div><div><br></div></body></html>