llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: ykhatav (ykhatav)
<details>
<summary>Changes</summary>
This PR adds parsing support for the OpenMP 6.0 brace-grouped prefer_type
modifier on the init clause of #pragma omp interop, while preserving the OpenMP
5.1 flat form. Each preference-specification can now carry an optional
fr(<foreign-runtime-id>) and zero or more
attr(<string-literal>...) selectors, eg:
#pragma omp interop init(prefer_type({fr("sycl"), attr("ompx_propX")}, \
{fr("level_zero")}, \
{attr("ompx_propY")}), targetsync: obj)
---
Patch is 29.68 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/198868.diff
12 Files Affected:
- (modified) clang/include/clang/AST/OpenMPClause.h (+75-7)
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+2)
- (modified) clang/include/clang/Basic/OpenMPKinds.h (+9-1)
- (modified) clang/include/clang/Parse/Parser.h (+6)
- (modified) clang/lib/AST/OpenMPClause.cpp (+78-20)
- (modified) clang/lib/Parse/ParseOpenMP.cpp (+113-13)
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-3)
- (modified) clang/lib/Sema/TreeTransform.h (+21-6)
- (modified) clang/lib/Serialization/ASTReader.cpp (+20-2)
- (modified) clang/lib/Serialization/ASTWriter.cpp (+12)
- (added) clang/test/OpenMP/interop_prefer_type_brace_ast_print.cpp (+71)
- (added) clang/test/OpenMP/interop_prefer_type_brace_messages.cpp (+42)
``````````diff
diff --git a/clang/include/clang/AST/OpenMPClause.h
b/clang/include/clang/AST/OpenMPClause.h
index ccf2c40bc5efa..629d03f9e74a6 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -8851,7 +8851,7 @@ class OMPOrderClause final : public OMPClause {
/// \endcode
class OMPInitClause final
: public OMPVarListClause<OMPInitClause>,
- private llvm::TrailingObjects<OMPInitClause, Expr *> {
+ private llvm::TrailingObjects<OMPInitClause, Expr *, unsigned> {
friend class OMPClauseReader;
friend OMPVarListClause;
friend TrailingObjects;
@@ -8861,6 +8861,30 @@ class OMPInitClause final
bool IsTarget = false;
bool IsTargetSync = false;
+ bool HasPreferAttrs = false;
+
+ /// Total number of attr() exprs across all pref-specs (sum of the
+ /// per-pref-spec counts in the trailing unsigned[]).
+ unsigned NumAttrs = 0;
+
+ /// Trailing-objects layout (single contiguous Expr* array):
+ /// Expr*[ varlist_size() + NumAttrs ]:
+ /// [0] = InteropVar
+ /// [1 .. NumPrefs] = Fr expr per pref-spec (null if attr-only)
+ /// [varlist_size() ..] = flat list of attr exprs, concatenated in
+ /// pref-spec order
+ /// unsigned[ NumPrefs ]:
+ /// [i] = number of attr() exprs in pref-spec i
+ ///
+ /// varlist_size() = 1 + NumPrefs, so OMPVarListClause iteration covers
+ /// InteropVar + the Fr block.
+
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size() + NumAttrs;
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getNumPrefs();
+ }
void setInteropVar(Expr *E) { varlist_begin()[0] = E; }
@@ -8868,6 +8892,10 @@ class OMPInitClause final
void setIsTargetSync(bool V) { IsTargetSync = V; }
+ void setHasPreferAttrs(bool V) { HasPreferAttrs = V; }
+
+ void setAttrs(ArrayRef<unsigned> Counts, ArrayRef<Expr *> Attrs);
+
/// Sets the location of the interop variable.
void setVarLoc(SourceLocation Loc) { VarLoc = Loc; }
@@ -8879,7 +8907,7 @@ class OMPInitClause final
/// \param LParenLoc Location of '('.
/// \param VarLoc Location of the interop variable.
/// \param EndLoc Ending location of the clause.
- /// \param N Number of expressions.
+ /// \param N Number of varlist entries (1 + NumPrefs).
OMPInitClause(bool IsTarget, bool IsTargetSync, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation VarLoc,
SourceLocation EndLoc, unsigned N)
@@ -8894,6 +8922,14 @@ class OMPInitClause final
}
public:
+ struct PrefView {
+ /// Foreign-runtime-id expression. Null for attr-only specs.
+ Expr *Fr;
+ /// attr() string-literal expressions. Empty for fr-only or OMP 5.1
+ /// flat specs.
+ ArrayRef<Expr *> Attrs;
+ };
+
/// Creates a fully specified clause.
///
/// \param C AST context.
@@ -8909,11 +8945,14 @@ class OMPInitClause final
SourceLocation LParenLoc, SourceLocation VarLoc,
SourceLocation EndLoc);
- /// Creates an empty clause with \a N expressions.
+ /// Creates an empty clause sized for \a NumPrefs pref-specs and \a NumAttrs
+ /// total attr() exprs across them.
///
/// \param C AST context.
- /// \param N Number of expression items.
- static OMPInitClause *CreateEmpty(const ASTContext &C, unsigned N);
+ /// \param NumPrefs Number of pref-specs (length of the Fr block).
+ /// \param NumAttrs Total attr() exprs across all pref-specs.
+ static OMPInitClause *CreateEmpty(const ASTContext &C, unsigned NumPrefs,
+ unsigned NumAttrs);
/// Returns the location of the interop variable.
SourceLocation getVarLoc() const { return VarLoc; }
@@ -8928,9 +8967,38 @@ class OMPInitClause final
/// Returns true is interop-type 'targetsync' is used.
bool getIsTargetSync() const { return IsTargetSync; }
+ /// Returns true if OMP 6.0 {fr/attr} syntax is used.
+ bool getHasPreferAttrs() const { return HasPreferAttrs; }
+
+ /// Number of pref-specs in prefer_type(...).
+ unsigned getNumPrefs() const { return varlist_size() - 1; }
+
+ /// Total attrs across all pref-specs.
+ unsigned getNumAttrs() const { return NumAttrs; }
+
+ /// Per-pref-spec attr counts (one entry per pref-spec).
+ ArrayRef<unsigned> getAttrCounts() const {
+ return getTrailingObjects<unsigned>(getNumPrefs());
+ }
+
+ PrefView getPref(unsigned I) {
+ assert(I < getNumPrefs() && "pref-spec index out of range");
+ Expr **E = getTrailingObjects<Expr *>();
+ ArrayRef<unsigned> Counts = getAttrCounts();
+ unsigned AttrStart = 0;
+ for (unsigned K = 0; K < I; ++K)
+ AttrStart += Counts[K];
+ return PrefView{
+ E[1 + I], ArrayRef<Expr *>(E + varlist_size() + AttrStart, Counts[I])};
+ }
+ PrefView getPref(unsigned I) const {
+ return const_cast<OMPInitClause *>(this)->getPref(I);
+ }
+
child_range children() {
- return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
- reinterpret_cast<Stmt **>(varlist_end()));
+ return child_range(
+ reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_begin() + varlist_size() +
NumAttrs));
}
const_child_range children() const {
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 7bcd1870a2600..6abda0671add2 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1691,6 +1691,8 @@ def err_omp_expected_interop_type : Error<
def warn_omp_more_one_interop_type
: Warning<"interop type '%0' cannot be specified more than once">,
InGroup<OpenMPClauses>;
+def err_omp_interop_multiple_fr : Error<
+ "only one 'fr' selector allowed per preference-specification">;
def err_expected_sequence_or_directive : Error<
"expected an OpenMP 'directive' or 'sequence' attribute argument">;
def ext_omp_attributes : ExtWarn<
diff --git a/clang/include/clang/Basic/OpenMPKinds.h
b/clang/include/clang/Basic/OpenMPKinds.h
index 4e83bfcd0128b..72b25e0908a34 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -292,12 +292,20 @@ static constexpr unsigned
NumberOfOMPAllocateClauseModifiers =
/// Contains 'interop' data for 'append_args' and 'init' clauses.
class Expr;
+/// One entry of a prefer_type list. Each pref-spec carries an optional fr()
+/// foreign-runtime-id expression and zero or more attr() ext-string-literal
+/// expressions. Fr is nullptr for attr-only specs.
+struct OMPInteropPref final {
+ Expr *Fr = nullptr;
+ llvm::SmallVector<Expr *, 2> Attrs;
+};
struct OMPInteropInfo final {
OMPInteropInfo(bool IsTarget = false, bool IsTargetSync = false)
: IsTarget(IsTarget), IsTargetSync(IsTargetSync) {}
bool IsTarget;
bool IsTargetSync;
- llvm::SmallVector<Expr *, 4> PreferTypes;
+ bool HasPreferAttrs = false;
+ llvm::SmallVector<OMPInteropPref, 4> Prefs;
};
OpenMPDefaultClauseVariableCategory
diff --git a/clang/include/clang/Parse/Parser.h
b/clang/include/clang/Parse/Parser.h
index dc3dc8a4ae0e9..ada8ca7e7e52c 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -7001,6 +7001,12 @@ class Parser : public CodeCompletionHandler {
/// Parses the 'interop' parts of the 'append_args' and 'init' clauses.
bool ParseOMPInteropInfo(OMPInteropInfo &InteropInfo, OpenMPClauseKind Kind);
+ /// Parses 'fr(<foreign-runtime-id>)'.
+ ExprResult ParseOMPInteropFrSelector();
+
+ /// Parses 'attr(<string-literal>[, ...])', appending to \p Attrs.
+ bool ParseOMPInteropAttrSelector(SmallVectorImpl<Expr *> &Attrs);
+
/// Parses clause with an interop variable of kind \a Kind.
///
/// \verbatim
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 3a35e17aff40b..9fce666ce00d8 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1805,19 +1805,52 @@ OMPInitClause *OMPInitClause::Create(const ASTContext
&C, Expr *InteropVar,
SourceLocation VarLoc,
SourceLocation EndLoc) {
- void *Mem =
- C.Allocate(totalSizeToAlloc<Expr *>(InteropInfo.PreferTypes.size() + 1));
- auto *Clause = new (Mem) OMPInitClause(
- InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
- VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
- Clause->setInteropVar(InteropVar);
- llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects() + 1);
+ unsigned NumPrefs = InteropInfo.Prefs.size();
+ unsigned NumAttrs = 0;
+ for (const OMPInteropPref &P : InteropInfo.Prefs)
+ NumAttrs += P.Attrs.size();
+
+ // Trailing layout: Expr*[1 + NumPrefs + NumAttrs], unsigned[NumPrefs].
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<Expr *, unsigned>(1 + NumPrefs + NumAttrs, NumPrefs));
+ auto *Clause = new (Mem)
+ OMPInitClause(InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc,
+ LParenLoc, VarLoc, EndLoc, /*VarListN=*/1 + NumPrefs);
+ Clause->NumAttrs = NumAttrs;
+ Clause->HasPreferAttrs = InteropInfo.HasPreferAttrs;
+
+ Expr **E = Clause->getTrailingObjects<Expr *>();
+ E[0] = InteropVar;
+ for (unsigned I = 0; I < NumPrefs; ++I)
+ E[1 + I] = InteropInfo.Prefs[I].Fr;
+ unsigned *Counts = Clause->getTrailingObjects<unsigned>();
+ unsigned AttrPos = 1 + NumPrefs;
+ for (unsigned I = 0; I < NumPrefs; ++I) {
+ Counts[I] = InteropInfo.Prefs[I].Attrs.size();
+ for (Expr *A : InteropInfo.Prefs[I].Attrs)
+ E[AttrPos++] = A;
+ }
return Clause;
}
-OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
- return new (Mem) OMPInitClause(N);
+OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C,
+ unsigned NumPrefs,
+ unsigned NumAttrs) {
+ void *Mem = C.Allocate(
+ totalSizeToAlloc<Expr *, unsigned>(1 + NumPrefs + NumAttrs, NumPrefs));
+ auto *Clause = new (Mem) OMPInitClause(/*VarListN=*/1 + NumPrefs);
+ Clause->NumAttrs = NumAttrs;
+ return Clause;
+}
+
+void OMPInitClause::setAttrs(ArrayRef<unsigned> Counts,
+ ArrayRef<Expr *> Attrs) {
+ assert(Counts.size() == getNumPrefs() &&
+ "attr-count vector size must match number of pref-specs");
+ assert(Attrs.size() == NumAttrs &&
+ "attr-expr count must match preallocated NumAttrs");
+ llvm::copy(Counts, getTrailingObjects<unsigned>());
+ llvm::copy(Attrs, getTrailingObjects<Expr *>() + varlist_size());
}
OMPBindClause *
@@ -2388,17 +2421,42 @@ void OMPClausePrinter::VisitOMPHintClause(OMPHintClause
*Node) {
void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
OS << "init(";
- bool First = true;
- for (const Expr *E : Node->prefs()) {
- if (First)
- OS << "prefer_type(";
- else
- OS << ",";
- E->printPretty(OS, nullptr, Policy);
- First = false;
- }
- if (!First)
+ unsigned NumPrefs = Node->getNumPrefs();
+ if (NumPrefs > 0) {
+ OS << "prefer_type(";
+ if (Node->getHasPreferAttrs()) {
+ // OMP 6.0 brace-grouped form
+ llvm::interleaveComma(
+ llvm::seq<unsigned>(0, NumPrefs), OS, [&](unsigned I) {
+ OMPInitClause::PrefView P = Node->getPref(I);
+ OS << "{";
+ if (P.Fr) {
+ OS << "fr(";
+ P.Fr->printPretty(OS, nullptr, Policy);
+ OS << ")";
+ if (!P.Attrs.empty())
+ OS << ", ";
+ }
+ if (!P.Attrs.empty()) {
+ OS << "attr(";
+ llvm::interleaveComma(P.Attrs, OS, [&](const Expr *A) {
+ A->printPretty(OS, nullptr, Policy);
+ });
+ OS << ")";
+ }
+ OS << "}";
+ });
+ } else {
+ llvm::interleave(
+ llvm::seq<unsigned>(0, NumPrefs), OS,
+ [&](unsigned I) {
+ if (Expr *Fr = Node->getPref(I).Fr)
+ Fr->printPretty(OS, nullptr, Policy);
+ },
+ ",");
+ }
OS << "), ";
+ }
if (Node->getIsTarget())
OS << "target";
if (Node->getIsTargetSync()) {
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 7f3c575fb68bb..de844460c0a15 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -3681,6 +3681,55 @@ bool Parser::ParseOpenMPIndirectClause(
return false;
}
+ExprResult Parser::ParseOMPInteropFrSelector() {
+ ConsumeToken(); // 'fr'
+ BalancedDelimiterTracker FT(*this, tok::l_paren,
+ tok::annot_pragma_openmp_end);
+ if (FT.expectAndConsume(diag::err_expected_lparen_after, "fr")) {
+ SkipUntil(
+ {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
+ StopBeforeMatch);
+ return ExprError();
+ }
+ SourceLocation Loc = Tok.getLocation();
+ ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
+ ExprResult Arg = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+ Arg = Actions.ActOnFinishFullExpr(Arg.get(), Loc, /*DiscardedValue=*/false);
+ FT.consumeClose();
+ return Arg;
+}
+
+bool Parser::ParseOMPInteropAttrSelector(SmallVectorImpl<Expr *> &Attrs) {
+ ConsumeToken(); // 'attr'
+ BalancedDelimiterTracker AT(*this, tok::l_paren,
+ tok::annot_pragma_openmp_end);
+ if (AT.expectAndConsume(diag::err_expected_lparen_after, "attr")) {
+ SkipUntil(
+ {tok::comma, tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end},
+ StopBeforeMatch);
+ return true;
+ }
+ bool HasError = false;
+ while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::r_brace) &&
+ Tok.isNot(tok::annot_pragma_openmp_end)) {
+ if (Tok.is(tok::string_literal)) {
+ ExprResult S = ParseStringLiteralExpression();
+ if (S.isUsable())
+ Attrs.push_back(S.get());
+ else
+ HasError = true;
+ } else {
+ HasError = true;
+ Diag(Tok, diag::err_expected) << tok::string_literal;
+ ConsumeToken();
+ }
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ }
+ AT.consumeClose();
+ return HasError;
+}
+
bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
OpenMPClauseKind Kind) {
const Token &Tok = getCurToken();
@@ -3690,9 +3739,8 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo
&InteropInfo,
while (Tok.is(tok::identifier)) {
// Currently prefer_type is only allowed with 'init' and it must be first.
- bool PreferTypeAllowed = Kind == OMPC_init &&
- InteropInfo.PreferTypes.empty() && !IsTarget &&
- !IsTargetSync;
+ bool PreferTypeAllowed = Kind == OMPC_init && InteropInfo.Prefs.empty() &&
+ !IsTarget && !IsTargetSync;
if (Tok.getIdentifierInfo()->isStr("target")) {
// OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
// Each interop-type may be specified on an action-clause at most
@@ -3715,17 +3763,69 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo
&InteropInfo,
HasError = true;
while (Tok.isNot(tok::r_paren)) {
- SourceLocation Loc = Tok.getLocation();
- ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
- ExprResult PTExpr = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
- PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
- /*DiscardedValue=*/false);
- if (PTExpr.isUsable()) {
- InteropInfo.PreferTypes.push_back(PTExpr.get());
- } else {
- HasError = true;
- SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+ // OMP 6.0: { fr(...), attr(...) } brace-grouped pref-spec
+ if (Tok.is(tok::l_brace)) {
+ BalancedDelimiterTracker BT(*this, tok::l_brace,
+ tok::annot_pragma_openmp_end);
+ BT.consumeOpen();
+ Expr *FrExpr = nullptr;
+ SmallVector<Expr *, 2> AttrExprs;
+ bool SeenFr = false;
+
+ while (Tok.isNot(tok::r_brace) &&
+ Tok.isNot(tok::annot_pragma_openmp_end)) {
+ if (!Tok.is(tok::identifier)) {
+ HasError = true;
+ Diag(Tok, diag::err_omp_expected_interop_type);
+ ConsumeToken();
+ } else if (Tok.getIdentifierInfo()->isStr("fr")) {
+ if (SeenFr) {
+ Diag(Tok, diag::err_omp_interop_multiple_fr);
+ HasError = true;
+ ConsumeToken(); // 'fr'
+ SkipUntil(
+ {tok::comma, tok::r_brace, tok::annot_pragma_openmp_end},
StopBeforeMatch);
+ continue;
+ }
+ SeenFr = true;
+ ExprResult Fr = ParseOMPInteropFrSelector();
+ if (Fr.isUsable())
+ FrExpr = Fr.get();
+ else
+ HasError = true;
+ } else if (Tok.getIdentifierInfo()->isStr("attr")) {
+ if (ParseOMPInteropAttrSelector(AttrExprs))
+ HasError = true;
+ } else {
+ HasError = true;
+ Diag(Tok, diag::err_omp_expected_interop_type);
+ ConsumeToken();
+ }
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ }
+ if (BT.consumeClose())
+ HasError = true;
+
+ InteropInfo.Prefs.push_back({FrExpr, std::move(AttrExprs)});
+ InteropInfo.HasPreferAttrs = true;
+ } else {
+ // OMP 5.1: flat foreign-runtime-id (string or int). Stored as a
+ // pref-spec with Fr=expr and no attr() entries.
+ SourceLocation Loc = Tok.getLocation();
+ ExprResult LHS = ParseCastExpression(CastParseKind::AnyCastExpr);
+ ExprResult PTExpr =
+ ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+ PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
+ /*DiscardedValue=*/false);
+ if (PTExpr.isUsable()) {
+ InteropInfo.Prefs.push_back({PTExpr.get(), {}});
+ } else {
+ HasError = true;
+ SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ }
}
if (Tok.is(tok::comma))
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d6f6bc919a31b..ff3afd932bc27 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -18967,9 +18967,14 @@ OMPClause *SemaOpenMP::ActOnOpenMPInitClause(
if (!isValidInteropVariable(SemaRef, InteropVar, VarLoc, OMPC_init))
return nullptr;
- // Check prefer_type values. These foreign-runtime-id values are either
- // string literals or constant integral expressions.
- for (const Expr *E : InteropInfo.PreferTypes) {
+ // Check prefer_type values. fr() arguments are either string literals or
+ // constant integral expressions; null Fr is only valid in OMP 6.0
+ for (const OMPInteropPref &P : InteropInfo.Prefs) {
+ const Expr *E = P.Fr;
+ if (!E) {
+ assert(InteropInfo.HasPreferAttrs && "null Fr requires OMP 6.0 syntax");
+ continue;
+ }
if (E->isValueDependent() || E->isTypeDependent() ||
E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
continue;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 9c0479fe8aa4f..736a30fe7535e 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -10997,13 +10997,28 @@ OMPClause
*TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
return nullptr;
OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
- InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
- for (Expr *E : llvm::drop_begin(C->varlist())) {
- ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
- if (ER.isInvalid())
- return nullptr;
- InteropInfo...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/198868
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits