Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0736f7f

Browse files
committed
[OPENMP5.0]Allow multiple context selectors in the context selector
sets. According to OpenMP 5.0, context selector set might include several context selectors, separated with commas. Patch fixes this problem. llvm-svn: 372235
1 parent 97a18dc commit 0736f7f

File tree

9 files changed

+172
-125
lines changed

9 files changed

+172
-125
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,10 +2834,15 @@ class Parser : public CodeCompletionHandler {
28342834
DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
28352835
CachedTokens &Toks,
28362836
SourceLocation Loc);
2837+
/// Parses OpenMP context selectors and calls \p Callback for each
2838+
/// successfully parsed context selector.
2839+
bool
2840+
parseOpenMPContextSelectors(SourceLocation Loc,
2841+
llvm::function_ref<void(SourceRange)> Callback);
2842+
28372843
/// Parse clauses for '#pragma omp declare variant'.
2838-
DeclGroupPtrTy ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr,
2839-
CachedTokens &Toks,
2840-
SourceLocation Loc);
2844+
void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
2845+
SourceLocation Loc);
28412846
/// Parse clauses for '#pragma omp declare target'.
28422847
DeclGroupPtrTy ParseOMPDeclareTargetClauses();
28432848
/// Parse '#pragma omp end declare target'.

clang/include/clang/Sema/Sema.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9529,15 +9529,26 @@ class Sema {
95299529
ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
95309530
ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR);
95319531

9532+
/// Checks '\#pragma omp declare variant' variant function and original
9533+
/// functions after parsing of the associated method/function.
9534+
/// \param DG Function declaration to which declare variant directive is
9535+
/// applied to.
9536+
/// \param VariantRef Expression that references the variant function, which
9537+
/// must be used instead of the original one, specified in \p DG.
9538+
/// \returns None, if the function/variant function are not compatible with
9539+
/// the pragma,pair of original function/variant ref expression otherwise.
9540+
Optional<std::pair<FunctionDecl *, Expr *>>
9541+
checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
9542+
SourceRange SR);
9543+
95329544
/// Called on well-formed '\#pragma omp declare variant' after parsing of
95339545
/// the associated method/function.
9534-
/// \param DG Function declaration to which declare variant directive is
9546+
/// \param FD Function declaration to which declare variant directive is
95359547
/// applied to.
95369548
/// \param VariantRef Expression that references the variant function, which
95379549
/// must be used instead of the original one, specified in \p DG.
9538-
DeclGroupPtrTy ActOnOpenMPDeclareVariantDirective(DeclGroupPtrTy DG,
9539-
Expr *VariantRef,
9540-
SourceRange SR);
9550+
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef,
9551+
SourceRange SR);
95419552

95429553
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
95439554
Expr *Expr,

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 86 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -788,65 +788,53 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
788788

789789
/// Parses clauses for 'declare variant' directive.
790790
/// clause:
791-
/// 'match' '('
792791
/// <selector_set_name> '=' '{' <context_selectors> '}'
793-
/// ')'
794-
static bool parseDeclareVariantClause(Parser &P) {
795-
Token Tok = P.getCurToken();
796-
// Parse 'match'.
797-
if (!Tok.is(tok::identifier) ||
798-
P.getPreprocessor().getSpelling(Tok).compare("match")) {
799-
P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
800-
<< "match";
801-
while (!P.SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
802-
;
803-
return true;
804-
}
805-
(void)P.ConsumeToken();
806-
// Parse '('.
807-
BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
808-
if (T.expectAndConsume(diag::err_expected_lparen_after, "match"))
809-
return true;
810-
// Parse inner context selector.
811-
Tok = P.getCurToken();
812-
if (!Tok.is(tok::identifier)) {
813-
P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
814-
<< "match";
815-
return true;
816-
}
817-
SmallString<16> Buffer;
818-
StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
819-
// Parse '='.
820-
(void)P.ConsumeToken();
821-
Tok = P.getCurToken();
822-
if (Tok.isNot(tok::equal)) {
823-
P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
824-
<< CtxSelectorName;
825-
return true;
826-
}
827-
(void)P.ConsumeToken();
828-
// Unknown selector - just ignore it completely.
829-
{
830-
// Parse '{'.
831-
BalancedDelimiterTracker TBr(P, tok::l_brace, tok::annot_pragma_openmp_end);
832-
if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
792+
/// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
793+
bool Parser::parseOpenMPContextSelectors(
794+
SourceLocation Loc, llvm::function_ref<void(SourceRange)> Callback) {
795+
do {
796+
// Parse inner context selector set name.
797+
if (!Tok.is(tok::identifier)) {
798+
Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector)
799+
<< "match";
833800
return true;
834-
while (!P.SkipUntil(tok::r_brace, tok::r_paren,
835-
tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
836-
;
837-
// Parse '}'.
838-
(void)TBr.consumeClose();
839-
}
840-
// Parse ')'.
841-
(void)T.consumeClose();
842-
// TBD: add parsing of known context selectors.
801+
}
802+
SmallString<16> Buffer;
803+
StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer);
804+
// Parse '='.
805+
(void)ConsumeToken();
806+
if (Tok.isNot(tok::equal)) {
807+
Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
808+
<< CtxSelectorName;
809+
return true;
810+
}
811+
(void)ConsumeToken();
812+
// TBD: add parsing of known context selectors.
813+
// Unknown selector - just ignore it completely.
814+
{
815+
// Parse '{'.
816+
BalancedDelimiterTracker TBr(*this, tok::l_brace,
817+
tok::annot_pragma_openmp_end);
818+
if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
819+
return true;
820+
while (!SkipUntil(tok::r_brace, tok::r_paren,
821+
tok::annot_pragma_openmp_end, StopBeforeMatch))
822+
;
823+
// Parse '}'.
824+
(void)TBr.consumeClose();
825+
}
826+
Callback(SourceRange(Loc, Tok.getLocation()));
827+
// Consume ','
828+
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end))
829+
(void)ExpectAndConsume(tok::comma);
830+
} while (Tok.isAnyIdentifier());
843831
return false;
844832
}
845833

846834
/// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
847-
Parser::DeclGroupPtrTy
848-
Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
849-
CachedTokens &Toks, SourceLocation Loc) {
835+
void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
836+
CachedTokens &Toks,
837+
SourceLocation Loc) {
850838
PP.EnterToken(Tok, /*IsReinject*/ true);
851839
PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
852840
/*IsReinject*/ true);
@@ -868,23 +856,53 @@ Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
868856
;
869857
// Skip the last annot_pragma_openmp_end.
870858
(void)ConsumeAnnotationToken();
871-
return Ptr;
859+
return;
872860
}
861+
Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
862+
Actions.checkOpenMPDeclareVariantFunction(
863+
Ptr, AssociatedFunction.get(), SourceRange(Loc, Tok.getLocation()));
873864

874-
bool IsError = parseDeclareVariantClause(*this);
875-
// Need to check for extra tokens.
876-
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
877-
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
878-
<< getOpenMPDirectiveName(OMPD_declare_variant);
879-
while (Tok.isNot(tok::annot_pragma_openmp_end))
880-
ConsumeAnyToken();
865+
// Parse 'match'.
866+
if (!Tok.is(tok::identifier) || PP.getSpelling(Tok).compare("match")) {
867+
Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
868+
<< "match";
869+
while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
870+
;
871+
// Skip the last annot_pragma_openmp_end.
872+
(void)ConsumeAnnotationToken();
873+
return;
874+
}
875+
(void)ConsumeToken();
876+
// Parse '('.
877+
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
878+
if (T.expectAndConsume(diag::err_expected_lparen_after, "match")) {
879+
while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
880+
;
881+
// Skip the last annot_pragma_openmp_end.
882+
(void)ConsumeAnnotationToken();
883+
return;
884+
}
885+
886+
// Parse inner context selectors.
887+
if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) {
888+
if (DeclVarData.hasValue())
889+
Actions.ActOnOpenMPDeclareVariantDirective(
890+
DeclVarData.getValue().first, DeclVarData.getValue().second, SR);
891+
})) {
892+
// Parse ')'.
893+
(void)T.consumeClose();
894+
// Need to check for extra tokens.
895+
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
896+
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
897+
<< getOpenMPDirectiveName(OMPD_declare_variant);
898+
}
881899
}
900+
901+
// Skip last tokens.
902+
while (Tok.isNot(tok::annot_pragma_openmp_end))
903+
ConsumeAnyToken();
882904
// Skip the last annot_pragma_openmp_end.
883-
SourceLocation EndLoc = ConsumeAnnotationToken();
884-
if (IsError)
885-
return Ptr;
886-
return Actions.ActOnOpenMPDeclareVariantDirective(
887-
Ptr, AssociatedFunction.get(), SourceRange(Loc, EndLoc));
905+
(void)ConsumeAnnotationToken();
888906
}
889907

890908
/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
@@ -1248,7 +1266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
12481266
return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
12491267
assert(DKind == OMPD_declare_variant &&
12501268
"Expected declare variant directive only");
1251-
return ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1269+
ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1270+
return Ptr;
12521271
}
12531272
case OMPD_declare_target: {
12541273
SourceLocation DTLoc = ConsumeAnyToken();

0 commit comments

Comments
 (0)