Skip to content

Commit 2cce3d1

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

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.
@@ -642,10 +642,10 @@ class Lexer : public PreprocessorLexer {
642642
BufferPtr = TokEnd;
643643
}
644644

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

650650
//===--------------------------------------------------------------------===//
651651
// Lexer character reading interfaces.

clang/include/clang/Lex/Preprocessor.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2282,7 +2282,9 @@ class Preprocessor {
22822282
/// Determine whether the next preprocessor token to be
22832283
/// lexed is a '('. If so, consume the token and return true, if not, this
22842284
/// method should have no observable side-effect on the lexed tokens.
2285-
bool isNextPPTokenLParen();
2285+
bool isNextPPTokenLParen() {
2286+
return peekNextPPToken().value_or(Token{}).is(tok::l_paren);
2287+
}
22862288

22872289
private:
22882290
/// Identifiers used for SEH handling in Borland. These are only
@@ -2661,6 +2663,10 @@ class Preprocessor {
26612663

26622664
void removeCachedMacroExpandedTokensOfLastLexer();
26632665

2666+
/// Peek the next token. If so, return the token, if not, this
2667+
/// method should have no observable side-effect on the lexed tokens.
2668+
std::optional<Token> peekNextPPToken();
2669+
26642670
/// After reading "MACRO(", this method is invoked to read all of the formal
26652671
/// arguments specified for the macro invocation. Returns null on error.
26662672
MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,

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
@@ -3200,18 +3200,19 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
32003200
return PP->HandleEndOfFile(Result, isPragmaLexer());
32013201
}
32023202

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

32103209
if (isDependencyDirectivesLexer()) {
32113210
if (NextDepDirectiveTokenIndex == DepDirectives.front().Tokens.size())
3212-
return 2;
3213-
return DepDirectives.front().Tokens[NextDepDirectiveTokenIndex].is(
3214-
tok::l_paren);
3211+
return std::nullopt;
3212+
Token Result;
3213+
(void)convertDependencyDirectiveToken(
3214+
DepDirectives.front().Tokens[NextDepDirectiveTokenIndex], Result);
3215+
return Result;
32153216
}
32163217

32173218
// Switch to 'skipping' mode. This will ensure that we can lex a token
@@ -3240,8 +3241,8 @@ unsigned Lexer::isNextPPTokenLParen() {
32403241
LexingRawMode = false;
32413242

32423243
if (Tok.is(tok::eof))
3243-
return 2;
3244-
return Tok.is(tok::l_paren);
3244+
return std::nullopt;
3245+
return Tok;
32453246
}
32463247

32473248
/// 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
@@ -418,42 +418,40 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
418418
return !llvm::is_contained(MI->params(), II);
419419
}
420420

421-
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
422-
/// lexed is a '('. If so, consume the token and return true, if not, this
423-
/// method should have no observable side-effect on the lexed tokens.
424-
bool Preprocessor::isNextPPTokenLParen() {
421+
/// isNextPPTokenLParen - Peek the next token. If so, return the token, if not,
422+
/// this method should have no observable side-effect on the lexed tokens.
423+
std::optional<Token> Preprocessor::peekNextPPToken() {
425424
// Do some quick tests for rejection cases.
426-
unsigned Val;
425+
std::optional<Token> Val;
427426
if (CurLexer)
428-
Val = CurLexer->isNextPPTokenLParen();
427+
Val = CurLexer->peekNextPPToken();
429428
else
430-
Val = CurTokenLexer->isNextTokenLParen();
429+
Val = CurTokenLexer->peekNextPPToken();
431430

432-
if (Val == 2) {
431+
if (!Val) {
433432
// We have run off the end. If it's a source file we don't
434433
// examine enclosing ones (C99 5.1.1.2p4). Otherwise walk up the
435434
// macro stack.
436435
if (CurPPLexer)
437-
return false;
436+
return std::nullopt;
438437
for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
439438
if (Entry.TheLexer)
440-
Val = Entry.TheLexer->isNextPPTokenLParen();
439+
Val = Entry.TheLexer->peekNextPPToken();
441440
else
442-
Val = Entry.TheTokenLexer->isNextTokenLParen();
441+
Val = Entry.TheTokenLexer->peekNextPPToken();
443442

444-
if (Val != 2)
443+
if (Val)
445444
break;
446445

447446
// Ran off the end of a source file?
448447
if (Entry.ThePPLexer)
449-
return false;
448+
return std::nullopt;
450449
}
451450
}
452451

453-
// Okay, if we know that the token is a '(', lex it and return. Otherwise we
454-
// have found something that isn't a '(' or we found the end of the
455-
// translation unit. In either case, return false.
456-
return Val == 1;
452+
// Okay, we found the token and return. Otherwise we found the end of the
453+
// translation unit.
454+
return Val;
457455
}
458456

459457
/// 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
@@ -921,13 +921,13 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
921921
}
922922

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

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

0 commit comments

Comments
 (0)