[clang] [Clang][OpenMP 6.0] Support positional arguments in `adjust_args` clause (PR #225081)

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 17:50:05 PDT 2026


================
@@ -3232,3 +3281,96 @@ bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
     DiagUnknownTrait(RawString);
   return false;
 }
+
+/// Evaluate one bound of an 'adjust_args' parameter range: either an
+/// 'omp_num_args [+- logical_offset]' expression, or a plain constant integer
+/// expression. An omitted bound leaves Result unchanged. Returns false if the
+/// bound is dependent or not constant.
+static bool evalOMPAdjustArgsBound(const OMPAdjustArgsItem::Bound &Bound,
+                                   unsigned NumArgs, const ASTContext &Ctx,
+                                   int64_t &Result) {
+  if (Bound.Kind == OMPAdjustArgsItem::Bound::Omitted)
+    return true;
+  if (Bound.Kind == OMPAdjustArgsItem::Bound::NumArgs) {
+    int64_t Offset = 0;
+    if (const Expr *OffsetExpr = Bound.E) {
+      if (OffsetExpr->isValueDependent())
+        return false;
+      std::optional<llvm::APSInt> Val = OffsetExpr->getIntegerConstantExpr(Ctx);
+      if (!Val)
+        return false;
+      Offset = Val->getLimitedValue(INT32_MAX);
+    }
+    Result = static_cast<int64_t>(NumArgs) +
+             (Bound.IsSubtraction ? -Offset : Offset);
+    return true;
+  }
+  if (Bound.Kind != OMPAdjustArgsItem::Bound::Expression || !Bound.E)
+    return false;
+  const Expr *E = Bound.E->IgnoreParenImpCasts();
+  if (E->isValueDependent())
+    return false;
+  std::optional<llvm::APSInt> Val = E->getIntegerConstantExpr(Ctx);
+  if (!Val)
+    return false;
+  Result = Val->getLimitedValue(INT32_MAX);
+  return true;
+}
+
+bool clang::resolveOMPAdjustArgsItem(const OMPAdjustArgsItem &Item,
+                                     const FunctionDecl *FD, unsigned NumArgs,
+                                     const ASTContext &Ctx,
+                                     SmallVectorImpl<unsigned> &Positions) {
+  auto AppendIfInRange = [&](int64_t Pos) {
+    if (Pos >= 1 && Pos <= static_cast<int64_t>(NumArgs))
+      Positions.push_back(static_cast<unsigned>(Pos));
+  };
+
+  // A parameter range 'lb:ub'. An omitted lb defaults to 1, an omitted ub to
+  // 'NumArgs' (OpenMP 6.0 [5.2.1]).
+  if (Item.Kind == OMPAdjustArgsItem::Range) {
+    int64_t Lower = 1;
+    int64_t Upper = NumArgs;
+    if (!evalOMPAdjustArgsBound(Item.Lower, NumArgs, Ctx, Lower) ||
+        !evalOMPAdjustArgsBound(Item.Upper, NumArgs, Ctx, Upper))
+      return false;
+    // An out-of-range literal bound must not turn this into an
+    // unbounded loop.
+    Lower = std::max<int64_t>(Lower, 1);
+    Upper = std::min<int64_t>(Upper, NumArgs);
+    if (Lower > Upper)
+      return true;
+    for (int64_t Pos : llvm::seq_inclusive<int64_t>(Lower, Upper))
+      AppendIfInRange(Pos);
+    return true;
+  }
+
+  if (!Item.E)
+    return false;
+  const Expr *E = Item.E->IgnoreParenImpCasts();
+
+  // A named parameter list item.
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+    const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl());
+    if (!PVD)
+      return false;
----------------
alexey-bataev wrote:

Fall through to the integer branch instead

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


More information about the cfe-commits mailing list