brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · 4a8c1c3 Raw
278 lines · cpp
1//===---- ModernizeModuleTest.cpp - 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-exception6//7//===----------------------------------------------------------------------===//8#include "ClangTidyTest.h"9#include "modernize/IntegralLiteralExpressionMatcher.h"10#include "clang/Lex/Lexer.h"11#include "gtest/gtest.h"12 13#include <cstring>14#include <iterator>15#include <string>16#include <vector>17 18namespace clang {19namespace tidy {20namespace test {21 22static std::vector<Token> tokenify(const char *Text) {23  LangOptions LangOpts;24  std::vector<std::string> Includes;25  LangOptions::setLangDefaults(LangOpts, Language::CXX, llvm::Triple(),26                               Includes, LangStandard::lang_cxx20);27  Lexer Lex(SourceLocation{}, LangOpts, Text, Text, Text + std::strlen(Text));28  std::vector<Token> Tokens;29  bool End = false;30  while (!End) {31    Token Tok;32    End = Lex.LexFromRawLexer(Tok);33    Tokens.push_back(Tok);34  }35 36  return Tokens;37}38 39static bool matchText(const char *Text, bool AllowComma) {40  std::vector<Token> Tokens{tokenify(Text)};41  modernize::IntegralLiteralExpressionMatcher Matcher(Tokens, AllowComma);42 43  return Matcher.match();44}45 46static modernize::LiteralSize sizeText(const char *Text) {47  std::vector<Token> Tokens{tokenify(Text)};48  modernize::IntegralLiteralExpressionMatcher Matcher(Tokens, true);49  if (Matcher.match())50    return Matcher.largestLiteralSize();51  return modernize::LiteralSize::Unknown;52}53 54static const char *toString(modernize::LiteralSize Value) {55  switch (Value) {56  case modernize::LiteralSize::Int:57    return "Int";58  case modernize::LiteralSize::UnsignedInt:59    return "UnsignedInt";60  case modernize::LiteralSize::Long:61    return "Long";62  case modernize::LiteralSize::UnsignedLong:63    return "UnsignedLong";64  case modernize::LiteralSize::LongLong:65    return "LongLong";66  case modernize::LiteralSize::UnsignedLongLong:67    return "UnsignedLongLong";68  default:69    return "Unknown";70  }71}72 73namespace {74 75struct MatchParam {76  bool AllowComma;77  bool Matched;78  const char *Text;79 80  friend std::ostream &operator<<(std::ostream &Str, const MatchParam &Value) {81    return Str << "Allow operator,: " << std::boolalpha << Value.AllowComma82               << ", Matched: " << std::boolalpha << Value.Matched83               << ", Text: '" << Value.Text << '\'';84  }85};86 87struct SizeParam {88  modernize::LiteralSize Size;89  const char *Text;90 91  friend std::ostream &operator<<(std::ostream &Str, const SizeParam &Value) {92    return Str << "Size: " << toString(Value.Size) << ", Text: '" << Value.Text << '\'';93  }94};95 96class MatcherTest : public ::testing::TestWithParam<MatchParam> {};97 98class SizeTest : public ::testing::TestWithParam<SizeParam> {};99 100} // namespace101 102static const MatchParam MatchParams[] = {103    // Accept integral literals.104    {true, true, "1"},105    {true, true, "0177"},106    {true, true, "0xdeadbeef"},107    {true, true, "0b1011"},108    {true, true, "'c'"},109    // Reject non-integral literals.110    {true, false, "1.23"},111    {true, false, "0x1p3"},112    {true, false, R"("string")"},113    {true, false, "1i"},114 115    // Accept literals with these unary operators.116    {true, true, "-1"},117    {true, true, "+1"},118    {true, true, "~1"},119    {true, true, "!1"},120    // Reject invalid unary operators.121    {true, false, "1-"},122    {true, false, "1+"},123    {true, false, "1~"},124    {true, false, "1!"},125 126    // Accept valid binary operators.127    {true, true, "1+1"},128    {true, true, "1-1"},129    {true, true, "1*1"},130    {true, true, "1/1"},131    {true, true, "1%2"},132    {true, true, "1<<1"},133    {true, true, "1>>1"},134    {true, true, "1<=>1"},135    {true, true, "1<1"},136    {true, true, "1>1"},137    {true, true, "1<=1"},138    {true, true, "1>=1"},139    {true, true, "1==1"},140    {true, true, "1!=1"},141    {true, true, "1&1"},142    {true, true, "1^1"},143    {true, true, "1|1"},144    {true, true, "1&&1"},145    {true, true, "1||1"},146    {true, true, "1+ +1"}, // A space is needed to avoid being tokenized as ++ or --.147    {true, true, "1- -1"},148    // Comma is only valid when inside parentheses.149    {true, true, "(1,1)"},150    // Reject invalid binary operators.151    {true, false, "1+"},152    {true, false, "1-"},153    {true, false, "1*"},154    {true, false, "1/"},155    {true, false, "1%"},156    {true, false, "1<<"},157    {true, false, "1>>"},158    {true, false, "1<=>"},159    {true, false, "1<"},160    {true, false, "1>"},161    {true, false, "1<="},162    {true, false, "1>="},163    {true, false, "1=="},164    {true, false, "1!="},165    {true, false, "1&"},166    {true, false, "1^"},167    {true, false, "1|"},168    {true, false, "1&&"},169    {true, false, "1||"},170    {true, false, "1,"},171    {true, false, ",1"},172    {true, false, "1,1"},173 174    // Accept valid ternary operators.175    {true, true, "1?1:1"},176    {true, true, "1?:1"}, // A gcc extension treats x ? : y as x ? x : y.177    // Reject invalid ternary operators.178    {true, false, "?"},179    {true, false, "?1"},180    {true, false, "?:"},181    {true, false, "?:1"},182    {true, false, "?1:"},183    {true, false, "?1:1"},184    {true, false, "1?"},185    {true, false, "1?1"},186    {true, false, "1?:"},187    {true, false, "1?1:"},188 189    // Accept parenthesized expressions.190    {true, true, "(1)"},191    {true, true, "((+1))"},192    {true, true, "((+(1)))"},193    {true, true, "(-1)"},194    {true, true, "-(1)"},195    {true, true, "(+1)"},196    {true, true, "((+1))"},197    {true, true, "+(1)"},198    {true, true, "(~1)"},199    {true, true, "~(1)"},200    {true, true, "(!1)"},201    {true, true, "!(1)"},202    {true, true, "(1+1)"},203    {true, true, "(1-1)"},204    {true, true, "(1*1)"},205    {true, true, "(1/1)"},206    {true, true, "(1%2)"},207    {true, true, "(1<<1)"},208    {true, true, "(1>>1)"},209    {true, true, "(1<=>1)"},210    {true, true, "(1<1)"},211    {true, true, "(1>1)"},212    {true, true, "(1<=1)"},213    {true, true, "(1>=1)"},214    {true, true, "(1==1)"},215    {true, true, "(1!=1)"},216    {true, true, "(1&1)"},217    {true, true, "(1^1)"},218    {true, true, "(1|1)"},219    {true, true, "(1&&1)"},220    {true, true, "(1||1)"},221    {true, true, "(1?1:1)"},222 223    // Accept more complicated "chained" expressions.224    {true, true, "1+1+1"},225    {true, true, "1+1+1+1"},226    {true, true, "1+1+1+1+1"},227    {true, true, "1*1*1"},228    {true, true, "1*1*1*1"},229    {true, true, "1*1*1*1*1"},230    {true, true, "1<<1<<1"},231    {true, true, "4U>>1>>1"},232    {true, true, "1<1<1"},233    {true, true, "1>1>1"},234    {true, true, "1<=1<=1"},235    {true, true, "1>=1>=1"},236    {true, true, "1==1==1"},237    {true, true, "1!=1!=1"},238    {true, true, "1&1&1"},239    {true, true, "1^1^1"},240    {true, true, "1|1|1"},241    {true, true, "1&&1&&1"},242    {true, true, "1||1||1"},243    {true, true, "(1,1,1)"},244 245    // Optionally reject comma operator246    {false, false, "1,1"}247};248 249TEST_P(MatcherTest, MatchResult) {250  const MatchParam &Param = GetParam();251 252  EXPECT_TRUE(matchText(Param.Text, Param.AllowComma) == Param.Matched);253}254 255INSTANTIATE_TEST_SUITE_P(IntegralLiteralExpressionMatcherTests, MatcherTest,256                         ::testing::ValuesIn(MatchParams));257 258static const SizeParam SizeParams[] = {259    {modernize::LiteralSize::Int, "1"},260    {modernize::LiteralSize::UnsignedInt, "1U"},261    {modernize::LiteralSize::Long, "1L"},262    {modernize::LiteralSize::UnsignedLong, "1UL"},263    {modernize::LiteralSize::UnsignedLong, "1LU"},264    {modernize::LiteralSize::LongLong, "1LL"},265    {modernize::LiteralSize::UnsignedLongLong, "1ULL"},266    {modernize::LiteralSize::UnsignedLongLong, "1LLU"}};267 268TEST_P(SizeTest, TokenSize) {269  EXPECT_EQ(sizeText(GetParam().Text), GetParam().Size);270}271 272INSTANTIATE_TEST_SUITE_P(IntegralLiteralExpressionMatcherTests, SizeTest,273                         ::testing::ValuesIn(SizeParams));274 275} // namespace test276} // namespace tidy277} // namespace clang278