1 //===--- IntegralLiteralExpressionMatcher.h - clang-tidy ------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_INTEGRAL_LITERAL_EXPRESSION_MATCHER_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_INTEGRAL_LITERAL_EXPRESSION_MATCHER_H 11 12 #include <clang/Lex/Token.h> 13 #include <llvm/ADT/ArrayRef.h> 14 15 namespace clang { 16 namespace tidy { 17 namespace modernize { 18 19 enum class LiteralSize { 20 Unknown = 0, 21 Int, 22 UnsignedInt, 23 Long, 24 UnsignedLong, 25 LongLong, 26 UnsignedLongLong 27 }; 28 29 // Parses an array of tokens and returns true if they conform to the rules of 30 // C++ for whole expressions involving integral literals. Follows the operator 31 // precedence rules of C++. Optionally exclude comma operator expressions. 32 class IntegralLiteralExpressionMatcher { 33 public: IntegralLiteralExpressionMatcher(ArrayRef<Token> Tokens,bool CommaAllowed)34 IntegralLiteralExpressionMatcher(ArrayRef<Token> Tokens, bool CommaAllowed) 35 : Current(Tokens.begin()), End(Tokens.end()), CommaAllowed(CommaAllowed) { 36 } 37 38 bool match(); 39 LiteralSize largestLiteralSize() const; 40 41 private: 42 bool advance(); 43 bool consume(tok::TokenKind Kind); 44 bool nonTerminalChainedExpr( 45 bool (IntegralLiteralExpressionMatcher::*NonTerminal)(), 46 const std::function<bool(Token)> &IsKind); 47 template <tok::TokenKind Kind> nonTerminalChainedExpr(bool (IntegralLiteralExpressionMatcher::* NonTerminal)())48 bool nonTerminalChainedExpr( 49 bool (IntegralLiteralExpressionMatcher::*NonTerminal)()) { 50 return nonTerminalChainedExpr(NonTerminal, 51 [](Token Tok) { return Tok.is(Kind); }); 52 } 53 template <tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind... Ks> nonTerminalChainedExpr(bool (IntegralLiteralExpressionMatcher::* NonTerminal)())54 bool nonTerminalChainedExpr( 55 bool (IntegralLiteralExpressionMatcher::*NonTerminal)()) { 56 return nonTerminalChainedExpr( 57 NonTerminal, [](Token Tok) { return Tok.isOneOf(K1, K2, Ks...); }); 58 } 59 60 bool unaryOperator(); 61 bool unaryExpr(); 62 bool multiplicativeExpr(); 63 bool additiveExpr(); 64 bool shiftExpr(); 65 bool compareExpr(); 66 bool relationalExpr(); 67 bool equalityExpr(); 68 bool andExpr(); 69 bool exclusiveOrExpr(); 70 bool inclusiveOrExpr(); 71 bool logicalAndExpr(); 72 bool logicalOrExpr(); 73 bool conditionalExpr(); 74 bool commaExpr(); 75 bool expr(); 76 77 ArrayRef<Token>::iterator Current; 78 ArrayRef<Token>::iterator End; 79 LiteralSize LargestSize{LiteralSize::Unknown}; 80 bool CommaAllowed; 81 }; 82 83 } // namespace modernize 84 } // namespace tidy 85 } // namespace clang 86 87 #endif 88