llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: ykhatav (ykhatav)

<details>
<summary>Changes</summary>

Extends the `adjust_args` to accept positional arguments as specified in OpenMP 
6.0 spec, in addition to the existing named-parameter form.This PR adds 
parsing, Sema, AST, and serialization support for it.

---

Patch is 76.79 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/225081.diff


36 Files Affected:

- (modified) clang/bindings/python/clang/cindex.py (+6) 
- (modified) clang/include/clang-c/Index.h (+13-1) 
- (modified) clang/include/clang/AST/ComputeDependence.h (+4) 
- (modified) clang/include/clang/AST/ExprOpenMP.h (+140) 
- (modified) clang/include/clang/AST/OpenMPClause.h (+23) 
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+2) 
- (modified) clang/include/clang/AST/TextNodeDumper.h (+1) 
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+4) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) 
- (modified) clang/include/clang/Basic/StmtNodes.td (+2) 
- (modified) clang/include/clang/Parse/Parser.h (+11) 
- (modified) clang/include/clang/Sema/SemaOpenMP.h (+14) 
- (modified) clang/include/clang/Serialization/ASTBitCodes.h (+2) 
- (modified) clang/lib/AST/AttrImpl.cpp (+12-5) 
- (modified) clang/lib/AST/ComputeDependence.cpp (+20) 
- (modified) clang/lib/AST/Expr.cpp (+2) 
- (modified) clang/lib/AST/ExprClassification.cpp (+2) 
- (modified) clang/lib/AST/ExprConstant.cpp (+2) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+2) 
- (modified) clang/lib/AST/OpenMPClause.cpp (+85) 
- (modified) clang/lib/AST/StmtPrinter.cpp (+18) 
- (modified) clang/lib/AST/StmtProfile.cpp (+13) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (+6) 
- (modified) clang/lib/Parse/ParseOpenMP.cpp (+110-3) 
- (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2) 
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+164-19) 
- (modified) clang/lib/Sema/TreeTransform.h (+64) 
- (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+23) 
- (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+17) 
- (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+2) 
- (added) 
clang/test/OpenMP/declare_variant_adjust_args_positional_ast_print.cpp (+175) 
- (added) clang/test/OpenMP/declare_variant_adjust_args_positional_messages.cpp 
(+228) 
- (added) clang/test/OpenMP/declare_variant_adjust_args_positional_template.cpp 
(+62) 
- (modified) clang/test/OpenMP/declare_variant_clauses_messages.cpp (+9-7) 
- (modified) clang/tools/libclang/CIndex.cpp (+4) 
- (modified) clang/tools/libclang/CXCursor.cpp (+8) 


``````````diff
diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index bc00dd770ce3b5..a21eb9e9d543f4 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1113,6 +1113,12 @@ def is_unexposed(self):
     # Represents a C++26 pack indexing expression.
     PACK_INDEXING_EXPR = 156
 
+    # OpenMP 6.0 [5.2.1] 'omp_num_args [+/- logical_offset]' bound expression.
+    OMP_NUM_ARGS_EXPR = 157
+
+    # OpenMP 6.0 [5.2.1] parameter range 'lb:ub' expression.
+    OMP_ARGUMENT_RANGE_EXPR = 158
+
     # A statement whose specific kind is not exposed via this interface.
     #
     # Unexposed statements have the same operations as any other kind of
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 1c8d097f1beab4..1ab3635f2ea3a3 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -1691,7 +1691,19 @@ enum CXCursorKind {
    */
   CXCursor_PackIndexingExpr = 156,
 
-  CXCursor_LastExpr = CXCursor_PackIndexingExpr,
+  /**
+   * OpenMP 6.0 [5.2.1, Parameter List Items]
+   * The 'omp_num_args' identifier with an optional logical offset.
+   */
+  CXCursor_OMPNumArgsExpr = 157,
+
+  /**
+   * OpenMP 6.0 [5.2.1, Parameter List Items]
+   * A parameter range 'lb:ub', either bound of which may be omitted.
+   */
+  CXCursor_OMPArgumentRangeExpr = 158,
+
+  CXCursor_LastExpr = CXCursor_OMPArgumentRangeExpr,
 
   /* Statements */
   CXCursor_FirstStmt = 200,
diff --git a/clang/include/clang/AST/ComputeDependence.h 
b/clang/include/clang/AST/ComputeDependence.h
index 6430081a40350d..4a36588d399e17 100644
--- a/clang/include/clang/AST/ComputeDependence.h
+++ b/clang/include/clang/AST/ComputeDependence.h
@@ -100,6 +100,8 @@ class AtomicExpr;
 class ArraySectionExpr;
 class OMPArrayShapingExpr;
 class OMPIteratorExpr;
+class OMPNumArgsExpr;
+class OMPArgumentRangeExpr;
 class ObjCArrayLiteral;
 class ObjCDictionaryLiteral;
 class ObjCBoxedExpr;
@@ -200,6 +202,8 @@ ExprDependence computeDependence(AtomicExpr *E);
 ExprDependence computeDependence(ArraySectionExpr *E);
 ExprDependence computeDependence(OMPArrayShapingExpr *E);
 ExprDependence computeDependence(OMPIteratorExpr *E);
+ExprDependence computeDependence(OMPNumArgsExpr *E);
+ExprDependence computeDependence(OMPArgumentRangeExpr *E);
 
 ExprDependence computeDependence(ObjCArrayLiteral *E);
 ExprDependence computeDependence(ObjCDictionaryLiteral *E);
diff --git a/clang/include/clang/AST/ExprOpenMP.h 
b/clang/include/clang/AST/ExprOpenMP.h
index 4d3c5f54ad7dde..bc293465e3ff80 100644
--- a/clang/include/clang/AST/ExprOpenMP.h
+++ b/clang/include/clang/AST/ExprOpenMP.h
@@ -296,6 +296,146 @@ class OMPIteratorExpr final
   }
 };
 
+/// OpenMP 6.0 [5.2.1, Parameter List Items]
+/// Represents the 'omp_num_args' identifier used as a bound of a parameter
+/// range, together with an optional logical offset:
+/// \code
+/// omp_num_args [ ('+' | '-') logical_offset ]
+/// \endcode
+class OMPNumArgsExpr final : public Expr {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+  /// The logical offset, or null if none was written.
+  Stmt *Offset = nullptr;
+  /// Location of the 'omp_num_args' identifier.
+  SourceLocation NumArgsLoc;
+  /// Location of the '+' or '-'; invalid if there is no offset.
+  SourceLocation OpLoc;
+  /// True if the offset was written with '-'.
+  bool IsSubtraction = false;
+
+public:
+  OMPNumArgsExpr(QualType Type, SourceLocation NumArgsLoc, SourceLocation 
OpLoc,
+                 bool IsSubtraction, Expr *Offset)
+      : Expr(OMPNumArgsExprClass, Type, VK_PRValue, OK_Ordinary),
+        Offset(Offset), NumArgsLoc(NumArgsLoc), OpLoc(OpLoc),
+        IsSubtraction(IsSubtraction) {
+    setDependence(computeDependence(this));
+  }
+
+  /// Create an empty 'omp_num_args' expression.
+  explicit OMPNumArgsExpr(EmptyShell Shell)
+      : Expr(OMPNumArgsExprClass, Shell) {}
+
+  /// Gets the logical offset, or null if none was written.
+  Expr *getOffset() { return cast_or_null<Expr>(Offset); }
+  const Expr *getOffset() const { return cast_or_null<Expr>(Offset); }
+  void setOffset(Expr *E) { Offset = E; }
+
+  /// True if the offset was written with '-' rather than '+'.
+  bool isSubtraction() const { return IsSubtraction; }
+  void setIsSubtraction(bool IS) { IsSubtraction = IS; }
+
+  SourceLocation getNumArgsLoc() const { return NumArgsLoc; }
+  void setNumArgsLoc(SourceLocation L) { NumArgsLoc = L; }
+
+  SourceLocation getOperatorLoc() const { return OpLoc; }
+  void setOperatorLoc(SourceLocation L) { OpLoc = L; }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY { return NumArgsLoc; }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+    return Offset ? Offset->getEndLoc() : NumArgsLoc;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPNumArgsExprClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(&Offset, &Offset + 1); }
+  const_child_range children() const {
+    return const_child_range(&Offset, &Offset + 1);
+  }
+};
+
+/// OpenMP 6.0 [5.2.1, Parameter List Items]
+/// Represents a parameter range, one list item that stands for every parameter
+/// position from a lower to an upper bound:
+/// \code
+/// [ lb ] ':' [ ub ]
+/// \endcode
+/// Either bound may be omitted: an omitted \c lb defaults to 1 and an omitted
+/// \c ub defaults to 'omp_num_args'. A bound may be an 'omp_num_args'
+/// expression, which is why this node's children are general expressions 
rather
+/// than integer literals.
+///
+/// The type is 'void': a range is never a value, it only ever appears as an
+/// item of an 'adjust_args' parameter list in \c OMPDeclareVariantAttr.
+class OMPArgumentRangeExpr final : public Expr {
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+  enum { LOWER_BOUND, UPPER_BOUND, NUM_SUBEXPRS };
+
+  /// The two bounds; either may be null when the bound was omitted.
+  Stmt *SubExprs[NUM_SUBEXPRS] = {nullptr, nullptr};
+  /// Location of the ':' separating the bounds.
+  SourceLocation ColonLoc;
+
+public:
+  OMPArgumentRangeExpr(QualType Type, Expr *LowerBound, SourceLocation 
ColonLoc,
+                       Expr *UpperBound)
+      : Expr(OMPArgumentRangeExprClass, Type, VK_PRValue, OK_Ordinary),
+        ColonLoc(ColonLoc) {
+    SubExprs[LOWER_BOUND] = LowerBound;
+    SubExprs[UPPER_BOUND] = UpperBound;
+    setDependence(computeDependence(this));
+  }
+
+  /// Create an empty parameter range expression.
+  explicit OMPArgumentRangeExpr(EmptyShell Shell)
+      : Expr(OMPArgumentRangeExprClass, Shell) {}
+
+  /// Gets the lower bound, or null if it was omitted (meaning 1).
+  Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
+  const Expr *getLowerBound() const {
+    return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
+  }
+  void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }
+
+  /// Gets the upper bound, or null if it was omitted (meaning 'omp_num_args').
+  Expr *getUpperBound() { return cast_or_null<Expr>(SubExprs[UPPER_BOUND]); }
+  const Expr *getUpperBound() const {
+    return cast_or_null<Expr>(SubExprs[UPPER_BOUND]);
+  }
+  void setUpperBound(Expr *E) { SubExprs[UPPER_BOUND] = E; }
+
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  void setColonLoc(SourceLocation L) { ColonLoc = L; }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+    return SubExprs[LOWER_BOUND] ? SubExprs[LOWER_BOUND]->getBeginLoc()
+                                 : ColonLoc;
+  }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+    return SubExprs[UPPER_BOUND] ? SubExprs[UPPER_BOUND]->getEndLoc()
+                                 : ColonLoc;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPArgumentRangeExprClass;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(&SubExprs[LOWER_BOUND], &SubExprs[NUM_SUBEXPRS]);
+  }
+  const_child_range children() const {
+    return const_child_range(&SubExprs[LOWER_BOUND], &SubExprs[NUM_SUBEXPRS]);
+  }
+};
+
 } // end namespace clang
 
 #endif
diff --git a/clang/include/clang/AST/OpenMPClause.h 
b/clang/include/clang/AST/OpenMPClause.h
index 9e9295e1a0c549..f79c9b2c12ce69 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -10566,6 +10566,29 @@ class OMPXBareClause : public 
OMPNoChildClause<llvm::omp::OMPC_ompx_bare> {
   OMPXBareClause() = default;
 };
 
+/// Resolve one 'adjust_args' parameter-list item to the 1-based argument
+/// positions it identifies (OpenMP 6.0 [5.2.1]).
+///
+/// \param Item     A named item (\c DeclRefExpr to a \c ParmVarDecl of \p FD),
+///                 a positional item (a constant integer expression), or an
+///                 \c OMPArgumentRangeExpr. Callers pass 
IgnoreParenImpCasts().
+/// \param FD       The base function the OMPDeclareVariantAttr is attached to.
+/// \param NumArgs  The value of 'omp_num_args' at the point of resolution:
+///                 \c max(FD->getNumParams(), Call->getNumArgs()) at a call
+///                 site, or \c FD->getNumParams() with no call site available
+///                 (OpenMP 6.0 [20.1]).
+/// \param Positions Resolved positions are appended here, ascending. Positions
+///                 outside [1, NumArgs] are silently dropped
+///                 (OpenMP 6.0 [9.6.2]).
+/// \returns false if \p Item is not a resolvable item shape, or if a bound is
+///          dependent or not a constant expression.
+///
+/// Emits no diagnostics: it lives in the AST library so it can later be
+/// shared with CodeGen. Sema diagnoses separately, before calling this.
+bool resolveOMPAdjustArgsItem(const Expr *Item, const FunctionDecl *FD,
+                              unsigned NumArgs, const ASTContext &Ctx,
+                              SmallVectorImpl<unsigned> &Positions);
+
 } // namespace clang
 
 #endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 1f7c8d762e1b52..5a66c147ac8cab 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2954,6 +2954,8 @@ DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
 DEF_TRAVERSE_STMT(ArraySectionExpr, {})
 DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
 DEF_TRAVERSE_STMT(OMPIteratorExpr, {})
+DEF_TRAVERSE_STMT(OMPNumArgsExpr, {})
+DEF_TRAVERSE_STMT(OMPArgumentRangeExpr, {})
 
 DEF_TRAVERSE_STMT(BlockExpr, {
   TRY_TO(TraverseDecl(S->getBlockDecl()));
diff --git a/clang/include/clang/AST/TextNodeDumper.h 
b/clang/include/clang/AST/TextNodeDumper.h
index 1cdd8c37c7fc63..f2fd730d34c5d1 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -328,6 +328,7 @@ class TextNodeDumper
   void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
   void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
   void VisitOMPIteratorExpr(const OMPIteratorExpr *Node);
+  void VisitOMPNumArgsExpr(const OMPNumArgsExpr *Node);
   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *Node);
   void VisitRequiresExpr(const RequiresExpr *Node);
 
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 6a48d74079f4ed..5c826aba1c200f 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1623,6 +1623,10 @@ def err_omp_unknown_adjust_args_op
     : Error<
           "incorrect 'adjust_args' type, expected 'need_device_ptr'%select{|, "
           "'need_device_addr',}0 or 'nothing'">;
+def err_omp_num_args_invalid_form
+    : Error<"'omp_num_args' %select{is only allowed as a bound of a parameter "
+            "range|may only be followed by '+' or '-' and a constant logical "
+            "offset}0">;
 def err_omp_declare_variant_wrong_clause : Error<
   "expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause "
   "on 'omp declare variant' directive">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3a910c9c3f2b92..090acdfa4cac84 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12815,6 +12815,9 @@ def err_omp_instantiation_not_supported
     : Error<"instantiation of '%0' not supported yet">;
 def err_omp_adjust_arg_multiple_clauses : Error<
   "'adjust_arg' argument %0 used in multiple clauses">;
+def err_omp_adjust_args_invalid_item : Error<
+  "expected a parameter name, a parameter position, or a parameter range in "
+  "'adjust_args' clause">;
 def err_omp_clause_requires_dispatch_construct : Error<
   "'%0' clause requires 'dispatch' context selector">;
 def err_omp_append_args_with_varargs : Error<
diff --git a/clang/include/clang/Basic/StmtNodes.td 
b/clang/include/clang/Basic/StmtNodes.td
index 84804d6705d2b9..e9f64565677e9d 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -85,6 +85,8 @@ def MatrixSingleSubscriptExpr : StmtNode<Expr>;
 def MatrixSubscriptExpr : StmtNode<Expr>;
 def ArraySectionExpr : StmtNode<Expr>;
 def OMPIteratorExpr : StmtNode<Expr>;
+def OMPNumArgsExpr : StmtNode<Expr>;
+def OMPArgumentRangeExpr : StmtNode<Expr>;
 def CallExpr : StmtNode<Expr>;
 def MemberExpr : StmtNode<Expr>;
 def CastExpr : StmtNode<Expr, 1>;
diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 163aa483a84e3f..832835b27edc51 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -7053,6 +7053,17 @@ class Parser : public CodeCompletionHandler {
   bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
                                   SemaOpenMP::OpenMPVarListDataTy &Data,
                                   const LangOptions &LangOpts);
+
+  /// Parses one bound of an OpenMP 6.0 'adjust_args' parameter range, which 
may
+  /// be 'omp_num_args' with an optional logical offset, or the whole
+  /// parameter-list item when no range colon follows it.
+  ExprResult ParseOpenMPAdjustArgsBound();
+
+  /// Parses an OpenMP 6.0 'adjust_args' parameter list, whose items may be
+  /// parameter names, positions, or ranges with optional bounds.
+  /// Returns true on error.
+  bool ParseOpenMPAdjustArgsList(SmallVectorImpl<Expr *> &Vars);
+
   /// Parses clauses with list.
   bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
                           SmallVectorImpl<Expr *> &Vars,
diff --git a/clang/include/clang/Sema/SemaOpenMP.h 
b/clang/include/clang/Sema/SemaOpenMP.h
index 361473140e2364..99199ac06c2a23 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -1491,6 +1491,20 @@ class SemaOpenMP : public SemaBase {
                                   SourceLocation LLoc, SourceLocation RLoc,
                                   ArrayRef<OMPIteratorData> Data);
 
+  /// Called on a well-formed 'omp_num_args' expression appearing as a bound of
+  /// an 'adjust_args' parameter range. \a Offset is null if no logical offset
+  /// was written, in which case \a OpLoc is invalid.
+  ExprResult ActOnOMPNumArgsExpr(SourceLocation NumArgsLoc,
+                                 SourceLocation OpLoc, bool IsSubtraction,
+                                 Expr *Offset);
+
+  /// Called on a well-formed 'adjust_args' parameter range 'lb:ub'. Either
+  /// bound may be null, meaning 1 for \a LowerBound and 'omp_num_args' for
+  /// \a UpperBound.
+  ExprResult ActOnOMPArgumentRangeExpr(Expr *LowerBound,
+                                       SourceLocation ColonLoc,
+                                       Expr *UpperBound);
+
   ExprResult ActOnOpenMPDimsModifier(OpenMPClauseKind Kind, int Modifier,
                                      Expr *ModifierExpr,
                                      SourceLocation ModifierLoc,
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 6a52a9e4fa780f..678b17b63a9ffc 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -2057,6 +2057,8 @@ enum StmtCode {
   EXPR_ARRAY_SECTION,
   EXPR_OMP_ARRAY_SHAPING,
   EXPR_OMP_ITERATOR,
+  EXPR_OMP_NUM_ARGS,
+  EXPR_OMP_ARGUMENT_RANGE,
 
   // ARC
   EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp
index 7272ad0de9a2cc..09165226152af6 100644
--- a/clang/lib/AST/AttrImpl.cpp
+++ b/clang/lib/AST/AttrImpl.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTStructuralEquivalence.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/Type.h"
 #include <optional>
 #include <type_traits>
@@ -209,12 +210,18 @@ void OMPDeclareVariantAttr::printPrettyPragma(
   OS << " match(" << traitInfos << ")";
 
   auto PrintExprs = [&OS, &Policy](Expr **Begin, Expr **End) {
-    for (Expr **I = Begin; I != End; ++I) {
-      assert(*I && "Expected non-null Stmt");
-      if (I != Begin)
-        OS << ",";
-      (*I)->printPretty(OS, nullptr, Policy);
+    if (Begin != End) {
+      if (const auto *Range = dyn_cast<OMPArgumentRangeExpr>(*Begin);
+          Range && !Range->getLowerBound())
+        OS << " ";
     }
+    llvm::interleave(
+        Begin, End,
+        [&](Expr *E) {
+          assert(E && "Expected non-null Stmt");
+          E->printPretty(OS, nullptr, Policy);
+        },
+        [&OS] { OS << ","; });
   };
   if (adjustArgsNothing_size()) {
     OS << " adjust_args(nothing:";
diff --git a/clang/lib/AST/ComputeDependence.cpp 
b/clang/lib/AST/ComputeDependence.cpp
index 0fc9da18b93940..4f33ed8beca4e3 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -500,6 +500,26 @@ ExprDependence clang::computeDependence(OMPIteratorExpr 
*E) {
   return D;
 }
 
+ExprDependence clang::computeDependence(OMPNumArgsExpr *E) {
+  // The type is always 'int', so the expression is never type-dependent; only
+  // the logical offset can make it value- or instantiation-dependent.
+  if (Expr *Offset = E->getOffset())
+    return Offset->getDependence() & ~ExprDependence::Type;
+  return ExprDependence::None;
+}
+
+ExprDependence clang::computeDependence(OMPArgumentRangeExpr *E) {
+  // The type is always 'void', so the expression is never type-dependent.
+  // Either bound may be omitted, meaning 1 for the lower bound and
+  // 'omp_num_args' for the upper bound.
+  auto D = ExprDependence::None;
+  if (Expr *LB = E->getLowerBound())
+    D |= LB->getDependence();
+  if (Expr *UB = E->getUpperBound())
+    D |= UB->getDependence();
+  return D & ~ExprDependence::Type;
+}
+
 /// Compute the type-, value-, and instantiation-dependence of a
 /// declaration reference
 /// based on the declaration being referenced.
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index e501527ed9b04b..90622bde37beda 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3831,6 +3831,8 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
   case ArraySectionExprClass:
   case OMPArrayShapingExprClass:
   case OMPIteratorExprClass:
+  case OMPNumArgsExprClass:
+  case OMPArgumentRangeExprClass:
   case MemberExprClass:
   case ConditionalOperatorClass:
   case BinaryConditionalOperatorClass:
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index eebae17d7b948b..6f3cd087b2660b 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -220,6 +220,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const 
Expr *E) {
   case Expr::RequiresExprClass:
   case Expr::CXXReflectExprClass:
   case Expr::CXXExpansionSelectExprClass:
+  case Expr::OMPNumArgsExprClass:
+  case Expr::OMPArgumentRangeExprClass:
     return Cl::CL_PRValue;
 
   case Expr::EmbedExprClass:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d55749100658f7..034142aac4c706 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -22398,6 +22398,8 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext 
&Ctx) {
   case Expr::ArraySectionExprClass:
   case Expr::OMPArrayShapingExprClass:
   case Expr::OMPIteratorExprClass:
+  case...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/225081
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to