diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index e08c07bd20d8..4d2994feb331 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -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)); diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 1ce3796aa792..f0d3d67acae3 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -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 TokLexer; if (NumCachedTokenLexers == 0) { diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp index bbd53b2bdd69..c9cc6b807902 100644 --- a/clang/test/Parser/cxx-template-argument.cpp +++ b/clang/test/Parser/cxx-template-argument.cpp @@ -106,3 +106,8 @@ namespace pr16225add { { }; } + +namespace PR18793 { + template struct S {}; + template int g(S *); +}