PR18793: If we try to EnterTokenStream when our current lexer is a caching

lexer, add the token buffer underneath the caching lexer where possible and
push the tokens directly into the caching lexer otherwise. We previously
put the lexer into a corrupted state where we could not guarantee to provide
the tokens in the right order and would sometimes assert.

llvm-svn: 218333
This commit is contained in:
Richard Smith 2014-09-23 21:05:52 +00:00
parent 6dbbbc28b0
commit bdf54a21b5
3 changed files with 25 additions and 0 deletions

View File

@ -1361,6 +1361,7 @@ public:
private:
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.push_back(IncludeStackInfo(
CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
CurPPLexer, std::move(CurTokenLexer), CurDirLookup));

View File

@ -190,6 +190,25 @@ void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd,
void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,
bool DisableMacroExpansion,
bool OwnsTokens) {
if (CurLexerKind == CLK_CachingLexer) {
if (CachedLexPos < CachedTokens.size()) {
// We're entering tokens into the middle of our cached token stream. We
// can't represent that, so just insert the tokens into the buffer.
CachedTokens.insert(CachedTokens.begin() + CachedLexPos,
Toks, Toks + NumToks);
if (OwnsTokens)
delete [] Toks;
return;
}
// New tokens are at the end of the cached token sequnece; insert the
// token stream underneath the caching lexer.
ExitCachingLexMode();
EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens);
EnterCachingLexMode();
return;
}
// Create a macro expander to expand from the specified token stream.
std::unique_ptr<TokenLexer> TokLexer;
if (NumCachedTokenLexers == 0) {

View File

@ -106,3 +106,8 @@ namespace pr16225add {
{ };
}
namespace PR18793 {
template<typename T, T> struct S {};
template<typename T> int g(S<T, (T())> *);
}