-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][OpenMP] Shorten directive classification in ParseOpenMP #94691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The file OMP.td is becoming tedious to update by hand due to the seemingly random ordering of various items in it. This patch brings order to it by sorting most of the contents. The clause definitions are sorted alphabetically with respect to the spelling of the clause.[1] The directive definitions are split into two leaf directives and compound directives.[2] Within each, definitions are sorted alphabetically with respect to the spelling, with the exception that "end xyz" directives are placed immediately following the definition of "xyz".[3] Within each directive definition, the lists of clauses are also sorted alphabetically. [1] All spellings are made of lowercase letters, _, or space. Ordering between non-letters follow the order assumed by `sort` utility. [2] Compound directives refer to the consituent leaf directives, hence the leaf definitions must come first. [3] Some of the "end xyz" directives have properties derived from the corresponding "xyz" directive. This exception guarantees that "xyz" precedes the "end xyz".
The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand.
Use directive categories to simplify long lists of `case` statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically. The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be.
@llvm/pr-subscribers-clang Author: Krzysztof Parzyszek (kparzysz) ChangesUse directive categories to simplify long lists of Patch is 21.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94691.diff 2 Files Affected:
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d054b8cf0d240..88571a4a46f2c 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3509,6 +3509,19 @@ class Parser : public CodeCompletionHandler {
/// metadirective and therefore ends on the closing paren.
StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
+
+ /// Parses executable directive.
+ ///
+ /// \param StmtCtx The context in which we're parsing the directive.
+ /// \param DKind The kind of the executable directive.
+ /// \param Loc Source location of the beginning of the directive.
+ /// \param ReadDirectiveWithinMetadirective true if directive is within a
+ /// metadirective and therefore ends on the closing paren.
+ StmtResult
+ ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
+ OpenMPDirectiveKind DKind, SourceLocation Loc,
+ bool ReadDirectiveWithinMetadirective);
+
/// Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 50a872fedebf7..a10bb009ec835 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2374,86 +2374,209 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_unknown:
Diag(Tok, diag::err_omp_unknown_directive);
break;
- case OMPD_parallel:
- case OMPD_simd:
- case OMPD_tile:
- case OMPD_unroll:
- case OMPD_task:
- case OMPD_taskyield:
+ default:
+ switch (getDirectiveCategory(DKind)) {
+ case Category::Executable:
+ case Category::Meta:
+ case Category::Subsidiary:
+ case Category::Utility:
+ Diag(Tok, diag::err_omp_unexpected_directive)
+ << 1 << getOpenMPDirectiveName(DKind);
+ break;
+ default:
+ break;
+ }
+ }
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ ConsumeAnyToken();
+ return nullptr;
+}
+
+StmtResult
+Parser::ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
+ OpenMPDirectiveKind DKind,
+ SourceLocation Loc,
+ bool ReadDirectiveWithinMetadirective) {
+ bool HasAssociatedStatement = true;
+
+ switch (DKind) {
case OMPD_barrier:
- case OMPD_taskwait:
- case OMPD_taskgroup:
- case OMPD_flush:
+ case OMPD_cancel:
+ case OMPD_cancellation_point:
case OMPD_depobj:
+ case OMPD_error:
+ case OMPD_flush:
+ case OMPD_interop:
case OMPD_scan:
- case OMPD_for:
- case OMPD_for_simd:
- case OMPD_sections:
- case OMPD_section:
- case OMPD_single:
- case OMPD_master:
- case OMPD_ordered:
- case OMPD_critical:
- case OMPD_parallel_for:
- case OMPD_parallel_for_simd:
- case OMPD_parallel_sections:
- case OMPD_parallel_master:
- case OMPD_parallel_masked:
- case OMPD_atomic:
- case OMPD_target:
- case OMPD_teams:
- case OMPD_cancellation_point:
- case OMPD_cancel:
- case OMPD_target_data:
case OMPD_target_enter_data:
case OMPD_target_exit_data:
- case OMPD_target_parallel:
- case OMPD_target_parallel_for:
- case OMPD_taskloop:
- case OMPD_taskloop_simd:
- case OMPD_master_taskloop:
- case OMPD_master_taskloop_simd:
- case OMPD_parallel_master_taskloop:
- case OMPD_parallel_master_taskloop_simd:
- case OMPD_masked_taskloop:
- case OMPD_masked_taskloop_simd:
- case OMPD_parallel_masked_taskloop:
- case OMPD_parallel_masked_taskloop_simd:
- case OMPD_distribute:
case OMPD_target_update:
- case OMPD_distribute_parallel_for:
- case OMPD_distribute_parallel_for_simd:
- case OMPD_distribute_simd:
- case OMPD_target_parallel_for_simd:
- case OMPD_target_simd:
- case OMPD_scope:
- case OMPD_teams_distribute:
- case OMPD_teams_distribute_simd:
- case OMPD_teams_distribute_parallel_for_simd:
- case OMPD_teams_distribute_parallel_for:
- case OMPD_target_teams:
- case OMPD_target_teams_distribute:
- case OMPD_target_teams_distribute_parallel_for:
- case OMPD_target_teams_distribute_parallel_for_simd:
- case OMPD_target_teams_distribute_simd:
- case OMPD_dispatch:
- case OMPD_masked:
- case OMPD_metadirective:
- case OMPD_loop:
- case OMPD_teams_loop:
- case OMPD_target_teams_loop:
- case OMPD_parallel_loop:
- case OMPD_target_parallel_loop:
- Diag(Tok, diag::err_omp_unexpected_directive)
- << 1 << getOpenMPDirectiveName(DKind);
- break;
- default:
+ case OMPD_taskwait:
+ case OMPD_taskyield:
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+ ParsedStmtContext()) {
+ Diag(Tok, diag::err_omp_immediate_directive)
+ << getOpenMPDirectiveName(DKind) << 0;
+ if (DKind == OMPD_error) {
+ SkipUntil(tok::annot_pragma_openmp_end);
+ return StmtError();
+ }
+ }
+ HasAssociatedStatement = false;
break;
}
- while (Tok.isNot(tok::annot_pragma_openmp_end))
- ConsumeAnyToken();
- ConsumeAnyToken();
- return nullptr;
+
+ SourceLocation EndLoc;
+ SmallVector<OMPClause *, 5> Clauses;
+ std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
+ DeclarationNameInfo DirName;
+ OpenMPDirectiveKind CancelRegion = OMPD_unknown;
+ unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
+ Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
+
+ // Special processing for flush and depobj clauses.
+ Token ImplicitTok;
+ bool ImplicitClauseAllowed = false;
+ if (DKind == OMPD_flush || DKind == OMPD_depobj) {
+ ImplicitTok = Tok;
+ ImplicitClauseAllowed = true;
+ }
+ ConsumeToken();
+ // Parse directive name of the 'critical' directive if any.
+ if (DKind == OMPD_critical) {
+ BalancedDelimiterTracker T(*this, tok::l_paren,
+ tok::annot_pragma_openmp_end);
+ if (!T.consumeOpen()) {
+ if (Tok.isAnyIdentifier()) {
+ DirName =
+ DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
+ ConsumeAnyToken();
+ } else {
+ Diag(Tok, diag::err_omp_expected_identifier_for_critical);
+ }
+ T.consumeClose();
+ }
+ } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
+ CancelRegion = parseOpenMPDirectiveKind(*this);
+ if (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeToken();
+ }
+
+ if (isOpenMPLoopDirective(DKind))
+ ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
+ if (isOpenMPSimdDirective(DKind))
+ ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
+ ParseScope OMPDirectiveScope(this, ScopeFlags);
+ Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
+ Loc);
+
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ // If we are parsing for a directive within a metadirective, the directive
+ // ends with a ')'.
+ if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
+ while (Tok.isNot(tok::annot_pragma_openmp_end))
+ ConsumeAnyToken();
+ break;
+ }
+ bool HasImplicitClause = false;
+ if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
+ HasImplicitClause = true;
+ // Push copy of the current token back to stream to properly parse
+ // pseudo-clause OMPFlushClause or OMPDepobjClause.
+ PP.EnterToken(Tok, /*IsReinject*/ true);
+ PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
+ ConsumeAnyToken();
+ }
+ OpenMPClauseKind CKind = Tok.isAnnotation()
+ ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ if (HasImplicitClause) {
+ assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
+ if (DKind == OMPD_flush) {
+ CKind = OMPC_flush;
+ } else {
+ assert(DKind == OMPD_depobj && "Expected flush or depobj directives.");
+ CKind = OMPC_depobj;
+ }
+ }
+ // No more implicit clauses allowed.
+ ImplicitClauseAllowed = false;
+ Actions.OpenMP().StartOpenMPClause(CKind);
+ HasImplicitClause = false;
+ OMPClause *Clause =
+ ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
+ SeenClauses[unsigned(CKind)] = true;
+ if (Clause)
+ Clauses.push_back(Clause);
+
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.OpenMP().EndOpenMPClause();
+ }
+ // End location of the directive.
+ EndLoc = Tok.getLocation();
+ // Consume final annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+
+ if (DKind == OMPD_ordered) {
+ // If the depend or doacross clause is specified, the ordered construct
+ // is a stand-alone directive.
+ for (auto CK : {OMPC_depend, OMPC_doacross}) {
+ if (SeenClauses[unsigned(CK)]) {
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+ ParsedStmtContext()) {
+ Diag(Loc, diag::err_omp_immediate_directive)
+ << getOpenMPDirectiveName(DKind) << 1 << getOpenMPClauseName(CK);
+ }
+ HasAssociatedStatement = false;
+ }
+ }
+ }
+
+ if (DKind == OMPD_tile && !SeenClauses[unsigned(OMPC_sizes)]) {
+ Diag(Loc, diag::err_omp_required_clause)
+ << getOpenMPDirectiveName(OMPD_tile) << "sizes";
+ }
+
+ StmtResult AssociatedStmt;
+ if (HasAssociatedStatement) {
+ // The body is a block scope like in Lambdas and Blocks.
+ Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
+ // FIXME: We create a bogus CompoundStmt scope to hold the contents of
+ // the captured region. Code elsewhere assumes that any FunctionScopeInfo
+ // should have at least one compound statement scope within it.
+ ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
+ {
+ Sema::CompoundScopeRAII Scope(Actions);
+ AssociatedStmt = ParseStatement();
+
+ if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
+ getLangOpts().OpenMPIRBuilder)
+ AssociatedStmt =
+ Actions.OpenMP().ActOnOpenMPLoopnest(AssociatedStmt.get());
+ }
+ AssociatedStmt =
+ Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+ } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
+ DKind == OMPD_target_exit_data) {
+ Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
+ AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
+ Actions.ActOnCompoundStmt(Loc, Loc, std::nullopt,
+ /*isStmtExpr=*/false));
+ AssociatedStmt =
+ Actions.OpenMP().ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
+ }
+
+ StmtResult Directive = Actions.OpenMP().ActOnOpenMPExecutableDirective(
+ DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, EndLoc);
+
+ // Exit scope.
+ Actions.OpenMP().EndOpenMPDSABlock(Directive.get());
+ OMPDirectiveScope.Exit();
+
+ return Directive;
}
/// Parsing of declarative or executable OpenMP directives.
@@ -2503,24 +2626,36 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
"Not an OpenMP directive!");
ParsingOpenMPDirectiveRAII DirScope(*this);
ParenBraceBracketBalancer BalancerRAIIObj(*this);
- SmallVector<OMPClause *, 5> Clauses;
- std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses;
- unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
- Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
SourceLocation Loc = ReadDirectiveWithinMetadirective
? Tok.getLocation()
- : ConsumeAnnotationToken(),
- EndLoc;
+ : ConsumeAnnotationToken();
OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
Diag(Tok, diag::err_omp_unknown_directive);
return StmtError();
}
- OpenMPDirectiveKind CancelRegion = OMPD_unknown;
- // Name of critical directive.
- DeclarationNameInfo DirName;
+
StmtResult Directive = StmtError();
- bool HasAssociatedStatement = true;
+
+ bool IsExecutable = [&]() {
+ if (DKind == OMPD_error) // OMPD_error is handled as executable
+ return true;
+ switch (getDirectiveCategory(DKind)) {
+ case Category::Executable:
+ case Category::Subsidiary:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }();
+
+ if (IsExecutable) {
+ Directive = ParseOpenMPExecutableDirective(
+ StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective);
+ assert(!Directive.isUnset());
+ return Directive;
+ }
switch (DKind) {
case OMPD_nothing:
@@ -2763,233 +2898,6 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
}
break;
}
- case OMPD_flush:
- case OMPD_depobj:
- case OMPD_scan:
- case OMPD_taskyield:
- case OMPD_error:
- case OMPD_barrier:
- case OMPD_taskwait:
- case OMPD_cancellation_point:
- case OMPD_cancel:
- case OMPD_target_enter_data:
- case OMPD_target_exit_data:
- case OMPD_target_update:
- case OMPD_interop:
- if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
- ParsedStmtContext()) {
- Diag(Tok, diag::err_omp_immediate_directive)
- << getOpenMPDirectiveName(DKind) << 0;
- if (DKind == OMPD_error) {
- SkipUntil(tok::annot_pragma_openmp_end);
- break;
- }
- }
- HasAssociatedStatement = false;
- // Fall through for further analysis.
- [[fallthrough]];
- case OMPD_parallel:
- case OMPD_simd:
- case OMPD_tile:
- case OMPD_unroll:
- case OMPD_for:
- case OMPD_for_simd:
- case OMPD_sections:
- case OMPD_single:
- case OMPD_section:
- case OMPD_master:
- case OMPD_critical:
- case OMPD_parallel_for:
- case OMPD_parallel_for_simd:
- case OMPD_parallel_sections:
- case OMPD_parallel_master:
- case OMPD_parallel_masked:
- case OMPD_task:
- case OMPD_ordered:
- case OMPD_atomic:
- case OMPD_target:
- case OMPD_teams:
- case OMPD_taskgroup:
- case OMPD_target_data:
- case OMPD_target_parallel:
- case OMPD_target_parallel_for:
- case OMPD_loop:
- case OMPD_teams_loop:
- case OMPD_target_teams_loop:
- case OMPD_parallel_loop:
- case OMPD_target_parallel_loop:
- case OMPD_scope:
- case OMPD_taskloop:
- case OMPD_taskloop_simd:
- case OMPD_master_taskloop:
- case OMPD_masked_taskloop:
- case OMPD_master_taskloop_simd:
- case OMPD_masked_taskloop_simd:
- case OMPD_parallel_master_taskloop:
- case OMPD_parallel_masked_taskloop:
- case OMPD_parallel_master_taskloop_simd:
- case OMPD_parallel_masked_taskloop_simd:
- case OMPD_distribute:
- case OMPD_distribute_parallel_for:
- case OMPD_distribute_parallel_for_simd:
- case OMPD_distribute_simd:
- case OMPD_target_parallel_for_simd:
- case OMPD_target_simd:
- case OMPD_teams_distribute:
- case OMPD_teams_distribute_simd:
- case OMPD_teams_distribute_parallel_for_simd:
- case OMPD_teams_distribute_parallel_for:
- case OMPD_target_teams:
- case OMPD_target_teams_distribute:
- case OMPD_target_teams_distribute_parallel_for:
- case OMPD_target_teams_distribute_parallel_for_simd:
- case OMPD_target_teams_distribute_simd:
- case OMPD_dispatch:
- case OMPD_masked: {
- // Special processing for flush and depobj clauses.
- Token ImplicitTok;
- bool ImplicitClauseAllowed = false;
- if (DKind == OMPD_flush || DKind == OMPD_depobj) {
- ImplicitTok = Tok;
- ImplicitClauseAllowed = true;
- }
- ConsumeToken();
- // Parse directive name of the 'critical' directive if any.
- if (DKind == OMPD_critical) {
- BalancedDelimiterTracker T(*this, tok::l_paren,
- tok::annot_pragma_openmp_end);
- if (!T.consumeOpen()) {
- if (Tok.isAnyIdentifier()) {
- DirName =
- DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
- ConsumeAnyToken();
- } else {
- Diag(Tok, diag::err_omp_expected_identifier_for_critical);
- }
- T.consumeClose();
- }
- } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
- CancelRegion = parseOpenMPDirectiveKind(*this);
- if (Tok.isNot(tok::annot_pragma_openmp_end))
- ConsumeToken();
- }
-
- if (isOpenMPLoopDirective(DKind))
- ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
- if (isOpenMPSimdDirective(DKind))
- ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
- ParseScope OMPDirectiveScope(this, ScopeFlags);
- Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(),
- Loc);
-
- while (Tok.isNot(tok::annot_pragma_openmp_end)) {
- // If we are parsing for a directive within a metadirective, the directive
- // ends with a ')'.
- if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
- while (Tok.isNot(tok::annot_pragma_openmp_end))
- ConsumeAnyToken();
- break;
- }
- bool HasImplicitClause = false;
- if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
- HasImplicitClause = true;
- // Push copy of the current token back to stream to properly parse
- // pseudo-clause OMPFlushClause or OMPDepobjClause.
- PP.EnterToken(Tok, /*IsReinject*/ true);
- PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
- ConsumeAnyToken();
- }
- OpenMPClauseKind CKind = Tok.isAnnotation()
- ? OMPC_unknown
- : getOpenMPClauseKind(PP.getSpelling(Tok));
- if (HasImplicitClause) {
- assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
- if (DKind == OMPD_flush) {
- CKind = OMPC_flush;
- } else {
- assert(DKind == OMPD_depobj &&
- "Expected flush or depobj directives.");
- CKind = OMPC_depobj;
- }
- }
- // No more implicit clauses allowed.
- ImplicitClauseAllowed = false;
- Actions.OpenMP().StartOpenMPClause(CKind);
- HasImplicitClause = false;
- OMPClause *Clause =
- ParseOpenMPClause(DKind, CKind, !SeenClauses[unsigned(CKind)]);
- SeenClauses[unsigned(CKind)] = true;
- if (Clause)
- Clauses.push_back(Clause);
-
- // Skip ',' if any.
- if (Tok.is(tok::comma))
- ConsumeToken();
- Actions.OpenMP().EndOpenMPClause();
- }
- // End location of the directive.
- EndLoc = Tok.getLocation();
- // Consume final annot_pragma_openmp_end.
- ConsumeAnnotationToken();
-
- if (DKind == OMPD_ordered) {
- // If the depend or doacross clause is specified, the ordered construct
- // is a stand-alone directive.
- for (auto CK : {OMPC_depend, OMPC_doacross}) {
- if (SeenClauses[unsigned(CK)]) {
- if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
- ParsedStmtContext()) {
- Diag(Loc, diag::err_omp_immediate_directive)
- << getOpenMPDirectiveName(DKind) << 1
- << getOpenMPClauseName(CK);
- }
- HasAssociatedStatement = false;
- }
- }
- }
-
- if (DKind == OMPD_tile && !SeenClauses[unsigned(OMPC_sizes)]) {
- Diag(Loc, diag::err_omp_required_clause)
- << getOpenMPDirectiveName(OMPD_tile) << "sizes";
- }
-
- StmtResult AssociatedStmt;
- if (HasAssociatedStatement) {
- // The body is a block scope like in Lambdas and Blocks.
- Actions.OpenMP().ActOnOpenMPRegionStart(DKind, getCurScope());
- // FIXME: We create a bogus CompoundStmt scope to hold the contents of
- // the captured region. Code elsewhere assumes that any FunctionScopeInfo
- // should have at least one compound statement scope within it.
- ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
- {
- Sema::CompoundScopeRAII Scope(Actions);
- AssociatedStmt = ParseStatement();
-
- if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
- getLangOpts().OpenMPIRBuilder)
- AssociatedStmt =
- Actions.OpenMP().ActOnOpenMPLoopnest(Assoc...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Ping. Anyone? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I both like and hate the huge fully-covered switches we have. I like when I add new directives and know exactly where to add code. I hate having to read code like this though. Seems like this is going in the right direction.
clang/lib/Parse/ParseOpenMP.cpp
Outdated
default: | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be a fully covered switch instead?
For 'Declarative' I suspect there should be a case to handle it, if not it can assert here so we know we need to add code there.
And do whatever is needed for 'Informational' directives arriving here.
The idea is when someone adds a new directive it doesn't just fall through silently but alerts us to the missing code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
clang/lib/Parse/ParseOpenMP.cpp
Outdated
bool ReadDirectiveWithinMetadirective) { | ||
bool HasAssociatedStatement = true; | ||
|
||
switch (DKind) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to use the Association somehow here instead of the switch?
So when a new directive is added we don't have to update this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
clang/lib/Parse/ParseOpenMP.cpp
Outdated
|
||
SourceLocation EndLoc; | ||
SmallVector<OMPClause *, 5> Clauses; | ||
std::bitset<llvm::omp::Clause_enumSize + 1> SeenClauses; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use SmallBitVector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
clang/lib/Parse/ParseOpenMP.cpp
Outdated
if (IsExecutable) { | ||
Directive = ParseOpenMPExecutableDirective( | ||
StmtCtx, DKind, Loc, ReadDirectiveWithinMetadirective); | ||
assert(!Directive.isUnset()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add assertion message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Co-authored-by: Alexey Bataev <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
…#94691) Use directive categories to simplify long lists of `case` statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically. The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be. --------- Co-authored-by: Alexey Bataev <[email protected]>
…#94691) Use directive categories to simplify long lists of `case` statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically. The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be. --------- Co-authored-by: Alexey Bataev <[email protected]>
Use directive categories to simplify long lists of
case
statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically.The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be.