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