From 0d69f8315bea40e96100593c509c177659f27fbf Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Thu, 6 Mar 2025 17:14:20 -0800 Subject: [PATCH 01/10] ACC token and context duplication fixed --- flang/lib/Parser/message.cpp | 40 +++- flang/lib/Parser/openacc-parsers.cpp | 9 +- flang/test/Driver/debug-parsing-log.f90 | 18 +- flang/test/Parser/acc-data-statement.f90 | 245 +++++++++++++++++++++++ flang/test/Parser/acc.f | 96 +++++++++ 5 files changed, 392 insertions(+), 16 deletions(-) create mode 100644 flang/test/Parser/acc-data-statement.f90 create mode 100644 flang/test/Parser/acc.f diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp index 69e4814bf246c..0b8d300189a1b 100644 --- a/flang/lib/Parser/message.cpp +++ b/flang/lib/Parser/message.cpp @@ -272,6 +272,10 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) { return llvm::raw_ostream::SAVEDCOLOR; } +// FIXME: Make these configurable, based on verbosity level. +const int MAX_CONTEXTS_EMITTED = 2; +const bool OMIT_SHARED_CONTEXTS = true; + void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, bool echoSourceLine) const { std::optional provenanceRange{GetProvenanceRange(allCooked)}; @@ -279,12 +283,38 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()), PrefixColor(severity()), echoSourceLine); bool isContext{attachmentIsContext_}; + int contextsEmitted{isContext ? 1 : 0}; + // Emit attachments. for (const Message *attachment{attachment_.get()}; attachment; - attachment = attachment->attachment_.get()) { + attachment = attachment->attachment_.get()) { Severity severity = isContext ? Severity::Context : attachment->severity(); - sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked), - attachment->ToString(), Prefix(severity), PrefixColor(severity), - echoSourceLine); + auto emitAttachment = [&]() { + sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked), + attachment->ToString(), Prefix(severity), PrefixColor(severity), + echoSourceLine); + }; + // TODO isContext is not used correctly here. + if (attachment->attachmentIsContext_) { + // Truncate the number of contexts emitted. + if (contextsEmitted <= MAX_CONTEXTS_EMITTED) { + emitAttachment(); + contextsEmitted += 1; + } + if (OMIT_SHARED_CONTEXTS) { + // Skip less specific contexts at the same location. + for (const Message *next_attachment{attachment->attachment_.get()}; + next_attachment && next_attachment->attachmentIsContext_ && + next_attachment->AtSameLocation(*attachment); + next_attachment = next_attachment->attachment_.get()) { + attachment = next_attachment; + } + // NB, this loop increments `attachment` one more time after the + // previous loop is done advancing it to the last context at the same + // location. + } + } else { + emitAttachment(); + } } } @@ -298,7 +328,7 @@ bool Message::operator==(const Message &that) const { } const Message *thatAttachment{that.attachment_.get()}; for (const Message *attachment{attachment_.get()}; attachment; - attachment = attachment->attachment_.get()) { + attachment = attachment->attachment_.get()) { if (!thatAttachment || !attachment->AtSameLocation(*thatAttachment) || attachment->ToString() != thatAttachment->ToString() || attachment->severity() != thatAttachment->severity()) { diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index c78676664e0a3..6739bcc035fc2 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -19,8 +19,12 @@ // OpenACC Directives and Clauses namespace Fortran::parser { +// Only need to handle ! line comments because prescanning normalizes the +// other types of line comments from fixed form. constexpr auto startAccLine{skipStuffBeforeStatement >> - ("!$ACC "_sptok || "C$ACC "_sptok || "*$ACC "_sptok)}; + withMessage( + "expected OpenACC comment '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US, + "!$ACC "_sptok)}; constexpr auto endAccLine{space >> endOfLine}; // Autogenerated clauses parser. Information is taken from ACC.td and the @@ -225,7 +229,8 @@ TYPE_PARSER(startAccLine >> sourced(construct("END"_tok >> TYPE_PARSER(construct( Parser{} / endAccLine, block, - Parser{} / endAccLine)) + withMessage("expected OpenACC end block directive"_err_en_US, + Parser{} / endAccLine))) // Standalone constructs TYPE_PARSER(construct( diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90 index 7297163109450..4e56add386ef8 100644 --- a/flang/test/Driver/debug-parsing-log.f90 +++ b/flang/test/Driver/debug-parsing-log.f90 @@ -12,14 +12,14 @@ ! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: IMPLICIT statement ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: implicit part -! CHECK-NEXT: END PROGRAM -! CHECK-NEXT: ^ -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: specification part -! CHECK-NEXT: END PROGRAM -! CHECK-NEXT: ^ -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: main program -! CHECK-NEXT: END PROGRAM -! CHECK-NEXT: ^ + + + + + + + + + END PROGRAM diff --git a/flang/test/Parser/acc-data-statement.f90 b/flang/test/Parser/acc-data-statement.f90 new file mode 100644 index 0000000000000..1e369a0db3780 --- /dev/null +++ b/flang/test/Parser/acc-data-statement.f90 @@ -0,0 +1,245 @@ +! RUN: not %flang_fc1 -fsyntax-only -fopenacc %s 2>&1 | FileCheck %s +program acc_data_test + implicit none + integer :: a(100), b(100), c(100), d(100) + integer :: i, s ! FIXME: if s is named sum you get semantic errors. + + ! Positive tests + + ! Basic data construct in program body + !$acc data copy(a, b) create(c) + a = 1 + b = 2 + c = a + b + !$acc end data + print *, "After first data region" + + ! Data construct within IF block + if (.true.) then + !$acc data copyout(a) + a = a + 1 + !$acc end data + print *, "Inside if block" + end if + + ! Data construct within DO loop + do i = 1, 10 + !$acc data present(a) + a(i) = a(i) * 2 + !$acc end data + print *, "Loop iteration", i + end do + + ! Nested data constructs + !$acc data copyin(a) + s = 0 + !$acc data copy(s) + s = s + 1 + !$acc end data + print *, "After nested data" + !$acc end data + + ! Negative tests + ! Basic data construct in program body + !$acc data copy(a, b) create(d) + a = 1 + b = 2 + d = a + b +! !$acc end data + print *, "After first data region" + + ! Data construct within IF block + if (.true.) then + !$acc data copyout(a) + a = a + 1 +! !$acc end data + print *, "Inside if block" + ! First error in the file. + !CHECK: acc-data-statement.f90: + !CHECK-SAME: [[ELINE1:[0-9]+]]:{{[0-9]+}}: + !CHECK-SAME: error: expected OpenACC end block directive + !CHECK-NEXT: end if + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyout(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: IF construct + !CHECK-NEXT: if (.true.) then + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: end if + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyout(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: IF construct + !CHECK-NEXT: if (.true.) then + !CHECK-NEXT: ^ + end if + + ! Data construct within DO loop + do i = 1, 10 + !$acc data present(a) + a(i) = a(i) * 2 +! !$acc end data + print *, "Loop iteration", i + !CHECK: acc-data-statement.f90: + !CHECK-NOT: [[ELINE1]] + !CHECK-SAME: [[ELINE2:[0-9]+]]:{{[0-9]+}}: + !CHECK-SAME: error: expected OpenACC end block directive + !CHECK-NEXT: end do + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data present(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: DO construct + !CHECK-NEXT: do i = 1, 10 + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: end do + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data present(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: DO construct + !CHECK-NEXT: do i = 1, 10 + !CHECK-NEXT: ^ + end do + + ! Nested data constructs + !$acc data copyin(a) + s = 0 + !$acc data copy(s) + s = s + 1 +! !$acc end data + print *, "After nested data" +! !$acc end data + + print *, "Program finished" + !CHECK: acc-data-statement.f90: + !CHECK-NOT: [[ELINE2]] + !CHECK-SAME: [[ELINE3:[0-9]+]]:{{[0-9]+}}: + !CHECK-SAME: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(s) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: execution part + !CHECK-NEXT: !$acc data copy(a, b) create(c) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(s) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyin(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyin(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: execution part + !CHECK-NEXT: !$acc data copy(a, b) create(c) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(s) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(a, b) create(d) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(s) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyin(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyin(a) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(a, b) create(d) + !CHECK-NEXT: ^ + !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK-NEXT: contains + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(a, b) create(d) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: execution part + !CHECK-NEXT: !$acc data copy(a, b) create(c) + !CHECK-NEXT: ^ +contains + subroutine positive_process_array(x) + integer, intent(inout) :: x(:) + + ! Data construct in subroutine + !$acc data copy(x) + x = x + 1 + !$acc end data + print *, "Subroutine finished" + end subroutine + + function positive_compute_sum(x) result(total) + integer, intent(in) :: x(:) + integer :: total + + ! Data construct in function + !$acc data copyin(x) copy(total) + total = sum(x) + !$acc end data + print *, "Function finished" + end function + + subroutine negative_process_array(x) + integer, intent(inout) :: x(:) + + ! Data construct in subroutine + !$acc data copy(x) + x = x + 1 +! !$acc end data + print *, "Subroutine finished" + !CHECK: error: expected OpenACC directive + !CHECK-NEXT: !$acc data copy(x) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: specification construct + !CHECK-NEXT: !$acc data copy(x) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: specification part + !CHECK-NEXT: integer, intent(inout) :: x(:) + !CHECK-NEXT: ^ + end subroutine + + function negative_compute_sum(x) result(total) + integer, intent(in) :: x(:) + integer :: total + total = sum(x) + ! Data construct in function + !$acc data copyin(x) copy(total) + total = total + x +! !$acc end data + print *, "Function finished" + !CHECK: error: expected OpenACC end block directive + !CHECK-NEXT: end function + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copyin(x) copy(total) + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: execution part + !CHECK-NEXT: total = sum(x) + !CHECK-NEXT: ^ + end function +end program acc_data_test \ No newline at end of file diff --git a/flang/test/Parser/acc.f b/flang/test/Parser/acc.f new file mode 100644 index 0000000000000..b0c3927772568 --- /dev/null +++ b/flang/test/Parser/acc.f @@ -0,0 +1,96 @@ +! RUN: %flang_fc1 -fsyntax-only -fopenacc %s 2>&1 +C Test file for OpenACC directives in fixed-form Fortran + PROGRAM ACCTEST + IMPLICIT NONE + INTEGER :: N, I, J + PARAMETER (N=100) + REAL :: A(N), B(N), C(N), D(N) + REAL :: SUM + +C Initialize arrays + DO I = 1, N + A(I) = I * 1.0 + B(I) = I * 2.0 + C(I) = 0.0 + D(I) = 1.0 + END DO + +C Basic data construct using C$ACC +C$ACC DATA COPYIN(A,B) COPYOUT(C) + DO I = 1, N + C(I) = A(I) + B(I) + END DO +C$ACC END DATA + +* Parallel construct with loop using *$ACC +*$ACC PARALLEL PRESENT(A,B,C) +*$ACC LOOP + DO I = 1, N + C(I) = C(I) * 2.0 + END DO +*$ACC END PARALLEL + +C Nested loops with collapse - C$ACC style +C$ACC PARALLEL LOOP COLLAPSE(2) + DO I = 1, N + DO J = 1, N + A(J) = A(J) + B(J) + END DO + END DO +C$ACC END PARALLEL LOOP + +* Combined parallel loop with reduction - *$ACC style + SUM = 0.0 +*$ACC PARALLEL LOOP REDUCTION(+:SUM) + DO I = 1, N + SUM = SUM + C(I) + END DO +*$ACC END PARALLEL LOOP + +C Kernels construct - C$ACC with continuation +C$ACC KERNELS +C$ACC+ COPYOUT(A) + DO I = 1, N + A(I) = A(I) * 2.0 + END DO +C$ACC END KERNELS + +* Data construct with update - *$ACC with continuation +*$ACC DATA COPY(B) +*$ACC+ PRESENT(D) + B(1) = 999.0 +*$ACC UPDATE HOST(B(1:1)) + PRINT *, 'B(1) = ', B(1) +*$ACC END DATA + +C Mixed style directives in nested constructs +C$ACC DATA COPY(A,B,C) +*$ACC PARALLEL LOOP + DO I = 1, N + A(I) = B(I) + C(I) + END DO +*$ACC END PARALLEL LOOP +C$ACC END DATA + +* Subroutine call within data region - *$ACC style +*$ACC DATA COPY(A,B,C) + CALL SUB1(A, B, C, N) +*$ACC END DATA + + PRINT *, 'Sum = ', SUM + END PROGRAM + +C Subroutine with mixed ACC directive styles + SUBROUTINE SUB1(X, Y, Z, M) + INTEGER M, I + REAL X(M), Y(M), Z(M) + +*$ACC PARALLEL PRESENT(X,Y) +C$ACC LOOP PRIVATE(I) + DO I = 1, M + Z(I) = X(I) + Y(I) + END DO +C$ACC END LOOP +*$ACC END PARALLEL + RETURN + END SUBROUTINE \ No newline at end of file From ce39b4221707ed154abf4f5c9f19868471313da5 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Wed, 12 Mar 2025 17:07:20 -0700 Subject: [PATCH 02/10] add more descriptive error message and remove newlines --- flang/lib/Parser/openacc-parsers.cpp | 2 +- flang/lib/Parser/stmt-parser.h | 2 +- flang/test/Driver/debug-parsing-log.f90 | 16 +++------------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index 6739bcc035fc2..41aedd47d58bb 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -23,7 +23,7 @@ namespace Fortran::parser { // other types of line comments from fixed form. constexpr auto startAccLine{skipStuffBeforeStatement >> withMessage( - "expected OpenACC comment '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US, + "expected OpenACC directive sentinal: '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US, "!$ACC "_sptok)}; constexpr auto endAccLine{space >> endOfLine}; diff --git a/flang/lib/Parser/stmt-parser.h b/flang/lib/Parser/stmt-parser.h index ee45c6fd5d38c..61e6b95f0ddbb 100644 --- a/flang/lib/Parser/stmt-parser.h +++ b/flang/lib/Parser/stmt-parser.h @@ -98,7 +98,7 @@ constexpr auto progUnitEndStmt{ "PROCEDURE"_tok || "MODULE"_tok || "SUBMODULE"_tok || "PROGRAM"_tok || "BLOCK DATA"_tok)}; constexpr auto constructEndStmtErrorRecovery{ - !progUnitEndStmt >> ("END"_tok >> SkipTo<'\n'>{} || ok)}; + !progUnitEndStmt >> (("!$ACC "_sptok >> "END"_tok) || "END"_tok >> SkipTo<'\n'>{} || ok)}; constexpr auto namedConstructEndStmtErrorRecovery{ constructEndStmtErrorRecovery >> missingOptionalName}; diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90 index 4e56add386ef8..fdf52071ab956 100644 --- a/flang/test/Driver/debug-parsing-log.f90 +++ b/flang/test/Driver/debug-parsing-log.f90 @@ -2,24 +2,14 @@ ! Below are just few lines extracted from the dump. The actual output is much _much_ bigger. -! CHECK: {{.*[/\\]}}debug-parsing-log.f90:25:1: IMPLICIT statement +! CHECK: {{.*[/\\]}}debug-parsing-log.f90:15:1: IMPLICIT statement ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ ! CHECK-NEXT: fail 3 -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: error: expected 'IMPLICIT NONE' +! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:15:1: error: expected 'IMPLICIT NONE' ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ -! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: IMPLICIT statement +! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:15:1: in the context: IMPLICIT statement ! CHECK-NEXT: END PROGRAM ! CHECK-NEXT: ^ - - - - - - - - - - END PROGRAM From acc06e89281857a08819ead366594315fe83f564 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Wed, 12 Mar 2025 17:11:18 -0700 Subject: [PATCH 03/10] back out mistake in constructEndStmtRecovery --- flang/lib/Parser/stmt-parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Parser/stmt-parser.h b/flang/lib/Parser/stmt-parser.h index 61e6b95f0ddbb..ee45c6fd5d38c 100644 --- a/flang/lib/Parser/stmt-parser.h +++ b/flang/lib/Parser/stmt-parser.h @@ -98,7 +98,7 @@ constexpr auto progUnitEndStmt{ "PROCEDURE"_tok || "MODULE"_tok || "SUBMODULE"_tok || "PROGRAM"_tok || "BLOCK DATA"_tok)}; constexpr auto constructEndStmtErrorRecovery{ - !progUnitEndStmt >> (("!$ACC "_sptok >> "END"_tok) || "END"_tok >> SkipTo<'\n'>{} || ok)}; + !progUnitEndStmt >> ("END"_tok >> SkipTo<'\n'>{} || ok)}; constexpr auto namedConstructEndStmtErrorRecovery{ constructEndStmtErrorRecovery >> missingOptionalName}; From af72c8ed5fb1eb3f5febe4a23fa09de1e9fa9e3e Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Fri, 14 Mar 2025 16:03:22 -0700 Subject: [PATCH 04/10] add recovery to openacc block parser --- flang/lib/Parser/openacc-parsers.cpp | 25 +++++-- flang/test/Parser/acc-data-statement.f90 | 83 ++++-------------------- 2 files changed, 33 insertions(+), 75 deletions(-) diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index 41aedd47d58bb..0144336da6d2d 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -23,9 +23,12 @@ namespace Fortran::parser { // other types of line comments from fixed form. constexpr auto startAccLine{skipStuffBeforeStatement >> withMessage( - "expected OpenACC directive sentinal: '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US, + "expected OpenACC directive sentinal: !$ACC (free-form) / C$ACC or *$ACC (fixed-form)"_err_en_US, "!$ACC "_sptok)}; -constexpr auto endAccLine{space >> endOfLine}; +constexpr auto endAccLine{space >> + recovery( + withMessage("expected end of OpenACC directive"_err_en_US, endOfLine), + SkipTo<'\n'>{} || ok)}; // Autogenerated clauses parser. Information is taken from ACC.td and the // parser is generated by tablegen. @@ -225,12 +228,19 @@ TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) TYPE_PARSER(startAccLine >> sourced(construct("END"_tok >> - sourced(Parser{})))) + sourced(recovery(Parser{}, + construct(pure( + llvm::acc::Directive::ACCD_data))))))) TYPE_PARSER(construct( Parser{} / endAccLine, block, - withMessage("expected OpenACC end block directive"_err_en_US, - Parser{} / endAccLine))) + // TODO: This still allows mismatched directives. + recovery(withMessage("expected OpenACC end block directive"_err_en_US, + Parser{} / endAccLine), + // TODO: Is there a simpler way to build this? + sourced(construct( + sourced(construct( + pure(llvm::acc::Directive::ACCD_data)))))))) // Standalone constructs TYPE_PARSER(construct( @@ -254,8 +264,11 @@ TYPE_PARSER(sourced(construct( TYPE_CONTEXT_PARSER("OpenACC construct"_en_US, startAccLine >> withMessage("expected OpenACC directive"_err_en_US, - first(construct(Parser{}), + // Combined constructs before block constructs so we try to match + // the longest possible match first. + first( construct(Parser{}), + construct(Parser{}), construct(Parser{}), construct( Parser{}), diff --git a/flang/test/Parser/acc-data-statement.f90 b/flang/test/Parser/acc-data-statement.f90 index 1e369a0db3780..163f0601f9047 100644 --- a/flang/test/Parser/acc-data-statement.f90 +++ b/flang/test/Parser/acc-data-statement.f90 @@ -56,7 +56,6 @@ program acc_data_test print *, "Inside if block" ! First error in the file. !CHECK: acc-data-statement.f90: - !CHECK-SAME: [[ELINE1:[0-9]+]]:{{[0-9]+}}: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: end if !CHECK-NEXT: ^ @@ -66,15 +65,6 @@ program acc_data_test !CHECK-NEXT: in the context: IF construct !CHECK-NEXT: if (.true.) then !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: end if - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copyout(a) - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: IF construct - !CHECK-NEXT: if (.true.) then - !CHECK-NEXT: ^ end if ! Data construct within DO loop @@ -84,8 +74,6 @@ program acc_data_test ! !$acc end data print *, "Loop iteration", i !CHECK: acc-data-statement.f90: - !CHECK-NOT: [[ELINE1]] - !CHECK-SAME: [[ELINE2:[0-9]+]]:{{[0-9]+}}: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: end do !CHECK-NEXT: ^ @@ -95,15 +83,6 @@ program acc_data_test !CHECK-NEXT: in the context: DO construct !CHECK-NEXT: do i = 1, 10 !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: end do - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data present(a) - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: DO construct - !CHECK-NEXT: do i = 1, 10 - !CHECK-NEXT: ^ end do ! Nested data constructs @@ -117,67 +96,31 @@ program acc_data_test print *, "Program finished" !CHECK: acc-data-statement.f90: - !CHECK-NOT: [[ELINE2]] - !CHECK-SAME: [[ELINE3:[0-9]+]]:{{[0-9]+}}: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: contains !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copy(s) !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: execution part - !CHECK-NEXT: !$acc data copy(a, b) create(c) - !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: contains - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(s) - !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copyin(a) !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK: acc-data-statement.f90: + !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: contains !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copyin(a) !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: execution part - !CHECK-NEXT: !$acc data copy(a, b) create(c) - !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: contains - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(s) - !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copy(a, b) create(d) !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: contains - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(s) - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copyin(a) - !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive + !CHECK: acc-data-statement.f90: + !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: contains - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copyin(a) - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(a, b) create(d) !CHECK-NEXT: ^ - !CHECK-NEXT: error: expected OpenACC end block directive - !CHECK-NEXT: contains - !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(a, b) create(d) + !CHECK-NEXT: $acc data copy(a, b) create(d) !CHECK-NEXT: ^ !CHECK-NEXT: in the context: execution part !CHECK-NEXT: !$acc data copy(a, b) create(c) @@ -212,14 +155,15 @@ subroutine negative_process_array(x) x = x + 1 ! !$acc end data print *, "Subroutine finished" - !CHECK: error: expected OpenACC directive - !CHECK-NEXT: !$acc data copy(x) - !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: specification construct + !CHECK: acc-data-statement.f90: + !CHECK-SAME: error: expected OpenACC end block directive + !CHECK-NEXT: end subroutine + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copy(x) !CHECK-NEXT: ^ - !CHECK-NEXT: in the context: specification part - !CHECK-NEXT: integer, intent(inout) :: x(:) + !CHECK-NEXT: in the context: SUBROUTINE subprogram + !CHECK-NEXT: subroutine negative_process_array(x) !CHECK-NEXT: ^ end subroutine @@ -232,7 +176,8 @@ function negative_compute_sum(x) result(total) total = total + x ! !$acc end data print *, "Function finished" - !CHECK: error: expected OpenACC end block directive + !CHECK: acc-data-statement.f90: + !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: end function !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct From 4ddd1772ce81a75f0f8959ca3d3ae49d4ba11fa4 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Fri, 14 Mar 2025 17:09:31 -0700 Subject: [PATCH 05/10] clean-up --- flang/lib/Parser/message.cpp | 12 ++++++---- flang/test/Parser/acc-data-statement.f90 | 29 ++++++++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp index 0b8d300189a1b..862e61b29b57f 100644 --- a/flang/lib/Parser/message.cpp +++ b/flang/lib/Parser/message.cpp @@ -272,7 +272,7 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) { return llvm::raw_ostream::SAVEDCOLOR; } -// FIXME: Make these configurable, based on verbosity level. +// TODO: Make these configurable, based on verbosity level. const int MAX_CONTEXTS_EMITTED = 2; const bool OMIT_SHARED_CONTEXTS = true; @@ -282,10 +282,12 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, const AllSources &sources{allCooked.allSources()}; sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()), PrefixColor(severity()), echoSourceLine); + // Always refers to if the attachment in the loop below is a context. bool isContext{attachmentIsContext_}; - int contextsEmitted{isContext ? 1 : 0}; + int contextsEmitted{0}; // Emit attachments. for (const Message *attachment{attachment_.get()}; attachment; + isContext = attachment->attachmentIsContext_, attachment = attachment->attachment_.get()) { Severity severity = isContext ? Severity::Context : attachment->severity(); auto emitAttachment = [&]() { @@ -293,10 +295,10 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, attachment->ToString(), Prefix(severity), PrefixColor(severity), echoSourceLine); }; - // TODO isContext is not used correctly here. - if (attachment->attachmentIsContext_) { + + if (isContext) { // Truncate the number of contexts emitted. - if (contextsEmitted <= MAX_CONTEXTS_EMITTED) { + if (contextsEmitted < MAX_CONTEXTS_EMITTED) { emitAttachment(); contextsEmitted += 1; } diff --git a/flang/test/Parser/acc-data-statement.f90 b/flang/test/Parser/acc-data-statement.f90 index 163f0601f9047..40c76b2561b24 100644 --- a/flang/test/Parser/acc-data-statement.f90 +++ b/flang/test/Parser/acc-data-statement.f90 @@ -41,7 +41,17 @@ program acc_data_test ! Negative tests ! Basic data construct in program body - !$acc data copy(a, b) create(d) + !$acc data copy(a, b) create(d) bogus() + !CHECK: acc-data-statement.f90: + !CHECK-SAME: error: expected end of OpenACC directive + !CHECK-NEXT: !$acc data copy(a, b) create(d) bogus() + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: OpenACC construct + !CHECK-NEXT: !$acc data copy(a, b) create(d) bogus() + !CHECK-NEXT: ^ + !CHECK-NEXT: in the context: execution part + !CHECK-NEXT: !$acc data copy(a, b) create(c) + !CHECK-NEXT: ^ a = 1 b = 2 d = a + b @@ -54,7 +64,6 @@ program acc_data_test a = a + 1 ! !$acc end data print *, "Inside if block" - ! First error in the file. !CHECK: acc-data-statement.f90: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: end if @@ -92,19 +101,19 @@ program acc_data_test s = s + 1 ! !$acc end data print *, "After nested data" -! !$acc end data - - print *, "Program finished" + !$acc end data I forgot to comment this out. !CHECK: acc-data-statement.f90: - !CHECK-SAME: error: expected OpenACC end block directive - !CHECK-NEXT: contains - !CHECK-NEXT: ^ + !CHECK-SAME: error: expected end of OpenACC directive + !CHECK-NEXT: !$acc end data I forgot to comment this out. + !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copy(s) !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct !CHECK-NEXT: !$acc data copyin(a) !CHECK-NEXT: ^ + print *, "Program finished" + !CHECK: acc-data-statement.f90: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: contains @@ -113,14 +122,14 @@ program acc_data_test !CHECK-NEXT: !$acc data copyin(a) !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: !$acc data copy(a, b) create(d) + !CHECK-NEXT: !$acc data copy(a, b) create(d) bogus() !CHECK-NEXT: ^ !CHECK: acc-data-statement.f90: !CHECK-SAME: error: expected OpenACC end block directive !CHECK-NEXT: contains !CHECK-NEXT: ^ !CHECK-NEXT: in the context: OpenACC construct - !CHECK-NEXT: $acc data copy(a, b) create(d) + !CHECK-NEXT: $acc data copy(a, b) create(d) bogus() !CHECK-NEXT: ^ !CHECK-NEXT: in the context: execution part !CHECK-NEXT: !$acc data copy(a, b) create(c) From 58229d75a76a4f90cba1a823322286c68544959c Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Mon, 17 Mar 2025 13:52:58 -0700 Subject: [PATCH 06/10] fix off by one error in position --- flang/lib/Parser/openacc-parsers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index 0144336da6d2d..5816ad7bc37d8 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -236,7 +236,7 @@ TYPE_PARSER(construct( Parser{} / endAccLine, block, // TODO: This still allows mismatched directives. recovery(withMessage("expected OpenACC end block directive"_err_en_US, - Parser{} / endAccLine), + attempt(Parser{} / endAccLine)), // TODO: Is there a simpler way to build this? sourced(construct( sourced(construct( From 990e9058587ba475d0ffa1d4da5001eba5dc2746 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Mon, 17 Mar 2025 15:26:52 -0700 Subject: [PATCH 07/10] addressing feedback --- flang/lib/Parser/message.cpp | 10 +++++----- flang/lib/Parser/openacc-parsers.cpp | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp index 862e61b29b57f..b97338f2266a1 100644 --- a/flang/lib/Parser/message.cpp +++ b/flang/lib/Parser/message.cpp @@ -273,8 +273,8 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) { } // TODO: Make these configurable, based on verbosity level. -const int MAX_CONTEXTS_EMITTED = 2; -const bool OMIT_SHARED_CONTEXTS = true; +static constexpr int MAX_CONTEXTS_EMITTED{2}; +static constexpr bool OMIT_SHARED_CONTEXTS{true}; void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, bool echoSourceLine) const { @@ -282,7 +282,7 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, const AllSources &sources{allCooked.allSources()}; sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()), PrefixColor(severity()), echoSourceLine); - // Always refers to if the attachment in the loop below is a context. + // Always refers to whether the attachment in the loop below is a context. bool isContext{attachmentIsContext_}; int contextsEmitted{0}; // Emit attachments. @@ -300,9 +300,9 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, // Truncate the number of contexts emitted. if (contextsEmitted < MAX_CONTEXTS_EMITTED) { emitAttachment(); - contextsEmitted += 1; + ++contextsEmitted; } - if (OMIT_SHARED_CONTEXTS) { + if constexpr (OMIT_SHARED_CONTEXTS) { // Skip less specific contexts at the same location. for (const Message *next_attachment{attachment->attachment_.get()}; next_attachment && next_attachment->attachmentIsContext_ && diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index 5816ad7bc37d8..89ebbe5a774d4 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -23,7 +23,7 @@ namespace Fortran::parser { // other types of line comments from fixed form. constexpr auto startAccLine{skipStuffBeforeStatement >> withMessage( - "expected OpenACC directive sentinal: !$ACC (free-form) / C$ACC or *$ACC (fixed-form)"_err_en_US, + "expected OpenACC directive sentinel: !$ACC (free-form) / C$ACC or *$ACC (fixed-form)"_err_en_US, "!$ACC "_sptok)}; constexpr auto endAccLine{space >> recovery( @@ -238,9 +238,8 @@ TYPE_PARSER(construct( recovery(withMessage("expected OpenACC end block directive"_err_en_US, attempt(Parser{} / endAccLine)), // TODO: Is there a simpler way to build this? - sourced(construct( - sourced(construct( - pure(llvm::acc::Directive::ACCD_data)))))))) + construct(construct( + pure(llvm::acc::Directive::ACCD_data)))))) // Standalone constructs TYPE_PARSER(construct( From b805e5e4127b8d5e4b5cce5e8be8047cd2ad0ee6 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Tue, 18 Mar 2025 16:51:37 -0700 Subject: [PATCH 08/10] update expected sentinel message --- flang/lib/Parser/openacc-parsers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index 89ebbe5a774d4..d6bf35d587c2d 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -23,7 +23,7 @@ namespace Fortran::parser { // other types of line comments from fixed form. constexpr auto startAccLine{skipStuffBeforeStatement >> withMessage( - "expected OpenACC directive sentinel: !$ACC (free-form) / C$ACC or *$ACC (fixed-form)"_err_en_US, + "expected OpenACC directive sentinel: !$ACC, C$ACC, or *$ACC"_err_en_US, "!$ACC "_sptok)}; constexpr auto endAccLine{space >> recovery( From 727a97725e7600c09f1aec940ef1f6bfabe598c8 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Fri, 21 Mar 2025 08:03:26 -0700 Subject: [PATCH 09/10] addressing TODOs in comments --- flang/lib/Parser/message.cpp | 6 ++++-- flang/lib/Parser/openacc-parsers.cpp | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp index b97338f2266a1..8e47647cf18ae 100644 --- a/flang/lib/Parser/message.cpp +++ b/flang/lib/Parser/message.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace Fortran::parser { @@ -272,7 +273,6 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) { return llvm::raw_ostream::SAVEDCOLOR; } -// TODO: Make these configurable, based on verbosity level. static constexpr int MAX_CONTEXTS_EMITTED{2}; static constexpr bool OMIT_SHARED_CONTEXTS{true}; @@ -282,7 +282,9 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, const AllSources &sources{allCooked.allSources()}; sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()), PrefixColor(severity()), echoSourceLine); - // Always refers to whether the attachment in the loop below is a context. + // Refers to whether the attachment in the loop below is a context, but can't + // be declared inside the loop because the previous iteration's + // attachment->attachmentIsContext_ indicates this. bool isContext{attachmentIsContext_}; int contextsEmitted{0}; // Emit attachments. diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index d6bf35d587c2d..a48982c84f2b0 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -228,18 +228,18 @@ TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) TYPE_PARSER(startAccLine >> sourced(construct("END"_tok >> - sourced(recovery(Parser{}, + recovery(sourced(Parser{}), construct(pure( - llvm::acc::Directive::ACCD_data))))))) + llvm::acc::Directive::ACCD_data)))))) TYPE_PARSER(construct( Parser{} / endAccLine, block, - // TODO: This still allows mismatched directives. + // NB, This allows mismatched directives, but semantics checks that they match. recovery(withMessage("expected OpenACC end block directive"_err_en_US, attempt(Parser{} / endAccLine)), - // TODO: Is there a simpler way to build this? - construct(construct( - pure(llvm::acc::Directive::ACCD_data)))))) + construct( + construct(pure( + llvm::acc::Directive::ACCD_data)))))) // Standalone constructs TYPE_PARSER(construct( From 5e75f73898a7ab53ac2c9f0daf891a2b37a1ad61 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt Date: Fri, 21 Mar 2025 08:04:29 -0700 Subject: [PATCH 10/10] clang-format --- flang/lib/Parser/message.cpp | 2 +- flang/lib/Parser/openacc-parsers.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp index 8e47647cf18ae..799998c54b531 100644 --- a/flang/lib/Parser/message.cpp +++ b/flang/lib/Parser/message.cpp @@ -283,7 +283,7 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked, sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()), PrefixColor(severity()), echoSourceLine); // Refers to whether the attachment in the loop below is a context, but can't - // be declared inside the loop because the previous iteration's + // be declared inside the loop because the previous iteration's // attachment->attachmentIsContext_ indicates this. bool isContext{attachmentIsContext_}; int contextsEmitted{0}; diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp index a48982c84f2b0..fb731ee52cbba 100644 --- a/flang/lib/Parser/openacc-parsers.cpp +++ b/flang/lib/Parser/openacc-parsers.cpp @@ -234,12 +234,12 @@ TYPE_PARSER(startAccLine >> sourced(construct("END"_tok >> TYPE_PARSER(construct( Parser{} / endAccLine, block, - // NB, This allows mismatched directives, but semantics checks that they match. + // NB, This allows mismatched directives, but semantics checks that they + // match. recovery(withMessage("expected OpenACC end block directive"_err_en_US, attempt(Parser{} / endAccLine)), - construct( - construct(pure( - llvm::acc::Directive::ACCD_data)))))) + construct(construct( + pure(llvm::acc::Directive::ACCD_data)))))) // Standalone constructs TYPE_PARSER(construct(