================
@@ -48,6 +48,59 @@ class ActionCommentHandler : public CommentHandler {
};
} // end anonymous namespace
+class Parser::TokenInjectionHandlerImpl : public sema::TokenInjectionHandler {
+ Parser &P;
+
+public:
+ explicit TokenInjectionHandlerImpl(Parser &P) : P{P} {}
+
+ ExprResult ParseAsExpression(StringRef Code,
+ const llvm::StringMap<Token> &Replacements,
+ SourceLocation InjectionLoc) override {
+ // Collect tokens.
+ SmallVector<Token> Tokens;
+ if (P.PP.LexTokensInString(Tokens, Code, InjectionLoc))
+ return ExprError();
+
+ for (Token &Tok : Tokens) {
+ if (Tok.is(tok::identifier)) {
+ auto It = Replacements.find(Tok.getIdentifierInfo()->getName());
+ if (It != Replacements.end())
+ Tok = It->getValue();
+ }
+ }
+
+ // Add an EOF token so we know when to stop.
+ char EofMarker{};
+ Token &EofToken = Tokens.emplace_back();
+ EofToken.startToken();
+ EofToken.setKind(tok::eof);
+ EofToken.setEofData(&EofMarker);
+
+ // Start parsing the tokens; we need to save the current token so we
+ // don't lose it, and consume it since EnterTokenStream() doesn't change
+ // the current token.
+ //
+ // Disable macro expansion since that was already done as part of the call
+ // to LexTokensInString() above; 'IsReinjected' is for phase 4 tokens, so
+ // we don't want that either here.
+ SaveAndRestore SaveCurTok{P.Tok};
+ P.PP.EnterTokenStream(Tokens, /*DisableMacroExpansion=*/true,
+ /*IsReinjected=*/false);
+ P.ConsumeAnyToken();
+ ExprResult Res = P.ParseExpression();
+
+ // We should have parsed exactly one expression; if we still have tokens
+ // left, then there was probably an error; don't diagnose this and just
+ // skip them.
+ while (P.Tok.isNot(tok::eof))
+ P.ConsumeAnyToken();
+
+ assert(P.Tok.getEofData() == &EofMarker);
+ return Res;
----------------
cor3ntin wrote:
Not a fan of that either - The assert should be before we flush the tokens.
We are not parsing some user-provided content that could be bogus - we are
calling an api with a payload of our own making so there should never be non
sense tokens (assuming the expression is valid)
so `assert(P.Tok.is(tok::eof) || Res.isInvalid()` ?
But i wonder if we should have a "ParsingInjectedTokens" mode in Lexer that
would inject EOF for us? here, maybe not but it's worth thinking about
https://github.com/llvm/llvm-project/pull/208877
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits