<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 10, 2015 at 3:28 PM, Ben Langmuir <span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div class="h5"><blockquote type="cite"><div>On Mar 23, 2015, at 8:20 PM, Ben Langmuir <<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>> wrote:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite"><div><br>On Mar 23, 2015, at 7:52 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 23, 2015 at 7:36 PM, Ben Langmuir<span> </span><span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div><blockquote type="cite"><div>On Mar 23, 2015, at 5:06 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 23, 2015 at 5:01 PM, Ben Langmuir<span> </span><span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div><blockquote type="cite"><div>On Mar 23, 2015, at 4:18 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 23, 2015 at 3:59 PM, Ben Langmuir<span> </span><span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On Mar 23, 2015, at 3:43 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 23, 2015 at 2:41 PM, Ben Langmuir<span> </span><span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On Mar 23, 2015, at 1:05 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote">On Sat, Mar 14, 2015 at 9:25 AM, Ben Langmuir<span> </span><span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Richard,<br><br>This commit looks like it caused a regression in PCH-loading performance when the PCH imports modules.  It doesn’t affect performance of loading modules on their own, or of a PCH that doesn’t use modules.  If you have access to a Darwin system, it’s easy to reproduce with:<br><br>$ cat t.h<br>@import Cocoa;<br><br>$ cat t.m<br>// empty<br><br>$ clang -fmodules -fmodules-cache-path=mcp -x objective-c-header t.h -o t.pch<br>$ time clang -fmodules -fmodules-cache-path=mcp -Xclang -include-pch -Xclang t.pch t.m -fsyntax-only<br><br>I’m seeing ~8x difference between r228233 and r228234.  In real world code (where the .m file isn’t empty) we’ve seen up to a ~90% difference.<br><br>Do you know what’s going on here?</blockquote><div><br></div><div>Hmm. I suspect this change causes the lookup table for the translation unit to be built, which in turn pulls in all the lexical contents of the translation unit (because outside of C++ we don't serialize a DeclContext lookup table for the TU, nor even build one usually).</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">When a PCH loads I think we do it without Sema, but (at least previously) queued up the interesting Decls we saw for when Sema was added later.  So I’m surprised this had such a big effect.</blockquote><div><br></div><div>If we were loading PCHs without Sema, then I think before this change we would not have merged declarations of the same entity from two independent modules imported into the same PCH.</div></div></div></div></div></blockquote><div><br></div></span><div>Wouldn’t that happen in InitializeSema() when we called pushExternalDeclIntoScope() on the contents of PreloadedDeclIDs?</div></div></div></blockquote><div><br></div><div>No; we're talking about the case where a Decl is deserialized before we have a Sema instance. If we never deserialized the Decl from its DeclID before we had a Sema (which I think is what you're suggesting) we'd never have reached the modified code.</div></div></div></div></div></blockquote><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>If we want to support loading Decls without Sema, we need to be able to merge them without Sema. If we don't, then we should find whichever codepath is leading us to do so and fix it. Being able to load a serialized AST without a Sema seems useful to me, in the absence of a good reason why it shouldn't work.</div></div></div></div></div></blockquote><div><br></div></span><div>I thought PCH intentionally wouldn’t deserialize decls until after we initialized Sema.   Maybe we have a bug (which wouldn’t surprise me), or maybe that wasn’t the intent (which would scare me a bit since then we have some decls showing up immediately and some waiting for sema with no clear split between them).</div><span><br><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div>Perhaps we should use a separate side-table for merging in this case outside C++, rather than falling back to DeclContext lookup?</div></div></div></div></div></blockquote><div><br></div></span><div>I don’t know this code path well enough to say.  What would go into the table (or perhaps more importantly what wouldn’t)?</div></div></div></blockquote><div><br></div><div>Any deserialized declarations that should be visible by name lookup in the TU would be in the table. The only difference would be that we'd be more careful to ensure that we never trigger the import of all lexical declarations in the TU in order to build the table.</div><div><br></div><div>Are you still seeing this performance problem with Clang trunk? Towards the end of last week I fixed a bug where we would unnecessarily pull in all lexical declarations within the TU when doing certain lookups, which might have fixed this slowdown. (If not, it'd be useful to find out whether that's the problem, and if so, what is causing us to load these declarations.)</div></div></div></div></div></blockquote><div><br></div></span><div>Cool, I’ll give ToT a shot.  I last tried with r232229.</div></div></div></blockquote><div><br></div><div>r232928 onwards, or a revision in [232793, 232905), have the change I'm referring to.</div></div></div></div></div></blockquote><div><br></div></div></div><div>ToT got faster, but not even close to pre-228234.</div><div><br></div><div>r228233: 0.0574 s <== “before”</div><div>r228234: 0.4433 s <== “after"</div><div>r232229: 0.4028 s</div><div>r233028: 0.3097 s <== ToT</div></div></div></blockquote><div><br></div><div>Where's ToT spending its time?</div></div></div></div></div></blockquote><div><br></div></div></div><div>Suspiciously it’s coming from LoadLexicalDeclsFromExternalStorage inside **noload_lookup**…</div></div></div></blockquote><div><br></div><div>Aha, thanks! Should be fixed in r233046, let me know if there are still problems.</div></div></div></div></div></blockquote><div><br></div><div>Excellent, thanks for the fix!  I’ve verified we’re back to the pre-228234 performance.</div></div></div></blockquote><div><br></div><div><br></div></div></div><div>Hey Richard,</div><div><br></div><div>Sorry to drag this back up, but apparently I didn’t verify it carefully enough.  Your commit fixed the regression for initially loading the PCH, but it’s still slow if you actually do any lookups into the ASTReader.  If I add:</div><div><br></div><div>void foo() {</div><div>}</div><div><br></div><div>to my test .m file, which means we try to lookup ‘foo’ in the ASTReader, clang is still slow (3-5 seconds with -fsyntax-only).  The trace is:</div><div><br></div><div><div>Running Time<span style="white-space:pre-wrap">    </span>Self (ms)<span style="white-space:pre-wrap">               </span>Symbol Name</div><div>3202.0ms   98.6%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>              clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&)</div><div>3202.0ms   98.6%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>               clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>)</div><div>3202.0ms   98.6%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool)</div><div>3202.0ms   98.6%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                 clang::DeclContext::makeDeclVisibleInContextWithFlags(clang::NamedDecl*, bool, bool)</div><div>3202.0ms   98.6%<span style="white-space:pre-wrap">   </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                  clang::DeclContext::buildLookup()</div><div>3199.0ms   98.5%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                   clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const</div><div>3004.0ms   92.5%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                    clang::ASTReader::FinishedDeserializing()</div><div>3004.0ms   92.5%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                     clang::ASTReader::finishPendingActions()</div><div>2955.0ms   91.0%<span style="white-space:pre-wrap"> </span>3.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                      clang::ASTReader::pushExternalDeclIntoScope(clang::NamedDecl*, clang::DeclarationName)</div><div>2942.0ms   90.6%<span style="white-space:pre-wrap"> </span>1721.0<span style="white-space:pre-wrap">  </span> <span style="white-space:pre-wrap">       </span>                       llvm::MapVector<clang::IdentifierInfo*, llvm::SmallVector<clang::NamedDecl*, 2u>, llvm::SmallDenseMap<clang::IdentifierInfo*, unsigned int, 16u, llvm::DenseMapInfo<clang::IdentifierInfo*>, llvm::detail::DenseMapPair<clang::IdentifierInfo*, unsigned int> >, llvm::SmallVector<std::__1::pair<clang::IdentifierInfo*, llvm::SmallVector<clang::NamedDecl*, 2u> >, 16u> >::erase(std::__1::pair<clang::IdentifierInfo*, llvm::SmallVector<clang::NamedDecl*, 2u> >*)</div><div><br></div></div><div><br></div><div>Most of this is because MapVector::erase is O(n), so as a workaround I switched to clear() ing the contained SmallVector in r234655.  But I think there’s a more fundamental issue here, because even with that improvement the whole compile still takes 0.25 - 0.5 seconds, rather than the 0.02 seconds it takes without PCH, or without Modules (ie. only the combination of both is slow).  The trace after removing the MapVector::erase is:</div><div><br></div><div><div>Running Time<span style="white-space:pre-wrap"> </span>Self (ms)<span style="white-space:pre-wrap">               </span>Symbol Name</div><div>246.0ms   84.2%<span style="white-space:pre-wrap">      </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>              clang::Sema::ActOnStartOfFunctionDef(clang::Scope*, clang::Declarator&)</div><div>246.0ms   84.2%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>               clang::Sema::HandleDeclarator(clang::Scope*, clang::Declarator&, llvm::MutableArrayRef<clang::TemplateParameterList*>)</div><div>245.0ms   83.9%<span style="white-space:pre-wrap">   </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                clang::Sema::PushOnScopeChains(clang::NamedDecl*, clang::Scope*, bool)</div><div>245.0ms   83.9%<span style="white-space:pre-wrap">   </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                 clang::DeclContext::makeDeclVisibleInContextWithFlags(clang::NamedDecl*, bool, bool)</div><div>245.0ms   83.9%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                  clang::DeclContext::buildLookup()</div><div>242.0ms   82.8%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                   clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const</div></div></div></div></blockquote><div><br></div><div>This shouldn't be happening; I think makeDeclVisibleInContextWithFlags is too eager to build the lookup table for a DeclContext. Can you try removing the 'hasExternalVisibleStorage() ||' from it?</div><div> </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><div><div>189.0ms   64.7%<span style="white-space:pre-wrap">       </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                    non-virtual thunk to clang::ASTReader::FindExternalLexicalDecls(clang::DeclContext const*, bool (*)(clang::Decl::Kind), llvm::SmallVectorImpl<clang::Decl*>&)</div><div>189.0ms   64.7%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                     clang::serialization::ModuleManager::visitDepthFirst(bool (*)(clang::serialization::ModuleFile&, bool, void*), void*)</div><div>189.0ms   64.7%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                      visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>189.0ms   64.7%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                       visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>189.0ms   64.7%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                        visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>170.0ms   58.2%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                         visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>98.0ms   33.5%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                          visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>71.0ms   24.3%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                           (anonymous namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, bool, void*)</div><div>27.0ms    9.2%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                           visitDepthFirst(clang::serialization::ModuleFile&, bool (*)(clang::serialization::ModuleFile&, bool, void*), void*, llvm::SmallVectorImpl<bool>&)</div><div>72.0ms   24.6%<span style="white-space:pre-wrap">       </span>0.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                          (anonymous namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, bool, void*)</div><div>19.0ms    6.5%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap">     </span> <span style="white-space:pre-wrap">       </span>                         (anonymous namespace)::FindExternalLexicalDeclsVisitor::visit(clang::serialization::ModuleFile&, bool, void*)</div><div><br></div></div><div><br></div><div>We still seem to be eagerly loading something that we shouldn’t.  -print-stats gives:</div><div><br></div><div>*** AST File Statistics:<br>  28/96751 source location entries read (0.028940%)<br>  24388/29520 types read (82.615181%)<br>  64783/142552 declarations read (45.445171%)<br>  29024/90665 identifiers read (32.012352%)<br>  1527/19301 macros read (7.911507%)<br>  0/10332 selectors read (0.000000%)<br>  204/49951 statements read (0.408400%)<br>  1527/19301 macros read (7.911507%)<br>  1/6984 lexical declcontexts read (0.014318%)<br>  0/5973 visible declcontexts read (0.000000%)<br>  0/9318 method pool entries read (0.000000%)<br>  24171 / 52370 identifier table lookups succeeded (46.154287%)</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Ben</div></font></span><div><div class="h5"><br><blockquote type="cite"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div>are we setting <span style="font-family:Menlo">hasExternalVisibleStorage incorrectly?</span></div><div><br></div><div><div>Running Time<span style="white-space:pre-wrap">   </span>Self<span style="white-space:pre-wrap">            </span>Symbol Name</div><div>341.0ms   97.1%<span style="white-space:pre-wrap">      </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span> <span> </span>cc1_main(llvm::ArrayRef<char const*>, char const*, void*)</div><div>340.0ms   96.8%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>   clang::ExecuteCompilerInvocation(clang::CompilerInstance*)</div><div>340.0ms   96.8%<span style="white-space:pre-wrap">       </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>   <span> </span>clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)</div><div>336.0ms   95.7%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>     clang::FrontendAction::BeginSourceFile(clang::CompilerInstance&, clang::FrontendInputFile const&)</div><div>335.0ms   95.4%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>     <span> </span>clang::CompilerInstance::createPCHExternalASTSource(llvm::StringRef, bool, bool, void*, bool)</div><div>335.0ms   95.4%<span style="white-space:pre-wrap">      </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>       clang::CompilerInstance::createPCHExternalASTSource(llvm::StringRef, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, bool, clang::Preprocessor&, clang::ASTContext&, void*, bool, bool, bool)</div><div>335.0ms   95.4%<span style="white-space:pre-wrap">    </span>1.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>       <span> </span>clang::ASTReader::ReadAST(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, clang::serialization::ModuleKind, clang::SourceLocation, unsigned int)</div><div>248.0ms   70.6%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>         clang::ASTReader::InitializeContext()</div><div>247.0ms   70.3%<span style="white-space:pre-wrap">   </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>         <span> </span>clang::ASTReader::GetType(unsigned int)</div><div>247.0ms   70.3%<span style="white-space:pre-wrap">      </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>           clang::ASTReader::readTypeRecord(unsigned int)</div><div>247.0ms   70.3%<span style="white-space:pre-wrap">       </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>           <span> </span>clang::ASTReader::ReadDeclRecord(unsigned int)</div><div>247.0ms   70.3%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>             clang::ASTDeclReader::Visit(clang::Decl*)</div><div>247.0ms   70.3%<span style="white-space:pre-wrap"> </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>             <span> </span>clang::declvisitor::Base<clang::declvisitor::make_ptr, clang::ASTDeclReader, void>::Visit(clang::Decl*)</div><div>247.0ms   70.3%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>               clang::ASTDeclReader::VisitTypedefNameDecl(clang::TypedefNameDecl*)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>               <span> </span>clang::ASTReader::GetTypeSourceInfo(clang::serialization::ModuleFile&, llvm::SmallVector<unsigned long long, 64u> const&, unsigned int&)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                 clang::ASTReader::GetType(unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                 <span> </span>clang::ASTReader::readTypeRecord(unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">   </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                   clang::ASTReader::GetType(unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                   <span> </span>clang::ASTReader::readTypeRecord(unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                     clang::ASTReader::ReadDeclRecord(unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                     <span> </span>clang::ASTDeclReader::Visit(clang::Decl*)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                       clang::declvisitor::Base<clang::declvisitor::make_ptr, clang::ASTDeclReader, void>::Visit(clang::Decl*)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">      </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                       <span> </span>clang::ASTDeclReader::VisitTagDecl(clang::TagDecl*)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                         void clang::ASTDeclReader::mergeRedeclarable<clang::TagDecl>(clang::Redeclarable<clang::TagDecl>*, clang::ASTDeclReader::RedeclarableResult&, unsigned int)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">     </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                         <span> </span>clang::ASTDeclReader::findExisting(clang::NamedDecl*)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">        </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                           clang::DeclContext::noload_lookup(clang::DeclarationName)</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">    </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                           <span> </span>clang::DeclContext::lookup(clang::DeclarationName) const</div><div>246.0ms   70.0%<span style="white-space:pre-wrap">  </span>0.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                             clang::DeclContext::buildLookup()</div><div>242.0ms   68.9%<span style="white-space:pre-wrap"> </span>1.0<span style="white-space:pre-wrap">     </span><span> </span><span style="white-space:pre-wrap">     </span><span> </span>                             <span> </span>clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const</div><div><br></div><div><br></div></div><div><div><br><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span><font color="#888888"><div>Ben</div></font></span><div><div><br><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><font color="#888888">Ben<br></font></span><div><div><br>> On Feb 4, 2015, at 3:37 PM, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>> wrote:<br>><br>> Author: rsmith<br>> Date: Wed Feb  4 17:37:59 2015<br>> New Revision: 228234<br>><br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project?rev=228234&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228234&view=rev</a><br>> Log:<br>> [modules] When using -E, we may try to merge decls despite having no Sema<br>> object. In such a case, use the TU's DC for merging global decls rather than<br>> giving up when we find there is no TU scope.<br>><br>> Ultimately, we should probably avoid all loading of decls when preprocessing,<br>> but there are other reasonable use cases for loading an AST file with no Sema<br>> object for which this is the right thing.<br>><br>> Added:<br>>    cfe/trunk/test/Modules/Inputs/preprocess/<br>>    cfe/trunk/test/Modules/Inputs/preprocess/file.h<br>>    cfe/trunk/test/Modules/Inputs/preprocess/fwd.h<br>>    cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap<br>> Modified:<br>>    cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>>    cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>>    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>>    cfe/trunk/test/Modules/preprocess.m<br>><br>> Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=228234&r1=228233&r2=228234&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=228234&r1=228233&r2=228234&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)<br>> +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Wed Feb  4 17:37:59 2015<br>> @@ -588,7 +588,7 @@ public:<br>>   /// Create an external AST source to read a PCH file.<br>>   ///<br>>   /// \return - The new object on success, or null on failure.<br>> -  static ExternalASTSource *createPCHExternalASTSource(<br>> +  static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(<br>>       StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,<br>>       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,<br>>       void *DeserializationListener, bool OwnDeserializationListener,<br>><br>> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=228234&r1=228233&r2=228234&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=228234&r1=228233&r2=228234&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)<br>> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Feb  4 17:37:59 2015<br>> @@ -388,32 +388,30 @@ void CompilerInstance::createASTContext(<br>> void CompilerInstance::createPCHExternalASTSource(<br>>     StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,<br>>     void *DeserializationListener, bool OwnDeserializationListener) {<br>> -  IntrusiveRefCntPtr<ExternalASTSource> Source;<br>>   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;<br>> -  Source = createPCHExternalASTSource(<br>> +  ModuleManager = createPCHExternalASTSource(<br>>       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,<br>>       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),<br>>       DeserializationListener, OwnDeserializationListener, Preamble,<br>>       getFrontendOpts().UseGlobalModuleIndex);<br>> -  ModuleManager = static_cast<ASTReader*>(Source.get());<br>> -  getASTContext().setExternalSource(Source);<br>> }<br>><br>> -ExternalASTSource *CompilerInstance::createPCHExternalASTSource(<br>> +IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(<br>>     StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,<br>>     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,<br>>     void *DeserializationListener, bool OwnDeserializationListener,<br>>     bool Preamble, bool UseGlobalModuleIndex) {<br>>   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();<br>><br>> -  std::unique_ptr<ASTReader> Reader;<br>> -  Reader.reset(new ASTReader(PP, Context,<br>> -                             Sysroot.empty() ? "" : Sysroot.c_str(),<br>> -                             DisablePCHValidation,<br>> -                             AllowPCHWithCompilerErrors,<br>> -                             /*AllowConfigurationMismatch*/false,<br>> -                             HSOpts.ModulesValidateSystemHeaders,<br>> -                             UseGlobalModuleIndex));<br>> +  IntrusiveRefCntPtr<ASTReader> Reader(<br>> +      new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(),<br>> +                    DisablePCHValidation, AllowPCHWithCompilerErrors,<br>> +                    /*AllowConfigurationMismatch*/ false,<br>> +                    HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));<br>> +<br>> +  // We need the external source to be set up before we read the AST, because<br>> +  // eagerly-deserialized declarations may use it.<br>> +  Context.setExternalSource(Reader.get());<br>><br>>   Reader->setDeserializationListener(<br>>       static_cast<ASTDeserializationListener *>(DeserializationListener),<br>> @@ -427,7 +425,7 @@ ExternalASTSource *CompilerInstance::cre<br>>     // Set the predefines buffer as suggested by the PCH reader. Typically, the<br>>     // predefines buffer will be empty.<br>>     PP.setPredefines(Reader->getSuggestedPredefines());<br>> -    return Reader.release();<br>> +    return Reader;<br>><br>>   case ASTReader::Failure:<br>>     // Unrecoverable failure: don't even try to process the input file.<br>> @@ -442,6 +440,7 @@ ExternalASTSource *CompilerInstance::cre<br>>     break;<br>>   }<br>><br>> +  Context.setExternalSource(nullptr);<br>>   return nullptr;<br>> }<br>><br>><br>> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228234&r1=228233&r2=228234&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=228234&r1=228233&r2=228234&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Feb  4 17:37:59 2015<br>> @@ -2591,6 +2591,11 @@ DeclContext *ASTDeclReader::getPrimaryCo<br>>     return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()<br>>                                                       : nullptr;<br>><br>> +  // We can see the TU here only if we have no Sema object. In that case,<br>> +  // there's no TU scope to look in, so using the DC alone is sufficient.<br>> +  if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))<br>> +    return TU;<br>> +<br>>   return nullptr;<br>> }<br>><br>><br>> Added: cfe/trunk/test/Modules/Inputs/preprocess/file.h<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/file.h?rev=228234&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/file.h?rev=228234&view=auto</a><br>> ==============================================================================<br>> --- cfe/trunk/test/Modules/Inputs/preprocess/file.h (added)<br>> +++ cfe/trunk/test/Modules/Inputs/preprocess/file.h Wed Feb  4 17:37:59 2015<br>> @@ -0,0 +1,3 @@<br>> +struct __FILE;<br>> +#include "fwd.h"<br>> +typedef struct __FILE FILE;<br>><br>> Added: cfe/trunk/test/Modules/Inputs/preprocess/fwd.h<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/fwd.h?rev=228234&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/fwd.h?rev=228234&view=auto</a><br>> ==============================================================================<br>> --- cfe/trunk/test/Modules/Inputs/preprocess/fwd.h (added)<br>> +++ cfe/trunk/test/Modules/Inputs/preprocess/fwd.h Wed Feb  4 17:37:59 2015<br>> @@ -0,0 +1 @@<br>> +struct __FILE;<br>><br>> Added: cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap?rev=228234&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap?rev=228234&view=auto</a><br>> ==============================================================================<br>> --- cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap (added)<br>> +++ cfe/trunk/test/Modules/Inputs/preprocess/module.modulemap Wed Feb  4 17:37:59 2015<br>> @@ -0,0 +1,2 @@<br>> +module fwd { header "fwd.h" export * }<br>> +module file { header "file.h" export * }<br>><br>> Modified: cfe/trunk/test/Modules/preprocess.m<br>> URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=228234&r1=228233&r2=228234&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/preprocess.m?rev=228234&r1=228233&r2=228234&view=diff</a><br>> ==============================================================================<br>> --- cfe/trunk/test/Modules/preprocess.m (original)<br>> +++ cfe/trunk/test/Modules/preprocess.m Wed Feb  4 17:37:59 2015<br>> @@ -1,9 +1,14 @@<br>> // RUN: rm -rf %t<br>> -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s<br>> -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -x objective-c-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch<br>> -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s<br>> +//<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++ -include %S/Inputs/preprocess-prefix.h -E %s | FileCheck -strict-whitespace %s<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++-header -emit-pch %S/Inputs/preprocess-prefix.h -o %t.pch<br>> +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -I %S/Inputs/preprocess -x objective-c++ -include-pch %t.pch -E %s | FileCheck -strict-whitespace %s<br>> #import "diamond_right.h"<br>> #import "diamond_right.h" // to check that imports get their own line<br>> +#include "file.h"<br>> void test() {<br>>   top_left_before();<br>>   left_and_right();<br>> @@ -15,6 +20,7 @@ void test() {<br>><br>> // CHECK: @import diamond_right; /* clang -E: implicit import for "{{.*}}diamond_right.h" */{{$}}<br>> // CHECK: @import diamond_right; /* clang -E: implicit import for "{{.*}}diamond_right.h" */{{$}}<br>> +// CHECK: @import file; /* clang -E: implicit import for "{{.*}}file.h" */{{$}}<br>> // CHECK-NEXT: void test() {{{$}}<br>> // CHECK-NEXT:    top_left_before();{{$}}<br>> // CHECK-NEXT:    left_and_right();{{$}}<br>><br>><br>> _______________________________________________<br>> cfe-commits mailing list<br>><span> </span><a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>><span> </span><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">cfe-commits mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:cfe-commits@cs.uiuc.edu" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">cfe-commits@cs.uiuc.edu</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:14px;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a></div></blockquote></div></div></div><br></div></blockquote></div><br></div></div>