diff options
| author | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-05-09 14:59:13 +0000 |
|---|---|---|
| committer | Dmitry Polukhin <dmitry.polukhin@gmail.com> | 2016-05-09 14:59:13 +0000 |
| commit | d69b505e3c6728013322cd00e3c18d8badacff51 (patch) | |
| tree | 83ebd3a39bc402044304d291357e08b8e874fd82 /clang/lib | |
| parent | 98f489ce82f250b31a50b0f1475783642e4ad557 (diff) | |
| download | bcm5719-llvm-d69b505e3c6728013322cd00e3c18d8badacff51.tar.gz bcm5719-llvm-d69b505e3c6728013322cd00e3c18d8badacff51.zip | |
[OpenMP] Parse+Sema for '#pragma omp declare target' syntax version 4.5
Support OpenMP version 4.5 syntax for #pragma omp declare target.
Syntax:
#pragma omp declare target (extended-list) new-line
or
#pragma omp declare target clause[ [,] clause ... ] new-line
Where clause is one of the following:
to(extended-list)
link(list)
Differential Revision: http://reviews.llvm.org/D20011
llvm-svn: 268925
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Frontend/MultiplexConsumer.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 97 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 93 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 6 |
5 files changed, 162 insertions, 47 deletions
diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 581ed13ce09..17cdaee4be0 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -125,7 +125,8 @@ public: void FunctionDefinitionInstantiated(const FunctionDecl *D) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; - void DeclarationMarkedOpenMPDeclareTarget(const Decl *D) override; + void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) override; @@ -221,9 +222,9 @@ void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate( Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D); } void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget( - const Decl *D) { + const Decl *D, const Attr *Attr) { for (auto *L : Listeners) - L->DeclarationMarkedOpenMPDeclareTarget(D); + L->DeclarationMarkedOpenMPDeclareTarget(D, Attr); } void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index b1538fde257..5a3b4ac825c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -40,6 +40,21 @@ enum OpenMPDirectiveKindEx { OMPD_target_enter, OMPD_target_exit }; + +class ThreadprivateListParserHelper final { + SmallVector<Expr *, 4> Identifiers; + Parser *P; + +public: + ThreadprivateListParserHelper(Parser *P) : P(P) {} + void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { + ExprResult Res = + P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo); + if (Res.isUsable()) + Identifiers.push_back(Res.get()); + } + llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; } +}; } // namespace // Map token string to extended OMP token kind that are @@ -525,13 +540,13 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ParenBraceBracketBalancer BalancerRAIIObj(*this); SourceLocation Loc = ConsumeToken(); - SmallVector<Expr *, 4> Identifiers; auto DKind = ParseOpenMPDirectiveKind(*this); switch (DKind) { - case OMPD_threadprivate: + case OMPD_threadprivate: { ConsumeToken(); - if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) { + ThreadprivateListParserHelper Helper(this); + if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) { // The last seen token is annot_pragma_openmp_end - need to check for // extra tokens. if (Tok.isNot(tok::annot_pragma_openmp_end)) { @@ -541,9 +556,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( } // Skip the last annot_pragma_openmp_end. ConsumeToken(); - return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers); + return Actions.ActOnOpenMPThreadprivateDirective(Loc, + Helper.getIdentifiers()); } break; + } case OMPD_declare_reduction: ConsumeToken(); if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) { @@ -599,10 +616,40 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_declare_target: { SourceLocation DTLoc = ConsumeAnyToken(); if (Tok.isNot(tok::annot_pragma_openmp_end)) { - Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(OMPD_declare_target); + // OpenMP 4.5 syntax with list of entities. + llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls; + while (Tok.isNot(tok::annot_pragma_openmp_end)) { + OMPDeclareTargetDeclAttr::MapTypeTy MT = + OMPDeclareTargetDeclAttr::MT_To; + if (Tok.is(tok::identifier)) { + IdentifierInfo *II = Tok.getIdentifierInfo(); + StringRef ClauseName = II->getName(); + // Parse 'to|link' clauses. + if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, + MT)) { + Diag(Tok, diag::err_omp_declare_target_unexpected_clause) + << ClauseName; + break; + } + ConsumeToken(); + } + auto Callback = [this, MT, &SameDirectiveDecls]( + CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { + Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT, + SameDirectiveDecls); + }; + if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true)) + break; + + // Consume optional ','. + if (Tok.is(tok::comma)) + ConsumeToken(); + } SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); + ConsumeAnyToken(); + return DeclGroupPtrTy(); } + // Skip the last annot_pragma_openmp_end. ConsumeAnyToken(); @@ -716,7 +763,6 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( AllowedContsructsKind Allowed) { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); ParenBraceBracketBalancer BalancerRAIIObj(*this); - SmallVector<Expr *, 5> Identifiers; SmallVector<OMPClause *, 5> Clauses; SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> FirstClauses(OMPC_unknown + 1); @@ -732,13 +778,14 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( bool FlushHasClause = false; switch (DKind) { - case OMPD_threadprivate: + case OMPD_threadprivate: { if (Allowed != ACK_Any) { Diag(Tok, diag::err_omp_immediate_directive) << getOpenMPDirectiveName(DKind) << 0; } ConsumeToken(); - if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) { + ThreadprivateListParserHelper Helper(this); + if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) { // The last seen token is annot_pragma_openmp_end - need to check for // extra tokens. if (Tok.isNot(tok::annot_pragma_openmp_end)) { @@ -746,12 +793,13 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( << getOpenMPDirectiveName(OMPD_threadprivate); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } - DeclGroupPtrTy Res = - Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers); + DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective( + Loc, Helper.getIdentifiers()); Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); } SkipUntil(tok::annot_pragma_openmp_end); break; + } case OMPD_declare_reduction: ConsumeToken(); if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) { @@ -913,16 +961,15 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( return Directive; } -/// \brief Parses list of simple variables for '#pragma omp threadprivate' -/// directive. -/// -/// simple-variable-list: -/// '(' id-expression {, id-expression} ')' -/// -bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, - SmallVectorImpl<Expr *> &VarList, - bool AllowScopeSpecifier) { - VarList.clear(); +// Parses simple list: +// simple-variable-list: +// '(' id-expression {, id-expression} ')' +// +bool Parser::ParseOpenMPSimpleVarList( + OpenMPDirectiveKind Kind, + const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> & + Callback, + bool AllowScopeSpecifier) { // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, @@ -959,11 +1006,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, << tok::identifier << SourceRange(PrevTok.getLocation(), PrevTokLocation); } else { - DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name); - ExprResult Res = - Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo); - if (Res.isUsable()) - VarList.push_back(Res.get()); + Callback(SS, Actions.GetNameFromUnqualifiedId(Name)); } // Consume ','. if (Tok.is(tok::comma)) { @@ -979,7 +1022,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, // Parse ')'. IsCorrect = !T.consumeClose() && IsCorrect; - return !IsCorrect && VarList.empty(); + return !IsCorrect; } /// \brief Parsing of OpenMP clauses. diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index cbcf70b41fc..ea26f6a4f16 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1101,6 +1101,23 @@ public: return false; } }; + +class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { +private: + Sema &SemaRef; + +public: + explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} + bool ValidateCandidate(const TypoCorrection &Candidate) override { + NamedDecl *ND = Candidate.getCorrectionDecl(); + if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { + return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), + SemaRef.getCurScope()); + } + return false; + } +}; + } // namespace ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, @@ -10752,6 +10769,52 @@ void Sema::ActOnFinishOpenMPDeclareTargetDirective() { IsInOpenMPDeclareTargetContext = false; } +void +Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id, + OMPDeclareTargetDeclAttr::MapTypeTy MT, + NamedDeclSetType &SameDirectiveDecls) { + LookupResult Lookup(*this, Id, LookupOrdinaryName); + LookupParsedName(Lookup, CurScope, &ScopeSpec, true); + + if (Lookup.isAmbiguous()) + return; + Lookup.suppressDiagnostics(); + + if (!Lookup.isSingleResult()) { + if (TypoCorrection Corrected = + CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, + llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), + CTK_ErrorRecovery)) { + diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) + << Id.getName()); + checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); + return; + } + + Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); + return; + } + + NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); + if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { + if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) + Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); + + if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); + ND->addAttr(A); + if (ASTMutationListener *ML = Context.getASTMutationListener()) + ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); + checkDeclIsAllowedInOpenMPTarget(nullptr, ND); + } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { + Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) + << Id.getName(); + } + } else + Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); +} + static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D) { if (!D) @@ -10765,9 +10828,11 @@ static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, // If this is an implicit variable that is legal and we do not need to do // anything. if (cast<VarDecl>(D)->isImplicit()) { - D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( + SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); + D->addAttr(A); if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) - ML->DeclarationMarkedOpenMPDeclareTarget(D); + ML->DeclarationMarkedOpenMPDeclareTarget(D, A); return; } @@ -10780,9 +10845,11 @@ static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, // target region (it can be e.g. a lambda) that is legal and we do not need // to do anything else. if (LD == D) { - D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( + SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); + D->addAttr(A); if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) - ML->DeclarationMarkedOpenMPDeclareTarget(D); + ML->DeclarationMarkedOpenMPDeclareTarget(D, A); return; } } @@ -10810,9 +10877,11 @@ static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, SemaRef.Diag(SL, diag::note_used_here) << SR; } // Mark decl as declared target to prevent further diagnostic. - D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( + SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); + D->addAttr(A); if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) - ML->DeclarationMarkedOpenMPDeclareTarget(D); + ML->DeclarationMarkedOpenMPDeclareTarget(D, A); } } @@ -10846,9 +10915,11 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { // Mark decl as declared target to prevent further diagnostic. if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { - VD->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( + Context, OMPDeclareTargetDeclAttr::MT_To); + VD->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) - ML->DeclarationMarkedOpenMPDeclareTarget(VD); + ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); } return; } @@ -10857,9 +10928,11 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { // Checking declaration inside declare target region. if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { - D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); + Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( + Context, OMPDeclareTargetDeclAttr::MT_To); + D->addAttr(A); if (ASTMutationListener *ML = Context.getASTMutationListener()) - ML->DeclarationMarkedOpenMPDeclareTarget(D); + ML->DeclarationMarkedOpenMPDeclareTarget(D, A); } return; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 1a013cee219..6b933f2bba1 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3890,11 +3890,6 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, Reader.Context, ReadSourceRange(Record, Idx))); break; - case UPD_DECL_MARKED_OPENMP_DECLARETARGET: - D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit( - Reader.Context, ReadSourceRange(Record, Idx))); - break; - case UPD_DECL_EXPORTED: { unsigned SubmoduleID = readSubmoduleID(Record, Idx); auto *Exported = cast<NamedDecl>(D); @@ -3920,6 +3915,7 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, break; } + case UPD_DECL_MARKED_OPENMP_DECLARETARGET: case UPD_ADDED_ATTR_TO_RECORD: AttrVec Attrs; Reader.ReadAttributes(F, Attrs, Record, Idx); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 606228af753..29a20b2e45e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -5816,12 +5816,14 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE)); } -void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D) { +void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) { assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) return; - DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET)); + DeclUpdates[D].push_back( + DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET, Attr)); } void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) { |

