Mercurial > hg > CbC > CbC_llvm
diff clang-tools-extra/clang-tidy/utils/LexerUtils.h @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.h Thu Feb 13 15:10:13 2020 +0900 @@ -0,0 +1,112 @@ +//===--- LexerUtils.h - clang-tidy-------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H + +#include "clang/AST/ASTContext.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Lex/Lexer.h" + +namespace clang { +namespace tidy { +namespace utils { +namespace lexer { + +/// Returns previous token or ``tok::unknown`` if not found. +Token getPreviousToken(SourceLocation Location, const SourceManager &SM, + const LangOptions &LangOpts, bool SkipComments = true); + +SourceLocation findPreviousTokenStart(SourceLocation Start, + const SourceManager &SM, + const LangOptions &LangOpts); + +SourceLocation findPreviousTokenKind(SourceLocation Start, + const SourceManager &SM, + const LangOptions &LangOpts, + tok::TokenKind TK); + +SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM, + const LangOptions &LangOpts); + +template <typename TokenKind, typename... TokenKinds> +SourceLocation findPreviousAnyTokenKind(SourceLocation Start, + const SourceManager &SM, + const LangOptions &LangOpts, + TokenKind TK, TokenKinds... TKs) { + if (Start.isInvalid() || Start.isMacroID()) + return SourceLocation(); + while (true) { + SourceLocation L = findPreviousTokenStart(Start, SM, LangOpts); + if (L.isInvalid() || L.isMacroID()) + return SourceLocation(); + + Token T; + // Returning 'true' is used to signal failure to retrieve the token. + if (Lexer::getRawToken(L, T, SM, LangOpts, /*IgnoreWhiteSpace=*/true)) + return SourceLocation(); + + if (T.isOneOf(TK, TKs...)) + return T.getLocation(); + + Start = L; + } +} + +template <typename TokenKind, typename... TokenKinds> +SourceLocation findNextAnyTokenKind(SourceLocation Start, + const SourceManager &SM, + const LangOptions &LangOpts, TokenKind TK, + TokenKinds... TKs) { + while (true) { + Optional<Token> CurrentToken = Lexer::findNextToken(Start, SM, LangOpts); + + if (!CurrentToken) + return SourceLocation(); + + Token PotentialMatch = *CurrentToken; + if (PotentialMatch.isOneOf(TK, TKs...)) + return PotentialMatch.getLocation(); + + // If we reach the end of the file, and eof is not the target token, we stop + // the loop, otherwise we will get infinite loop (findNextToken will return + // eof on eof). + if (PotentialMatch.is(tok::eof)) + return SourceLocation(); + Start = PotentialMatch.getLastLoc(); + } +} + +// Finds next token that's not a comment. +Optional<Token> findNextTokenSkippingComments(SourceLocation Start, + const SourceManager &SM, + const LangOptions &LangOpts); + +/// Re-lex the provide \p Range and return \c false if either a macro spans +/// multiple tokens, a pre-processor directive or failure to retrieve the +/// next token is found, otherwise \c true. +bool rangeContainsExpansionsOrDirectives(SourceRange Range, + const SourceManager &SM, + const LangOptions &LangOpts); + +/// Assuming that ``Range`` spans a CVR-qualified type, returns the +/// token in ``Range`` that is responsible for the qualification. ``Range`` +/// must be valid with respect to ``SM``. Returns ``None`` if no qualifying +/// tokens are found. +/// \note: doesn't support member function qualifiers. +llvm::Optional<Token> getQualifyingToken(tok::TokenKind TK, + CharSourceRange Range, + const ASTContext &Context, + const SourceManager &SM); + +} // namespace lexer +} // namespace utils +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_LEXER_UTILS_H