summaryrefslogtreecommitdiff
path: root/lib/Parse/ParseOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseOpenMP.cpp')
-rw-r--r--lib/Parse/ParseOpenMP.cpp153
1 files changed, 86 insertions, 67 deletions
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 293660ec4c..8d852b5dcb 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -788,65 +788,53 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
/// Parses clauses for 'declare variant' directive.
/// clause:
-/// 'match' '('
/// <selector_set_name> '=' '{' <context_selectors> '}'
-/// ')'
-static bool parseDeclareVariantClause(Parser &P) {
- Token Tok = P.getCurToken();
- // Parse 'match'.
- if (!Tok.is(tok::identifier) ||
- P.getPreprocessor().getSpelling(Tok).compare("match")) {
- P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
- << "match";
- while (!P.SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
- ;
- return true;
- }
- (void)P.ConsumeToken();
- // Parse '('.
- BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
- if (T.expectAndConsume(diag::err_expected_lparen_after, "match"))
- return true;
- // Parse inner context selector.
- Tok = P.getCurToken();
- if (!Tok.is(tok::identifier)) {
- P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
- << "match";
- return true;
- }
- SmallString<16> Buffer;
- StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
- // Parse '='.
- (void)P.ConsumeToken();
- Tok = P.getCurToken();
- if (Tok.isNot(tok::equal)) {
- P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
- << CtxSelectorName;
- return true;
- }
- (void)P.ConsumeToken();
- // Unknown selector - just ignore it completely.
- {
- // Parse '{'.
- BalancedDelimiterTracker TBr(P, tok::l_brace, tok::annot_pragma_openmp_end);
- if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
+/// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
+bool Parser::parseOpenMPContextSelectors(
+ SourceLocation Loc, llvm::function_ref<void(SourceRange)> Callback) {
+ do {
+ // Parse inner context selector set name.
+ if (!Tok.is(tok::identifier)) {
+ Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
+ << "match";
return true;
- while (!P.SkipUntil(tok::r_brace, tok::r_paren,
- tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
- ;
- // Parse '}'.
- (void)TBr.consumeClose();
- }
- // Parse ')'.
- (void)T.consumeClose();
- // TBD: add parsing of known context selectors.
+ }
+ SmallString<16> Buffer;
+ StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer);
+ // Parse '='.
+ (void)ConsumeToken();
+ if (Tok.isNot(tok::equal)) {
+ Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
+ << CtxSelectorName;
+ return true;
+ }
+ (void)ConsumeToken();
+ // TBD: add parsing of known context selectors.
+ // Unknown selector - just ignore it completely.
+ {
+ // 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))
+ ;
+ // Parse '}'.
+ (void)TBr.consumeClose();
+ }
+ Callback(SourceRange(Loc, Tok.getLocation()));
+ // Consume ','
+ if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end))
+ (void)ExpectAndConsume(tok::comma);
+ } while (Tok.isAnyIdentifier());
return false;
}
/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
-Parser::DeclGroupPtrTy
-Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
- CachedTokens &Toks, SourceLocation Loc) {
+void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
+ CachedTokens &Toks,
+ SourceLocation Loc) {
PP.EnterToken(Tok, /*IsReinject*/ true);
PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
/*IsReinject*/ true);
@@ -868,23 +856,53 @@ Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
;
// Skip the last annot_pragma_openmp_end.
(void)ConsumeAnnotationToken();
- return Ptr;
+ return;
}
+ Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
+ Actions.checkOpenMPDeclareVariantFunction(
+ Ptr, AssociatedFunction.get(), SourceRange(Loc, Tok.getLocation()));
- bool IsError = parseDeclareVariantClause(*this);
- // Need to check for extra tokens.
- if (Tok.isNot(tok::annot_pragma_openmp_end)) {
- Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
- << getOpenMPDirectiveName(OMPD_declare_variant);
- while (Tok.isNot(tok::annot_pragma_openmp_end))
- ConsumeAnyToken();
+ // Parse 'match'.
+ if (!Tok.is(tok::identifier) || PP.getSpelling(Tok).compare("match")) {
+ Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
+ << "match";
+ while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
+ ;
+ // Skip the last annot_pragma_openmp_end.
+ (void)ConsumeAnnotationToken();
+ return;
+ }
+ (void)ConsumeToken();
+ // Parse '('.
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+ if (T.expectAndConsume(diag::err_expected_lparen_after, "match")) {
+ while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
+ ;
+ // Skip the last annot_pragma_openmp_end.
+ (void)ConsumeAnnotationToken();
+ return;
+ }
+
+ // Parse inner context selectors.
+ if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) {
+ if (DeclVarData.hasValue())
+ Actions.ActOnOpenMPDeclareVariantDirective(
+ DeclVarData.getValue().first, DeclVarData.getValue().second, SR);
+ })) {
+ // Parse ')'.
+ (void)T.consumeClose();
+ // Need to check for extra tokens.
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(OMPD_declare_variant);
+ }
}
+
+ // Skip last tokens.
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
// Skip the last annot_pragma_openmp_end.
- SourceLocation EndLoc = ConsumeAnnotationToken();
- if (IsError)
- return Ptr;
- return Actions.ActOnOpenMPDeclareVariantDirective(
- Ptr, AssociatedFunction.get(), SourceRange(Loc, EndLoc));
+ (void)ConsumeAnnotationToken();
}
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
@@ -1248,7 +1266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
assert(DKind == OMPD_declare_variant &&
"Expected declare variant directive only");
- return ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
+ ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
+ return Ptr;
}
case OMPD_declare_target: {
SourceLocation DTLoc = ConsumeAnyToken();