[clang-tools-extra] [clang-tidy] Speed up `readability-uppercase-literal-suffix` (PR #178149)

Victor Chernyakin via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 28 05:30:38 PST 2026


================
@@ -191,43 +190,38 @@ void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) {
   // Sadly, we can't check whether the literal has suffix or not.
   // E.g. i32 suffix still results in 'BuiltinType::Kind::Int'.
   // And such an info is not stored in the *Literal itself.
-  Finder->addMatcher(
-      stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
-                  floatLiteral().bind(FloatingLiteralCheck::Name)),
-           unless(anyOf(hasParent(userDefinedLiteral()),
-                        hasAncestor(substNonTypeTemplateParmExpr())))),
-      this);
+
+  Finder->addMatcher(userDefinedLiteral().bind("expr"), this);
+  Finder->addMatcher(integerLiteral().bind("expr"), this);
+  Finder->addMatcher(floatLiteral().bind("expr"), this);
 }
 
-template <typename LiteralType>
-bool UppercaseLiteralSuffixCheck::checkBoundMatch(
+void UppercaseLiteralSuffixCheck::check(
     const MatchFinder::MatchResult &Result) {
-  const auto *Literal =
-      Result.Nodes.getNodeAs<typename LiteralType::type>(LiteralType::Name);
-  if (!Literal)
-    return false;
+  const auto *const Literal = Result.Nodes.getNodeAs<Expr>("expr");
+  if (isa<UserDefinedLiteral>(Literal)) {
+    LatestUserDefinedLiteralLoc = Literal->getBeginLoc();
+    return;
+  }
+  if (Literal->getBeginLoc() == LatestUserDefinedLiteralLoc)
+    return;
----------------
localspook wrote:

Okay, hold up. I was working on the next installment of the "speed up X" series (for `bugprone-standalone-empty`), and I was seeing performance numbers I couldn't explain: it was as if simply *mentioning* `hasParent` in a matcher caused a massive slowdown.

Here's what I found: the first time *anyone* executes a `hasParent` or `hasAncestor` matcher, the matcher framework goes and walks the entire TU to compute a map from nodes to their parents. With the TU I've been testing on, this takes about 200 ms (measured by running a check that does nothing but call `hasParent` once). This is effectively a fixed cost amortized over the entire clang-tidy run, but `--enable-check-profile` will count that 200 ms against whichever unlucky check executes a `hasParent` or `hasAncestor` first.

With that in mind, I believe this is a false optimization.

https://github.com/llvm/llvm-project/pull/178149


More information about the cfe-commits mailing list