<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Put a patch for review here:</div><div class=""><a href="https://reviews.llvm.org/D34263" class="">https://reviews.llvm.org/D34263</a></div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Jun 14, 2017, at 6:25 PM, Argyrios Kyrtzidis via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hey all,<div class=""><br class=""></div><div class="">In r305044 I introduced a preprocessor option (bool SingleFileParseMode) and clang-c/Index.h enumerator (CXTranslationUnit_SingleFileParse) to assist with ‘parsing a single file only’. I’m going to provide some details and context on why such parsing is useful and why a new option is necessary.</div><div class=""><br class=""></div><div class="">Parsing a single file (essentially parse it normally but without including any other headers) is useful as a way to determine the global symbols that exist in the source files, in an inaccurate but ‘lightning-super-fast’ mode. For example, if the source is like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">@implementation Foo</div><div class="">-(void)testSomething {}</div><div class="">-(NSString*)returnIt { return @“blah”; }</div><div class="">@end</div></blockquote><div class=""><br class=""></div><div class="">The parser can determine that there is an ObjC @implementation named ‘Foo’ with 2 methods, -testSomething, and -returnIt. Even if no SDK header gets included and ‘NSString’ becomes unresolved, the parser can still provide the associated global symbols.</div><div class=""><br class=""></div><div class="">In general terms, think of this like approximating the inaccurate parsing that something like SublimeText is doing, where there’s no preprocessor or precise typechecking but it can still provide you with a list of symbols and some rudimentary jump-to-definition.</div><div class=""><br class=""></div><div class="">We’ve used this for a while now in Xcode to do something like ‘fast-scanning’ specifically for ObjC unit tests (<b class="">*</b>). This allows us to show the available unit tests almost immediately once you open a project, without waiting for the full-accurate indexing to complete.</div><div class="">If the ‘fast-scan’ is missing something, e.g. due to preprocessor directives or macros, it will still show up once the accurate indexing catches up.</div><div class=""><br class=""></div><div class="">To clarify, this is working without any modifications to clang, we were just using libclang to parse the file containing the unit tests and did not pass any search paths, which had the practical effect of not including headers. So why adding the option now ?</div><div class=""><br class=""></div><div class="">This is due to the limitation of the 'fast scan' not seeing symbols inside preprocessor directives. For example, with code like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">#if ENABLE_FOO_TESTS</div><div class=""><br class=""></div><div class=""><div class="">@implementation Foo</div></div><div class=""><div class="">-(void)testSomething {}</div></div><div class="">@end</div><div class=""><br class=""></div><div class="">#endif</div></blockquote><div class=""><br class=""></div><div class="">‘ENABLE_FOO_TESTS’ is not defined so the preprocessor skips this block and we miss getting these tests via the ‘fast scan’. Here’s what I’d like to propose:</div><div class=""><br class=""></div><div class=""><span id="x-apple-selection:end" class=""></span>If ‘SingleFileParseMode’ is true, the preprocessor will treat undefined identifiers in preprocessor directives specially. If the directive is making use of an undefined identifier then it will cause it to ignore the directive and parse all blocks of the directive (the #if block, and the #else one as well).</div><div class="">If the directive is using literals like:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class="">#if 0</div></div><div class="">…</div><div class="">#endif</div><div class=""><br class=""></div><div class=""><div class="">#if 1</div></div><div class=""><div class="">…</div></div><div class=""><div class="">#endif</div></div></blockquote><div class=""><br class=""></div><div class="">Or making use of defined macros then there’s no change of behavior.</div><div class=""><br class=""></div><div class="">With such a change, in this ‘fast-scan-inaccurate-mode’ we’ll be able to gather the symbols that exist in preprocessor directives like the "#if ENABLE_FOO_TESTS” example.</div><div class=""><br class=""></div><div class="">Let me know what you think!</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">(<b class="">*</b>) Dealing only with detection of ObjC unit tests has a restricted scope and clang was well equipped to help with unmodified. If we want to extend ‘fast/inaccurate’ parsing and try to gather such symbol info from all files, clang would need to be enhanced to improve its error recovery and not drop valuable information from its AST when there are compiler errors. But this is a discussion for another thread at some later point in future.</div></div>_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""></div></blockquote></div><br class=""></body></html>