diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 |
commit | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (patch) | |
tree | a1fd89b864d9b93e2ad68fe1dcf7afee2e3c8d76 /clang/lib/Parse/ParseOpenMP.cpp | |
parent | 77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (diff) | |
download | src-6f8fc217eaa12bf657be1c6468ed9938d10168b3.tar.gz src-6f8fc217eaa12bf657be1c6468ed9938d10168b3.zip |
Diffstat (limited to 'clang/lib/Parse/ParseOpenMP.cpp')
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 122 |
1 files changed, 96 insertions, 26 deletions
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 300b022d83b9..8ad5edb1bcd6 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/UniqueVector.h" +#include "llvm/Frontend/OpenMP/OMPAssume.h" #include "llvm/Frontend/OpenMP/OMPContext.h" using namespace clang; @@ -469,8 +470,8 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { SourceLocation LParLoc = T.getOpenLocation(); auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() { QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(), - OmpPrivParm->getLocation(), Exprs, LParLoc); + OmpPrivParm->getType()->getCanonicalTypeInternal(), + OmpPrivParm->getLocation(), Exprs, LParLoc, /*Braced=*/false); CalledSignatureHelp = true; return PreferredType; }; @@ -1813,38 +1814,55 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { void Parser::ParseOMPDeclareTargetClauses( Sema::DeclareTargetContextInfo &DTCI) { SourceLocation DeviceTypeLoc; - bool RequiresToOrLinkClause = false; - bool HasToOrLinkClause = false; + bool RequiresToOrLinkOrIndirectClause = false; + bool HasToOrLinkOrIndirectClause = false; while (Tok.isNot(tok::annot_pragma_openmp_end)) { OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To; bool HasIdentifier = Tok.is(tok::identifier); if (HasIdentifier) { // If we see any clause we need a to or link clause. - RequiresToOrLinkClause = true; + RequiresToOrLinkOrIndirectClause = true; IdentifierInfo *II = Tok.getIdentifierInfo(); StringRef ClauseName = II->getName(); bool IsDeviceTypeClause = getLangOpts().OpenMP >= 50 && getOpenMPClauseKind(ClauseName) == OMPC_device_type; + bool IsIndirectClause = getLangOpts().OpenMP >= 51 && + getOpenMPClauseKind(ClauseName) == OMPC_indirect; + if (DTCI.Indirect.hasValue() && IsIndirectClause) { + Diag(Tok, diag::err_omp_more_one_clause) + << getOpenMPDirectiveName(OMPD_declare_target) + << getOpenMPClauseName(OMPC_indirect) << 0; + break; + } bool IsToOrLinkClause = OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT); assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!"); - if (!IsDeviceTypeClause && DTCI.Kind == OMPD_begin_declare_target) { + if (!IsDeviceTypeClause && !IsIndirectClause && + DTCI.Kind == OMPD_begin_declare_target) { Diag(Tok, diag::err_omp_declare_target_unexpected_clause) - << ClauseName << 0; + << ClauseName << (getLangOpts().OpenMP >= 51 ? 3 : 0); break; } - if (!IsDeviceTypeClause && !IsToOrLinkClause) { + if (!IsDeviceTypeClause && !IsToOrLinkClause && !IsIndirectClause) { Diag(Tok, diag::err_omp_declare_target_unexpected_clause) - << ClauseName << (getLangOpts().OpenMP >= 50 ? 2 : 1); + << ClauseName + << (getLangOpts().OpenMP >= 51 ? 4 + : getLangOpts().OpenMP >= 50 ? 2 + : 1); break; } - if (IsToOrLinkClause) - HasToOrLinkClause = true; + if (IsToOrLinkClause || IsIndirectClause) + HasToOrLinkOrIndirectClause = true; + if (IsIndirectClause) { + if (!ParseOpenMPIndirectClause(DTCI, /*ParseOnly*/ false)) + break; + continue; + } // Parse 'device_type' clause and go to next clause if any. if (IsDeviceTypeClause) { Optional<SimpleClauseData> DevTypeData = @@ -1910,10 +1928,14 @@ void Parser::ParseOMPDeclareTargetClauses( ConsumeToken(); } + if (DTCI.Indirect.hasValue() && DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any) + Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type); + // For declare target require at least 'to' or 'link' to be present. - if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkClause && - !HasToOrLinkClause) - Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause); + if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause && + !HasToOrLinkOrIndirectClause) + Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause) + << (getLangOpts().OpenMP >= 51 ? 1 : 0); SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } @@ -2188,12 +2210,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( VariantMatchInfo VMI; TI.getAsVariantMatchInfo(ASTCtx, VMI); - std::function<void(StringRef)> DiagUnknownTrait = [this, Loc]( - StringRef ISATrait) { - // TODO Track the selector locations in a way that is accessible here to - // improve the diagnostic location. - Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait; - }; + std::function<void(StringRef)> DiagUnknownTrait = + [this, Loc](StringRef ISATrait) { + // TODO Track the selector locations in a way that is accessible here + // to improve the diagnostic location. + Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait; + }; TargetOMPContext OMPCtx( ASTCtx, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, @@ -2282,11 +2304,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_declare_target: { SourceLocation DTLoc = ConsumeAnyToken(); bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end); - bool HasImplicitMappings = - DKind == OMPD_begin_declare_target || !HasClauses; Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc); if (HasClauses) ParseOMPDeclareTargetClauses(DTCI); + bool HasImplicitMappings = + DKind == OMPD_begin_declare_target || !HasClauses || + (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect.hasValue()); // Skip the last annot_pragma_openmp_end. ConsumeAnyToken(); @@ -2528,7 +2551,13 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { TPA.Revert(); // End of the first iteration. Parser is reset to the start of metadirective - TargetOMPContext OMPCtx(ASTContext, /* DiagUnknownTrait */ nullptr, + std::function<void(StringRef)> DiagUnknownTrait = + [this, Loc](StringRef ISATrait) { + // TODO Track the selector locations in a way that is accessible here + // to improve the diagnostic location. + Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait; + }; + TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, ArrayRef<llvm::omp::TraitProperty>()); @@ -2936,7 +2965,7 @@ bool Parser::ParseOpenMPSimpleVarList( if (AllowScopeSpecifier && getLangOpts().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, false)) { + /*ObjectHasErrors=*/false, false)) { IsCorrect = false; SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -3383,6 +3412,47 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); } +/// Parse indirect clause for '#pragma omp declare target' directive. +/// 'indirect' '[' '(' invoked-by-fptr ')' ']' +/// where invoked-by-fptr is a constant boolean expression that evaluates to +/// true or false at compile time. +bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI, + bool ParseOnly) { + SourceLocation Loc = ConsumeToken(); + SourceLocation RLoc; + + if (Tok.isNot(tok::l_paren)) { + if (ParseOnly) + return false; + DTCI.Indirect = nullptr; + return true; + } + + ExprResult Val = + ParseOpenMPParensExpr(getOpenMPClauseName(OMPC_indirect), RLoc); + if (Val.isInvalid()) + return false; + + if (ParseOnly) + return false; + + if (!Val.get()->isValueDependent() && !Val.get()->isTypeDependent() && + !Val.get()->isInstantiationDependent() && + !Val.get()->containsUnexpandedParameterPack()) { + ExprResult Ret = Actions.CheckBooleanCondition(Loc, Val.get()); + if (Ret.isInvalid()) + return false; + llvm::APSInt Result; + Ret = Actions.VerifyIntegerConstantExpression(Val.get(), &Result, + Sema::AllowFold); + if (Ret.isInvalid()) + return false; + DTCI.Indirect = Val.get(); + return true; + } + return false; +} + /// Parsing of OpenMP clauses that use an interop-var. /// /// init-clause: @@ -3817,7 +3887,7 @@ bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) { if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); @@ -4050,7 +4120,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); InvalidReductionId = ParseReductionId( *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId); |