Skip to content

Commit e25019f

Browse files
committed
[Clang] Add peekNextPPToken, makes peek next token without side-effects
Signed-off-by: yronglin <[email protected]>
1 parent efa62c3 commit e25019f

File tree

6 files changed

+46
-42
lines changed

6 files changed

+46
-42
lines changed

clang/include/clang/Lex/Lexer.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class Lexer : public PreprocessorLexer {
124124
//===--------------------------------------------------------------------===//
125125
// Context that changes as the file is lexed.
126126
// NOTE: any state that mutates when in raw mode must have save/restore code
127-
// in Lexer::isNextPPTokenLParen.
127+
// in Lexer::peekNextPPToken.
128128

129129
// BufferPtr - Current pointer into the buffer. This is the next character
130130
// to be lexed.
@@ -629,10 +629,10 @@ class Lexer : public PreprocessorLexer {
629629
BufferPtr = TokEnd;
630630
}
631631

632-
/// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
633-
/// tok::l_paren token, 0 if it is something else and 2 if there are no more
634-
/// tokens in the buffer controlled by this lexer.
635-
unsigned isNextPPTokenLParen();
632+
/// peekNextPPToken - Return std::nullopt if there are no more tokens in the
633+
/// buffer controlled by this lexer, otherwise return the next unexpanded
634+
/// token.
635+
std::optional<Token> peekNextPPToken();
636636

637637
//===--------------------------------------------------------------------===//
638638
// Lexer character reading interfaces.

clang/include/clang/Lex/Preprocessor.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2649,10 +2649,16 @@ class Preprocessor {
26492649

26502650
void removeCachedMacroExpandedTokensOfLastLexer();
26512651

2652+
/// Peek the next token. If so, return the token, if not, this
2653+
/// method should have no observable side-effect on the lexed tokens.
2654+
std::optional<Token> peekNextPPToken();
2655+
26522656
/// Determine whether the next preprocessor token to be
26532657
/// lexed is a '('. If so, consume the token and return true, if not, this
26542658
/// method should have no observable side-effect on the lexed tokens.
2655-
bool isNextPPTokenLParen();
2659+
bool isNextPPTokenLParen() {
2660+
return peekNextPPToken().value_or(Token{}).is(tok::l_paren);
2661+
}
26562662

26572663
/// After reading "MACRO(", this method is invoked to read all of the formal
26582664
/// arguments specified for the macro invocation. Returns null on error.

clang/include/clang/Lex/TokenLexer.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,9 @@ class TokenLexer {
139139
void Init(const Token *TokArray, unsigned NumToks, bool DisableMacroExpansion,
140140
bool OwnsTokens, bool IsReinject);
141141

142-
/// If the next token lexed will pop this macro off the
143-
/// expansion stack, return 2. If the next unexpanded token is a '(', return
144-
/// 1, otherwise return 0.
145-
unsigned isNextTokenLParen() const;
142+
/// If the next token lexed will pop this macro off the expansion stack,
143+
/// return std::nullopt, otherwise return the next unexpanded token.
144+
std::optional<Token> peekNextPPToken() const;
146145

147146
/// Lex and return a token from this macro stream.
148147
bool Lex(Token &Tok);

clang/lib/Lex/Lexer.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3193,18 +3193,19 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
31933193
return PP->HandleEndOfFile(Result, isPragmaLexer());
31943194
}
31953195

3196-
/// isNextPPTokenLParen - Return 1 if the next unexpanded token lexed from
3197-
/// the specified lexer will return a tok::l_paren token, 0 if it is something
3198-
/// else and 2 if there are no more tokens in the buffer controlled by the
3199-
/// lexer.
3200-
unsigned Lexer::isNextPPTokenLParen() {
3196+
/// peekNextPPToken - Return std::nullopt if there are no more tokens in the
3197+
/// buffer controlled by this lexer, otherwise return the next unexpanded
3198+
/// token.
3199+
std::optional<Token> Lexer::peekNextPPToken() {
32013200
assert(!LexingRawMode && "How can we expand a macro from a skipping buffer?");
32023201

32033202
if (isDependencyDirectivesLexer()) {
32043203
if (NextDepDirectiveTokenIndex == DepDirectives.front().Tokens.size())
3205-
return 2;
3206-
return DepDirectives.front().Tokens[NextDepDirectiveTokenIndex].is(
3207-
tok::l_paren);
3204+
return std::nullopt;
3205+
Token Result;
3206+
(void)convertDependencyDirectiveToken(
3207+
DepDirectives.front().Tokens[NextDepDirectiveTokenIndex], Result);
3208+
return Result;
32083209
}
32093210

32103211
// Switch to 'skipping' mode. This will ensure that we can lex a token
@@ -3233,8 +3234,8 @@ unsigned Lexer::isNextPPTokenLParen() {
32333234
LexingRawMode = false;
32343235

32353236
if (Tok.is(tok::eof))
3236-
return 2;
3237-
return Tok.is(tok::l_paren);
3237+
return std::nullopt;
3238+
return Tok;
32383239
}
32393240

32403241
/// Find the end of a version control conflict marker.

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -437,42 +437,40 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
437437
return !llvm::is_contained(MI->params(), II);
438438
}
439439

440-
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
441-
/// lexed is a '('. If so, consume the token and return true, if not, this
442-
/// method should have no observable side-effect on the lexed tokens.
443-
bool Preprocessor::isNextPPTokenLParen() {
440+
/// isNextPPTokenLParen - Peek the next token. If so, return the token, if not,
441+
/// this method should have no observable side-effect on the lexed tokens.
442+
std::optional<Token> Preprocessor::peekNextPPToken() {
444443
// Do some quick tests for rejection cases.
445-
unsigned Val;
444+
std::optional<Token> Val;
446445
if (CurLexer)
447-
Val = CurLexer->isNextPPTokenLParen();
446+
Val = CurLexer->peekNextPPToken();
448447
else
449-
Val = CurTokenLexer->isNextTokenLParen();
448+
Val = CurTokenLexer->peekNextPPToken();
450449

451-
if (Val == 2) {
450+
if (!Val) {
452451
// We have run off the end. If it's a source file we don't
453452
// examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the
454453
// macro stack.
455454
if (CurPPLexer)
456-
return false;
455+
return std::nullopt;
457456
for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
458457
if (Entry.TheLexer)
459-
Val = Entry.TheLexer->isNextPPTokenLParen();
458+
Val = Entry.TheLexer->peekNextPPToken();
460459
else
461-
Val = Entry.TheTokenLexer->isNextTokenLParen();
460+
Val = Entry.TheTokenLexer->peekNextPPToken();
462461

463-
if (Val != 2)
462+
if (Val)
464463
break;
465464

466465
// Ran off the end of a source file?
467466
if (Entry.ThePPLexer)
468-
return false;
467+
return std::nullopt;
469468
}
470469
}
471470

472-
// Okay, if we know that the token is a '(', lex it and return. Otherwise we
473-
// have found something that isn't a '(' or we found the end of the
474-
// translation unit. In either case, return false.
475-
return Val == 1;
471+
// Okay, we found the token and return. Otherwise we found the end of the
472+
// translation unit.
473+
return Val;
476474
}
477475

478476
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be

clang/lib/Lex/TokenLexer.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -922,13 +922,13 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
922922
}
923923

924924
/// isNextTokenLParen - If the next token lexed will pop this macro off the
925-
/// expansion stack, return 2. If the next unexpanded token is a '(', return
926-
/// 1, otherwise return 0.
927-
unsigned TokenLexer::isNextTokenLParen() const {
925+
/// expansion stack, return std::nullopt, otherwise return the next unexpanded
926+
/// token.
927+
std::optional<Token> TokenLexer::peekNextPPToken() const {
928928
// Out of tokens?
929929
if (isAtEnd())
930-
return 2;
931-
return Tokens[CurTokenIdx].is(tok::l_paren);
930+
return std::nullopt;
931+
return Tokens[CurTokenIdx];
932932
}
933933

934934
/// isParsingPreprocessorDirective - Return true if we are in the middle of a

0 commit comments

Comments
 (0)