<div dir="ltr">I think this is a useful addition that has been requested multiple times in the past - have you by chance tried this on C++ code? I'd predict it doesn't work well there, but I'd be curious whether you have other results :)</div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jun 16, 2017 at 2:11 AM Argyrios Kyrtzidis <<a href="mailto:kyrtzidis@apple.com">kyrtzidis@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Put a patch for review here:</div><div><a href="https://reviews.llvm.org/D34263" target="_blank">https://reviews.llvm.org/D34263</a></div><div><br></div><div><blockquote type="cite"></blockquote></div></div><div style="word-wrap:break-word"><div><blockquote type="cite"><div>On Jun 14, 2017, at 6:25 PM, Argyrios Kyrtzidis via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="m_1034824691286228418Apple-interchange-newline"></blockquote></div></div><div style="word-wrap:break-word"><div><blockquote type="cite"><div><div style="word-wrap:break-word">Hey all,<div><br></div><div>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><br></div><div>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><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>@implementation Foo</div><div>-(void)testSomething {}</div><div>-(NSString*)returnIt { return @“blah”; }</div><div>@end</div></blockquote><div><br></div><div>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><br></div><div>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><br></div><div>We’ve used this for a while now in Xcode to do something like ‘fast-scanning’ specifically for ObjC unit tests (<b>*</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>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><br></div><div>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><br></div><div>This is due to the limitation of the 'fast scan' not seeing symbols inside preprocessor directives. For example, with code like this:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>#if ENABLE_FOO_TESTS</div><div><br></div><div><div>@implementation Foo</div></div><div><div>-(void)testSomething {}</div></div><div>@end</div><div><br></div><div>#endif</div></blockquote><div><br></div><div>‘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><br></div><div><span id="m_1034824691286228418x-apple-selection:end"></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>If the directive is using literals like:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div>#if 0</div></div><div>…</div><div>#endif</div><div><br></div><div><div>#if 1</div></div><div><div>…</div></div><div><div>#endif</div></div></blockquote><div><br></div><div>Or making use of defined macros then there’s no change of behavior.</div><div><br></div><div>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><br></div><div>Let me know what you think!</div><div><br></div><div><br></div><div>(<b>*</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></div></blockquote></div></div><div style="word-wrap:break-word"><div><blockquote type="cite"><div>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br></div></blockquote></div><br></div></blockquote></div>