diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3291,8 +3291,10 @@ /// Parses declarative or executable directive. /// /// \param StmtCtx The context in which we're parsing the directive. - StmtResult - ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx); + /// \param ReadDirectiveWithinMetadirective true if directive is within a + /// metadirective and therefore ends on the closing paren. + StmtResult ParseOpenMPDeclarativeOrExecutableDirective( + ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false); /// 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 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2451,9 +2451,8 @@ /// for simd' | 'target teams distribute simd' | 'masked' {clause} /// annot_pragma_openmp_end /// -StmtResult -Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { - static bool ReadDirectiveWithinMetadirective = false; +StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( + ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective) { if (!ReadDirectiveWithinMetadirective) assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) && "Not an OpenMP directive!"); @@ -2615,9 +2614,9 @@ } // Parse Directive - ReadDirectiveWithinMetadirective = true; - Directive = ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx); - ReadDirectiveWithinMetadirective = false; + Directive = ParseOpenMPDeclarativeOrExecutableDirective( + StmtCtx, + /*ReadDirectiveWithinMetadirective=*/true); break; } break; diff --git a/clang/test/OpenMP/metadirective_ast_print.c b/clang/test/OpenMP/metadirective_ast_print.c --- a/clang/test/OpenMP/metadirective_ast_print.c +++ b/clang/test/OpenMP/metadirective_ast_print.c @@ -47,6 +47,16 @@ : parallel) default(parallel for) for (int i = 0; i < 100; i++) ; + +// Test metadirective with nested OpenMP directive. + int array[16]; + #pragma omp metadirective when(user = {condition(1)} \ + : parallel for) + for (int i = 0; i < 16; i++) { + #pragma omp simd + for (int j = 0; j < 16; j++) + array[i] = i; + } } // CHECK: void bar(); @@ -69,5 +79,9 @@ // CHECK-NEXT: for (int i = 0; i < 100; i++) // CHECK: #pragma omp parallel // CHECK-NEXT: for (int i = 0; i < 100; i++) +// CHECK: #pragma omp parallel for +// CHECK-NEXT: for (int i = 0; i < 16; i++) { +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int j = 0; j < 16; j++) #endif