================
@@ -0,0 +1,246 @@
+//===--- AvoidPlatformSpecificFundamentalTypesCheck.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 "AvoidPlatformSpecificFundamentalTypesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/TargetInfo.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::portability {
+
+AvoidPlatformSpecificFundamentalTypesCheck::
+    AvoidPlatformSpecificFundamentalTypesCheck(StringRef Name,
+                                               ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      WarnOnFloats(Options.get("WarnOnFloats", false)),
+      IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+                                               utils::IncludeSorter::IS_LLVM),
+                      areDiagsSelfContained()) {}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) 
{
+  IncludeInserter.registerPreprocessor(PP);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "WarnOnFloats", WarnOnFloats);
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
+std::string AvoidPlatformSpecificFundamentalTypesCheck::getFloatReplacement(
+    const BuiltinType *BT, ASTContext &Context) const {
+  const TargetInfo &Target = Context.getTargetInfo();
+
+  auto GetReplacementType = [](unsigned Width) {
+    switch (Width) {
+    // This is ambiguous by default since it could be bfloat16 or float16
+    case 16U:
+      return "";
+    case 32U:
+      return "float32_t";
+    case 64U:
+      return "float64_t";
+    case 128U:
+      return "float128_t";
+    default:
+      return "";
+    }
+  };
+
+  switch (BT->getKind()) {
+  // Not an ambiguous type
+  case BuiltinType::BFloat16:
+    return "bfloat16_t";
+  case BuiltinType::Half:
+    return GetReplacementType(Target.getHalfWidth());
+  case BuiltinType::Float:
+    return GetReplacementType(Target.getFloatWidth());
+  case BuiltinType::Double:
+    return GetReplacementType(Target.getDoubleWidth());
+  default:
+    return "";
+  }
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::registerMatchers(
+    MatchFinder *Finder) {
+  // Build the list of type strings to match
+  std::vector<std::string> TypeStrings = {"short",
+                                          "short int",
+                                          "signed short",
+                                          "signed short int",
+                                          "unsigned short",
+                                          "unsigned short int",
+                                          "int",
+                                          "signed",
+                                          "signed int",
+                                          "unsigned",
+                                          "unsigned int",
+                                          "long",
+                                          "long int",
+                                          "signed long",
+                                          "signed long int",
+                                          "unsigned long",
+                                          "unsigned long int",
+                                          "long long",
+                                          "long long int",
+                                          "signed long long",
+                                          "signed long long int",
+                                          "unsigned long long",
+                                          "unsigned long long int"};
+
+  // Add float types if the option is enabled
+  if (WarnOnFloats) {
+    TypeStrings.push_back("half");
+    TypeStrings.push_back("__bf16");
+    TypeStrings.push_back("float");
+    TypeStrings.push_back("double");
+    TypeStrings.push_back("long double");
+  }
+
+  // Create the matcher dynamically
+  auto TypeMatcher = asString(TypeStrings[0]);
+  for (size_t i = 1; i < TypeStrings.size(); ++i) {
+    TypeMatcher = anyOf(TypeMatcher, asString(TypeStrings[i]));
+  }
+
+  auto PlatformSpecificFundamentalType = qualType(allOf(
+      // Must be a builtin type directly (not through typedef)
+      builtinType(),
+      // Match the specific fundamental types we care about
+      TypeMatcher));
+
+  // Match variable declarations with platform-specific fundamental types
+  Finder->addMatcher(
+      varDecl(hasType(PlatformSpecificFundamentalType)).bind("var_decl"), 
this);
+
+  // Match function declarations with platform-specific fundamental return 
types
+  Finder->addMatcher(
+      functionDecl(returns(PlatformSpecificFundamentalType)).bind("func_decl"),
+      this);
+
+  // Match function parameters with platform-specific fundamental types
+  Finder->addMatcher(
+      parmVarDecl(hasType(PlatformSpecificFundamentalType)).bind("param_decl"),
+      this);
+
+  // Match field declarations with platform-specific fundamental types
+  Finder->addMatcher(
+      fieldDecl(hasType(PlatformSpecificFundamentalType)).bind("field_decl"),
+      this);
+
+  // Match typedef declarations with platform-specific fundamental underlying
+  // types
+  Finder->addMatcher(
+      typedefDecl(hasUnderlyingType(PlatformSpecificFundamentalType))
+          .bind("typedef_decl"),
+      this);
+
+  // Match type alias declarations with platform-specific fundamental 
underlying
+  // types
+  Finder->addMatcher(typeAliasDecl(hasType(PlatformSpecificFundamentalType))
+                         .bind("alias_decl"),
+                     this);
+}
+
+void AvoidPlatformSpecificFundamentalTypesCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  SourceLocation Loc;
+  QualType QT;
+  SourceRange TypeRange;
+
+  if (const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var_decl")) {
+    Loc = VD->getLocation();
+    QT = VD->getType();
+    if (VD->getTypeSourceInfo()) {
+      TypeRange = VD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else if (const auto *FD =
+                 Result.Nodes.getNodeAs<FunctionDecl>("func_decl")) {
+    Loc = FD->getLocation();
+    QT = FD->getReturnType();
+    if (FD->getTypeSourceInfo()) {
+      TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else if (const auto *PD =
+                 Result.Nodes.getNodeAs<ParmVarDecl>("param_decl")) {
+    Loc = PD->getLocation();
+    QT = PD->getType();
+    if (PD->getTypeSourceInfo()) {
+      TypeRange = PD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else if (const auto *FD = Result.Nodes.getNodeAs<FieldDecl>("field_decl")) 
{
+    Loc = FD->getLocation();
+    QT = FD->getType();
+    if (FD->getTypeSourceInfo()) {
+      TypeRange = FD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else if (const auto *TD =
+                 Result.Nodes.getNodeAs<TypedefDecl>("typedef_decl")) {
+    Loc = TD->getLocation();
+    QT = TD->getUnderlyingType();
+    if (TD->getTypeSourceInfo()) {
+      TypeRange = TD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else if (const auto *AD =
+                 Result.Nodes.getNodeAs<TypeAliasDecl>("alias_decl")) {
+    Loc = AD->getLocation();
+    QT = AD->getUnderlyingType();
+    if (AD->getTypeSourceInfo()) {
+      TypeRange = AD->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+    }
+  } else {
+    return;
+  }
+
+  // Get the type name for the diagnostic
+  const std::string TypeName = QT.getAsString();
+
+  // Check if this is a floating point type
+  const auto *BT = QT->getAs<BuiltinType>();
+  bool IsFloatingPoint = BT && (BT->getKind() == BuiltinType::Half ||
+                                BT->getKind() == BuiltinType::BFloat16 ||
+                                BT->getKind() == BuiltinType::Float ||
----------------
jj-marr wrote:

is this redundant?

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

Reply via email to