File indexing completed on 2026-05-10 08:36:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H
0010 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H
0011
0012 #include "clang/AST/ASTContext.h"
0013 #include "clang/Basic/TokenKinds.h"
0014 #include "clang/Lex/Lexer.h"
0015 #include <optional>
0016 #include <utility>
0017
0018 namespace clang {
0019
0020 class Stmt;
0021
0022 namespace tidy::utils::lexer {
0023
0024
0025 Token getPreviousToken(SourceLocation Location, const SourceManager &SM,
0026 const LangOptions &LangOpts, bool SkipComments = true);
0027 std::pair<Token, SourceLocation>
0028 getPreviousTokenAndStart(SourceLocation Location, const SourceManager &SM,
0029 const LangOptions &LangOpts, bool SkipComments = true);
0030
0031 SourceLocation findPreviousTokenStart(SourceLocation Start,
0032 const SourceManager &SM,
0033 const LangOptions &LangOpts);
0034
0035 SourceLocation findPreviousTokenKind(SourceLocation Start,
0036 const SourceManager &SM,
0037 const LangOptions &LangOpts,
0038 tok::TokenKind TK);
0039
0040 SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM,
0041 const LangOptions &LangOpts);
0042
0043 template <typename TokenKind, typename... TokenKinds>
0044 SourceLocation findPreviousAnyTokenKind(SourceLocation Start,
0045 const SourceManager &SM,
0046 const LangOptions &LangOpts,
0047 TokenKind TK, TokenKinds... TKs) {
0048 if (Start.isInvalid() || Start.isMacroID())
0049 return {};
0050 while (true) {
0051 SourceLocation L = findPreviousTokenStart(Start, SM, LangOpts);
0052 if (L.isInvalid() || L.isMacroID())
0053 return {};
0054
0055 Token T;
0056
0057 if (Lexer::getRawToken(L, T, SM, LangOpts, true))
0058 return {};
0059
0060 if (T.isOneOf(TK, TKs...))
0061 return T.getLocation();
0062
0063 Start = L;
0064 }
0065 }
0066
0067 template <typename TokenKind, typename... TokenKinds>
0068 SourceLocation findNextAnyTokenKind(SourceLocation Start,
0069 const SourceManager &SM,
0070 const LangOptions &LangOpts, TokenKind TK,
0071 TokenKinds... TKs) {
0072 while (true) {
0073 std::optional<Token> CurrentToken =
0074 Lexer::findNextToken(Start, SM, LangOpts);
0075
0076 if (!CurrentToken)
0077 return {};
0078
0079 Token PotentialMatch = *CurrentToken;
0080 if (PotentialMatch.isOneOf(TK, TKs...))
0081 return PotentialMatch.getLocation();
0082
0083
0084
0085
0086 if (PotentialMatch.is(tok::eof))
0087 return {};
0088 Start = PotentialMatch.getLastLoc();
0089 }
0090 }
0091
0092 inline std::optional<Token>
0093 findNextTokenIncludingComments(SourceLocation Start, const SourceManager &SM,
0094 const LangOptions &LangOpts) {
0095 return Lexer::findNextToken(Start, SM, LangOpts, true);
0096 }
0097
0098
0099 std::optional<Token> findNextTokenSkippingComments(SourceLocation Start,
0100 const SourceManager &SM,
0101 const LangOptions &LangOpts);
0102
0103
0104
0105
0106 bool rangeContainsExpansionsOrDirectives(SourceRange Range,
0107 const SourceManager &SM,
0108 const LangOptions &LangOpts);
0109
0110
0111
0112
0113
0114
0115 std::optional<Token> getQualifyingToken(tok::TokenKind TK,
0116 CharSourceRange Range,
0117 const ASTContext &Context,
0118 const SourceManager &SM);
0119
0120
0121
0122 SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM,
0123 const LangOptions &LangOpts);
0124
0125
0126
0127 SourceLocation getLocationForNoexceptSpecifier(const FunctionDecl *FuncDecl,
0128 const SourceManager &SM);
0129
0130 }
0131 }
0132
0133 #endif