[OPENMP50]Parsing/sema support for 'implementation/vendor' context
selector.
Added basic parsing/semantic support for
'implementation={vendor(<vendor>)}' context selector.
llvm-svn: 372917
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 570f246..46c8238 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -786,12 +786,72 @@
LinModifiers, Steps, SourceRange(Loc, EndLoc));
}
+/// Parse context selector for 'implementation' selector set:
+/// 'vendor' '(' <vendor> ')'
+static void
+parseImplementationSelector(Parser &P,
+ Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
+ const Token &Tok = P.getCurToken();
+ // Parse inner context selector set name, if any.
+ if (!Tok.is(tok::identifier)) {
+ P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected)
+ << "implementation";
+ // Skip until either '}', ')', or end of directive.
+ while (!P.SkipUntil(tok::r_brace, tok::r_paren,
+ tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
+ ;
+ return;
+ }
+ SmallString<16> Buffer;
+ StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
+ OMPDeclareVariantAttr::CtxSelectorType CSKind =
+ OMPDeclareVariantAttr::CtxUnknown;
+ (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName,
+ CSKind);
+ (void)P.ConsumeToken();
+ switch (CSKind) {
+ case OMPDeclareVariantAttr::CtxVendor: {
+ // Parse '('.
+ BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
+ (void)T.expectAndConsume(diag::err_expected_lparen_after,
+ CtxSelectorName.data());
+ // Parse <vendor>.
+ StringRef VendorName;
+ if (Tok.is(tok::identifier)) {
+ VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
+ (void)P.ConsumeToken();
+ } else {
+ P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
+ << "vendor identifier" << "vendor" << "implementation";
+ }
+ // Parse ')'.
+ (void)T.consumeClose();
+ if (!VendorName.empty())
+ Data.ImplVendor = VendorName;
+ break;
+ }
+ case OMPDeclareVariantAttr::CtxUnknown:
+ P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected)
+ << "implementation";
+ // Skip until either '}', ')', or end of directive.
+ while (!P.SkipUntil(tok::r_brace, tok::r_paren,
+ tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
+ ;
+ return;
+ }
+ Data.CtxSet = OMPDeclareVariantAttr::CtxSetImplementation;
+ Data.Ctx = CSKind;
+}
+
/// Parses clauses for 'declare variant' directive.
/// clause:
/// <selector_set_name> '=' '{' <context_selectors> '}'
/// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
bool Parser::parseOpenMPContextSelectors(
- SourceLocation Loc, llvm::function_ref<void(SourceRange)> Callback) {
+ SourceLocation Loc,
+ llvm::function_ref<void(SourceRange,
+ const Sema::OpenMPDeclareVariantCtsSelectorData &)>
+ Callback) {
do {
// Parse inner context selector set name.
if (!Tok.is(tok::identifier)) {
@@ -800,30 +860,43 @@
return true;
}
SmallString<16> Buffer;
- StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer);
+ StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer);
// Parse '='.
(void)ConsumeToken();
if (Tok.isNot(tok::equal)) {
Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
- << CtxSelectorName;
+ << CtxSelectorSetName;
return true;
}
(void)ConsumeToken();
// TBD: add parsing of known context selectors.
// Unknown selector - just ignore it completely.
+ Sema::OpenMPDeclareVariantCtsSelectorData Data;
{
// Parse '{'.
BalancedDelimiterTracker TBr(*this, tok::l_brace,
tok::annot_pragma_openmp_end);
if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
return true;
- while (!SkipUntil(tok::r_brace, tok::r_paren,
- tok::annot_pragma_openmp_end, StopBeforeMatch))
- ;
+ OMPDeclareVariantAttr::CtxSelectorSetType CSSKind =
+ OMPDeclareVariantAttr::CtxSetUnknown;
+ (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType(
+ CtxSelectorSetName, CSSKind);
+ switch (CSSKind) {
+ case OMPDeclareVariantAttr::CtxSetImplementation:
+ parseImplementationSelector(*this, Data);
+ break;
+ case OMPDeclareVariantAttr::CtxSetUnknown:
+ // Skip until either '}', ')', or end of directive.
+ while (!SkipUntil(tok::r_brace, tok::r_paren,
+ tok::annot_pragma_openmp_end, StopBeforeMatch))
+ ;
+ break;
+ }
// Parse '}'.
(void)TBr.consumeClose();
}
- Callback(SourceRange(Loc, Tok.getLocation()));
+ Callback(SourceRange(Loc, Tok.getLocation()), Data);
// Consume ','
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end))
(void)ExpectAndConsume(tok::comma);
@@ -888,11 +961,15 @@
}
// Parse inner context selectors.
- if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) {
- if (DeclVarData.hasValue())
- Actions.ActOnOpenMPDeclareVariantDirective(
- DeclVarData.getValue().first, DeclVarData.getValue().second, SR);
- })) {
+ if (!parseOpenMPContextSelectors(
+ Loc, [this, &DeclVarData](
+ SourceRange SR,
+ const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
+ if (DeclVarData.hasValue())
+ Actions.ActOnOpenMPDeclareVariantDirective(
+ DeclVarData.getValue().first, DeclVarData.getValue().second,
+ SR, Data);
+ })) {
// Parse ')'.
(void)T.consumeClose();
// Need to check for extra tokens.
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 34ce66c..0403f11 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5101,11 +5101,14 @@
return std::make_pair(FD, cast<Expr>(DRE));
}
-void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
- Expr *VariantRef,
- SourceRange SR) {
- auto *NewAttr =
- OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, SR);
+void Sema::ActOnOpenMPDeclareVariantDirective(
+ FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
+ const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
+ if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown ||
+ Data.Ctx == OMPDeclareVariantAttr::CtxUnknown)
+ return;
+ auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
+ Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR);
FD->addAttr(NewAttr);
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 684254b..f6cf369 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -395,9 +395,11 @@
if (!DeclVarData)
return;
// Instantiate the attribute.
+ Sema::OpenMPDeclareVariantCtsSelectorData Data(
+ Attr.getCtxSelectorSet(), Attr.getCtxSelector(), Attr.getImplVendor());
S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
DeclVarData.getValue().second,
- Attr.getRange());
+ Attr.getRange(), Data);
}
static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(