[clang] [llvm] [clang] Introduce target-specific `Sema` components (PR #93179)

Vlad Serebrennikov via llvm-commits llvm-commits at lists.llvm.org
Tue May 28 09:42:45 PDT 2024


================
@@ -3548,6 +3561,56 @@ class Sema final : public SemaBase {
     BuiltinFunction
   };
 
+  /// A helper function to provide Attribute Location for the Attr types
+  /// AND the ParsedAttr.
+  template <typename AttrInfo>
+  static std::enable_if_t<std::is_base_of_v<Attr, AttrInfo>, SourceLocation>
+  getAttrLoc(const AttrInfo &AL) {
+    return AL.getLocation();
+  }
+  SourceLocation getAttrLoc(const ParsedAttr &AL);
+
+  /// If Expr is a valid integer constant, get the value of the integer
+  /// expression and return success or failure. May output an error.
+  ///
+  /// Negative argument is implicitly converted to unsigned, unless
+  /// \p StrictlyUnsigned is true.
+  template <typename AttrInfo>
+  bool checkUInt32Argument(const AttrInfo &AI, const Expr *Expr, uint32_t &Val,
+                           unsigned Idx = UINT_MAX,
+                           bool StrictlyUnsigned = false) {
+    std::optional<llvm::APSInt> I = llvm::APSInt(32);
+    if (Expr->isTypeDependent() ||
+        !(I = Expr->getIntegerConstantExpr(Context))) {
+      if (Idx != UINT_MAX)
+        Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
+            << &AI << Idx << AANT_ArgumentIntegerConstant
+            << Expr->getSourceRange();
+      else
+        Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
+            << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
+      return false;
+    }
+
+    if (!I->isIntN(32)) {
+      Diag(Expr->getExprLoc(), diag::err_ice_too_large)
+          << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
+      return false;
+    }
+
+    if (StrictlyUnsigned && I->isSigned() && I->isNegative()) {
+      Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
+          << &AI << /*non-negative*/ 1;
+      return false;
+    }
+
+    Val = (uint32_t)I->getZExtValue();
+    return true;
+  }
+
+  bool isFunctionOrMethod(const Decl *D);
+  bool isFunctionOrMethodOrBlock(const Decl *D);
----------------
Endilll wrote:

I see `isFunctionOrMethod` used in AVR-, MIPS-, MSP430-, and X86-specific functions in `SemaDeclAttr.cpp`. If we're to move target specific functions, which I'll try to do, I'd need to replicate the hack every time. I can inline the function where it's used, or I can copy-paste the definition of static function where it's needed. We can also rename it to e.g. `isFunctionDeclOrMethodDecl` to avoid the confusion.

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


More information about the llvm-commits mailing list