diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2019-10-08 17:47:52 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-10-08 17:47:52 +0000 |
| commit | 70d2e5427ed31889456fac933c3e596b4bb5a762 (patch) | |
| tree | dcfe2df9dc95b4378d98eb75885b73c7eb5f4708 /clang/lib/Parse/ParseOpenMP.cpp | |
| parent | 190a17bbd1c24f677ba0fdca6df97d9cd208e131 (diff) | |
| download | bcm5719-llvm-70d2e5427ed31889456fac933c3e596b4bb5a762.tar.gz bcm5719-llvm-70d2e5427ed31889456fac933c3e596b4bb5a762.zip | |
[OPENMP50]Do not allow multiple same context traits in the same context
selector.
According to OpenMP 5.0, 2.3.2 Context Selectors, Restrictions, each
trait-selector-name can only be specified once. Added check for this
restriction.
llvm-svn: 374093
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index e487e0ab652..f667b83b583 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -815,7 +815,7 @@ static ExprResult parseContextScore(Parser &P) { /// 'vendor' '(' [ 'score' '(' <score _expr> ')' ':' ] <vendor> { ',' <vendor> } /// ')' static void parseImplementationSelector( - Parser &P, SourceLocation Loc, + Parser &P, SourceLocation Loc, llvm::StringMap<SourceLocation> &UsedCtx, llvm::function_ref<void(SourceRange, const Sema::OpenMPDeclareVariantCtsSelectorData &)> Callback) { @@ -832,6 +832,15 @@ static void parseImplementationSelector( } SmallString<16> Buffer; StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer); + auto Res = UsedCtx.try_emplace(CtxSelectorName, Tok.getLocation()); + if (!Res.second) { + // OpenMP 5.0, 2.3.2 Context Selectors, Restrictions. + // Each trait-selector-name can only be specified once. + P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_ctx_mutiple_use) + << CtxSelectorName << "implementation"; + P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here) + << CtxSelectorName; + } OMPDeclareVariantAttr::CtxSelectorType CSKind = OMPDeclareVariantAttr::CtxUnknown; (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName, @@ -932,17 +941,25 @@ bool Parser::parseOpenMPContextSelectors( OMPDeclareVariantAttr::CtxSetUnknown; (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType( CtxSelectorSetName, CSSKind); - switch (CSSKind) { - case OMPDeclareVariantAttr::CtxSetImplementation: - parseImplementationSelector(*this, Loc, Callback); - 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; - } + llvm::StringMap<SourceLocation> UsedCtx; + do { + switch (CSSKind) { + case OMPDeclareVariantAttr::CtxSetImplementation: + parseImplementationSelector(*this, Loc, UsedCtx, Callback); + 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; + } + const Token PrevTok = Tok; + if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace)) + Diag(Tok, diag::err_omp_expected_comma_brace) + << (PrevTok.isAnnotation() ? "context selector trait" + : PP.getSpelling(PrevTok)); + } while (Tok.is(tok::identifier)); // Parse '}'. (void)TBr.consumeClose(); } |

