Skip to content

Commit 75e6d0e

Browse files
[flang][OpenMP]Add support for OpenMP ERROR directive (llvm#119582)
Lowering leads to a TODO, with a test to confirm. Also testing unparse. --------- Co-authored-by: Krzysztof Parzyszek <[email protected]>
1 parent ea8e328 commit 75e6d0e

File tree

11 files changed

+123
-1
lines changed

11 files changed

+123
-1
lines changed

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
143143
},
144144
c.u);
145145
},
146+
[&](const OpenMPErrorConstruct &c) -> std::string {
147+
const CharBlock &source{std::get<0>(c.t).source};
148+
return normalize_construct_name(source.ToString());
149+
},
146150
[&](const OpenMPSectionConstruct &c) -> std::string {
147151
return "section";
148152
},

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,9 @@ class ParseTreeDumper {
488488
NODE(parser, OmpAlignment)
489489
NODE(parser, OmpAlignedClause)
490490
NODE(OmpAlignedClause, Modifier)
491+
NODE(parser, OmpAtClause)
492+
NODE_ENUM(OmpAtClause, ActionTime)
493+
NODE_ENUM(OmpSeverityClause, Severity)
491494
NODE(parser, OmpAtomic)
492495
NODE(parser, OmpAtomicCapture)
493496
NODE(OmpAtomicCapture, Stmt1)
@@ -566,6 +569,7 @@ class ParseTreeDumper {
566569
NODE(parser, OmpStepSimpleModifier)
567570
NODE(parser, OmpLoopDirective)
568571
NODE(parser, OmpMapClause)
572+
NODE(parser, OmpMessageClause)
569573
NODE(OmpMapClause, Modifier)
570574
static std::string GetNodeName(const llvm::omp::Clause &x) {
571575
return llvm::Twine(
@@ -609,6 +613,7 @@ class ParseTreeDumper {
609613
NODE(parser, OmpScheduleClause)
610614
NODE(OmpScheduleClause, Modifier)
611615
NODE_ENUM(OmpScheduleClause, Kind)
616+
NODE(parser, OmpSeverityClause)
612617
NODE(parser, OmpDeviceClause)
613618
NODE(OmpDeviceClause, Modifier)
614619
NODE(parser, OmpDeviceModifier)
@@ -657,6 +662,7 @@ class ParseTreeDumper {
657662
NODE(parser, OmpAtomicDefaultMemOrderClause)
658663
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
659664
NODE(parser, OpenMPDepobjConstruct)
665+
NODE(parser, OpenMPErrorConstruct)
660666
NODE(parser, OpenMPFlushConstruct)
661667
NODE(parser, OpenMPLoopConstruct)
662668
NODE(parser, OpenMPExecutableAllocate)

flang/include/flang/Parser/parse-tree.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3778,6 +3778,13 @@ struct OmpAllocateClause {
37783778
std::tuple<MODIFIERS(), OmpObjectList> t;
37793779
};
37803780

3781+
// Ref: [5.2:216-217 (sort of, as it's only mentioned in passing)
3782+
// AT(compilation|execution)
3783+
struct OmpAtClause {
3784+
ENUM_CLASS(ActionTime, Compilation, Execution);
3785+
WRAPPER_CLASS_BOILERPLATE(OmpAtClause, ActionTime);
3786+
};
3787+
37813788
// Ref: [5.0:60-63], [5.1:83-86], [5.2:210-213]
37823789
//
37833790
// atomic-default-mem-order-clause ->
@@ -4028,6 +4035,13 @@ struct OmpMapClause {
40284035
std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t;
40294036
};
40304037

4038+
// Ref: [5.2:217-218]
4039+
// message-clause ->
4040+
// MESSAGE("message-text")
4041+
struct OmpMessageClause {
4042+
WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr);
4043+
};
4044+
40314045
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
40324046
//
40334047
// num-tasks-clause ->
@@ -4090,6 +4104,14 @@ struct OmpScheduleClause {
40904104
std::tuple<MODIFIERS(), Kind, std::optional<ScalarIntExpr>> t;
40914105
};
40924106

4107+
// REF: [5.2:217]
4108+
// severity-clause ->
4109+
// SEVERITY(warning|fatal)
4110+
struct OmpSeverityClause {
4111+
ENUM_CLASS(Severity, Fatal, Warning);
4112+
WRAPPER_CLASS_BOILERPLATE(OmpSeverityClause, Severity);
4113+
};
4114+
40934115
// Ref: [5.0:232-234], [5.1:264-266], [5.2:137]
40944116
//
40954117
// task-reduction-clause ->
@@ -4476,6 +4498,14 @@ struct OpenMPDepobjConstruct {
44764498
std::tuple<Verbatim, OmpObject, OmpClause> t;
44774499
};
44784500

4501+
// Ref: OpenMP [5.2:216-218]
4502+
// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str)
4503+
struct OpenMPErrorConstruct {
4504+
TUPLE_CLASS_BOILERPLATE(OpenMPErrorConstruct);
4505+
CharBlock source;
4506+
std::tuple<Verbatim, OmpClauseList> t;
4507+
};
4508+
44794509
// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)]
44804510
struct OpenMPFlushConstruct {
44814511
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
@@ -4548,7 +4578,7 @@ struct OpenMPConstruct {
45484578
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
45494579
std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
45504580
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
4551-
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate,
4581+
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPErrorConstruct,
45524582
OpenMPExecutableAllocate, OpenMPAllocatorsConstruct,
45534583
OpenMPCriticalConstruct>
45544584
u;

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,6 +2911,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
29112911
queue.begin(), name);
29122912
}
29132913

2914+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
2915+
semantics::SemanticsContext &semaCtx,
2916+
lower::pft::Evaluation &eval,
2917+
const parser::OpenMPErrorConstruct &) {
2918+
TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct");
2919+
}
2920+
29142921
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
29152922
semantics::SemanticsContext &semaCtx,
29162923
lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,16 @@ TYPE_PARSER(construct<OmpBindClause>(
567567
"TEAMS" >> pure(OmpBindClause::Binding::Teams) ||
568568
"THREAD" >> pure(OmpBindClause::Binding::Thread)))
569569

570+
TYPE_PARSER(construct<OmpAtClause>(
571+
"EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) ||
572+
"COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation)))
573+
574+
TYPE_PARSER(construct<OmpSeverityClause>(
575+
"FATAL" >> pure(OmpSeverityClause::Severity::Fatal) ||
576+
"WARNING" >> pure(OmpSeverityClause::Severity::Warning)))
577+
578+
TYPE_PARSER(construct<OmpMessageClause>(expr))
579+
570580
TYPE_PARSER(
571581
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
572582
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
@@ -578,6 +588,8 @@ TYPE_PARSER(
578588
parenthesized(Parser<OmpAllocateClause>{}))) ||
579589
"ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
580590
parenthesized(scalarIntExpr))) ||
591+
"AT" >> construct<OmpClause>(construct<OmpClause::At>(
592+
parenthesized(Parser<OmpAtClause>{}))) ||
581593
"ATOMIC_DEFAULT_MEM_ORDER" >>
582594
construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
583595
parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
@@ -645,6 +657,8 @@ TYPE_PARSER(
645657
"MAP" >> construct<OmpClause>(construct<OmpClause::Map>(
646658
parenthesized(Parser<OmpMapClause>{}))) ||
647659
"MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) ||
660+
"MESSAGE" >> construct<OmpClause>(construct<OmpClause::Message>(
661+
parenthesized(Parser<OmpMessageClause>{}))) ||
648662
"NOGROUP" >> construct<OmpClause>(construct<OmpClause::Nogroup>()) ||
649663
"NONTEMPORAL" >> construct<OmpClause>(construct<OmpClause::Nontemporal>(
650664
parenthesized(nonemptyList(name)))) ||
@@ -688,6 +702,8 @@ TYPE_PARSER(
688702
"SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>(
689703
parenthesized(Parser<OmpScheduleClause>{}))) ||
690704
"SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) ||
705+
"SEVERITY" >> construct<OmpClause>(construct<OmpClause::Severity>(
706+
parenthesized(Parser<OmpSeverityClause>{}))) ||
691707
"SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>(
692708
parenthesized(Parser<OmpObjectList>{}))) ||
693709
"SIMD"_id >> construct<OmpClause>(construct<OmpClause::Simd>()) ||
@@ -1011,6 +1027,9 @@ TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok),
10111027
TYPE_PARSER(construct<OpenMPCriticalConstruct>(
10121028
Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{}))
10131029

1030+
TYPE_PARSER(sourced(construct<OpenMPErrorConstruct>(
1031+
verbatim("ERROR"_tok), Parser<OmpClauseList>{})))
1032+
10141033
// 2.11.3 Executable Allocate directive
10151034
TYPE_PARSER(
10161035
sourced(construct<OpenMPExecutableAllocate>(verbatim("ALLOCATE"_tok),
@@ -1108,6 +1127,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
11081127
// OpenMPStandaloneConstruct to resolve !$OMP ORDERED
11091128
construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
11101129
construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
1130+
construct<OpenMPConstruct>(Parser<OpenMPErrorConstruct>{}),
11111131
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
11121132
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
11131133
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),

flang/lib/Parser/unparse.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,15 @@ class UnparseVisitor {
27062706
Put(")\n");
27072707
EndOpenMP();
27082708
}
2709+
bool Pre(const OmpMessageClause &x) {
2710+
Walk(x.v);
2711+
return false;
2712+
}
2713+
void Unparse(const OpenMPErrorConstruct &x) {
2714+
Word("!$OMP ERROR ");
2715+
Walk(x.t);
2716+
Put("\n");
2717+
}
27092718
void Unparse(const OmpSectionsDirective &x) {
27102719
switch (x.v) {
27112720
case llvm::omp::Directive::OMPD_sections:
@@ -2896,6 +2905,7 @@ class UnparseVisitor {
28962905
WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
28972906
WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
28982907
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
2908+
WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
28992909
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
29002910
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
29012911
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
@@ -2907,6 +2917,7 @@ class UnparseVisitor {
29072917
WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier
29082918
WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type
29092919
WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind
2920+
WALK_NESTED_ENUM(OmpSeverityClause, Severity) // OMP severity
29102921
WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier
29112922
WALK_NESTED_ENUM(
29122923
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
16901690
dirContext_.pop_back();
16911691
}
16921692

1693+
void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) {
1694+
const auto &dir{std::get<parser::Verbatim>(x.t)};
1695+
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error);
1696+
}
1697+
1698+
void OmpStructureChecker::Leave(const parser::OpenMPErrorConstruct &x) {
1699+
dirContext_.pop_back();
1700+
}
1701+
16931702
void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
16941703
isPredefinedAllocator = true;
16951704
const auto &dir{std::get<parser::Verbatim>(x.t)};

flang/lib/Semantics/check-omp-structure.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class OmpStructureChecker
102102
void Enter(const parser::OmpDeclareTargetWithList &);
103103
void Enter(const parser::OmpDeclareTargetWithClause &);
104104
void Leave(const parser::OmpDeclareTargetWithClause &);
105+
void Enter(const parser::OpenMPErrorConstruct &);
106+
void Leave(const parser::OpenMPErrorConstruct &);
105107
void Enter(const parser::OpenMPExecutableAllocate &);
106108
void Leave(const parser::OpenMPExecutableAllocate &);
107109
void Enter(const parser::OpenMPAllocatorsConstruct &);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
2+
3+
! CHECK: not yet implemented: OpenMPErrorConstruct
4+
program p
5+
integer, allocatable :: x
6+
!$omp error at(compilation) severity(warning) message("an error")
7+
end program p
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
2+
! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE"
3+
program main
4+
character(*), parameter :: message = "This is an error"
5+
!CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here")
6+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
7+
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation
8+
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Warning
9+
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> LiteralConstant -> CharLiteralConstant
10+
!$omp error at(compilation) severity(warning) message("some message here")
11+
!CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message)
12+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
13+
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation
14+
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal
15+
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message'
16+
!$omp error at(compilation) severity(fatal) message(message)
17+
!CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message)
18+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
19+
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Execution
20+
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal
21+
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message'
22+
!$omp error at(EXECUTION) severity(fatal) message(message)
23+
end program main

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def OMPC_AppendArgs : Clause<"append_args"> {
6666
}
6767
def OMPC_At : Clause<"at"> {
6868
let clangClass = "OMPAtClause";
69+
let flangClass = "OmpAtClause";
6970
}
7071
def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
7172
let clangClass = "OMPAtomicDefaultMemOrderClause";
@@ -288,6 +289,7 @@ def OMPC_Mergeable : Clause<"mergeable"> {
288289
}
289290
def OMPC_Message : Clause<"message"> {
290291
let clangClass = "OMPMessageClause";
292+
let flangClass = "OmpMessageClause";
291293
}
292294
def OMPC_NoOpenMP : Clause<"no_openmp"> {
293295
let clangClass = "OMPNoOpenMPClause";
@@ -445,6 +447,7 @@ def OMPC_SeqCst : Clause<"seq_cst"> {
445447
}
446448
def OMPC_Severity : Clause<"severity"> {
447449
let clangClass = "OMPSeverityClause";
450+
let flangClass = "OmpSeverityClause";
448451
}
449452
def OMPC_Shared : Clause<"shared"> {
450453
let clangClass = "OMPSharedClause";

0 commit comments

Comments
 (0)