This is an archive of the discontinued LLVM Phabricator instance.

Handle delayed-template-parsing functions imported into a non-dtp TU
ClosedPublic

Authored by sammccall on Jun 9 2020, 8:30 AM.

Details

Summary

DelayedTemplateParsing is marked as BENIGN_LANGOPT, so we are allowed to
use a delayed template in a non-delayed TU.
(This is clangd's default configuration on windows: delayed-template-parsing
is on for the preamble and forced off for the current file)

However today clang fails to parse implicit instantiations in a non-dtp
TU of templates defined in a dtp PCH file (and presumably module?).
In this case the delayed parser is not registered, so the function is
simply marked "delayed" again. We then hit an assert:
end of TU template instantiation should not create more late-parsed templates

Diff Detail

Event Timeline

sammccall created this revision.Jun 9 2020, 8:30 AM
kadircet accepted this revision.Jun 11 2020, 2:36 AM

Looking at this some more, it looks like whenever clang is building a TU prefix(preamble), the assumption is that any delayed templates will be parsed at the end of the TU. That is unfortunately not true, if the rest of the TU is built with no-delayed-template-parsing. (as you've already said in the description)

This suggests that DelayedTemplateParsing shouldn't be a benign langopt. But since it is, we should be setting late template parser at the end of TU if there are any delayed templates coming from either the preamble or in the rest of the TU.
The latter is already done by checking for langopt, we can check for the former using Actions.ExternalSemaSource. But in the absence of delayed templates, setting the parser is (currently) a no-op. So setting it all the time should hopefully be OK.
Hence LGTM.

Another option would be to change preamble building logic to parse all the late parsed templates at the end, instead of just serializing the tokens. That sounds like a more intrusive change though, so I am more comfortable with current one.

This revision is now accepted and ready to land.Jun 11 2020, 2:36 AM

Thanks for reviewing! Going to land this now as the bug is surfaced by other pending changes.

Looking at this some more, it looks like whenever clang is building a TU prefix(preamble), the assumption is that any delayed templates will be parsed at the end of the TU. That is unfortunately not true, if the rest of the TU is built with no-delayed-template-parsing. (as you've already said in the description)

This suggests that DelayedTemplateParsing shouldn't be a benign langopt. But since it is, we should be setting late template parser at the end of TU if there are any delayed templates coming from either the preamble or in the rest of the TU.
The latter is already done by checking for langopt, we can check for the former using Actions.ExternalSemaSource. But in the absence of delayed templates, setting the parser is (currently) a no-op. So setting it all the time should hopefully be OK.
Hence LGTM.

Yeah I think checking ExternalSemaSource is probably correct. Not checking it is simpler though :-)

Another option would be to change preamble building logic to parse all the late parsed templates at the end, instead of just serializing the tokens. That sounds like a more intrusive change though, so I am more comfortable with current one.

This has different semantics - the point of delayed template parsing is to wait for more symbols to be visible. If we parse at the end of the PCH, then symbols defined in the main file (but before instantiation) are not visible.

This revision was automatically updated to reflect the committed changes.