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

Aaron Ballman via llvm-commits llvm-commits at lists.llvm.org
Tue May 28 09:22:16 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);
----------------
AaronBallman wrote:

It's not clear to me that these should be public interfaces in Sema. We have `DeclBase::isFunctionOrMethod()` which is subtly different. When these were static functions in SemaDeclAttr.cpp, they were a bit more reasonable (if still somewhat poorly named).

It looks like `isFunctionOrMethodOrBlock()` doesn't need to move out of SemaDeclAttr.cpp, and the only reason `isFunctionOrMethod()` is exposed is because of WebAssembly. Perhaps a horrible hack would be to leave the interface in SemaDeclAttr.cpp, make it `extern`, and forward declare for the use in wasm?

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


More information about the llvm-commits mailing list