diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 572e62249b46f..757873fd6d414 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -9475,6 +9475,7 @@ class ConstOMPClauseVisitor : class OMPClausePrinter final : public OMPClauseVisitor { raw_ostream &OS; const PrintingPolicy &Policy; + unsigned Version; /// Process clauses with list of variables. template void VisitOMPClauseList(T *Node, char StartSym); @@ -9482,8 +9483,9 @@ class OMPClausePrinter final : public OMPClauseVisitor { template void VisitOMPMotionClause(T *Node); public: - OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) - : OS(OS), Policy(Policy) {} + OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy, + unsigned OpenMPVersion) + : OS(OS), Policy(Policy), Version(OpenMPVersion) {} #define GEN_CLANG_CLAUSE_CLASS #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 22da5bf251ecd..3616419dce4ec 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1827,7 +1827,7 @@ void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { Out << ")"; } if (!D->clauselist_empty()) { - OMPClausePrinter Printer(Out, Policy); + OMPClausePrinter Printer(Out, Policy, Context.getLangOpts().OpenMP); for (OMPClause *C : D->clauselists()) { Out << " "; Printer.Visit(C); @@ -1838,7 +1838,7 @@ void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { Out << "#pragma omp requires "; if (!D->clauselist_empty()) { - OMPClausePrinter Printer(Out, Policy); + OMPClausePrinter Printer(Out, Policy, Context.getLangOpts().OpenMP); for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) Printer.Visit(*I); } @@ -1891,7 +1891,7 @@ void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { Out << D->getVarName(); Out << ")"; if (!D->clauselist_empty()) { - OMPClausePrinter Printer(Out, Policy); + OMPClausePrinter Printer(Out, Policy, Context.getLangOpts().OpenMP); for (auto *C : D->clauselists()) { Out << " "; Printer.Visit(C); diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 2226791a70b6e..c1682888934e5 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1821,7 +1821,7 @@ OMPThreadLimitClause *OMPThreadLimitClause::CreateEmpty(const ASTContext &C, void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) { OS << "if("; if (Node->getNameModifier() != OMPD_unknown) - OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": "; + OS << getOpenMPDirectiveName(Node->getNameModifier(), Version) << ": "; Node->getCondition()->printPretty(OS, nullptr, Policy, 0); OS << ")"; } @@ -2049,7 +2049,7 @@ void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) { for (auto &D : Node->getDirectiveKinds()) { if (!First) OS << ", "; - OS << getOpenMPDirectiveName(D); + OS << getOpenMPDirectiveName(D, Version); First = false; } OS << ")"; @@ -2067,7 +2067,7 @@ void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) { for (auto &D : Node->getDirectiveKinds()) { if (!First) OS << ", "; - OS << getOpenMPDirectiveName(D); + OS << getOpenMPDirectiveName(D, Version); First = false; } OS << ")"; diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index c6c49c6c1ba4d..dc8af1586624b 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -737,7 +737,9 @@ void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) { void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, bool ForceNoStmt) { - OMPClausePrinter Printer(OS, Policy); + unsigned OpenMPVersion = + Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion; + OMPClausePrinter Printer(OS, Policy, OpenMPVersion); ArrayRef Clauses = S->clauses(); for (auto *Clause : Clauses) if (Clause && !Clause->isImplicit()) { @@ -964,14 +966,18 @@ void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { void StmtPrinter::VisitOMPCancellationPointDirective( OMPCancellationPointDirective *Node) { + unsigned OpenMPVersion = + Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion; Indent() << "#pragma omp cancellation point " - << getOpenMPDirectiveName(Node->getCancelRegion()); + << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion); PrintOMPExecutableDirective(Node); } void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { + unsigned OpenMPVersion = + Context ? Context->getLangOpts().OpenMP : llvm::omp::FallbackVersion; Indent() << "#pragma omp cancel " - << getOpenMPDirectiveName(Node->getCancelRegion()); + << getOpenMPDirectiveName(Node->getCancelRegion(), OpenMPVersion); PrintOMPExecutableDirective(Node); } diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7b90861c78de0..a451fc7c01841 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -850,7 +850,8 @@ void clang::getOpenMPCaptureRegions( case OMPD_master: return false; default: - llvm::errs() << getOpenMPDirectiveName(LKind) << '\n'; + llvm::errs() << getOpenMPDirectiveName(LKind, llvm::omp::FallbackVersion) + << '\n'; llvm_unreachable("Unexpected directive"); } return false; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 8d8698e61216f..4f87d6c74b251 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -288,11 +288,12 @@ static DeclarationName parseOpenMPReductionId(Parser &P) { /// Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume( diag::err_expected_lparen_after, - getOpenMPDirectiveName(OMPD_declare_reduction).data())) { + getOpenMPDirectiveName(OMPD_declare_reduction, OMPVersion).data())) { SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); return DeclGroupPtrTy(); } @@ -540,10 +541,12 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) { bool IsCorrect = true; + unsigned OMPVersion = Actions.getLangOpts().OpenMP; // Parse '(' BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); - if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPDirectiveName(OMPD_declare_mapper).data())) { + if (T.expectAndConsume( + diag::err_expected_lparen_after, + getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion).data())) { SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); return DeclGroupPtrTy(); } @@ -626,7 +629,7 @@ Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) { } if (Clauses.empty()) { Diag(Tok, diag::err_omp_expected_clause) - << getOpenMPDirectiveName(OMPD_declare_mapper); + << getOpenMPDirectiveName(OMPD_declare_mapper, OMPVersion); IsCorrect = false; } @@ -745,8 +748,10 @@ static bool parseDeclareSimdClauses( P.ConsumeToken(); } else if (ClauseName == "simdlen") { if (SimdLen.isUsable()) { + unsigned OMPVersion = P.getActions().getLangOpts().OpenMP; P.Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0; + << getOpenMPDirectiveName(OMPD_declare_simd, OMPVersion) + << ClauseName << 0; IsError = true; } P.ConsumeToken(); @@ -1404,6 +1409,7 @@ bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) { void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, CachedTokens &Toks, SourceLocation Loc) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; PP.EnterToken(Tok, /*IsReinject*/ true); PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, /*IsReinject*/ true); @@ -1423,7 +1429,7 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated); AssociatedFunction = ParseOpenMPParensExpr( - getOpenMPDirectiveName(OMPD_declare_variant), RLoc, + getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion), RLoc, /*IsAddressOfOperand=*/true); } if (!AssociatedFunction.isUsable()) { @@ -1483,7 +1489,7 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, case OMPC_append_args: if (!AppendArgs.empty()) { Diag(AppendArgsLoc, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(OMPD_declare_variant) + << getOpenMPDirectiveName(OMPD_declare_variant, OMPVersion) << getOpenMPClauseName(CKind) << 0; IsError = true; } @@ -1740,8 +1746,9 @@ void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind, bool NextIsLPar = Tok.is(tok::l_paren); // Handle unknown clauses by skipping them. if (Idx == -1) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id) - << llvm::omp::getOpenMPDirectiveName(DKind) + << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion) << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar; if (NextIsLPar) SkipBraces(II ? II->getName() : "", /* IssueNote */ true); @@ -1854,8 +1861,9 @@ void Parser::ParseOMPDeclareTargetClauses( bool IsIndirectClause = getLangOpts().OpenMP >= 51 && getOpenMPClauseKind(ClauseName) == OMPC_indirect; if (DTCI.Indirect && IsIndirectClause) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(OMPD_declare_target) + << getOpenMPDirectiveName(OMPD_declare_target, OMPVersion) << getOpenMPClauseName(OMPC_indirect) << 0; break; } @@ -1988,8 +1996,9 @@ void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) { if (Tok.is(tok::annot_pragma_openmp_end)) return; + unsigned OMPVersion = Actions.getLangOpts().OpenMP; Diag(Tok, diag::warn_omp_extra_tokens_at_eol) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); while (Tok.isNot(tok::annot_pragma_openmp_end)) ConsumeAnyToken(); } @@ -2008,10 +2017,12 @@ void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind, return; } + unsigned OMPVersion = Actions.getLangOpts().OpenMP; Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant) << DiagSelection; Diag(BeginLoc, diag::note_matching) - << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str(); + << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind, OMPVersion) + "'") + .str(); if (SkipUntilOpenMPEnd) SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); } @@ -2070,6 +2081,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( "Not an OpenMP directive!"); ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); + unsigned OMPVersion = Actions.getLangOpts().OpenMP; SourceLocation Loc; OpenMPDirectiveKind DKind; @@ -2163,7 +2175,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( llvm::SmallBitVector SeenClauses(llvm::omp::Clause_enumSize + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) - << getOpenMPDirectiveName(OMPD_requires); + << getOpenMPDirectiveName(OMPD_requires, OMPVersion); break; } while (Tok.isNot(tok::annot_pragma_openmp_end)) { @@ -2190,7 +2202,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( // Consume final annot_pragma_openmp_end if (Clauses.empty()) { Diag(Tok, diag::err_omp_expected_clause) - << getOpenMPDirectiveName(OMPD_requires); + << getOpenMPDirectiveName(OMPD_requires, OMPVersion); ConsumeAnnotationToken(); return nullptr; } @@ -2378,7 +2390,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_end_declare_target: { if (!Actions.OpenMP().isInOpenMPDeclareTargetContext()) { Diag(Tok, diag::err_omp_unexpected_directive) - << 1 << getOpenMPDirectiveName(DKind); + << 1 << getOpenMPDirectiveName(DKind, OMPVersion); break; } const SemaOpenMP::DeclareTargetContextInfo &DTCI = @@ -2388,7 +2400,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( } case OMPD_assume: { Diag(Tok, diag::err_omp_unexpected_directive) - << 1 << getOpenMPDirectiveName(DKind); + << 1 << getOpenMPDirectiveName(DKind, OMPVersion); break; } case OMPD_unknown: @@ -2401,7 +2413,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case Category::Subsidiary: case Category::Utility: Diag(Tok, diag::err_omp_unexpected_directive) - << 1 << getOpenMPDirectiveName(DKind); + << 1 << getOpenMPDirectiveName(DKind, OMPVersion); break; case Category::Declarative: case Category::Informational: @@ -2418,6 +2430,7 @@ StmtResult Parser::ParseOpenMPExecutableDirective( ParsedStmtContext StmtCtx, OpenMPDirectiveKind DKind, SourceLocation Loc, bool ReadDirectiveWithinMetadirective) { assert(isOpenMPExecutableDirective(DKind) && "Unexpected directive category"); + unsigned OMPVersion = Actions.getLangOpts().OpenMP; bool HasAssociatedStatement = true; Association Assoc = getDirectiveAssociation(DKind); @@ -2431,7 +2444,7 @@ StmtResult Parser::ParseOpenMPExecutableDirective( if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Tok, diag::err_omp_immediate_directive) - << getOpenMPDirectiveName(DKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) << 0; if (DKind == OMPD_error) { SkipUntil(tok::annot_pragma_openmp_end); return StmtError(); @@ -2541,7 +2554,8 @@ StmtResult Parser::ParseOpenMPExecutableDirective( if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) - << getOpenMPDirectiveName(DKind) << 1 << getOpenMPClauseName(CK); + << getOpenMPDirectiveName(DKind, OMPVersion) << 1 + << getOpenMPClauseName(CK); } HasAssociatedStatement = false; } @@ -2551,7 +2565,7 @@ StmtResult Parser::ParseOpenMPExecutableDirective( if ((DKind == OMPD_tile || DKind == OMPD_stripe) && !SeenClauses[unsigned(OMPC_sizes)]) { Diag(Loc, diag::err_omp_required_clause) - << getOpenMPDirectiveName(DKind) << "sizes"; + << getOpenMPDirectiveName(DKind, OMPVersion) << "sizes"; } StmtResult AssociatedStmt; @@ -2707,6 +2721,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( SourceLocation Loc = ReadDirectiveWithinMetadirective ? Tok.getLocation() : ConsumeAnnotationToken(); + unsigned OMPVersion = Actions.getLangOpts().OpenMP; OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this); if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) { Diag(Tok, diag::err_omp_unknown_directive); @@ -2909,7 +2924,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Tok, diag::err_omp_immediate_directive) - << getOpenMPDirectiveName(DKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) << 0; } ConsumeToken(); DeclDirectiveListParserHelper Helper(this, DKind); @@ -2928,7 +2943,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Tok, diag::err_omp_immediate_directive) - << getOpenMPDirectiveName(DKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) << 0; } ConsumeToken(); DeclDirectiveListParserHelper Helper(this, DKind); @@ -3001,7 +3016,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( if (HasImplicitMappings) { Diag(Tok, diag::err_omp_unexpected_directive) - << 1 << getOpenMPDirectiveName(DKind); + << 1 << getOpenMPDirectiveName(DKind, OMPVersion); SkipUntil(tok::annot_pragma_openmp_end); break; } @@ -3020,7 +3035,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( case OMPD_end_declare_variant: case OMPD_declare_variant: Diag(Tok, diag::err_omp_unexpected_directive) - << 1 << getOpenMPDirectiveName(DKind); + << 1 << getOpenMPDirectiveName(DKind, OMPVersion); SkipUntil(tok::annot_pragma_openmp_end); break; case OMPD_assume: { @@ -3049,10 +3064,11 @@ bool Parser::ParseOpenMPSimpleVarList( const llvm::function_ref &Callback, bool AllowScopeSpecifier) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPDirectiveName(Kind).data())) + getOpenMPDirectiveName(Kind, OMPVersion).data())) return true; bool IsCorrect = true; bool NoIdentIsFound = true; @@ -3205,11 +3221,14 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OMPClause *Clause = nullptr; bool ErrorFound = false; bool WrongDirective = false; + unsigned OMPVersion = Actions.getLangOpts().OpenMP; + // Check if clause is allowed for the given directive. if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) { Diag(Tok, diag::err_omp_unexpected_clause) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); ErrorFound = true; WrongDirective = true; } @@ -3264,7 +3283,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // At most one message clause can appear on the directive if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -3298,7 +3318,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // At most one bind clause can appear on a loop directive. if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -3320,7 +3341,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) && (CKind != OMPC_order || getLangOpts().OpenMP >= 51) && !FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } [[fallthrough]]; @@ -3359,7 +3381,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // Each of the requires clauses can appear at most once on the directive. if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -3369,12 +3392,13 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // OpenMP [6.0, self_maps clause] if (getLangOpts().OpenMP < 60) { Diag(Tok, diag::err_omp_expected_clause) - << getOpenMPDirectiveName(OMPD_requires); + << getOpenMPDirectiveName(OMPD_requires, OMPVersion); ErrorFound = true; } if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } Clause = ParseOpenMPClause(CKind, WrongDirective); @@ -3382,7 +3406,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_update: if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -3394,7 +3419,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_thread_limit: if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } [[fallthrough]]; @@ -3433,7 +3459,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_sizes: if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } @@ -3442,7 +3469,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_permutation: if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } Clause = ParseOpenMPPermutationClause(); @@ -3454,7 +3482,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, if (DKind != OMPD_interop) { if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } Clause = ParseOpenMPClause(CKind, WrongDirective); @@ -3474,7 +3503,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_match: if (!WrongDirective) Diag(Tok, diag::err_omp_unexpected_clause) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); break; case OMPC_absent: @@ -3490,7 +3520,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, if (DK == OMPD_unknown) { skipUntilPragmaOpenMPEnd(OMPD_assume); Diag(Tok, diag::err_omp_unexpected_clause) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); break; } if (isOpenMPExecutableDirective(DK)) { @@ -3498,7 +3529,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, ConsumeToken(); } else { Diag(Tok, diag::err_omp_unexpected_clause) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); } } while (TryConsumeToken(tok::comma)); RLoc = Tok.getLocation(); @@ -3513,7 +3545,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_no_parallelism: { if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; + << getOpenMPDirectiveName(DKind, OMPVersion) + << getOpenMPClauseName(CKind) << 0; ErrorFound = true; } SourceLocation Loc = ConsumeToken(); @@ -3531,7 +3564,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, // to explicitly check whether this clause is applied to an `omp target` // without `teams` and emit an error. Diag(Tok, diag::err_omp_unexpected_clause) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); ErrorFound = true; WrongDirective = true; } @@ -3540,7 +3574,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, << getOpenMPClauseName(CKind) << "target teams"; if (!ErrorFound && !getLangOpts().OpenMPExtensions) { Diag(Tok, diag::err_omp_unexpected_clause_extension_only) - << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + << getOpenMPClauseName(CKind) + << getOpenMPDirectiveName(DKind, OMPVersion); ErrorFound = true; } Clause = ParseOpenMPClause(CKind, WrongDirective); @@ -5077,11 +5112,14 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, ConsumeToken(); else if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end) && - (!MayHaveTail || Tok.isNot(tok::colon))) + (!MayHaveTail || Tok.isNot(tok::colon))) { + unsigned OMPVersion = Actions.getLangOpts().OpenMP; Diag(Tok, diag::err_omp_expected_punc) - << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush) - : getOpenMPClauseName(Kind)) + << ((Kind == OMPC_flush) + ? getOpenMPDirectiveName(OMPD_flush, OMPVersion) + : getOpenMPClauseName(Kind)) << (Kind == OMPC_flush); + } } // Parse ')' for linear clause with modifier. diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 835dba22a858d..49aaceebcdba5 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3069,6 +3069,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind) { ASTContext &Context = getASTContext(); + unsigned OMPVersion = getLangOpts().OpenMP; LookupResult Lookup(SemaRef, Id, Sema::LookupOrdinaryName); SemaRef.LookupParsedName(Lookup, CurScope, &ScopeSpec, /*ObjectType=*/QualType(), @@ -3106,7 +3107,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, // Variables must be file-scope, namespace-scope, or static block-scope. if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { Diag(Id.getLoc(), diag::err_omp_global_var_arg) - << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); + << getOpenMPDirectiveName(Kind, OMPVersion) << !VD->isStaticLocal(); bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3123,7 +3124,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (CanonicalVD->getDeclContext()->isTranslationUnit() && !SemaRef.getCurLexicalContext()->isTranslationUnit()) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(Kind) << VD; + << getOpenMPDirectiveName(Kind, OMPVersion) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3138,7 +3139,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (CanonicalVD->isStaticDataMember() && !CanonicalVD->getDeclContext()->Equals(SemaRef.getCurLexicalContext())) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(Kind) << VD; + << getOpenMPDirectiveName(Kind, OMPVersion) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3155,7 +3156,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, !SemaRef.getCurLexicalContext()->Encloses( CanonicalVD->getDeclContext()))) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(Kind) << VD; + << getOpenMPDirectiveName(Kind, OMPVersion) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3169,7 +3170,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (CanonicalVD->isLocalVarDecl() && CurScope && !SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), CurScope)) { Diag(Id.getLoc(), diag::err_omp_var_scope) - << getOpenMPDirectiveName(Kind) << VD; + << getOpenMPDirectiveName(Kind, OMPVersion) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3184,7 +3185,7 @@ ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope, if (Kind == OMPD_threadprivate && VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { Diag(Id.getLoc(), diag::err_omp_var_used) - << getOpenMPDirectiveName(Kind) << VD; + << getOpenMPDirectiveName(Kind, OMPVersion) << VD; return ExprError(); } @@ -3266,8 +3267,10 @@ SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc, // OpenMP [2.9.2, Restrictions, C/C++, p.10] // A threadprivate variable must not have a reference type. if (VD->getType()->isReferenceType()) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(ILoc, diag::err_omp_ref_type_arg) - << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); + << getOpenMPDirectiveName(OMPD_threadprivate, OMPVersion) + << VD->getType(); bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), @@ -3513,10 +3516,12 @@ void SemaOpenMP::ActOnOpenMPAssumesDirective(SourceLocation Loc, OpenMPDirectiveKind DKind, ArrayRef Assumptions, bool SkippedClauses) { - if (!SkippedClauses && Assumptions.empty()) + if (!SkippedClauses && Assumptions.empty()) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(Loc, diag::err_omp_no_clause_for_directive) << llvm::omp::getAllAssumeClauseOptions() - << llvm::omp::getOpenMPDirectiveName(DKind); + << llvm::omp::getOpenMPDirectiveName(DKind, OMPVersion); + } auto *AA = OMPAssumeAttr::Create(getASTContext(), llvm::join(Assumptions, ","), Loc); @@ -3664,9 +3669,10 @@ static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, Reason = PDSA_LocalVarPrivate; } if (Reason != PDSA_Implicit) { + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) << Reason << ReportHint - << getOpenMPDirectiveName(Stack->getCurrentDirective()); + << getOpenMPDirectiveName(Stack->getCurrentDirective(), OMPVersion); } else if (DVar.ImplicitDSALoc.isValid()) { SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) << getOpenMPClauseNameForDiag(DVar.CKind); @@ -4683,8 +4689,9 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S, if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && OC->getNumForLoops()) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), OMPVersion); ErrorFound = true; } if (ErrorFound) { @@ -4764,8 +4771,9 @@ static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) return false; + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) - << getOpenMPDirectiveName(CancelRegion); + << getOpenMPDirectiveName(CancelRegion, OMPVersion); return true; } @@ -4796,17 +4804,18 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, ArrayRef ParentLOC = getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite); OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back(); + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; - if (SemaRef.LangOpts.OpenMP >= 50 && Stack->isParentOrderConcurrent() && + if (OMPVersion >= 50 && Stack->isParentOrderConcurrent() && !isOpenMPOrderConcurrentNestableDirective(CurrentRegion, SemaRef.LangOpts)) { SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order) - << getOpenMPDirectiveName(CurrentRegion); + << getOpenMPDirectiveName(CurrentRegion, OMPVersion); return true; } if (isOpenMPSimdDirective(ParentRegion) && - ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || - (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && + ((OMPVersion <= 45 && CurrentRegion != OMPD_ordered) || + (OMPVersion >= 50 && CurrentRegion != OMPD_ordered && CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && CurrentRegion != OMPD_scan))) { // OpenMP [2.16, Nesting of Regions] @@ -4824,7 +4833,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) ? diag::err_omp_prohibited_region_simd : diag::warn_omp_nesting_simd) - << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); + << (OMPVersion >= 50 ? 1 : 0); return CurrentRegion != OMPD_simd; } if (EnclosingConstruct == OMPD_atomic) { @@ -4841,7 +4850,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, if (EnclosingConstruct != OMPD_sections) { SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) << (ParentRegion != OMPD_unknown) - << getOpenMPDirectiveName(ParentRegion); + << getOpenMPDirectiveName(ParentRegion, OMPVersion); return true; } return false; @@ -4856,14 +4865,14 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, return false; // Checks needed for mapping "loop" construct. Please check mapLoopConstruct // for a detailed explanation - if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop && + if (OMPVersion >= 50 && CurrentRegion == OMPD_loop && (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) && (isOpenMPWorksharingDirective(ParentRegion) || EnclosingConstruct == OMPD_loop)) { int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4; SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) - << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber - << getOpenMPDirectiveName(CurrentRegion); + << true << getOpenMPDirectiveName(ParentRegion, OMPVersion) + << ErrorMsgNumber << getOpenMPDirectiveName(CurrentRegion, OMPVersion); return true; } if (CurrentRegion == OMPD_cancellation_point || @@ -4881,9 +4890,9 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, // construct-type-clause. ArrayRef Leafs = getLeafConstructsOrSelf(ParentRegion); if (CancelRegion == OMPD_taskgroup) { - NestingProhibited = EnclosingConstruct != OMPD_task && - (SemaRef.getLangOpts().OpenMP < 50 || - EnclosingConstruct != OMPD_taskloop); + NestingProhibited = + EnclosingConstruct != OMPD_task && + (OMPVersion < 50 || EnclosingConstruct != OMPD_taskloop); } else if (CancelRegion == OMPD_sections) { NestingProhibited = EnclosingConstruct != OMPD_section && EnclosingConstruct != OMPD_sections; @@ -4969,13 +4978,13 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, // If specified, a teams construct must be contained within a target // construct. NestingProhibited = - (SemaRef.LangOpts.OpenMP <= 45 && EnclosingConstruct != OMPD_target) || - (SemaRef.LangOpts.OpenMP >= 50 && EnclosingConstruct != OMPD_unknown && + (OMPVersion <= 45 && EnclosingConstruct != OMPD_target) || + (OMPVersion >= 50 && EnclosingConstruct != OMPD_unknown && EnclosingConstruct != OMPD_target); OrphanSeen = ParentRegion == OMPD_unknown; Recommend = ShouldBeInTargetRegion; } else if (CurrentRegion == OMPD_scan) { - if (SemaRef.LangOpts.OpenMP >= 50) { + if (OMPVersion >= 50) { // OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for, // simd, or for simd. This has to take into account combined directives. // In 5.2 this seems to be implied by the fact that the specified @@ -5045,11 +5054,11 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, if (NestingProhibited) { if (OrphanSeen) { SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) - << getOpenMPDirectiveName(CurrentRegion) << Recommend; + << getOpenMPDirectiveName(CurrentRegion, OMPVersion) << Recommend; } else { SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) - << CloseNesting << getOpenMPDirectiveName(OffendingRegion) - << Recommend << getOpenMPDirectiveName(CurrentRegion); + << CloseNesting << getOpenMPDirectiveName(OffendingRegion, OMPVersion) + << Recommend << getOpenMPDirectiveName(CurrentRegion, OMPVersion); } return true; } @@ -5068,6 +5077,7 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, llvm::IndexedMap FoundNameModifiers; FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); SmallVector NameModifierLoc; + unsigned OMPVersion = S.getLangOpts().OpenMP; for (const OMPClause *C : Clauses) { if (const auto *IC = dyn_cast_or_null(C)) { // At most one if clause without a directive-name-modifier can appear on @@ -5076,9 +5086,9 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, auto &FNM = FoundNameModifiers[CurNM]; if (FNM) { S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(Kind) + << getOpenMPDirectiveName(Kind, OMPVersion) << getOpenMPClauseNameForDiag(OMPC_if) << (CurNM != OMPD_unknown) - << getOpenMPDirectiveName(CurNM); + << getOpenMPDirectiveName(CurNM, OMPVersion); ErrorFound = true; } else if (CurNM != OMPD_unknown) { NameModifierLoc.push_back(IC->getNameModifierLoc()); @@ -5094,7 +5104,8 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { S.Diag(IC->getNameModifierLoc(), diag::err_omp_wrong_if_directive_name_modifier) - << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); + << getOpenMPDirectiveName(CurNM, OMPVersion) + << getOpenMPDirectiveName(Kind, OMPVersion); ErrorFound = true; } } @@ -5116,7 +5127,7 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; if (!FoundNameModifiers[NM]) { Values += "'"; - Values += getOpenMPDirectiveName(NM); + Values += getOpenMPDirectiveName(NM, OMPVersion); Values += "'"; if (AllowedCnt + 2 == TotalAllowedNum) Values += " or "; @@ -5320,9 +5331,10 @@ static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { + unsigned OMPVersion = S.getLangOpts().OpenMP; S.Diag(AC->getAllocator()->getExprLoc(), diag::warn_omp_allocate_thread_on_task_target_directive) - << getOpenMPDirectiveName(Stack->getCurrentDirective()); + << getOpenMPDirectiveName(Stack->getCurrentDirective(), OMPVersion); } for (Expr *E : AC->varlist()) { SourceLocation ELoc; @@ -9138,9 +9150,10 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && (DVar.CKind != OMPC_private || DVar.RefExpr)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) << getOpenMPClauseNameForDiag(DVar.CKind) - << getOpenMPDirectiveName(DKind) + << getOpenMPDirectiveName(DKind, OMPVersion) << getOpenMPClauseNameForDiag(PredeterminedCKind); if (DVar.RefExpr == nullptr) DVar.CKind = PredeterminedCKind; @@ -9195,9 +9208,10 @@ static bool checkOpenMPIterationSpace( auto *CXXFor = dyn_cast_or_null(S); // Ranged for is supported only in OpenMP 5.0. if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) - << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount + << getOpenMPDirectiveName(DKind, OMPVersion) << TotalNestedLoopCount << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; if (TotalNestedLoopCount > 1) { if (CollapseLoopCountExpr && OrderedLoopCountExpr) @@ -10482,6 +10496,7 @@ static bool checkSectionsDirective(Sema &SemaRef, OpenMPDirectiveKind DKind, return true; assert(isa(AStmt) && "Captured statement expected"); + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; auto BaseStmt = AStmt; while (auto *CS = dyn_cast_or_null(BaseStmt)) BaseStmt = CS->getCapturedStmt(); @@ -10496,7 +10511,7 @@ static bool checkSectionsDirective(Sema &SemaRef, OpenMPDirectiveKind DKind, if (SectionStmt) SemaRef.Diag(SectionStmt->getBeginLoc(), diag::err_omp_sections_substmt_not_section) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); return true; } cast(SectionStmt) @@ -10504,7 +10519,7 @@ static bool checkSectionsDirective(Sema &SemaRef, OpenMPDirectiveKind DKind, } } else { SemaRef.Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); return true; } return false; @@ -10609,8 +10624,9 @@ static bool checkGenericLoopLastprivate(Sema &S, ArrayRef Clauses, if (ValueDecl *D = Res.first) { auto &&Info = Stack->isLoopControlVariable(D); if (!Info.first) { + unsigned OMPVersion = S.getLangOpts().OpenMP; S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) - << getOpenMPDirectiveName(K); + << getOpenMPDirectiveName(K, OMPVersion); ErrorFound = true; } } @@ -11114,6 +11130,7 @@ StmtResult SemaOpenMP::ActOnOpenMPFlushDirective(ArrayRef Clauses, else OrderClause = C; } + unsigned OMPVersion = getLangOpts().OpenMP; OpenMPClauseKind MemOrderKind = OMPC_unknown; SourceLocation MemOrderLoc; for (const OMPClause *C : Clauses) { @@ -11123,7 +11140,7 @@ StmtResult SemaOpenMP::ActOnOpenMPFlushDirective(ArrayRef Clauses, C->getClauseKind() == OMPC_seq_cst /*OpenMP 5.1*/) { if (MemOrderKind != OMPC_unknown) { Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) - << getOpenMPDirectiveName(OMPD_flush) << 1 + << getOpenMPDirectiveName(OMPD_flush, OMPVersion) << 1 << SourceRange(C->getBeginLoc(), C->getEndLoc()); Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) << getOpenMPClauseNameForDiag(MemOrderKind); @@ -11178,9 +11195,11 @@ StmtResult SemaOpenMP::ActOnOpenMPScanDirective(ArrayRef Clauses, if (Scope *S = DSAStack->getCurScope()) { Scope *ParentS = S->getParent(); if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || - !ParentS->getBreakParent()->isOpenMPLoopScope()) + !ParentS->getBreakParent()->isOpenMPLoopScope()) { + unsigned OMPVersion = getLangOpts().OpenMP; return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) - << getOpenMPDirectiveName(OMPD_scan) << 5); + << getOpenMPDirectiveName(OMPD_scan, OMPVersion) << 5); + } } // Check that only one instance of scan directives is used in the same outer // region. @@ -11218,8 +11237,9 @@ SemaOpenMP::ActOnOpenMPOrderedDirective(ArrayRef Clauses, if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) || (DOC && (ODK.isSource(DOC)))) { if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) - << getOpenMPDirectiveName(OMPD_ordered) + << getOpenMPDirectiveName(OMPD_ordered, OMPVersion) << getOpenMPClauseNameForDiag(DC ? OMPC_depend : OMPC_doacross) << 2; ErrorFound = true; @@ -12374,6 +12394,7 @@ StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef Clauses, SourceLocation StartLoc, SourceLocation EndLoc) { ASTContext &Context = getASTContext(); + unsigned OMPVersion = getLangOpts().OpenMP; // Register location of the first atomic directive. DSAStack->addAtomicDirectiveLoc(StartLoc); if (!AStmt) @@ -12433,7 +12454,7 @@ StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef Clauses, case OMPC_relaxed: { if (MemOrderKind != OMPC_unknown) { Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) - << getOpenMPDirectiveName(OMPD_atomic) << 0 + << getOpenMPDirectiveName(OMPD_atomic, OMPVersion) << 0 << SourceRange(C->getBeginLoc(), C->getEndLoc()); Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) << getOpenMPClauseNameForDiag(MemOrderKind); @@ -13091,8 +13112,9 @@ SemaOpenMP::ActOnOpenMPTargetDataDirective(ArrayRef Clauses, Expected = "'map' or 'use_device_ptr'"; else Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; + unsigned OMPVersion = getLangOpts().OpenMP; Diag(StartLoc, diag::err_omp_no_clause_for_directive) - << Expected << getOpenMPDirectiveName(OMPD_target_data); + << Expected << getOpenMPDirectiveName(OMPD_target_data, OMPVersion); return StmtError(); } @@ -13113,8 +13135,10 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetEnterDataDirective( // OpenMP [2.10.2, Restrictions, p. 99] // At least one map clause must appear on the directive. if (!hasClauses(Clauses, OMPC_map)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(StartLoc, diag::err_omp_no_clause_for_directive) - << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); + << "'map'" + << getOpenMPDirectiveName(OMPD_target_enter_data, OMPVersion); return StmtError(); } @@ -13133,8 +13157,9 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetExitDataDirective( // OpenMP [2.10.3, Restrictions, p. 102] // At least one map clause must appear on the directive. if (!hasClauses(Clauses, OMPC_map)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(StartLoc, diag::err_omp_no_clause_for_directive) - << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); + << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data, OMPVersion); return StmtError(); } @@ -17097,9 +17122,10 @@ SemaOpenMP::ActOnOpenMPInteropDirective(ArrayRef Clauses, // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] // At least one action-clause must appear on a directive. if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { + unsigned OMPVersion = getLangOpts().OpenMP; StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; Diag(StartLoc, diag::err_omp_no_clause_for_directive) - << Expected << getOpenMPDirectiveName(OMPD_interop); + << Expected << getOpenMPDirectiveName(OMPD_interop, OMPVersion); return StmtError(); } @@ -17266,9 +17292,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation EndLoc) { if (!InteropVar && getLangOpts().OpenMP >= 52 && DSAStack->getCurrentDirective() == OMPD_depobj) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(StartLoc, diag::err_omp_expected_clause_argument) << getOpenMPClauseNameForDiag(OMPC_destroy) - << getOpenMPDirectiveName(OMPD_depobj); + << getOpenMPDirectiveName(OMPD_depobj, OMPVersion); return nullptr; } if (InteropVar && @@ -17610,6 +17637,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPPrivateClause(ArrayRef VarList, SourceLocation EndLoc) { SmallVector Vars; SmallVector PrivateCopies; + unsigned OMPVersion = getLangOpts().OpenMP; bool IsImplicitClause = StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); for (Expr *RefExpr : VarList) { @@ -17671,7 +17699,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPPrivateClause(ArrayRef VarList, isOpenMPTaskingDirective(CurrDir)) { Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) << getOpenMPClauseNameForDiag(OMPC_private) << Type - << getOpenMPDirectiveName(CurrDir); + << getOpenMPDirectiveName(CurrDir, OMPVersion); bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) == VarDecl::DeclarationOnly; Diag(D->getLocation(), @@ -17702,7 +17730,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPPrivateClause(ArrayRef VarList, Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) << getOpenMPClauseNameForDiag(OMPC_private) << getOpenMPClauseNameForDiag(ConflictKind) - << getOpenMPDirectiveName(CurrDir); + << getOpenMPDirectiveName(CurrDir, OMPVersion); reportOriginalDsa(SemaRef, DSAStack, D, DVar); continue; } @@ -17764,6 +17792,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPFirstprivateClause(ArrayRef VarList, bool IsImplicitClause = StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); + unsigned OMPVersion = getLangOpts().OpenMP; for (Expr *RefExpr : VarList) { assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); @@ -17905,7 +17934,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPFirstprivateClause(ArrayRef VarList, isOpenMPWorksharingDirective(DVar.DKind) || isOpenMPTeamsDirective(DVar.DKind))) { Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) - << getOpenMPDirectiveName(DVar.DKind); + << getOpenMPDirectiveName(DVar.DKind, OMPVersion); reportOriginalDsa(SemaRef, DSAStack, D, DVar); continue; } @@ -17934,7 +17963,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPFirstprivateClause(ArrayRef VarList, Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) << getOpenMPClauseNameForDiag(OMPC_firstprivate) << getOpenMPClauseNameForDiag(ConflictKind) - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), + OMPVersion); reportOriginalDsa(SemaRef, DSAStack, D, DVar); continue; } @@ -17946,7 +17976,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPFirstprivateClause(ArrayRef VarList, isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) << getOpenMPClauseNameForDiag(OMPC_firstprivate) << Type - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), + OMPVersion); bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) == VarDecl::DeclarationOnly; Diag(D->getLocation(), @@ -19999,9 +20030,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPCopyinClause(ArrayRef VarList, // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] // A list item that appears in a copyin clause must be threadprivate. if (!DSAStack->isThreadPrivate(VD)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(ELoc, diag::err_omp_required_access) << getOpenMPClauseNameForDiag(OMPC_copyin) - << getOpenMPDirectiveName(OMPD_threadprivate); + << getOpenMPDirectiveName(OMPD_threadprivate, OMPVersion); continue; } @@ -20108,9 +20140,11 @@ OMPClause *SemaOpenMP::ActOnOpenMPCopyprivateClause(ArrayRef VarList, // Variably modified types are not supported. if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) << getOpenMPClauseNameForDiag(OMPC_copyprivate) << Type - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), + OMPVersion); bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) == VarDecl::DeclarationOnly; Diag(D->getLocation(), @@ -21682,6 +21716,7 @@ static void checkMappableExpressionList( // We only expect mappable expressions in 'to', 'from', and 'map' clauses. assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && "Unexpected clause kind with mappable expressions!"); + unsigned OMPVersion = SemaRef.getLangOpts().OpenMP; // If the identifier of user-defined mapper is not specified, it is "default". // We do not change the actual name in this clause to distinguish whether a @@ -21886,7 +21921,7 @@ static void checkMappableExpressionList( SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) << (IsMapTypeImplicit ? 1 : 0) << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); continue; } @@ -21901,7 +21936,7 @@ static void checkMappableExpressionList( SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) << (IsMapTypeImplicit ? 1 : 0) << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); continue; } @@ -21916,7 +21951,7 @@ static void checkMappableExpressionList( diag::err_omp_invalid_map_type_modifier_for_directive) << getOpenMPSimpleClauseTypeName(OMPC_map, OMPC_MAP_MODIFIER_ompx_hold) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); continue; } @@ -21931,7 +21966,7 @@ static void checkMappableExpressionList( SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) << (IsMapTypeImplicit ? 1 : 0) << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) - << getOpenMPDirectiveName(DKind); + << getOpenMPDirectiveName(DKind, OMPVersion); continue; } @@ -21951,7 +21986,8 @@ static void checkMappableExpressionList( SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) << getOpenMPClauseNameForDiag(DVar.CKind) << getOpenMPClauseNameForDiag(OMPC_map) - << getOpenMPDirectiveName(DSAS->getCurrentDirective()); + << getOpenMPDirectiveName(DSAS->getCurrentDirective(), + OMPVersion); reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); continue; } @@ -22890,8 +22926,9 @@ void SemaOpenMP::DiagnoseUnterminatedOpenMPDeclareTarget() { if (DeclareTargetNesting.empty()) return; DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); + unsigned OMPVersion = getLangOpts().OpenMP; Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) - << getOpenMPDirectiveName(DTCI.Kind); + << getOpenMPDirectiveName(DTCI.Kind, OMPVersion); } NamedDecl *SemaOpenMP::lookupOpenMPDeclareTargetName( @@ -23406,10 +23443,12 @@ SemaOpenMP::ActOnOpenMPIsDevicePtrClause(ArrayRef VarList, // sharing attribute. DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); if (isOpenMPPrivate(DVar.CKind)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) << getOpenMPClauseNameForDiag(DVar.CKind) << getOpenMPClauseNameForDiag(OMPC_is_device_ptr) - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), + OMPVersion); reportOriginalDsa(SemaRef, DSAStack, D, DVar); continue; } @@ -23482,10 +23521,12 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef VarList, // sharing attribute. DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); if (isOpenMPPrivate(DVar.CKind)) { + unsigned OMPVersion = getLangOpts().OpenMP; Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) << getOpenMPClauseNameForDiag(DVar.CKind) << getOpenMPClauseNameForDiag(OMPC_has_device_addr) - << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); + << getOpenMPDirectiveName(DSAStack->getCurrentDirective(), + OMPVersion); reportOriginalDsa(SemaRef, DSAStack, D, DVar); continue; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 8b4b79c6ec039..0af897ad9a540 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9581,8 +9581,9 @@ template StmtResult TreeTransform::TransformOMPMetaDirective(OMPMetaDirective *D) { // TODO: Fix This + unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP; SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported) - << getOpenMPDirectiveName(D->getDirectiveKind()); + << getOpenMPDirectiveName(D->getDirectiveKind(), OMPVersion); return StmtError(); } diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index dbbf86a6c6151..bf66151d59950 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -267,8 +267,9 @@ void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) { "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";"; } void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) { - clauseDetails += - "name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";"; + clauseDetails += "name_modifier=" + + llvm::omp::getOpenMPDirectiveName(c.v, llvm::omp::FallbackVersion).str() + + ";"; } void OpenMPCounterVisitor::Post(const OmpClause &c) { PostClauseCommon(normalize_clause_name(c.source.ToString())); diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index a3721bc8410ba..df9278697346f 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -17,6 +17,7 @@ #include "flang/Common/idioms.h" #include "flang/Common/indirection.h" #include "flang/Support/Fortran.h" +#include "llvm/Frontend/OpenMP/OMP.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -545,8 +546,8 @@ class ParseTreeDumper { NODE(parser, OmpBeginSectionsDirective) NODE(parser, OmpBlockDirective) static std::string GetNodeName(const llvm::omp::Directive &x) { - return llvm::Twine( - "llvm::omp::Directive = ", llvm::omp::getOpenMPDirectiveName(x)) + return llvm::Twine("llvm::omp::Directive = ", + llvm::omp::getOpenMPDirectiveName(x, llvm::omp::FallbackVersion)) .str(); } NODE(parser, OmpClause) diff --git a/flang/include/flang/Parser/unparse.h b/flang/include/flang/Parser/unparse.h index 40094ecbc85e5..d796109ca8f86 100644 --- a/flang/include/flang/Parser/unparse.h +++ b/flang/include/flang/Parser/unparse.h @@ -18,6 +18,10 @@ namespace llvm { class raw_ostream; } +namespace Fortran::common { +class LangOptions; +} + namespace Fortran::evaluate { struct GenericExprWrapper; struct GenericAssignmentWrapper; @@ -47,15 +51,18 @@ struct AnalyzedObjectsAsFortran { // Converts parsed program (or fragment) to out as Fortran. template void Unparse(llvm::raw_ostream &out, const A &root, - Encoding encoding = Encoding::UTF_8, bool capitalizeKeywords = true, - bool backslashEscapes = true, preStatementType *preStatement = nullptr, + const common::LangOptions &langOpts, Encoding encoding = Encoding::UTF_8, + bool capitalizeKeywords = true, bool backslashEscapes = true, + preStatementType *preStatement = nullptr, AnalyzedObjectsAsFortran * = nullptr); extern template void Unparse(llvm::raw_ostream &out, const Program &program, - Encoding encoding, bool capitalizeKeywords, bool backslashEscapes, + const common::LangOptions &langOpts, Encoding encoding, + bool capitalizeKeywords, bool backslashEscapes, preStatementType *preStatement, AnalyzedObjectsAsFortran *); extern template void Unparse(llvm::raw_ostream &out, const Expr &expr, - Encoding encoding, bool capitalizeKeywords, bool backslashEscapes, + const common::LangOptions &langOpts, Encoding encoding, + bool capitalizeKeywords, bool backslashEscapes, preStatementType *preStatement, AnalyzedObjectsAsFortran *); } // namespace Fortran::parser diff --git a/flang/include/flang/Semantics/unparse-with-symbols.h b/flang/include/flang/Semantics/unparse-with-symbols.h index 5e18b3fc3063d..702911bbab627 100644 --- a/flang/include/flang/Semantics/unparse-with-symbols.h +++ b/flang/include/flang/Semantics/unparse-with-symbols.h @@ -16,6 +16,10 @@ namespace llvm { class raw_ostream; } +namespace Fortran::common { +class LangOptions; +} + namespace Fortran::parser { struct Program; } @@ -23,6 +27,7 @@ struct Program; namespace Fortran::semantics { class SemanticsContext; void UnparseWithSymbols(llvm::raw_ostream &, const parser::Program &, + const common::LangOptions &, parser::Encoding encoding = parser::Encoding::UTF_8); void UnparseWithModules(llvm::raw_ostream &, SemanticsContext &, const parser::Program &, diff --git a/flang/lib/Frontend/ParserActions.cpp b/flang/lib/Frontend/ParserActions.cpp index cc7e72f696f96..4fe575b06d29f 100644 --- a/flang/lib/Frontend/ParserActions.cpp +++ b/flang/lib/Frontend/ParserActions.cpp @@ -119,7 +119,7 @@ void debugUnparseNoSema(CompilerInstance &ci, llvm::raw_ostream &out) { auto &parseTree{ci.getParsing().parseTree()}; // TODO: Options should come from CompilerInvocation - Unparse(out, *parseTree, + Unparse(out, *parseTree, ci.getInvocation().getLangOpts(), /*encoding=*/parser::Encoding::UTF_8, /*capitalizeKeywords=*/true, /*backslashEscapes=*/false, /*preStatement=*/nullptr, @@ -131,6 +131,7 @@ void debugUnparseWithSymbols(CompilerInstance &ci) { auto &parseTree{*ci.getParsing().parseTree()}; semantics::UnparseWithSymbols(llvm::outs(), parseTree, + ci.getInvocation().getLangOpts(), /*encoding=*/parser::Encoding::UTF_8); } diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 3d3f26f06da26..593c9f478c73e 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -196,9 +196,11 @@ void ClauseProcessor::processTODO(mlir::Location currentLocation, auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; + unsigned version = semaCtx.langOptions().OpenMPVersion; TODO(currentLocation, "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + - " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + + " in " + + llvm::omp::getOpenMPDirectiveName(directive, version).upper() + " construct"); }; diff --git a/flang/lib/Lower/OpenMP/Decomposer.cpp b/flang/lib/Lower/OpenMP/Decomposer.cpp index 33568bf96b5df..251cba9204adc 100644 --- a/flang/lib/Lower/OpenMP/Decomposer.cpp +++ b/flang/lib/Lower/OpenMP/Decomposer.cpp @@ -70,7 +70,7 @@ struct ConstructDecomposition { namespace Fortran::lower::omp { LLVM_DUMP_METHOD llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const UnitConstruct &uc) { - os << llvm::omp::getOpenMPDirectiveName(uc.id); + os << llvm::omp::getOpenMPDirectiveName(uc.id, llvm::omp::FallbackVersion); for (auto [index, clause] : llvm::enumerate(uc.clauses)) { os << (index == 0 ? '\t' : ' '); os << llvm::omp::getOpenMPClauseName(clause.id); diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 099d5c604060f..efdf5c6f545fe 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -3751,9 +3751,11 @@ static void genOMPDispatch(lower::AbstractConverter &converter, item); break; case llvm::omp::Directive::OMPD_tile: - case llvm::omp::Directive::OMPD_unroll: + case llvm::omp::Directive::OMPD_unroll: { + unsigned version = semaCtx.langOptions().OpenMPVersion; TODO(loc, "Unhandled loop directive (" + - llvm::omp::getOpenMPDirectiveName(dir) + ")"); + llvm::omp::getOpenMPDirectiveName(dir, version) + ")"); + } // case llvm::omp::Directive::OMPD_workdistribute: case llvm::omp::Directive::OMPD_workshare: newOp = genWorkshareOp(converter, symTable, stmtCtx, semaCtx, eval, loc, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index c4728e0fabe61..ffee57144f7fb 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -125,7 +125,8 @@ OmpDirectiveNameParser::directives() const { void OmpDirectiveNameParser::initTokens(NameWithId *table) const { for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) { auto id{static_cast(i)}; - llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id)}; + llvm::StringRef name{ + llvm::omp::getOpenMPDirectiveName(id, llvm::omp::FallbackVersion)}; table[i] = std::make_pair(name.str(), id); } // Sort the table with respect to the directive name length in a descending diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp index 5839e7862b38b..3dd87ad9a3650 100644 --- a/flang/lib/Parser/parse-tree.cpp +++ b/flang/lib/Parser/parse-tree.cpp @@ -11,6 +11,7 @@ #include "flang/Common/indirection.h" #include "flang/Parser/tools.h" #include "flang/Parser/user-state.h" +#include "llvm/Frontend/OpenMP/OMP.h" #include "llvm/Support/raw_ostream.h" #include @@ -305,7 +306,9 @@ std::string OmpTraitSelectorName::ToString() const { return std::string(EnumToString(v)); }, [&](llvm::omp::Directive d) { - return llvm::omp::getOpenMPDirectiveName(d).str(); + return llvm::omp::getOpenMPDirectiveName( + d, llvm::omp::FallbackVersion) + .str(); }, [&](const std::string &s) { // return s; diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 1ee9096fcda56..a626888b7dfe5 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -17,6 +17,7 @@ #include "flang/Parser/parse-tree.h" #include "flang/Parser/tools.h" #include "flang/Support/Fortran.h" +#include "flang/Support/LangOptions.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -27,12 +28,14 @@ namespace Fortran::parser { class UnparseVisitor { public: - UnparseVisitor(llvm::raw_ostream &out, int indentationAmount, - Encoding encoding, bool capitalize, bool backslashEscapes, - preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran) - : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding}, - capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes}, - preStatement_{preStatement}, asFortran_{asFortran} {} + UnparseVisitor(llvm::raw_ostream &out, const common::LangOptions &langOpts, + int indentationAmount, Encoding encoding, bool capitalize, + bool backslashEscapes, preStatementType *preStatement, + AnalyzedObjectsAsFortran *asFortran) + : out_{out}, langOpts_{langOpts}, indentationAmount_{indentationAmount}, + encoding_{encoding}, capitalizeKeywords_{capitalize}, + backslashEscapes_{backslashEscapes}, preStatement_{preStatement}, + asFortran_{asFortran} {} // In nearly all cases, this code avoids defining Boolean-valued Pre() // callbacks for the parse tree walking framework in favor of two void @@ -2102,7 +2105,8 @@ class UnparseVisitor { Walk(":", std::get>(x.t)); } void Unparse(const llvm::omp::Directive &x) { - Word(llvm::omp::getOpenMPDirectiveName(x).str()); + unsigned ompVersion{langOpts_.OpenMPVersion}; + Word(llvm::omp::getOpenMPDirectiveName(x, ompVersion).str()); } void Unparse(const OmpDirectiveSpecification &x) { auto unparseArgs{[&]() { @@ -2167,7 +2171,8 @@ class UnparseVisitor { x.u); } void Unparse(const OmpDirectiveNameModifier &x) { - Word(llvm::omp::getOpenMPDirectiveName(x.v)); + unsigned ompVersion{langOpts_.OpenMPVersion}; + Word(llvm::omp::getOpenMPDirectiveName(x.v, ompVersion)); } void Unparse(const OmpIteratorSpecifier &x) { Walk(std::get(x.t)); @@ -3249,6 +3254,7 @@ class UnparseVisitor { } llvm::raw_ostream &out_; + const common::LangOptions &langOpts_; int indent_{0}; const int indentationAmount_{1}; int column_{1}; @@ -3341,17 +3347,20 @@ void UnparseVisitor::Word(const std::string_view &str) { } template -void Unparse(llvm::raw_ostream &out, const A &root, Encoding encoding, +void Unparse(llvm::raw_ostream &out, const A &root, + const common::LangOptions &langOpts, Encoding encoding, bool capitalizeKeywords, bool backslashEscapes, preStatementType *preStatement, AnalyzedObjectsAsFortran *asFortran) { - UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, backslashEscapes, - preStatement, asFortran}; + UnparseVisitor visitor{out, langOpts, 1, encoding, capitalizeKeywords, + backslashEscapes, preStatement, asFortran}; Walk(root, visitor); visitor.Done(); } -template void Unparse(llvm::raw_ostream &, const Program &, Encoding, - bool, bool, preStatementType *, AnalyzedObjectsAsFortran *); -template void Unparse(llvm::raw_ostream &, const Expr &, Encoding, bool, - bool, preStatementType *, AnalyzedObjectsAsFortran *); +template void Unparse(llvm::raw_ostream &, const Program &, + const common::LangOptions &, Encoding, bool, bool, preStatementType *, + AnalyzedObjectsAsFortran *); +template void Unparse(llvm::raw_ostream &, const Expr &, + const common::LangOptions &, Encoding, bool, bool, preStatementType *, + AnalyzedObjectsAsFortran *); } // namespace Fortran::parser diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index f17de42ca2466..f2c1197097f09 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2434,8 +2434,7 @@ void OmpStructureChecker::Enter( break; default: context_.Say(dirName.source, "%s is not a cancellable construct"_err_en_US, - parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(dirName.v).str())); + parser::ToUpperCaseLetters(getDirectiveName(dirName.v).str())); break; } } @@ -2468,7 +2467,7 @@ std::optional OmpStructureChecker::GetCancelType( // Given clauses from CANCEL or CANCELLATION_POINT, identify the construct // to which the cancellation applies. std::optional cancelee; - llvm::StringRef cancelName{llvm::omp::getOpenMPDirectiveName(cancelDir)}; + llvm::StringRef cancelName{getDirectiveName(cancelDir)}; for (const parser::OmpClause &clause : maybeClauses->v) { using CancellationConstructType = @@ -2496,7 +2495,7 @@ std::optional OmpStructureChecker::GetCancelType( void OmpStructureChecker::CheckCancellationNest( const parser::CharBlock &source, llvm::omp::Directive type) { - llvm::StringRef typeName{llvm::omp::getOpenMPDirectiveName(type)}; + llvm::StringRef typeName{getDirectiveName(type)}; if (CurrentDirectiveIsNested()) { // If construct-type-clause is taskgroup, the cancellation construct must be @@ -4002,10 +4001,10 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { if (auto *dnm{OmpGetUniqueModifier( modifiers)}) { llvm::omp::Directive sub{dnm->v}; - std::string subName{parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(sub).str())}; - std::string dirName{parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(dir).str())}; + std::string subName{ + parser::ToUpperCaseLetters(getDirectiveName(sub).str())}; + std::string dirName{ + parser::ToUpperCaseLetters(getDirectiveName(dir).str())}; parser::CharBlock modifierSource{OmpGetModifierSource(modifiers, dnm)}; auto desc{OmpGetDescriptor()}; @@ -5348,7 +5347,8 @@ llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) { llvm::StringRef OmpStructureChecker::getDirectiveName( llvm::omp::Directive directive) { - return llvm::omp::getOpenMPDirectiveName(directive); + unsigned version{context_.langOptions().OpenMPVersion}; + return llvm::omp::getOpenMPDirectiveName(directive, version); } const Symbol *OmpStructureChecker::GetObjectSymbol( diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp index ee356e56e4458..12fc553518cfd 100644 --- a/flang/lib/Semantics/mod-file.cpp +++ b/flang/lib/Semantics/mod-file.cpp @@ -50,7 +50,7 @@ static void CollectSymbols( const Scope &, SymbolVector &, SymbolVector &, SourceOrderedSymbolSet &); static void PutPassName(llvm::raw_ostream &, const std::optional &); static void PutInit(llvm::raw_ostream &, const Symbol &, const MaybeExpr &, - const parser::Expr *); + const parser::Expr *, SemanticsContext &); static void PutInit(llvm::raw_ostream &, const MaybeIntExpr &); static void PutBound(llvm::raw_ostream &, const Bound &); static void PutShapeSpec(llvm::raw_ostream &, const ShapeSpec &); @@ -605,7 +605,7 @@ void ModFileWriter::PutDECStructure( } decls_ << ref->name(); PutShape(decls_, object->shape(), '(', ')'); - PutInit(decls_, *ref, object->init(), nullptr); + PutInit(decls_, *ref, object->init(), nullptr, context_); emittedDECFields_.insert(*ref); } else if (any) { break; // any later use of this structure will use RECORD/str/ @@ -944,7 +944,8 @@ void ModFileWriter::PutObjectEntity( getSymbolAttrsToWrite(symbol)); PutShape(os, details.shape(), '(', ')'); PutShape(os, details.coshape(), '[', ']'); - PutInit(os, symbol, details.init(), details.unanalyzedPDTComponentInit()); + PutInit(os, symbol, details.init(), details.unanalyzedPDTComponentInit(), + context_); os << '\n'; if (auto tkr{GetIgnoreTKR(symbol)}; !tkr.empty()) { os << "!dir$ ignore_tkr("; @@ -1036,11 +1037,11 @@ void ModFileWriter::PutTypeParam(llvm::raw_ostream &os, const Symbol &symbol) { } void PutInit(llvm::raw_ostream &os, const Symbol &symbol, const MaybeExpr &init, - const parser::Expr *unanalyzed) { + const parser::Expr *unanalyzed, SemanticsContext &context) { if (IsNamedConstant(symbol) || symbol.owner().IsDerivedType()) { const char *assign{symbol.attrs().test(Attr::POINTER) ? "=>" : "="}; if (unanalyzed) { - parser::Unparse(os << assign, *unanalyzed); + parser::Unparse(os << assign, *unanalyzed, context.langOptions()); } else if (init) { init->AsFortran(os << assign); } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 8b1caca34a6a7..60531538e6d59 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1887,6 +1887,7 @@ std::int64_t OmpAttributeVisitor::GetAssociatedLoopLevelFromClauses( // construct with multiple associated do-loops are lastprivate. void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel( const parser::OpenMPLoopConstruct &x) { + unsigned version{context_.langOptions().OpenMPVersion}; std::int64_t level{GetContext().associatedLoopLevel}; if (level <= 0) { return; @@ -1922,7 +1923,8 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel( context_.Say(GetContext().directiveSource, "A DO loop must follow the %s directive"_err_en_US, parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(GetContext().directive).str())); + llvm::omp::getOpenMPDirectiveName(GetContext().directive, version) + .str())); } } void OmpAttributeVisitor::CheckAssocLoopLevel( @@ -2442,6 +2444,7 @@ static bool SymbolOrEquivalentIsInNamelist(const Symbol &symbol) { void OmpAttributeVisitor::ResolveOmpObject( const parser::OmpObject &ompObject, Symbol::Flag ompFlag) { + unsigned version{context_.langOptions().OpenMPVersion}; common::visit( common::visitors{ [&](const parser::Designator &designator) { @@ -2464,7 +2467,7 @@ void OmpAttributeVisitor::ResolveOmpObject( Symbol::OmpFlagToClauseName(secondOmpFlag), parser::ToUpperCaseLetters( llvm::omp::getOpenMPDirectiveName( - GetContext().directive) + GetContext().directive, version) .str())); } }; @@ -2500,7 +2503,7 @@ void OmpAttributeVisitor::ResolveOmpObject( "in which the %s directive appears"_err_en_US, parser::ToUpperCaseLetters( llvm::omp::getOpenMPDirectiveName( - GetContext().directive) + GetContext().directive, version) .str())); } if (ompFlag == Symbol::Flag::OmpReduction) { @@ -2924,6 +2927,7 @@ void OmpAttributeVisitor::CheckSourceLabel(const parser::Label &label) { void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source, const parser::CharBlock target, std::optional sourceContext, std::optional targetContext) { + unsigned version{context_.langOptions().OpenMPVersion}; if (targetContext && (!sourceContext || (sourceContext->scope != targetContext->scope && @@ -2932,8 +2936,8 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source, context_ .Say(source, "invalid branch into an OpenMP structured block"_err_en_US) .Attach(target, "In the enclosing %s directive branched into"_en_US, - parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(targetContext->directive) + parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName( + targetContext->directive, version) .str())); } if (sourceContext && @@ -2945,8 +2949,8 @@ void OmpAttributeVisitor::CheckLabelContext(const parser::CharBlock source, .Say(source, "invalid branch leaving an OpenMP structured block"_err_en_US) .Attach(target, "Outside the enclosing %s directive"_en_US, - parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(sourceContext->directive) + parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName( + sourceContext->directive, version) .str())); } } @@ -2979,12 +2983,14 @@ void OmpAttributeVisitor::CheckNameInAllocateStmt( } } } + unsigned version{context_.langOptions().OpenMPVersion}; context_.Say(source, "Object '%s' in %s directive not " "found in corresponding ALLOCATE statement"_err_en_US, name.ToString(), parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(GetContext().directive).str())); + llvm::omp::getOpenMPDirectiveName(GetContext().directive, version) + .str())); } void OmpAttributeVisitor::AddOmpRequiresToScope(Scope &scope, @@ -3030,9 +3036,10 @@ void OmpAttributeVisitor::IssueNonConformanceWarning( llvm::omp::Directive D, parser::CharBlock source) { std::string warnStr; llvm::raw_string_ostream warnStrOS(warnStr); + unsigned version{context_.langOptions().OpenMPVersion}; warnStrOS << "OpenMP directive " << parser::ToUpperCaseLetters( - llvm::omp::getOpenMPDirectiveName(D).str()) + llvm::omp::getOpenMPDirectiveName(D, version).str()) << " has been deprecated"; auto setAlternativeStr = [&warnStrOS](llvm::StringRef alt) { diff --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp index 2716d88efb9fb..634d46b8ccf40 100644 --- a/flang/lib/Semantics/unparse-with-symbols.cpp +++ b/flang/lib/Semantics/unparse-with-symbols.cpp @@ -107,13 +107,13 @@ void SymbolDumpVisitor::Post(const parser::Name &name) { } void UnparseWithSymbols(llvm::raw_ostream &out, const parser::Program &program, - parser::Encoding encoding) { + const common::LangOptions &langOpts, parser::Encoding encoding) { SymbolDumpVisitor visitor; parser::Walk(program, visitor); parser::preStatementType preStatement{ [&](const parser::CharBlock &location, llvm::raw_ostream &out, int indent) { visitor.PrintSymbols(location, out, indent); }}; - parser::Unparse(out, program, encoding, false, true, &preStatement); + parser::Unparse(out, program, langOpts, encoding, false, true, &preStatement); } // UnparseWithModules() @@ -150,6 +150,6 @@ void UnparseWithModules(llvm::raw_ostream &out, SemanticsContext &context, for (SymbolRef moduleRef : visitor.modulesUsed()) { writer.WriteClosure(out, *moduleRef, nonIntrinsicModulesWritten); } - parser::Unparse(out, program, encoding, false, true); + parser::Unparse(out, program, context.langOptions(), encoding, false, true); } } // namespace Fortran::semantics diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index dd771ac3b416f..c3381705093ad 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -47,6 +47,7 @@ static constexpr inline bool canHaveIterator(Clause C) { } } +static constexpr unsigned FallbackVersion = 52; ArrayRef getOpenMPVersions(); /// Create a nicer version of a function name for humans to look at. diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp index d218de225c362..6189d0954891b 100644 --- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp +++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp @@ -188,7 +188,7 @@ struct StringifyClause { } static std::string to_str(llvm::omp::Directive D) { - return getOpenMPDirectiveName(D).str(); + return getOpenMPDirectiveName(D, llvm::omp::FallbackVersion).str(); } static std::string to_str(llvm::omp::Clause C) { return getOpenMPClauseName(C).str(); @@ -279,7 +279,7 @@ struct StringifyClause { std::string stringify(const omp::DirectiveWithClauses &DWC) { std::stringstream Stream; - Stream << getOpenMPDirectiveName(DWC.id).str(); + Stream << getOpenMPDirectiveName(DWC.id, llvm::omp::FallbackVersion).str(); for (const omp::Clause &C : DWC.clauses) Stream << ' ' << StringifyClause(C).Str; diff --git a/llvm/unittests/Frontend/OpenMPParsingTest.cpp b/llvm/unittests/Frontend/OpenMPParsingTest.cpp index 80ec2f0ad4d32..6a02f8a2be69a 100644 --- a/llvm/unittests/Frontend/OpenMPParsingTest.cpp +++ b/llvm/unittests/Frontend/OpenMPParsingTest.cpp @@ -23,11 +23,11 @@ TEST(OpenMPParsingTest, OpenMPDirectiveKind) { } TEST(OpenMPParsingTest, getOpenMPDirectiveName) { - EXPECT_EQ(getOpenMPDirectiveName(OMPD_unknown), "unknown"); + EXPECT_EQ(getOpenMPDirectiveName(OMPD_unknown, FallbackVersion), "unknown"); - EXPECT_EQ(getOpenMPDirectiveName(OMPD_for), "for"); - EXPECT_EQ(getOpenMPDirectiveName(OMPD_simd), "simd"); - EXPECT_EQ(getOpenMPDirectiveName(OMPD_for_simd), "for simd"); + EXPECT_EQ(getOpenMPDirectiveName(OMPD_for, FallbackVersion), "for"); + EXPECT_EQ(getOpenMPDirectiveName(OMPD_simd, FallbackVersion), "simd"); + EXPECT_EQ(getOpenMPDirectiveName(OMPD_for_simd, FallbackVersion), "for simd"); } TEST(OpenMPParsingTest, getOpenMPClauseKind) { diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp index 9a0f647f75ad5..339b8d6acd622 100644 --- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp @@ -244,8 +244,13 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) { OS << "LLVM_ABI Directive get" << DirLang.getName() << "DirectiveKind(llvm::StringRef Str);\n"; OS << "\n"; + // For OpenMP the signature is + // getOpenMPDirectiveName(Directive D, unsigned V) OS << "LLVM_ABI llvm::StringRef get" << DirLang.getName() - << "DirectiveName(Directive D);\n"; + << "DirectiveName(Directive D"; + if (DirLang.getCppNamespace() == "omp") + OS << ", unsigned = 0"; + OS << ");\n"; OS << "\n"; OS << "LLVM_ABI Clause get" << DirLang.getName() << "ClauseKind(llvm::StringRef Str);\n"; @@ -280,9 +285,14 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) { static void generateGetName(ArrayRef Records, raw_ostream &OS, StringRef Enum, const DirectiveLanguage &DirLang, StringRef Prefix) { + // For OpenMP the "Directive" signature is + // getOpenMPDirectiveName(Directive D, unsigned V) OS << "\n"; OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get" - << DirLang.getName() << Enum << "Name(" << Enum << " Kind) {\n"; + << DirLang.getName() << Enum << "Name(" << Enum << " Kind"; + if (DirLang.getCppNamespace() == "omp" && Enum == "Directive") + OS << ", unsigned"; + OS << ") {\n"; OS << " switch (Kind) {\n"; for (const BaseRecord Rec : Records) { OS << " case " << Prefix << Rec.getFormattedName() << ":\n";