From 744b13155581654f7caf72c8bfabbedd38ff27db Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Fri, 6 Dec 2024 17:37:35 +0000 Subject: [PATCH 1/4] [flang][OpenMP]Add support for OpenMP ERROR directive Lowering leads to a TODO, with a test to confirm. Also testing unparse. --- flang/include/flang/Parser/dump-parse-tree.h | 6 ++++ flang/include/flang/Parser/parse-tree.h | 32 +++++++++++++++++++- flang/lib/Lower/OpenMP/OpenMP.cpp | 7 +++++ flang/lib/Parser/openmp-parsers.cpp | 20 ++++++++++++ flang/lib/Parser/unparse.cpp | 13 ++++++++ flang/lib/Semantics/check-omp-structure.cpp | 9 ++++++ flang/lib/Semantics/check-omp-structure.h | 2 ++ flang/test/Lower/OpenMP/Todo/error.f90 | 7 +++++ flang/test/Parser/OpenMP/error-unparse.f90 | 5 +++ llvm/include/llvm/Frontend/OpenMP/OMP.td | 3 ++ 10 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 flang/test/Lower/OpenMP/Todo/error.f90 create mode 100644 flang/test/Parser/OpenMP/error-unparse.f90 diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index c6f35a07d81ea..f535f67767ae7 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -488,6 +488,9 @@ class ParseTreeDumper { NODE(parser, OmpAlignment) NODE(parser, OmpAlignedClause) NODE(OmpAlignedClause, Modifier) + NODE(parser, OmpAtClause) + NODE(OmpAtClause, ActionTime) + NODE(OmpSeverityClause, Severity) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) @@ -564,6 +567,7 @@ class ParseTreeDumper { NODE_ENUM(OmpLinearModifier, Value) NODE(parser, OmpLoopDirective) NODE(parser, OmpMapClause) + NODE(parser, OmpMessageClause) NODE(OmpMapClause, Modifier) static std::string GetNodeName(const llvm::omp::Clause &x) { return llvm::Twine( @@ -604,6 +608,7 @@ class ParseTreeDumper { NODE(parser, OmpScheduleClause) NODE(OmpScheduleClause, Modifier) NODE_ENUM(OmpScheduleClause, Kind) + NODE(parser, OmpSeverityClause) NODE(parser, OmpDeviceClause) NODE(OmpDeviceClause, Modifier) NODE(parser, OmpDeviceModifier) @@ -652,6 +657,7 @@ class ParseTreeDumper { NODE(parser, OmpAtomicDefaultMemOrderClause) NODE_ENUM(common, OmpAtomicDefaultMemOrderType) NODE(parser, OpenMPDepobjConstruct) + NODE(parser, OpenMPErrorConstruct) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPExecutableAllocate) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 8160b095f06dd..0001afc3a0efc 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3761,6 +3761,13 @@ struct OmpAllocateClause { std::tuple t; }; +// Ref: [5.2:216-217 (sort of, as it's only mentioned in passing) +// AT(compilation|execution) +struct OmpAtClause { + ENUM_CLASS(ActionTime, Compilation, Execution); + WRAPPER_CLASS_BOILERPLATE(OmpAtClause, ActionTime); +}; + // Ref: [5.0:60-63], [5.1:83-86], [5.2:210-213] // // atomic-default-mem-order-clause -> @@ -4008,6 +4015,13 @@ struct OmpMapClause { std::tuple t; }; +// Ref: [5.2:217-218] +// message-clause -> +// MESSAGE("message-text") +struct OmpMessageClause { + WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, std::string); +}; + // Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270] // // num-tasks-clause -> @@ -4070,6 +4084,14 @@ struct OmpScheduleClause { std::tuple> t; }; +// REF: [5.2:217] +// severity-clause -> +// SEVERITY(warning|fatal) +struct OmpSeverityClause { + ENUM_CLASS(Severity, Fatal, Warning); + WRAPPER_CLASS_BOILERPLATE(OmpSeverityClause, Severity); +}; + // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] // // to-clause (in DECLARE TARGET) -> @@ -4445,6 +4467,14 @@ struct OpenMPDepobjConstruct { std::tuple t; }; +// Ref: OpenMP [5.2:216-218] +// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str) +struct OpenMPErrorConstruct { + TUPLE_CLASS_BOILERPLATE(OpenMPErrorConstruct); + CharBlock source; + std::tuple t; +}; + // 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)] struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); @@ -4517,7 +4547,7 @@ struct OpenMPConstruct { UNION_CLASS_BOILERPLATE(OpenMPConstruct); std::variant u; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index cd30bbb89ce47..c1bfd8900cf1c 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2905,6 +2905,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, queue.begin(), name); } +static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, + const parser::OpenMPErrorConstruct &) { + TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct"); +} + static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 86d475c1a1542..0a102db09d632 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -507,6 +507,16 @@ TYPE_PARSER(construct( "TEAMS" >> pure(OmpBindClause::Binding::Teams) || "THREAD" >> pure(OmpBindClause::Binding::Thread))) +TYPE_PARSER(construct( + "EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) || + "COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation))) + +TYPE_PARSER(construct( + "FATAL" >> pure(OmpSeverityClause::Severity::Fatal) || + "WARNING" >> pure(OmpSeverityClause::Severity::Warning))) + +TYPE_PARSER(construct(charLiteralConstantWithoutKind)) + TYPE_PARSER( "ACQUIRE" >> construct(construct()) || "ACQ_REL" >> construct(construct()) || @@ -518,6 +528,8 @@ TYPE_PARSER( parenthesized(Parser{}))) || "ALLOCATOR" >> construct(construct( parenthesized(scalarIntExpr))) || + "AT" >> construct(construct( + parenthesized(Parser{}))) || "ATOMIC_DEFAULT_MEM_ORDER" >> construct(construct( parenthesized(Parser{}))) || @@ -585,6 +597,8 @@ TYPE_PARSER( "MAP" >> construct(construct( parenthesized(Parser{}))) || "MERGEABLE" >> construct(construct()) || + "MESSAGE" >> construct(construct( + parenthesized(Parser{}))) || "NOGROUP" >> construct(construct()) || "NONTEMPORAL" >> construct(construct( parenthesized(nonemptyList(name)))) || @@ -627,6 +641,8 @@ TYPE_PARSER( "SCHEDULE" >> construct(construct( parenthesized(Parser{}))) || "SEQ_CST" >> construct(construct()) || + "SEVERITY" >> construct(construct( + parenthesized(Parser{}))) || "SHARED" >> construct(construct( parenthesized(Parser{}))) || "SIMD"_id >> construct(construct()) || @@ -946,6 +962,9 @@ TYPE_PARSER(sourced(construct(verbatim("CRITICAL"_tok), TYPE_PARSER(construct( Parser{}, block, Parser{})) +TYPE_PARSER(sourced(construct( + verbatim("ERROR"_tok), Parser{}))) + // 2.11.3 Executable Allocate directive TYPE_PARSER( sourced(construct(verbatim("ALLOCATE"_tok), @@ -1043,6 +1062,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, // OpenMPStandaloneConstruct to resolve !$OMP ORDERED construct(Parser{}), construct(Parser{}), + construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 4782cc1f2d7d7..5847d690db744 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2651,6 +2651,17 @@ class UnparseVisitor { Put(")\n"); EndOpenMP(); } + bool Pre(const OmpMessageClause &x) { + Word("\""); + Walk(x.v); + Put("\""); + return false; + } + void Unparse(const OpenMPErrorConstruct &x) { + Word("!$OMP ERROR "); + Walk(x.t); + Put("\n"); + } void Unparse(const OmpSectionsDirective &x) { switch (x.v) { case llvm::omp::Directive::OMPD_sections: @@ -2835,6 +2846,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(InquireSpec::LogVar, Kind) WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506 WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410 + WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default @@ -2846,6 +2858,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind + WALK_NESTED_ENUM(OmpSeverityClause, Severity) // OMP severity WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier WALK_NESTED_ENUM( OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 27e2b946732ab..09c7b5e1e85d0 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1662,6 +1662,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) { + const auto &dir{std::get(x.t)}; + PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error); +} + +void OmpStructureChecker::Leave(const parser::OpenMPErrorConstruct &x) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) { isPredefinedAllocator = true; const auto &dir{std::get(x.t)}; diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 1411a9271d466..76eb605a53f08 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -102,6 +102,8 @@ class OmpStructureChecker void Enter(const parser::OmpDeclareTargetWithList &); void Enter(const parser::OmpDeclareTargetWithClause &); void Leave(const parser::OmpDeclareTargetWithClause &); + void Enter(const parser::OpenMPErrorConstruct &); + void Leave(const parser::OpenMPErrorConstruct &); void Enter(const parser::OpenMPExecutableAllocate &); void Leave(const parser::OpenMPExecutableAllocate &); void Enter(const parser::OpenMPAllocatorsConstruct &); diff --git a/flang/test/Lower/OpenMP/Todo/error.f90 b/flang/test/Lower/OpenMP/Todo/error.f90 new file mode 100644 index 0000000000000..b97e2c20a0cdf --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/error.f90 @@ -0,0 +1,7 @@ +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s + +! CHECK: not yet implemented: OpenMPErrorConstruct +program p + integer, allocatable :: x + !$omp error at(compilation) severity(warning) message("an error") +end program p diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90 new file mode 100644 index 0000000000000..e6e8d9aad2731 --- /dev/null +++ b/flang/test/Parser/OpenMP/error-unparse.f90 @@ -0,0 +1,5 @@ +! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s +program main + !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here") + !$omp error at(compilation) severity(warning) message("some message here") +end program main diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index bd7fb2361aaeb..96280322cf8e3 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -66,6 +66,7 @@ def OMPC_AppendArgs : Clause<"append_args"> { } def OMPC_At : Clause<"at"> { let clangClass = "OMPAtClause"; + let flangClass = "OmpAtClause"; } def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> { let clangClass = "OMPAtomicDefaultMemOrderClause"; @@ -287,6 +288,7 @@ def OMPC_Mergeable : Clause<"mergeable"> { } def OMPC_Message : Clause<"message"> { let clangClass = "OMPMessageClause"; + let flangClass = "OmpMessageClause"; } def OMPC_NoOpenMP : Clause<"no_openmp"> { let clangClass = "OMPNoOpenMPClause"; @@ -444,6 +446,7 @@ def OMPC_SeqCst : Clause<"seq_cst"> { } def OMPC_Severity : Clause<"severity"> { let clangClass = "OMPSeverityClause"; + let flangClass = "OmpSeverityClause"; } def OMPC_Shared : Clause<"shared"> { let clangClass = "OMPSharedClause"; From 0dd8e14e499a22e0f5c5a39bb6182702c49ee9db Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 12 Dec 2024 12:54:02 +0000 Subject: [PATCH 2/4] Allow any expression as message --- flang/include/flang/Parser/parse-tree.h | 2 +- flang/lib/Parser/openmp-parsers.cpp | 2 +- flang/lib/Parser/unparse.cpp | 2 -- flang/test/Parser/OpenMP/error-unparse.f90 | 5 +++++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 0001afc3a0efc..9f6290b251fe9 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4019,7 +4019,7 @@ struct OmpMapClause { // message-clause -> // MESSAGE("message-text") struct OmpMessageClause { - WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, std::string); + WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr); }; // Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270] diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 0a102db09d632..e4494ecc2641e 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -515,7 +515,7 @@ TYPE_PARSER(construct( "FATAL" >> pure(OmpSeverityClause::Severity::Fatal) || "WARNING" >> pure(OmpSeverityClause::Severity::Warning))) -TYPE_PARSER(construct(charLiteralConstantWithoutKind)) +TYPE_PARSER(construct(expr)) TYPE_PARSER( "ACQUIRE" >> construct(construct()) || diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 5847d690db744..c4deca78a975a 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2652,9 +2652,7 @@ class UnparseVisitor { EndOpenMP(); } bool Pre(const OmpMessageClause &x) { - Word("\""); Walk(x.v); - Put("\""); return false; } void Unparse(const OpenMPErrorConstruct &x) { diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90 index e6e8d9aad2731..27b2cd09776a9 100644 --- a/flang/test/Parser/OpenMP/error-unparse.f90 +++ b/flang/test/Parser/OpenMP/error-unparse.f90 @@ -1,5 +1,10 @@ ! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s program main + character(*), parameter :: message = "This is an error" !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here") !$omp error at(compilation) severity(warning) message("some message here") + !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message) + !$omp error at(compilation) severity(fatal) message(message) + !CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message) + !$omp error at(EXECUTION) severity(fatal) message(message) end program main From 11ddecc9f0c60afb1c1cdf633913265512c3013b Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 12 Dec 2024 14:01:48 +0000 Subject: [PATCH 3/4] Add dump-parse-tree tests --- flang/include/flang/Parser/dump-parse-tree.h | 4 ++-- flang/test/Parser/OpenMP/error-unparse.f90 | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index f535f67767ae7..54be5dc3d7dbe 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -489,8 +489,8 @@ class ParseTreeDumper { NODE(parser, OmpAlignedClause) NODE(OmpAlignedClause, Modifier) NODE(parser, OmpAtClause) - NODE(OmpAtClause, ActionTime) - NODE(OmpSeverityClause, Severity) + NODE_ENUM(OmpAtClause, ActionTime) + NODE_ENUM(OmpSeverityClause, Severity) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90 index 27b2cd09776a9..fce5d8cf22863 100644 --- a/flang/test/Parser/OpenMP/error-unparse.f90 +++ b/flang/test/Parser/OpenMP/error-unparse.f90 @@ -1,10 +1,23 @@ ! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE" program main character(*), parameter :: message = "This is an error" !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here") + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Warning + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> LiteralConstant -> CharLiteralConstant !$omp error at(compilation) severity(warning) message("some message here") !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' !$omp error at(compilation) severity(fatal) message(message) !CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Execution + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' !$omp error at(EXECUTION) severity(fatal) message(message) end program main From 368ff7ecc22187efb57298151db5ade557549e7d Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 12 Dec 2024 17:02:06 +0000 Subject: [PATCH 4/4] Fix broken example --- flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index 2dc480f0c901b..665b92be00898 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -143,6 +143,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) { }, c.u); }, + [&](const OpenMPErrorConstruct &c) -> std::string { + const CharBlock &source{std::get<0>(c.t).source}; + return normalize_construct_name(source.ToString()); + }, [&](const OpenMPSectionConstruct &c) -> std::string { return "section"; },