ZaMaZaN4iK updated this revision to Diff 214043.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D65912/new/

https://reviews.llvm.org/D65912

Files:
  clang-tools-extra/clang-tidy/misc/CMakeLists.txt
  clang-tools-extra/clang-tidy/misc/MathConstantsCheck.cpp
  clang-tools-extra/clang-tidy/misc/MathConstantsCheck.h
  clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/misc-math-constants.rst
  clang-tools-extra/test/clang-tidy/misc-math-constants.cpp

Index: clang-tools-extra/test/clang-tidy/misc-math-constants.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/misc-math-constants.cpp
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s misc-math-constants %t
+
+// FIXME: Add something that triggers the check here.
+void f();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'f' is insufficiently awesome [misc-math-constants]
+
+// FIXME: Verify the applied fix.
+//   * Make the CHECK patterns specific enough and try to make verified lines
+//     unique to avoid incorrect matches.
+//   * Use {{}} for regular expressions.
+// CHECK-FIXES: {{^}}void awesome_f();{{$}}
+
+// FIXME: Add something that doesn't trigger the check here.
+void foo()
+{
+    double pi = 3.14;
+    double p_2 = 1.57;
+}
Index: clang-tools-extra/docs/clang-tidy/checks/misc-math-constants.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/misc-math-constants.rst
@@ -0,0 +1,6 @@
+.. title:: clang-tidy - misc-math-constants
+
+misc-math-constants
+===================
+
+FIXME: Describe what patterns does the check detect and why. Give examples.
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -276,6 +276,7 @@
    llvm-prefer-isa-or-dyn-cast-in-conditionals
    llvm-twine-local
    misc-definitions-in-headers
+   misc-math-constants
    misc-misplaced-const
    misc-new-delete-overloads
    misc-non-copyable-objects
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -85,6 +85,11 @@
 
 The improvements are...
 
+- New :doc:`misc-math-constants
+  <clang-tidy/checks/misc-math-constants>` check.
+
+  FIXME: add release notes.
+
 Improvements to clang-include-fixer
 -----------------------------------
 
Index: clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
 #include "DefinitionsInHeadersCheck.h"
+#include "MathConstantsCheck.h"
 #include "MisplacedConstCheck.h"
 #include "NewDeleteOverloadsCheck.h"
 #include "NonCopyableObjects.h"
@@ -32,6 +33,8 @@
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
     CheckFactories.registerCheck<DefinitionsInHeadersCheck>(
         "misc-definitions-in-headers");
+    CheckFactories.registerCheck<MathConstantsCheck>(
+        "misc-math-constants");
     CheckFactories.registerCheck<MisplacedConstCheck>("misc-misplaced-const");
     CheckFactories.registerCheck<NewDeleteOverloadsCheck>(
         "misc-new-delete-overloads");
Index: clang-tools-extra/clang-tidy/misc/MathConstantsCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/MathConstantsCheck.h
@@ -0,0 +1,59 @@
+//===--- MathConstantsCheck.h - clang-tidy ----------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MATHCONSTANTSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MATHCONSTANTSCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+#include "../utils/IncludeInserter.h"
+
+#include "llvm/ADT/Optional.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-math-constants.html
+class MathConstantsCheck : public ClangTidyCheck {
+public:
+  MathConstantsCheck(StringRef Name, ClangTidyContext *Context);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+private:
+  void insertHeader(DiagnosticBuilder &Diag, FileID FD);
+
+  struct MathConstantDescription
+  {
+      const Optional<std::string> NameInC;
+      const Optional<std::string> NameInCpp20;
+      const double Value;
+  };
+
+  const std::vector<MathConstantDescription> Constants;
+  const utils::IncludeSorter::IncludeStyle IncludeStyle;
+  std::string ChosenHeaderName;
+  std::unique_ptr<utils::IncludeInserter> Inserter;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MATHCONSTANTSCHECK_H
Index: clang-tools-extra/clang-tidy/misc/MathConstantsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/MathConstantsCheck.cpp
@@ -0,0 +1,153 @@
+//===--- MathConstantsCheck.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 "MathConstantsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "../../../clang/unittests/AST/Language.h"
+
+#include <cmath>
+#include <iostream>
+#include <string>
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace
+{
+
+constexpr char StdMathHeader[] = "math";
+constexpr char StdCmathHeader[] = "cmath";
+constexpr char StdCHeader[] = "math.h";
+constexpr char FloatType[] = "floatLiteral";
+constexpr double Epsilon = 0.01;
+
+std::string GetAngledName(const std::string& filename)
+{
+    return "<" + filename + ">";
+}
+
+} // namespace
+
+MathConstantsCheck::MathConstantsCheck(StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+    Constants
+    {
+            {{"M_E"}, {"std::math::e"}, 2.7182818284590452354},
+            {{"M_LOG2E"}, {"std::math::log2e"}, 1.4426950408889634074},
+            {{"M_LOG10E"}, {"std::math::log10e"}, 0.43429448190325182765},
+            {{"M_LN2"}, {"std::math::ln2"}, 0.69314718055994530942},
+            {{"M_LN10"}, {"std::math::ln10"}, 2.30258509299404568402},
+            {{"M_PI"}, {"std::math::pi"}, 3.14159265358979323846},
+            {{"M_PI_2"}, {}, 1.57079632679489661923},
+            {{"M_PI_4"}, {}, 0.78539816339744830962},
+            {{"M_1_PI"}, {"std::math::inv_pi"}, 0.31830988618379067154},
+            {{"M_2_PI"}, {}, 0.63661977236758134308},
+            {{"M_2_SQRTPI"}, {"std::math::inv_sqrtpi"}, 1.12837916709551257390},
+            {{"M_SQRT2"}, {"std::math::sqrt2"}, 1.41421356237309504880},
+            {{"M_SQRT1_2"}, {"std::math::"}, 0.70710678118654752440},
+            {{}, {"std::math::phi"}, 1.6180339887498948482},
+            {{}, {"std::math::egamma"}, 0.5772156649015328606 }
+    },
+    IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
+              Options.getLocalOrGlobal("IncludeStyle", "llvm")))
+{
+}
+
+void MathConstantsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+    Options.store(Opts, "IncludeStyle", IncludeStyle);
+}
+
+void MathConstantsCheck::registerMatchers(MatchFinder *Finder) {
+  // FIXME: Add matchers.
+  Finder->addMatcher(floatLiteral().bind(FloatType), this);
+}
+
+void MathConstantsCheck::registerPPCallbacks(const SourceManager &SM,
+                                             Preprocessor *PP,
+                                             Preprocessor *ModuleExpanderPP) {
+        Inserter = llvm::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
+                                                             IncludeStyle);
+        PP->addPPCallbacks(Inserter->CreatePPCallbacks());
+}
+
+void MathConstantsCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<FloatingLiteral>(FloatType);
+  const auto MatchedFloatConstant = MatchedDecl->getValue().convertToDouble();
+
+  const auto Language = getLangOpts();
+
+  for (const auto& MathConstant : Constants)
+  {
+      // Match constant
+      if (std::fabs(MatchedFloatConstant - MathConstant.Value) < Epsilon)
+      {
+          std::string ConstantName;
+          if(getLangOpts().CPlusPlus2a)
+          {
+              if(MathConstant.NameInCpp20.hasValue())
+              {
+                  ConstantName = MathConstant.NameInCpp20.getValue();
+                  ChosenHeaderName = StdMathHeader;
+              }
+              else
+              {
+                  ConstantName = MathConstant.NameInC.getValue();
+                  ChosenHeaderName = StdCmathHeader;
+              }
+          }
+          else // For other C++ standards and whole C
+          {
+              if(!MathConstant.NameInC.hasValue())
+              {
+                  // We have not such constant for old standards
+                  return;
+              }
+
+              ConstantName = MathConstant.NameInC.getValue();
+              if (Language.C99 || Language.C11 || Language.C17 || Language.C2x)
+              {
+                  ChosenHeaderName = StdCHeader;
+              }
+              else if (Language.CPlusPlus)
+              {
+                  ChosenHeaderName = StdCmathHeader;
+              }
+          }
+
+          diag(MatchedDecl->getLocation(), "The constant " + std::to_string(MatchedFloatConstant) + " is being utilized. "
+            "The resulting value could be inaccurate. Consider using the " + ConstantName +
+            " constant from " + GetAngledName(ChosenHeaderName));
+
+          // Fix-hint
+          auto Diag = diag(MatchedDecl->getLocation(), "insert '" + ConstantName + "'", DiagnosticIDs::Note)
+                  << FixItHint::CreateReplacement(MatchedDecl->getLocation(), ConstantName);
+
+          SourceManager &SM = *Result.SourceManager;
+          insertHeader(Diag, SM.getFileID(MatchedDecl->getExprLoc()));
+      }
+  }
+}
+
+void MathConstantsCheck::insertHeader(DiagnosticBuilder &Diag, FileID FD) {
+    if (ChosenHeaderName.empty()) {
+        return;
+    }
+    if (auto IncludeFixit = Inserter->CreateIncludeInsertion(
+            FD, ChosenHeaderName,
+            true)) {
+        Diag << *IncludeFixit;
+    }
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -2,6 +2,7 @@
 
 add_clang_library(clangTidyMiscModule
   DefinitionsInHeadersCheck.cpp
+  MathConstantsCheck.cpp
   MiscTidyModule.cpp
   MisplacedConstCheck.cpp
   NewDeleteOverloadsCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to