<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jul 27, 2012, at 4:07 PM, Alexander Kornienko <<a href="mailto:alexfh@google.com">alexfh@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jul 27, 2012 at 11:40 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
FWIW, at a high level I find the callback approach is very worrisome.<div><br></div><div>The callback system was designed to be fast when the callbacks were completely null, and impose a non-trivial cost on the preprocessor otherwise.</div>
</blockquote><div>I do not think that we'll get measurably worse performance as a result of this change. This code only works on macro definitions (does anyone know how many of those per translation unit should we expect IRL?),</div></div></div></blockquote><div><br></div><div>On the Mac, Cocoa.h has 9000 macro definitions. Boost's preprocessor library would be an interesting source of data here.</div><br><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote"><div> and in most cases this code will do no more than allocating a buffer (I can make this a class member, so it doesn't get allocated each time) and comparing a spelling of a couple of tokens (currently I wouldn't expect many macros which expansion start with "[[").</div></div></div></blockquote><div><br></div><div>The preprocessor is extremely performance-sensitive. Allocating a buffer and performing string comparisons is not considered cheap. This will need measurement.</div><br><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote">
<div>I can also implement Richard's suggestions to make overhead even less: 1. avoid adding callback when my warning isn't turned on; 2. lex the search string so that matching is done by comparing tokens and not text. And I'm going to run performance tests and find out if my patch really has some measurable performance penalty. If it doesn't, do you have any objections against callback approach?</div></div></div></blockquote><div><br></div><div>I object to the callback approach. If this is to be a core feature used by the preprocessor, parser, or semantic analysis to produce warnings, then it needs to be properly integrated into the AST, not placed alongside. The callbacks mechanism is for tools to extend Clang, not to decouple the implementation of Clang features.</div><div><br></div><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Can we not walk back through the macro definitions after-the-fact? I would expect the preprocessor to still have all the information we need.</div>
</blockquote><div>I'm not sure that we retain contents of #undef'ed and redefined macros. And we definitely need this as we run analysis after the whole file is lexed.</div></div></div></blockquote><div><br></div>I don't know what you mean by "after the whole file is lexed", since the lexer/preprocessor is integrated with the parser. There is certainly some skew when it comes to in-class member functions and template instantiations, which makes almost any approach sensitive to #undefs. Regardless, if a configuration macro is #undef'd at some point, then it's perfectly reasonable to not provide a Fix-It that uses that macro.</div><div><br></div><div>It seems that what we need is a lightweight, generic way to detect whether a macro is a configuration macro, and then be able to query the set of configuration macros when we produce a warning/error where a Fix-It might use one of these configuration macros. I think it's important to handle the generic case initially, because it's going to affect performance significantly: the current patch has string comparisons for "[[clang::fallthrough]]", but a generic solution would have many more string comparisons for a bunch of other attributes and forms.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><div><br></div><div><br></div><br><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><div class="gmail_extra"><div class="gmail_quote">
On Fri, Jul 27, 2012 at 2:36 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Hi Alex,<div><br></div><div>Please don't add the PP callback if the fallthrough warning isn't enabled. Also, have you made any performance measurements for this change?<br><br>I would prefer that the CompatibilityMacroFinder were given a list of token kinds and identifier infos to look for rather than a string. That would probably improve the performance a bit, and would allow your diagnostic to work in cases where the tokens don't have the obvious spelling (for instance, "<:<:clang::fallthrough:>:>").<div>

<div><br>
<br><div class="gmail_quote">On Tue, Jul 24, 2012 at 10:11 AM, Alexander Kornienko <span dir="ltr"><<a href="mailto:alexfh@google.com" target="_blank">alexfh@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


This patch adds an automatic detection of a compatibility macros used in specific projects to hide constructions based on non-portable features (e.g. custom C++11 attributes). It helps to adapt diagnostic messages and fix-it hints to use these compatibility macros instead of the actual construct.<div>



<div><br></div><div>This feature is implemented in AnalysisBasedWarnings.cpp, as there's currently only one diagnostic which gets profit from this - diagnostic of unannotated fall-through between switch labels. But the code of the CompatibilityMacroFinder class was intentionally made reasonably generic, and doesn't contain any specific bindings to this diagnostic. The class is a lightweight handler of PPCallbacks::MacroDefined calls. An instance of it is registered via Preprocessor::addPPCallbacks for each token sequence (specified in plain text) to find in macros (currently only one). It keeps all macros with the specified expansion token sequence and then can determine which one can be used instead of the actual construct in a specific code location.</div>



<div><br></div><div>A motivating example for this feature:</div><div>There's the <font face="courier new, monospace">-Wimplicit-fallthrough</font> warning, which detects <font face="courier new, monospace">[[clang::fallthrough]];</font> construct as an annotation of an intended fall-through. In projects which should be compiled both in C++11 mode and in C++03 mode, this construct can not be used as is, so it should be wrapped in a macro, e.g.:</div>



</div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><font face="courier new, monospace" size="1">#ifdef __clang__</font></div><div><div><font face="courier new, monospace" size="1">#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")</font></div>



</div><div><font face="courier new, monospace" size="1">#define LLVM_FALLTHROUGH [[clang::fallthrough]]</font></div><div><div><font face="courier new, monospace" size="1">#endif</font></div>



</div><div><font face="courier new, monospace" size="1">#endif</font></div><div><font face="courier new, monospace" size="1"><br></font></div><div><div><font face="courier new, monospace" size="1">#ifndef LLVM_FALLTHROUGH</font></div>



</div><div><font face="courier new, monospace" size="1">#define LLVM_FALLTHROUGH do { } while (0)</font></div><div><div><font face="courier new, monospace" size="1">#endif</font></div>



</div></blockquote><div><div><br></div><div>Prior to this feature diagnostic messages would say:</div><div><div><font face="courier new, monospace" size="1">test.cpp:156:5: <b>warning: unannotated fall-through between switch labels</b></font></div>



<div><font face="courier new, monospace" size="1">    case 223:</font></div><div><font face="courier new, monospace" size="1">    ^</font></div><div><font face="courier new, monospace" size="1">test.cpp:156:5: <b>note: insert '[[clang::fallthrough]];' to silence this warning</b></font></div>



<div><font face="courier new, monospace" size="1">    case 223:</font></div><div><font face="courier new, monospace" size="1">    ^</font></div><div><font face="courier new, monospace" size="1">    <b>[[clang::fallthrough]];</b> </font></div>



<div><font face="courier new, monospace" size="1">test.cpp:156:5: <b>note: insert 'break;' to avoid fall-through</b></font></div><div><font face="courier new, monospace" size="1">    case 223:</font></div><div><font face="courier new, monospace" size="1">    ^</font></div>



<div><font face="courier new, monospace" size="1">    break;</font></div></div><div><br></div><div>Applying the first of these fix-it hints will lead to broken builds in C++03 mode, which is usually not desired.</div><div>



<br></div><div>But with the automatic detection feature the diagnostic will suggest the correct compatibility macro available in the corresponding source location:</div><div><div><span style="font-family:'courier new',monospace;font-size:x-small">...</span></div>



<div><span style="font-family:'courier new',monospace;font-size:x-small">test.cpp:156:5:</span><span style="font-family:'courier new',monospace;font-size:x-small"> </span><b style="font-family:'courier new',monospace;font-size:x-small">note: insert 'LLVM_FALLTHROUGH;' to silence this warning</b><br>



</div><div><font face="courier new, monospace" size="1">    case 223:</font></div><div><font face="courier new, monospace" size="1">    ^</font></div><div><font face="courier new, monospace" size="1">    </font><b style="font-family:'courier new',monospace;font-size:x-small">LLVM_FALLTHROUGH; </b></div>



<div><font face="courier new, monospace" size="1">...</font></div></div><div><div><br></div><div>Please, review this patch. Thank you!</div><span><font color="#888888"><div><br></div><div>-- <br>
<div>Best regards,</div><div>Alexander Kornienko</div></div></font></span></div></div>
</blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div><br>-- <br>
</div><div class="gmail_extra">Best regards,</div><div class="gmail_extra">Alexander Kornienko</div>
</blockquote></div><br></body></html>