@@ -788,65 +788,53 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
788
788
789
789
// / Parses clauses for 'declare variant' directive.
790
790
// / clause:
791
- // / 'match' '('
792
791
// / <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" ;
833
800
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 ());
843
831
return false ;
844
832
}
845
833
846
834
// / 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) {
850
838
PP.EnterToken (Tok, /* IsReinject*/ true );
851
839
PP.EnterTokenStream (Toks, /* DisableMacroExpansion=*/ true ,
852
840
/* IsReinject*/ true );
@@ -868,23 +856,53 @@ Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
868
856
;
869
857
// Skip the last annot_pragma_openmp_end.
870
858
(void )ConsumeAnnotationToken ();
871
- return Ptr ;
859
+ return ;
872
860
}
861
+ Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
862
+ Actions.checkOpenMPDeclareVariantFunction (
863
+ Ptr, AssociatedFunction.get (), SourceRange (Loc, Tok.getLocation ()));
873
864
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
+ }
881
899
}
900
+
901
+ // Skip last tokens.
902
+ while (Tok.isNot (tok::annot_pragma_openmp_end))
903
+ ConsumeAnyToken ();
882
904
// 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 ();
888
906
}
889
907
890
908
// / Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
@@ -1248,7 +1266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
1248
1266
return ParseOMPDeclareSimdClauses (Ptr, Toks, Loc);
1249
1267
assert (DKind == OMPD_declare_variant &&
1250
1268
" Expected declare variant directive only" );
1251
- return ParseOMPDeclareVariantClauses (Ptr, Toks, Loc);
1269
+ ParseOMPDeclareVariantClauses (Ptr, Toks, Loc);
1270
+ return Ptr;
1252
1271
}
1253
1272
case OMPD_declare_target: {
1254
1273
SourceLocation DTLoc = ConsumeAnyToken ();
0 commit comments