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 | ef440caa0d55f6add3fdf23a55ebaa5e98ded541 (patch) | |
tree | 55496050bf317df093d86e69d22628457d4038e9 /lib/Parse/ParseOpenMP.cpp | |
parent | 36fa0d71c9d8086b7b53d0fa6eb60da8e3af11db (diff) | |
download | clang-ef440caa0d55f6add3fdf23a55ebaa5e98ded541.tar.gz |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374093 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseOpenMP.cpp')
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index e487e0ab65..f667b83b58 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/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(); } |