21 const char *Begin = Token.getLiteralData();
22 const char *End = Begin + Token.getLength();
25 if (Token.getLength() > 2 && Begin[0] ==
'0' && std::toupper(Begin[1]) ==
'X')
26 return std::none_of(Begin + 2, End, [](
char C) {
27 return C ==
'.' || std::toupper(
C) ==
'P';
31 return std::none_of(Begin, End, [](
char C) {
32 return C ==
'.' || std::toupper(
C) ==
'E' || std::toupper(
C) ==
'I';
36bool IntegralLiteralExpressionMatcher::advance() {
38 return Current != End;
41bool IntegralLiteralExpressionMatcher::consume(tok::TokenKind
Kind) {
42 if (Current->is(
Kind)) {
50template <
typename NonTerminalFunctor,
typename IsKindFunctor>
51bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
52 const NonTerminalFunctor &NonTerminal,
const IsKindFunctor &IsKind) {
58 while (Current != End) {
59 if (!IsKind(*Current))
72template <tok::TokenKind Kind,
typename NonTerminalFunctor>
73bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
74 const NonTerminalFunctor &NonTerminal) {
75 return nonTerminalChainedExpr(NonTerminal,
76 [](Token Tok) {
return Tok.is(
Kind); });
79template <tok::TokenKind K1, tok::TokenKind K2, tok::TokenKind... Ks,
80 typename NonTerminalFunctor>
81bool IntegralLiteralExpressionMatcher::nonTerminalChainedExpr(
82 const NonTerminalFunctor &NonTerminal) {
83 return nonTerminalChainedExpr(
84 NonTerminal, [](Token Tok) {
return Tok.isOneOf(K1, K2, Ks...); });
88bool IntegralLiteralExpressionMatcher::unaryOperator() {
89 if (Current->isOneOf(tok::TokenKind::minus, tok::TokenKind::plus,
90 tok::TokenKind::tilde, tok::TokenKind::exclaim)) {
98 unsigned int Length = Tok.getLength();
102 bool SeenUnsigned =
false;
103 bool SeenLong =
false;
104 bool SeenLongLong =
false;
105 const char *
Text = Tok.getLiteralData();
106 for (
unsigned int End =
Length - 1; End > 0; --End) {
107 if (std::isdigit(
Text[End]))
110 if (std::toupper(
Text[End]) ==
'U')
112 else if (std::toupper(
Text[End]) ==
'L') {
138 return static_cast<int>(LHS) <
static_cast<int>(RHS);
141bool IntegralLiteralExpressionMatcher::unaryExpr() {
142 if (!unaryOperator())
145 if (consume(tok::TokenKind::l_paren)) {
155 return consume(tok::TokenKind::r_paren);
158 if (!Current->isLiteral() || isStringLiteral(Current->getKind()) ||
169bool IntegralLiteralExpressionMatcher::multiplicativeExpr() {
170 return nonTerminalChainedExpr<tok::TokenKind::star, tok::TokenKind::slash,
171 tok::TokenKind::percent>(
172 [
this] {
return unaryExpr(); });
175bool IntegralLiteralExpressionMatcher::additiveExpr() {
176 return nonTerminalChainedExpr<tok::plus, tok::minus>(
177 [
this] {
return multiplicativeExpr(); });
180bool IntegralLiteralExpressionMatcher::shiftExpr() {
181 return nonTerminalChainedExpr<tok::TokenKind::lessless,
182 tok::TokenKind::greatergreater>(
183 [
this] {
return additiveExpr(); });
186bool IntegralLiteralExpressionMatcher::compareExpr() {
192 if (Current->is(tok::TokenKind::spaceship)) {
203bool IntegralLiteralExpressionMatcher::relationalExpr() {
204 return nonTerminalChainedExpr<tok::TokenKind::less, tok::TokenKind::greater,
205 tok::TokenKind::lessequal,
206 tok::TokenKind::greaterequal>(
207 [
this] {
return compareExpr(); });
210bool IntegralLiteralExpressionMatcher::equalityExpr() {
211 return nonTerminalChainedExpr<tok::TokenKind::equalequal,
212 tok::TokenKind::exclaimequal>(
213 [
this] {
return relationalExpr(); });
216bool IntegralLiteralExpressionMatcher::andExpr() {
217 return nonTerminalChainedExpr<tok::TokenKind::amp>(
218 [
this] {
return equalityExpr(); });
221bool IntegralLiteralExpressionMatcher::exclusiveOrExpr() {
222 return nonTerminalChainedExpr<tok::TokenKind::caret>(
223 [
this] {
return andExpr(); });
226bool IntegralLiteralExpressionMatcher::inclusiveOrExpr() {
227 return nonTerminalChainedExpr<tok::TokenKind::pipe>(
228 [
this] {
return exclusiveOrExpr(); });
231bool IntegralLiteralExpressionMatcher::logicalAndExpr() {
232 return nonTerminalChainedExpr<tok::TokenKind::ampamp>(
233 [
this] {
return inclusiveOrExpr(); });
236bool IntegralLiteralExpressionMatcher::logicalOrExpr() {
237 return nonTerminalChainedExpr<tok::TokenKind::pipepipe>(
238 [
this] {
return logicalAndExpr(); });
241bool IntegralLiteralExpressionMatcher::conditionalExpr() {
242 if (!logicalOrExpr())
247 if (Current->is(tok::TokenKind::question)) {
252 if (Current->is(tok::TokenKind::colon)) {
267 if (!Current->is(tok::TokenKind::colon))
279bool IntegralLiteralExpressionMatcher::commaExpr() {
280 auto NonTerminal = [
this] {
return conditionalExpr(); };
282 return nonTerminalChainedExpr<tok::TokenKind::comma>(NonTerminal);
283 return nonTerminalChainedExpr(NonTerminal, [](Token) {
return false; });
286bool IntegralLiteralExpressionMatcher::expr() {
return commaExpr(); }
291 return conditionalExpr() && Current == End;
LiteralSize largestLiteralSize() const
static bool isIntegralConstant(const Token &Token)
static LiteralSize literalTokenSize(const Token &Tok)
static bool operator<(LiteralSize LHS, LiteralSize RHS)