[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-06-10 Thread Piotr Zegar via cfe-commits

PiotrZSL wrote:

@BenBlaise Clang-tidy 19 branch out is in ... a month. Any plans to finish this 
? It's fine if this would get in limited scope (only for explicit casts), but 
some current issues need fixes.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-21 Thread Piotr Zegar via cfe-commits

PiotrZSL wrote:

@BenBlaise Ok, no problem, then it will get into next release.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-21 Thread via cfe-commits

BenBlaise wrote:

I would like to, but I won't get around to it by then (concentrating on a 
thesis defense for tomorrow).

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-20 Thread Piotr Zegar via cfe-commits

PiotrZSL wrote:

@BenBlaise Any plans to finish this ? Clang-tidy 18 branch-out is in ~3 days.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;
+  const auto  = Result.Nodes;
+
+  const auto *MatchedCast = Nodes.getNodeAs("expr");
+  const auto *Lit = Nodes.getNodeAs("lit");
+  assert(MatchedCast && Lit);
+
+  StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
+  std::string CastType = MatchedCast->getTypeAsWritten().getAsString();
+  std::string Fix; // Replacement string for the fix-it hint.
+  std::optional Seq; // Literal sequence, prefix or suffix.
+
+  if (const auto *CharLit = Nodes.getNodeAs("char");
+  CharLit && CharPrefix.contains(CastType)) {
+if (const Replacement  = CharPrefix.at(CastType); Rep(getLangOpts())) {
+
+  Seq = Rep.Seq;
+  if (!CharLit->getLocation().isMacroID()) {
+Fix.append(Rep.Seq);
+Fix.append(CharRegex.sub("", LitText.str()));
+  }
+}
+  } else if (const auto *IntLit = Nodes.getNodeAs("int");
+ IntLit && IntSuffix.contains(CastType)) {
+if (const Replacement  = IntSuffix.at(CastType); Rep(getLangOpts())) {
+
+  Seq = Rep.Seq;
+  if (!IntLit->getLocation().isMacroID()) {
+Fix.append(IntRegex.sub("", LitText.str()));
+Fix.append(Rep.Seq);
+  }
+}
+  } else if (const auto *FloatLit = Nodes.getNodeAs("float");
+ FloatLit && FloatSuffix.contains(CastType)) {
+if (const Replacement  = FloatSuffix.at(CastType); Rep(getLangOpts())) 
{
+
+  Seq = Rep.Seq;
+  if (!FloatLit->getLocation().isMacroID()) {
+Fix.append(FloatRegex.sub("", LitText.str()));
+Fix.append(Rep.Seq);
+  }
+}
+  }
+
+  const TypeLoc CastTypeLoc = 
MatchedCast->getTypeInfoAsWritten()->getTypeLoc();
+
+  if (!Fix.empty() && !CastTypeLoc.getBeginLoc().isMacroID()) {
+
+// Recommend 

[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;
+  const auto  = Result.Nodes;
+
+  const auto *MatchedCast = Nodes.getNodeAs("expr");
+  const auto *Lit = Nodes.getNodeAs("lit");
+  assert(MatchedCast && Lit);
+
+  StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
+  std::string CastType = MatchedCast->getTypeAsWritten().getAsString();
+  std::string Fix; // Replacement string for the fix-it hint.
+  std::optional Seq; // Literal sequence, prefix or suffix.
+
+  if (const auto *CharLit = Nodes.getNodeAs("char");
+  CharLit && CharPrefix.contains(CastType)) {
+if (const Replacement  = CharPrefix.at(CastType); Rep(getLangOpts())) {
+
+  Seq = Rep.Seq;
+  if (!CharLit->getLocation().isMacroID()) {
+Fix.append(Rep.Seq);
+Fix.append(CharRegex.sub("", LitText.str()));
+  }
+}
+  } else if (const auto *IntLit = Nodes.getNodeAs("int");
+ IntLit && IntSuffix.contains(CastType)) {
+if (const Replacement  = IntSuffix.at(CastType); Rep(getLangOpts())) {
+
+  Seq = Rep.Seq;
+  if (!IntLit->getLocation().isMacroID()) {
+Fix.append(IntRegex.sub("", LitText.str()));
+Fix.append(Rep.Seq);
+  }
+}
+  } else if (const auto *FloatLit = Nodes.getNodeAs("float");
+ FloatLit && FloatSuffix.contains(CastType)) {
+if (const Replacement  = FloatSuffix.at(CastType); Rep(getLangOpts())) 
{
+
+  Seq = Rep.Seq;
+  if (!FloatLit->getLocation().isMacroID()) {
+Fix.append(FloatRegex.sub("", LitText.str()));
+Fix.append(Rep.Seq);
+  }
+}
+  }
+
+  const TypeLoc CastTypeLoc = 
MatchedCast->getTypeInfoAsWritten()->getTypeLoc();
+
+  if (!Fix.empty() && !CastTypeLoc.getBeginLoc().isMacroID()) {
+
+// Recommend 

[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,105 @@
+// RUN: %check_clang_tidy %s readability-use-builtin-literals %t
+
+void warn_and_fix() {
+
+  (char16_t)U'a';
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: u'a';
+  (char32_t)u'a';
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: U'a';
+
+  (int)1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 1;
+  (unsigned int)0x1ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x1u;
+  (long int)2l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2L;
+  (unsigned long int)0x2lu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x2uL;
+  (long long int)3ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 3LL;
+  (unsigned long long int)0x3llu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x3uLL;
+
+  (double)1.f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 1.;
+  (float)2.;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2.f;
+  (long double)3e0f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 3e0L;
+
+  float(2.);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2.f;
+  double{2.};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2.;
+
+  static_cast(2.f);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2.;
+
+  reinterpret_cast(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 1;
+}
+
+#define OPSHIFT ((unsigned)27)
+#define OCHAR (2LU<
+T f() {
+  return T(1);
+}
+
+int no_warn() {
+
+(void)0;
+(unsigned*)0;
+
+static_cast(INT_MAX);
+(unsigned)MAXCOL;
+
+(SUINT)31;
+
+return f();
+}

PiotrZSL wrote:

Missing test for `size_t` and lack of warning & fix.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,38 @@
+.. title:: clang-tidy - readability-use-builtin-literals
+
+readability-use-builtin-literals
+
+
+Finds literals explicitly casted to a type that could be expressed using 
builtin prefixes or suffixes.
+
+In elementary cases, provides automated fix-it hints.
+
+.. code-block:: c++
+
+(char)'a';// -> 'a'

PiotrZSL wrote:

list here all supported types, for example in form of table, like type, 
example, replacement.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;
+  const auto  = Result.Nodes;
+
+  const auto *MatchedCast = Nodes.getNodeAs("expr");
+  const auto *Lit = Nodes.getNodeAs("lit");
+  assert(MatchedCast && Lit);
+
+  StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
+  std::string CastType = MatchedCast->getTypeAsWritten().getAsString();

PiotrZSL wrote:

double read of getTypeInfoAsWritten, read it once and assign to local variable.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},

PiotrZSL wrote:

Missing check for C++17.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,105 @@
+// RUN: %check_clang_tidy %s readability-use-builtin-literals %t
+
+void warn_and_fix() {
+
+  (char16_t)U'a';
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: u'a';
+  (char32_t)u'a';
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: U'a';
+
+  (int)1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 1;
+  (unsigned int)0x1ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x1u;
+  (long int)2l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2L;
+  (unsigned long int)0x2lu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x2uL;
+  (long long int)3ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 3LL;
+  (unsigned long long int)0x3llu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 0x3uLL;
+
+  (double)1.f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 1.;
+  (float)2.;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 2.f;
+  (long double)3e0f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use built-in literal instead of 
explicit cast [readability-use-builtin-literals]
+  // CHECK-FIXES: 3e0L;
+

PiotrZSL wrote:

missing tests for:
- float16_t
- float32_t
- float64_t
- float128_t
- bfloat16

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;
+  const auto  = Result.Nodes;
+
+  const auto *MatchedCast = Nodes.getNodeAs("expr");
+  const auto *Lit = Nodes.getNodeAs("lit");
+  assert(MatchedCast && Lit);
+
+  StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
+  std::string CastType = MatchedCast->getTypeAsWritten().getAsString();
+  std::string Fix; // Replacement string for the fix-it hint.
+  std::optional Seq; // Literal sequence, prefix or suffix.
+
+  if (const auto *CharLit = Nodes.getNodeAs("char");
+  CharLit && CharPrefix.contains(CastType)) {
+if (const Replacement  = CharPrefix.at(CastType); Rep(getLangOpts())) {
+
+  Seq = Rep.Seq;
+  if (!CharLit->getLocation().isMacroID()) {

PiotrZSL wrote:

Add option IgnoreMacros to check, to handle this situation.
You may also use get SpellingLocation to actualy do a replacement where that 
literal is in code.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;
+  const auto  = Result.Nodes;
+
+  const auto *MatchedCast = Nodes.getNodeAs("expr");
+  const auto *Lit = Nodes.getNodeAs("lit");
+  assert(MatchedCast && Lit);
+
+  StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
+  std::string CastType = MatchedCast->getTypeAsWritten().getAsString();
+  std::string Fix; // Replacement string for the fix-it hint.
+  std::optional Seq; // Literal sequence, prefix or suffix.
+
+  if (const auto *CharLit = Nodes.getNodeAs("char");
+  CharLit && CharPrefix.contains(CastType)) {

PiotrZSL wrote:

double search of CastType in map, consider spliting those 3 ifs into 3 methods.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},

PiotrZSL wrote:

use "U" instead of "u", to be in sync with readability-uppercase-literal-suffix 
check.
Verify also other suffixes.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(

PiotrZSL wrote:

`ignoringParenImpCasts` doesn't look to be needed because 
TK_IgnoreUnlessSpelledInSource is used, and without it all tests still pass. 
Remove or add tests to cover this.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),

PiotrZSL wrote:

change this "expr" into "cast", as later in check method is not so clear what 
it refers.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(

PiotrZSL wrote:

Do not make matchers `static`, this can be problematic

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL requested changes to this pull request.

Overall what is now is +- working.
Few fixes are still needed to tests, code, maybe some tiny refactoring and code 
formatting.

Consider adding support for implicit casts:
```
unsigned X = 10;

`-VarDecl  col:10 X 'unsigned int' cinit
  `-ImplicitCastExpr  'unsigned int' 
`-IntegerLiteral  'int' 10
```
To:
```
unsigned X = 10U;

`-VarDecl  col:10 X 'unsigned int' cinit
  `-IntegerLiteral  'unsigned int' 10
```

I worry also a little bit about integer overflow issues.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2024-01-05 Thread Piotr Zegar via cfe-commits

https://github.com/PiotrZSL edited 
https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits


@@ -0,0 +1,38 @@
+.. title:: clang-tidy - readability-use-builtin-literals
+
+readability-use-builtin-literals
+
+
+Finds literals explicitly casted to a type that could be expressed using 
builtin prefixes or suffixes.

EugeneZelenko wrote:

Please follow 80-characters limit.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

https://github.com/EugeneZelenko edited 
https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

https://github.com/EugeneZelenko requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits


@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+});
+
+static const llvm::Regex FloatRegex(
+"([fF]|[lL]|([fF]16)|([fF]32)|([fF]64)|([fF]128)|((bf|BF)16))?$");
+static const llvm::StringMap FloatSuffix({
+{"double", {""}},
+{"float", {"f"}},
+{"long double", {"L"}},
+{"std::float16_t", {"f16"}},
+{"std::float32_t", {"f32"}},
+{"std::float64_t", {"f64"}},
+{"std::float128_t", {"f128"}},
+{"std::bfloat16_t", {"bf16"}},
+{"float16_t", {"f16"}},
+{"float32_t", {"f32"}},
+{"float64_t", {"f64"}},
+{"float128_t", {"f128"}},
+{"bfloat16_t", {"bf16"}},
+});
+
+void UseBuiltinLiteralsCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto Literal = has(ignoringParenImpCasts(
+  expr(anyOf(characterLiteral().bind("char"), integerLiteral().bind("int"),
+ floatLiteral().bind("float")))
+  .bind("lit")));
+  Finder->addMatcher(
+  traverse(TK_IgnoreUnlessSpelledInSource,
+   explicitCastExpr(anyOf(Literal, has(initListExpr(Literal
+   .bind("expr")),
+  this);
+}
+
+static StringRef getRawStringRef(const SourceRange ,
+ const SourceManager ,
+ const LangOptions ) {
+  CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts);
+  return Lexer::getSourceText(TextRange, Sources, LangOpts);
+}
+
+void UseBuiltinLiteralsCheck::check(const MatchFinder::MatchResult ) {
+
+  const auto  = *Result.SourceManager;

EugeneZelenko wrote:

Please don't use `auto` unless type is explicitly stated in same statement or 
iterator. Same in other places.

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 7767c5856d85cd1acf2efc32f77fdf07f00f9ff4 
b4d7dbcf67117471a2d7025013fb1fcd188b33b6 -- 
clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp 
clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.h 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp17.cpp
 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp23.cpp
 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals.cpp 
clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
``





View the diff from clang-format here.


``diff
diff --git 
a/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
index ede4651789..6a10fbd51c 100644
--- a/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
@@ -104,7 +104,7 @@ void UseBuiltinLiteralsCheck::check(const 
MatchFinder::MatchResult ) {
 
   StringRef LitText = getRawStringRef(Lit->getExprLoc(), SM, getLangOpts());
   std::string CastType = MatchedCast->getTypeAsWritten().getAsString();
-  std::string Fix; // Replacement string for the fix-it hint.
+  std::string Fix;  // Replacement string for the fix-it hint.
   std::optional Seq; // Literal sequence, prefix or suffix.
 
   if (const auto *CharLit = Nodes.getNodeAs("char");
@@ -153,8 +153,8 @@ void UseBuiltinLiteralsCheck::check(const 
MatchFinder::MatchResult ) {
 diag(MatchedCast->getExprLoc(),
  "use built-in '%0' %1 instead of explicit cast to '%2'")
 << *Seq
-   << (Nodes.getNodeAs("char") ? "prefix" : 
"suffix")
-   << CastType;
+<< (Nodes.getNodeAs("char") ? "prefix" : "suffix")
+<< CastType;
   }
 }
 

``




https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tidy

Author: None (BenBlaise)


Changes

Finds literals explicitly casted to a type that could be expressed using 
builtin prefixes or suffixes.

In elementary cases, provides automated fix-it hints.

```cpp
(char)'a';// - 'a'
(char16_t)U'a';   // - u'a'
static_castunsigned int(0x1ul); // - 0x1u
reinterpret_castlong long int(3ll); // - 3LL
float(2.);// - 2.f
double{2.};   // - 2.
```

Defined for character, integer and floating literals.

---
Full diff: https://github.com/llvm/llvm-project/pull/76065.diff


10 Files Affected:

- (modified) clang-tools-extra/clang-tidy/readability/CMakeLists.txt (+1) 
- (modified) clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
(+3) 
- (added) clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp 
(+161) 
- (added) clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.h 
(+37) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6) 
- (modified) clang-tools-extra/docs/clang-tidy/checks/list.rst (+1) 
- (added) 
clang-tools-extra/docs/clang-tidy/checks/readability/use-builtin-literals.rst 
(+38) 
- (added) 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp17.cpp
 (+11) 
- (added) 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp23.cpp
 (+19) 
- (added) 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals.cpp 
(+105) 


``diff
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 5452c2d48a4617..3c5e12aaeb3bd4 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -51,6 +51,7 @@ add_clang_library(clangTidyReadabilityModule
   UniqueptrDeleteReleaseCheck.cpp
   UppercaseLiteralSuffixCheck.cpp
   UseAnyOfAllOfCheck.cpp
+  UseBuiltinLiteralsCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index b8e6e641432060..b0ec5a906cac55 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -54,6 +54,7 @@
 #include "UniqueptrDeleteReleaseCheck.h"
 #include "UppercaseLiteralSuffixCheck.h"
 #include "UseAnyOfAllOfCheck.h"
+#include "UseBuiltinLiteralsCheck.h"
 
 namespace clang::tidy {
 namespace readability {
@@ -151,6 +152,8 @@ class ReadabilityModule : public ClangTidyModule {
 "readability-uppercase-literal-suffix");
 CheckFactories.registerCheck(
 "readability-use-anyofallof");
+CheckFactories.registerCheck(
+"readability-use-builtin-literals");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
new file mode 100644
index 00..ede46517898d87
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static const llvm::Regex CharRegex("^(u8|u|U|L)?");
+static const llvm::StringMap CharPrefix({
+{"char", {""}},
+{"char8_t", {"u8"}},
+{"char16_t", {"u"}},
+{"char32_t", {"U"}},
+{"wchar_t", {"L"}},
+});
+
+static const llvm::Regex
+
IntRegex("(([uU]?[lL]{0,2})|([lL]{0,2}[uU]?)|([uU]?[zZ]?)|([zZ]?[uU]?))?$");
+static const llvm::StringMap IntSuffix({
+{"int", {""}},
+{"unsigned int", {"u"}},
+{"long", {"L"}},
+{"unsigned long", {"uL"}},
+{"long long", {"LL"}},
+{"unsigned long long", {"uLL"}},
+{"size_t", {"uz", [](const auto ) { return LS.isCPlusPlus23(); }}},
+{"std::size_t", {"uz", 

[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

github-actions[bot] wrote:

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/76065
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Add readability-use-builtin-literals check (PR #76065)

2023-12-20 Thread via cfe-commits

https://github.com/BenBlaise created 
https://github.com/llvm/llvm-project/pull/76065

Finds literals explicitly casted to a type that could be expressed using 
builtin prefixes or suffixes.

In elementary cases, provides automated fix-it hints.

```cpp
(char)'a';// -> 'a'
(char16_t)U'a';   // -> u'a'
static_cast(0x1ul); // -> 0x1u
reinterpret_cast(3ll); // -> 3LL
float(2.);// -> 2.f
double{2.};   // -> 2.
```

Defined for character, integer and floating literals.

>From b4d7dbcf67117471a2d7025013fb1fcd188b33b6 Mon Sep 17 00:00:00 2001
From: Benedict Blaise 
Date: Wed, 20 Dec 2023 16:07:10 +0100
Subject: [PATCH] [clang-tidy] Add readability-use-builtin-literals check

Finds literals explicitly casted to a type that could be expressed using
builtin prefixes or suffixes. In elementary cases, provides automated
fix-it hints. Defined for character, integer and floating literals.
---
 .../clang-tidy/readability/CMakeLists.txt |   1 +
 .../readability/ReadabilityTidyModule.cpp |   3 +
 .../readability/UseBuiltinLiteralsCheck.cpp   | 161 ++
 .../readability/UseBuiltinLiteralsCheck.h |  37 
 clang-tools-extra/docs/ReleaseNotes.rst   |   6 +
 .../docs/clang-tidy/checks/list.rst   |   1 +
 .../readability/use-builtin-literals.rst  |  38 +
 .../use-builtin-literals-cpp17.cpp|  11 ++
 .../use-builtin-literals-cpp23.cpp|  19 +++
 .../readability/use-builtin-literals.cpp  | 105 
 10 files changed, 382 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/readability/use-builtin-literals.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp17.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals-cpp23.cpp
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/readability/use-builtin-literals.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 5452c2d48a4617..3c5e12aaeb3bd4 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -51,6 +51,7 @@ add_clang_library(clangTidyReadabilityModule
   UniqueptrDeleteReleaseCheck.cpp
   UppercaseLiteralSuffixCheck.cpp
   UseAnyOfAllOfCheck.cpp
+  UseBuiltinLiteralsCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index b8e6e641432060..b0ec5a906cac55 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -54,6 +54,7 @@
 #include "UniqueptrDeleteReleaseCheck.h"
 #include "UppercaseLiteralSuffixCheck.h"
 #include "UseAnyOfAllOfCheck.h"
+#include "UseBuiltinLiteralsCheck.h"
 
 namespace clang::tidy {
 namespace readability {
@@ -151,6 +152,8 @@ class ReadabilityModule : public ClangTidyModule {
 "readability-uppercase-literal-suffix");
 CheckFactories.registerCheck(
 "readability-use-anyofallof");
+CheckFactories.registerCheck(
+"readability-use-builtin-literals");
   }
 };
 
diff --git 
a/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
new file mode 100644
index 00..ede46517898d87
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseBuiltinLiteralsCheck.cpp
@@ -0,0 +1,161 @@
+//===--- UseBuiltinLiteralsCheck.cpp - clang-tidy 
-===//
+//
+// 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
+//
+//===--===//
+
+#include "UseBuiltinLiteralsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include 
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+using RuleOnStd = bool (*)(const LangStandard );
+
+struct Replacement {
+  Replacement(StringRef Seq, const RuleOnStd Std = nullptr)
+  : Seq(Seq), Std(Std) {}
+  bool operator()(const LangOptions ) const {
+return Std ? Std(LangStandard::getLangStandardForKind(LO.LangStd)) : true;
+  }
+  StringRef Seq;
+  RuleOnStd Std;
+};
+
+} // namespace
+
+static