Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:22

0001 //===--- LexerUtils.h - clang-tidy-------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 /// Returns previous token or ``tok::unknown`` if not found.
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     // Returning 'true' is used to signal failure to retrieve the token.
0057     if (Lexer::getRawToken(L, T, SM, LangOpts, /*IgnoreWhiteSpace=*/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     // If we reach the end of the file, and eof is not the target token, we stop
0084     // the loop, otherwise we will get infinite loop (findNextToken will return
0085     // eof on eof).
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 // Finds next token that's not a comment.
0099 std::optional<Token> findNextTokenSkippingComments(SourceLocation Start,
0100                                                    const SourceManager &SM,
0101                                                    const LangOptions &LangOpts);
0102 
0103 /// Re-lex the provide \p Range and return \c false if either a macro spans
0104 /// multiple tokens, a pre-processor directive or failure to retrieve the
0105 /// next token is found, otherwise \c true.
0106 bool rangeContainsExpansionsOrDirectives(SourceRange Range,
0107                                          const SourceManager &SM,
0108                                          const LangOptions &LangOpts);
0109 
0110 /// Assuming that ``Range`` spans a CVR-qualified type, returns the
0111 /// token in ``Range`` that is responsible for the qualification. ``Range``
0112 /// must be valid with respect to ``SM``.  Returns ``std::nullopt`` if no
0113 /// qualifying tokens are found.
0114 /// \note: doesn't support member function qualifiers.
0115 std::optional<Token> getQualifyingToken(tok::TokenKind TK,
0116                                         CharSourceRange Range,
0117                                         const ASTContext &Context,
0118                                         const SourceManager &SM);
0119 
0120 /// Stmt->getEndLoc does not always behave the same way depending on Token type.
0121 /// See implementation for exceptions.
0122 SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM,
0123                                 const LangOptions &LangOpts);
0124 
0125 /// For a given FunctionDecl returns the location where you would need to place
0126 /// the noexcept specifier.
0127 SourceLocation getLocationForNoexceptSpecifier(const FunctionDecl *FuncDecl,
0128                                                const SourceManager &SM);
0129 
0130 } // namespace tidy::utils::lexer
0131 } // namespace clang
0132 
0133 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H