diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -254,28 +254,6 @@ return Body->getBeginLoc(); } -static Token getPreviousToken(SourceLocation &Location, const SourceManager &SM, - const LangOptions &LangOpts, - bool SkipComments = false) { - Token Token; - Token.setKind(tok::unknown); - - Location = Location.getLocWithOffset(-1); - if (Location.isInvalid()) - return Token; - - auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location)); - while (Location != StartOfFile) { - Location = Lexer::GetBeginningOfToken(Location, SM, LangOpts); - if (!Lexer::getRawToken(Location, Token, SM, LangOpts) && - (!SkipComments || !Token.is(tok::comment))) { - break; - } - Location = Location.getLocWithOffset(-1); - } - return Token; -} - bool isPrimaryExpression(const Expr *Expression) { // This function is an incomplete approximation of checking whether // an Expr is a primary expression. In particular, if this function @@ -300,7 +278,10 @@ if (PrevTokenLoc.isInvalid()) return std::nullopt; - Token PrevToken = getPreviousToken(PrevTokenLoc, SM, LangOpts); + const bool SkipComments = false; + Token PrevToken; + std::tie(PrevToken, PrevTokenLoc) = utils::lexer::getPreviousTokenAndStart( + PrevTokenLoc, SM, LangOpts, SkipComments); bool EndsWithDoubleSlash = PrevToken.is(tok::comment) && Lexer::getSourceText(CharSourceRange::getCharRange( diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.h b/clang-tools-extra/clang-tidy/utils/LexerUtils.h --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.h +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.h @@ -13,6 +13,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Lex/Lexer.h" #include +#include namespace clang { @@ -23,6 +24,9 @@ /// Returns previous token or ``tok::unknown`` if not found. Token getPreviousToken(SourceLocation Location, const SourceManager &SM, const LangOptions &LangOpts, bool SkipComments = true); +std::pair +getPreviousTokenAndStart(SourceLocation Location, const SourceManager &SM, + const LangOptions &LangOpts, bool SkipComments = true); SourceLocation findPreviousTokenStart(SourceLocation Start, const SourceManager &SM, diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp @@ -10,17 +10,19 @@ #include "clang/AST/AST.h" #include "clang/Basic/SourceManager.h" #include +#include namespace clang::tidy::utils::lexer { -Token getPreviousToken(SourceLocation Location, const SourceManager &SM, - const LangOptions &LangOpts, bool SkipComments) { +std::pair +getPreviousTokenAndStart(SourceLocation Location, const SourceManager &SM, + const LangOptions &LangOpts, bool SkipComments) { Token Token; Token.setKind(tok::unknown); Location = Location.getLocWithOffset(-1); if (Location.isInvalid()) - return Token; + return {Token, Location}; auto StartOfFile = SM.getLocForStartOfFile(SM.getFileID(Location)); while (Location != StartOfFile) { @@ -31,6 +33,13 @@ } Location = Location.getLocWithOffset(-1); } + return {Token, Location}; +} + +Token getPreviousToken(SourceLocation Location, const SourceManager &SM, + const LangOptions &LangOpts, bool SkipComments) { + auto [Token, Start] = + getPreviousTokenAndStart(Location, SM, LangOpts, SkipComments); return Token; }