diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2019-11-07 11:03:10 -0500 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-11-11 14:41:10 -0500 |
commit | fde11e9f23a3bf6c78ec0bcfa92e9759ee8b5054 (patch) | |
tree | ea24a8651f3da140e40ffdd9ce5bf001cb53ec78 /clang/lib | |
parent | f8c12edd1a5200abbbb2c8da754d6a3bfa7545a0 (diff) | |
download | bcm5719-llvm-fde11e9f23a3bf6c78ec0bcfa92e9759ee8b5054.tar.gz bcm5719-llvm-fde11e9f23a3bf6c78ec0bcfa92e9759ee8b5054.zip |
[OPENMP50]Generalize handling of context matching/scoring.
Summary:
Untie context matching/scoring from the attribute for declare variant
directive to simplify future uses in other context-dependent directives.
Reviewers: jdoerfert
Subscribers: guansong, kkwli0, caomhin, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69952
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/OpenMPKinds.cpp | 43 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 133 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 71 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 69 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 34 |
5 files changed, 240 insertions, 110 deletions
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 75199fbceac..4e6c677f11d 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -19,6 +19,49 @@ using namespace clang; +OpenMPContextSelectorSetKind +clang::getOpenMPContextSelectorSet(llvm::StringRef Str) { + return llvm::StringSwitch<OpenMPContextSelectorSetKind>(Str) +#define OPENMP_CONTEXT_SELECTOR_SET(Name) .Case(#Name, OMP_CTX_SET_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMP_CTX_SET_unknown); +} + +llvm::StringRef +clang::getOpenMPContextSelectorSetName(OpenMPContextSelectorSetKind Kind) { + switch (Kind) { + case OMP_CTX_SET_unknown: + return "unknown"; +#define OPENMP_CONTEXT_SELECTOR_SET(Name) \ + case OMP_CTX_SET_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + break; + } + llvm_unreachable("Invalid OpenMP context selector set kind"); +} + +OpenMPContextSelectorKind clang::getOpenMPContextSelector(llvm::StringRef Str) { + return llvm::StringSwitch<OpenMPContextSelectorKind>(Str) +#define OPENMP_CONTEXT_SELECTOR(Name) .Case(#Name, OMP_CTX_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMP_CTX_unknown); +} + +llvm::StringRef +clang::getOpenMPContextSelectorName(OpenMPContextSelectorKind Kind) { + switch (Kind) { + case OMP_CTX_unknown: + return "unknown"; +#define OPENMP_CONTEXT_SELECTOR(Name) \ + case OMP_CTX_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + break; + } + llvm_unreachable("Invalid OpenMP context selector kind"); +} + OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) { return llvm::StringSwitch<OpenMPDirectiveKind>(Str) #define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index b48c52dbc1e..ae881c3e2d7 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -11023,12 +11023,16 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF, return Address(Addr, Align); } +namespace { +using OMPContextSelectorData = + OpenMPCtxSelectorData<StringRef, ArrayRef<StringRef>, llvm::APSInt>; +using CompleteOMPContextSelectorData = SmallVector<OMPContextSelectorData, 4>; +} // anonymous namespace + /// Checks current context and returns true if it matches the context selector. -template <OMPDeclareVariantAttr::CtxSelectorSetType CtxSet, - OMPDeclareVariantAttr::CtxSelectorType Ctx> -static bool checkContext(const OMPDeclareVariantAttr *A) { - assert(CtxSet != OMPDeclareVariantAttr::CtxSetUnknown && - Ctx != OMPDeclareVariantAttr::CtxUnknown && +template <OpenMPContextSelectorSetKind CtxSet, OpenMPContextSelectorKind Ctx> +static bool checkContext(const OMPContextSelectorData &Data) { + assert(Data.CtxSet != OMP_CTX_SET_unknown && Data.Ctx != OMP_CTX_unknown && "Unknown context selector or context selector set."); return false; } @@ -11036,17 +11040,88 @@ static bool checkContext(const OMPDeclareVariantAttr *A) { /// Checks for implementation={vendor(<vendor>)} context selector. /// \returns true iff <vendor>="llvm", false otherwise. template <> -bool checkContext<OMPDeclareVariantAttr::CtxSetImplementation, - OMPDeclareVariantAttr::CtxVendor>( - const OMPDeclareVariantAttr *A) { - return llvm::all_of(A->implVendors(), +bool checkContext<OMP_CTX_SET_implementation, OMP_CTX_vendor>( + const OMPContextSelectorData &Data) { + return llvm::all_of(Data.Names, [](StringRef S) { return !S.compare_lower("llvm"); }); } -static bool greaterCtxScore(ASTContext &Ctx, const Expr *LHS, const Expr *RHS) { - llvm::APSInt LHSVal = LHS->EvaluateKnownConstInt(Ctx); - llvm::APSInt RHSVal = RHS->EvaluateKnownConstInt(Ctx); - return llvm::APSInt::compareValues(LHSVal, RHSVal) >= 0; +bool matchesContext(const CompleteOMPContextSelectorData &ContextData) { + for (const OMPContextSelectorData &Data : ContextData) { + switch (Data.CtxSet) { + case OMP_CTX_SET_implementation: + switch (Data.Ctx) { + case OMP_CTX_vendor: + if (!checkContext<OMP_CTX_SET_implementation, OMP_CTX_vendor>(Data)) + return false; + break; + case OMP_CTX_unknown: + llvm_unreachable("Unexpected context selector kind."); + } + break; + case OMP_CTX_SET_unknown: + llvm_unreachable("Unexpected context selector set kind."); + } + } + return true; +} + +static CompleteOMPContextSelectorData +translateAttrToContextSelectorData(ASTContext &C, + const OMPDeclareVariantAttr *A) { + CompleteOMPContextSelectorData Data; + for (unsigned I = 0, E = A->scores_size(); I < E; ++I) { + Data.emplace_back(); + auto CtxSet = static_cast<OpenMPContextSelectorSetKind>( + *std::next(A->ctxSelectorSets_begin(), I)); + auto Ctx = static_cast<OpenMPContextSelectorKind>( + *std::next(A->ctxSelectors_begin(), I)); + Data.back().CtxSet = CtxSet; + Data.back().Ctx = Ctx; + const Expr *Score = *std::next(A->scores_begin(), I); + Data.back().Score = Score->EvaluateKnownConstInt(C); + switch (CtxSet) { + case OMP_CTX_SET_implementation: + switch (Ctx) { + case OMP_CTX_vendor: + Data.back().Names = + llvm::makeArrayRef(A->implVendors_begin(), A->implVendors_end()); + break; + case OMP_CTX_unknown: + llvm_unreachable("Unexpected context selector kind."); + } + break; + case OMP_CTX_SET_unknown: + llvm_unreachable("Unexpected context selector set kind."); + } + } + return Data; +} + +static bool greaterCtxScore(const CompleteOMPContextSelectorData &LHS, + const CompleteOMPContextSelectorData &RHS) { + // Score is calculated as sum of all scores + 1. + llvm::APSInt LHSScore(llvm::APInt(64, 1), /*isUnsigned=*/false); + for (const OMPContextSelectorData &Data : LHS) { + if (Data.Score.getBitWidth() > LHSScore.getBitWidth()) { + LHSScore = LHSScore.extend(Data.Score.getBitWidth()) + Data.Score; + } else if (Data.Score.getBitWidth() < LHSScore.getBitWidth()) { + LHSScore += Data.Score.extend(LHSScore.getBitWidth()); + } else { + LHSScore += Data.Score; + } + } + llvm::APSInt RHSScore(llvm::APInt(64, 1), /*isUnsigned=*/false); + for (const OMPContextSelectorData &Data : RHS) { + if (Data.Score.getBitWidth() > RHSScore.getBitWidth()) { + RHSScore = RHSScore.extend(Data.Score.getBitWidth()) + Data.Score; + } else if (Data.Score.getBitWidth() < RHSScore.getBitWidth()) { + RHSScore += Data.Score.extend(RHSScore.getBitWidth()); + } else { + RHSScore += Data.Score; + } + } + return llvm::APSInt::compareValues(LHSScore, RHSScore) >= 0; } /// Finds the variant function that matches current context with its context @@ -11056,33 +11131,19 @@ static const FunctionDecl *getDeclareVariantFunction(ASTContext &Ctx, if (!FD->hasAttrs() || !FD->hasAttr<OMPDeclareVariantAttr>()) return FD; // Iterate through all DeclareVariant attributes and check context selectors. - auto &&Comparer = [&Ctx](const OMPDeclareVariantAttr *LHS, - const OMPDeclareVariantAttr *RHS) { - return greaterCtxScore(Ctx, LHS->getScore(), RHS->getScore()); - }; const OMPDeclareVariantAttr *TopMostAttr = nullptr; + CompleteOMPContextSelectorData TopMostData; for (const auto *A : FD->specific_attrs<OMPDeclareVariantAttr>()) { - const OMPDeclareVariantAttr *SelectedAttr = nullptr; - switch (A->getCtxSelectorSet()) { - case OMPDeclareVariantAttr::CtxSetImplementation: - switch (A->getCtxSelector()) { - case OMPDeclareVariantAttr::CtxVendor: - if (checkContext<OMPDeclareVariantAttr::CtxSetImplementation, - OMPDeclareVariantAttr::CtxVendor>(A)) - SelectedAttr = A; - break; - case OMPDeclareVariantAttr::CtxUnknown: - llvm_unreachable( - "Unknown context selector in implementation selector set."); - } - break; - case OMPDeclareVariantAttr::CtxSetUnknown: - llvm_unreachable("Unknown context selector set."); - } + CompleteOMPContextSelectorData Data = + translateAttrToContextSelectorData(Ctx, A); + if (!matchesContext(Data)) + continue; // If the attribute matches the context, find the attribute with the highest // score. - if (SelectedAttr && (!TopMostAttr || !Comparer(TopMostAttr, SelectedAttr))) - TopMostAttr = SelectedAttr; + if (!TopMostAttr || !greaterCtxScore(TopMostData, Data)) { + TopMostAttr = A; + TopMostData.swap(Data); + } } if (!TopMostAttr) return FD; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index e59b83dd999..8430e72d3c8 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -797,7 +797,7 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, /// Parse optional 'score' '(' <expr> ')' ':'. static ExprResult parseContextScore(Parser &P) { ExprResult ScoreExpr; - SmallString<16> Buffer; + Sema::OMPCtxStringType Buffer; StringRef SelectorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer); if (!SelectorName.equals("score")) @@ -817,11 +817,10 @@ static ExprResult parseContextScore(Parser &P) { /// Parse context selector for 'implementation' selector set: /// 'vendor' '(' [ 'score' '(' <score _expr> ')' ':' ] <vendor> { ',' <vendor> } /// ')' -static void parseImplementationSelector( - Parser &P, SourceLocation Loc, llvm::StringMap<SourceLocation> &UsedCtx, - llvm::function_ref<void(SourceRange, - const Sema::OpenMPDeclareVariantCtsSelectorData &)> - Callback) { +static void +parseImplementationSelector(Parser &P, SourceLocation Loc, + llvm::StringMap<SourceLocation> &UsedCtx, + SmallVectorImpl<Sema::OMPCtxSelectorData> &Data) { const Token &Tok = P.getCurToken(); // Parse inner context selector set name, if any. if (!Tok.is(tok::identifier)) { @@ -833,7 +832,7 @@ static void parseImplementationSelector( ; return; } - SmallString<16> Buffer; + Sema::OMPCtxStringType Buffer; StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer); auto Res = UsedCtx.try_emplace(CtxSelectorName, Tok.getLocation()); if (!Res.second) { @@ -844,19 +843,16 @@ static void parseImplementationSelector( P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here) << CtxSelectorName; } - OMPDeclareVariantAttr::CtxSelectorType CSKind = - OMPDeclareVariantAttr::CtxUnknown; - (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName, - CSKind); + OpenMPContextSelectorKind CSKind = getOpenMPContextSelector(CtxSelectorName); (void)P.ConsumeToken(); switch (CSKind) { - case OMPDeclareVariantAttr::CtxVendor: { + case OMP_CTX_vendor: { // Parse '('. BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); (void)T.expectAndConsume(diag::err_expected_lparen_after, CtxSelectorName.data()); - const ExprResult Score = parseContextScore(P); - llvm::UniqueVector<llvm::SmallString<16>> Vendors; + ExprResult Score = parseContextScore(P); + llvm::UniqueVector<Sema::OMPCtxStringType> Vendors; do { // Parse <vendor>. StringRef VendorName; @@ -879,18 +875,11 @@ static void parseImplementationSelector( } while (Tok.is(tok::identifier)); // Parse ')'. (void)T.consumeClose(); - if (!Vendors.empty()) { - SmallVector<StringRef, 4> ImplVendors(Vendors.size()); - llvm::copy(Vendors, ImplVendors.begin()); - Sema::OpenMPDeclareVariantCtsSelectorData Data( - OMPDeclareVariantAttr::CtxSetImplementation, CSKind, - llvm::makeMutableArrayRef(ImplVendors.begin(), ImplVendors.size()), - Score); - Callback(SourceRange(Loc, Tok.getLocation()), Data); - } + if (!Vendors.empty()) + Data.emplace_back(OMP_CTX_SET_implementation, CSKind, Score, Vendors); break; } - case OMPDeclareVariantAttr::CtxUnknown: + case OMP_CTX_unknown: P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected) << "implementation"; // Skip until either '}', ')', or end of directive. @@ -906,10 +895,7 @@ static void parseImplementationSelector( /// <selector_set_name> '=' '{' <context_selectors> '}' /// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ] bool Parser::parseOpenMPContextSelectors( - SourceLocation Loc, - llvm::function_ref<void(SourceRange, - const Sema::OpenMPDeclareVariantCtsSelectorData &)> - Callback) { + SourceLocation Loc, SmallVectorImpl<Sema::OMPCtxSelectorData> &Data) { llvm::StringMap<SourceLocation> UsedCtxSets; do { // Parse inner context selector set name. @@ -918,7 +904,7 @@ bool Parser::parseOpenMPContextSelectors( << getOpenMPClauseName(OMPC_match); return true; } - SmallString<16> Buffer; + Sema::OMPCtxStringType Buffer; StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer); auto Res = UsedCtxSets.try_emplace(CtxSelectorSetName, Tok.getLocation()); if (!Res.second) { @@ -946,17 +932,15 @@ bool Parser::parseOpenMPContextSelectors( tok::annot_pragma_openmp_end); if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "=")) return true; - OMPDeclareVariantAttr::CtxSelectorSetType CSSKind = - OMPDeclareVariantAttr::CtxSetUnknown; - (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType( - CtxSelectorSetName, CSSKind); + OpenMPContextSelectorSetKind CSSKind = + getOpenMPContextSelectorSet(CtxSelectorSetName); llvm::StringMap<SourceLocation> UsedCtx; do { switch (CSSKind) { - case OMPDeclareVariantAttr::CtxSetImplementation: - parseImplementationSelector(*this, Loc, UsedCtx, Callback); + case OMP_CTX_SET_implementation: + parseImplementationSelector(*this, Loc, UsedCtx, Data); break; - case OMPDeclareVariantAttr::CtxSetUnknown: + case OMP_CTX_SET_unknown: // Skip until either '}', ')', or end of directive. while (!SkipUntil(tok::r_brace, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch)) @@ -1036,15 +1020,8 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, } // Parse inner context selectors. - if (!parseOpenMPContextSelectors( - Loc, [this, &DeclVarData]( - SourceRange SR, - const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { - if (DeclVarData.hasValue()) - Actions.ActOnOpenMPDeclareVariantDirective( - DeclVarData.getValue().first, DeclVarData.getValue().second, - SR, Data); - })) { + SmallVector<Sema::OMPCtxSelectorData, 4> Data; + if (!parseOpenMPContextSelectors(Loc, Data)) { // Parse ')'. (void)T.consumeClose(); // Need to check for extra tokens. @@ -1057,6 +1034,10 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, // Skip last tokens. while (Tok.isNot(tok::annot_pragma_openmp_end)) ConsumeAnyToken(); + if (DeclVarData.hasValue()) + Actions.ActOnOpenMPDeclareVariantDirective( + DeclVarData.getValue().first, DeclVarData.getValue().second, + SourceRange(Loc, Tok.getLocation()), Data); // Skip the last annot_pragma_openmp_end. (void)ConsumeAnnotationToken(); } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5c1b39e0b39..290a7bbd15b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5200,28 +5200,59 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, void Sema::ActOnOpenMPDeclareVariantDirective( FunctionDecl *FD, Expr *VariantRef, SourceRange SR, - const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { - if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || - Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) + ArrayRef<OMPCtxSelectorData> Data) { + if (Data.empty()) return; - Expr *Score = nullptr; - if (Data.CtxScore.isUsable()) { - Score = Data.CtxScore.get(); - if (!Score->isTypeDependent() && !Score->isValueDependent() && - !Score->isInstantiationDependent() && - !Score->containsUnexpandedParameterPack()) { - llvm::APSInt Result; - ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); - if (ICE.isInvalid()) - return; + SmallVector<Expr *, 4> CtxScores; + SmallVector<unsigned, 4> CtxSets; + SmallVector<unsigned, 4> Ctxs; + SmallVector<StringRef, 4> ImplVendors; + bool IsError = false; + for (const OMPCtxSelectorData &D : Data) { + OpenMPContextSelectorSetKind CtxSet = D.CtxSet; + OpenMPContextSelectorKind Ctx = D.Ctx; + if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown) + return; + Expr *Score = nullptr; + if (D.Score.isUsable()) { + Score = D.Score.get(); + if (!Score->isTypeDependent() && !Score->isValueDependent() && + !Score->isInstantiationDependent() && + !Score->containsUnexpandedParameterPack()) { + Score = + PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score) + .get(); + if (Score) + Score = VerifyIntegerConstantExpression(Score).get(); + } + } else { + Score = ActOnIntegerConstant(SourceLocation(), 0).get(); } - } else { - Score = ActOnIntegerConstant(SourceLocation(), 0).get(); + switch (CtxSet) { + case OMP_CTX_SET_implementation: + switch (Ctx) { + case OMP_CTX_vendor: + ImplVendors.append(D.Names.begin(), D.Names.end()); + break; + case OMP_CTX_unknown: + llvm_unreachable("Unexpected context selector kind."); + } + break; + case OMP_CTX_SET_unknown: + llvm_unreachable("Unexpected context selector set kind."); + } + IsError = IsError || !Score; + CtxSets.push_back(CtxSet); + Ctxs.push_back(Ctx); + CtxScores.push_back(Score); + } + if (!IsError) { + auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( + Context, VariantRef, CtxScores.begin(), CtxScores.size(), + CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(), + ImplVendors.begin(), ImplVendors.size(), SR); + FD->addAttr(NewAttr); } - auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( - Context, VariantRef, Score, Data.CtxSet, Data.Ctx, - Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); - FD->addAttr(NewAttr); } void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 31a4302ba82..cd8b95231aa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -388,22 +388,36 @@ static void instantiateOMPDeclareVariantAttr( if (Expr *E = Attr.getVariantFuncRef()) VariantFuncRef = Subst(E); - ExprResult Score; - if (Expr *E = Attr.getScore()) - Score = Subst(E); - // Check function/variant ref. Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData = S.checkOpenMPDeclareVariantFunction( S.ConvertDeclToDeclGroup(New), VariantFuncRef.get(), Attr.getRange()); if (!DeclVarData) return; - // Instantiate the attribute. - Sema::OpenMPDeclareVariantCtsSelectorData Data( - Attr.getCtxSelectorSet(), Attr.getCtxSelector(), - llvm::makeMutableArrayRef(Attr.implVendors_begin(), - Attr.implVendors_size()), - Score); + SmallVector<Sema::OMPCtxSelectorData, 4> Data; + for (unsigned I = 0, E = Attr.scores_size(); I < E; ++I) { + ExprResult Score; + if (Expr *E = *std::next(Attr.scores_begin(), I)) + Score = Subst(E); + // Instantiate the attribute. + auto CtxSet = static_cast<OpenMPContextSelectorSetKind>( + *std::next(Attr.ctxSelectorSets_begin(), I)); + auto Ctx = static_cast<OpenMPContextSelectorKind>( + *std::next(Attr.ctxSelectors_begin(), I)); + switch (CtxSet) { + case OMP_CTX_SET_implementation: + switch (Ctx) { + case OMP_CTX_vendor: + Data.emplace_back(CtxSet, Ctx, Score, Attr.implVendors()); + break; + case OMP_CTX_unknown: + llvm_unreachable("Unexpected context selector kind."); + } + break; + case OMP_CTX_SET_unknown: + llvm_unreachable("Unexpected context selector set kind."); + } + } S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first, DeclVarData.getValue().second, Attr.getRange(), Data); |