1use super::{
2 ClauseRegistry, ClauseRegistryBuilder, ClauseRule, DirectiveRegistry, DirectiveRegistryBuilder,
3 Parser,
4};
5
6const OPENMP_DEFAULT_CLAUSE_RULE: ClauseRule = ClauseRule::Unsupported;
7
8macro_rules! openmp_clauses {
9 ($( $variant:ident => { name: $name:literal, rule: $rule:expr } ),+ $(,)?) => {
10 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11 pub enum OpenMpClause {
12 $( $variant, )+
13 }
14
15 impl OpenMpClause {
16 pub const ALL: &'static [OpenMpClause] = &[ $( OpenMpClause::$variant, )+ ];
17
18 pub const fn name(self) -> &'static str {
19 match self {
20 $( OpenMpClause::$variant => $name, )+
21 }
22 }
23
24 pub const fn rule(self) -> ClauseRule {
25 match self {
26 $( OpenMpClause::$variant => $rule, )+
27 }
28 }
29 }
30 };
31}
32
33openmp_clauses! {
34 AcqRel => { name: "acq_rel", rule: ClauseRule::Bare },
35 Acquire => { name: "acquire", rule: ClauseRule::Bare },
36 Affinity => { name: "affinity", rule: ClauseRule::Parenthesized },
37 Aligned => { name: "aligned", rule: ClauseRule::Parenthesized },
38 Allocate => { name: "allocate", rule: ClauseRule::Parenthesized },
39 Allocator => { name: "allocator", rule: ClauseRule::Parenthesized },
40 AtomicDefaultMemOrder => { name: "atomic_default_mem_order", rule: ClauseRule::Parenthesized },
41 Bind => { name: "bind", rule: ClauseRule::Parenthesized },
42 Capture => { name: "capture", rule: ClauseRule::Flexible },
43 Collapse => { name: "collapse", rule: ClauseRule::Parenthesized },
44 Compare => { name: "compare", rule: ClauseRule::Flexible },
45 Copyin => { name: "copyin", rule: ClauseRule::Parenthesized },
46 Copyprivate => { name: "copyprivate", rule: ClauseRule::Parenthesized },
47 Default => { name: "default", rule: ClauseRule::Parenthesized },
48 Defaultmap => { name: "defaultmap", rule: ClauseRule::Parenthesized },
49 Depend => { name: "depend", rule: ClauseRule::Parenthesized },
50 Destroy => { name: "destroy", rule: ClauseRule::Flexible },
51 Detach => { name: "detach", rule: ClauseRule::Parenthesized },
52 Device => { name: "device", rule: ClauseRule::Parenthesized },
53 DeviceResident => { name: "device_resident", rule: ClauseRule::Parenthesized },
54 DeviceType => { name: "device_type", rule: ClauseRule::Parenthesized },
55 DistSchedule => { name: "dist_schedule", rule: ClauseRule::Parenthesized },
56 Doacross => { name: "doacross", rule: ClauseRule::Parenthesized },
57 DynamicAllocators => { name: "dynamic_allocators", rule: ClauseRule::Bare },
58 Exclusive => { name: "exclusive", rule: ClauseRule::Bare },
59 Fail => { name: "fail", rule: ClauseRule::Flexible },
60 Final => { name: "final", rule: ClauseRule::Parenthesized },
61 Filter => { name: "filter", rule: ClauseRule::Parenthesized },
62 Firstprivate => { name: "firstprivate", rule: ClauseRule::Parenthesized },
63 From => { name: "from", rule: ClauseRule::Parenthesized },
64 Grainsize => { name: "grainsize", rule: ClauseRule::Parenthesized },
65 Hint => { name: "hint", rule: ClauseRule::Parenthesized },
66 Holds => { name: "holds", rule: ClauseRule::Parenthesized },
67 If => { name: "if", rule: ClauseRule::Parenthesized },
68 InReduction => { name: "in_reduction", rule: ClauseRule::Parenthesized },
69 Inbranch => { name: "inbranch", rule: ClauseRule::Bare },
70 Inclusive => { name: "inclusive", rule: ClauseRule::Bare },
71 Init => { name: "init", rule: ClauseRule::Parenthesized },
72 Interop => { name: "interop", rule: ClauseRule::Parenthesized },
73 IsDevicePtr => { name: "is_device_ptr", rule: ClauseRule::Parenthesized },
74 Label => { name: "label", rule: ClauseRule::Parenthesized },
75 Lastprivate => { name: "lastprivate", rule: ClauseRule::Parenthesized },
76 Linear => { name: "linear", rule: ClauseRule::Parenthesized },
77 Link => { name: "link", rule: ClauseRule::Parenthesized },
78 Map => { name: "map", rule: ClauseRule::Parenthesized },
79 Match => { name: "match", rule: ClauseRule::Parenthesized },
80 Message => { name: "message", rule: ClauseRule::Parenthesized },
81 Mergeable => { name: "mergeable", rule: ClauseRule::Bare },
82 Nogroup => { name: "nogroup", rule: ClauseRule::Bare },
83 NoOpenmp => { name: "no_openmp", rule: ClauseRule::Flexible },
84 NoOpenmpRoutines => { name: "no_openmp_routines", rule: ClauseRule::Flexible },
85 NoParallelism => { name: "no_parallelism", rule: ClauseRule::Flexible },
86 Notinbranch => { name: "notinbranch", rule: ClauseRule::Bare },
87 Novariants => { name: "novariants", rule: ClauseRule::Flexible },
88 Nowait => { name: "nowait", rule: ClauseRule::Bare },
89 NumTasks => { name: "num_tasks", rule: ClauseRule::Parenthesized },
90 NumTeams => { name: "num_teams", rule: ClauseRule::Parenthesized },
91 NumThreads => { name: "num_threads", rule: ClauseRule::Parenthesized },
92 Nontemporal => { name: "nontemporal", rule: ClauseRule::Parenthesized },
93 Order => { name: "order", rule: ClauseRule::Parenthesized },
94 Ordered => { name: "ordered", rule: ClauseRule::Flexible },
95 Partial => { name: "partial", rule: ClauseRule::Flexible },
96 Priority => { name: "priority", rule: ClauseRule::Parenthesized },
97 Private => { name: "private", rule: ClauseRule::Parenthesized },
98 ProcBind => { name: "proc_bind", rule: ClauseRule::Parenthesized },
99 Public => { name: "public", rule: ClauseRule::Flexible },
100 Reduction => { name: "reduction", rule: ClauseRule::Parenthesized },
101 Release => { name: "release", rule: ClauseRule::Bare },
102 Relaxed => { name: "relaxed", rule: ClauseRule::Bare },
103 Reverse => { name: "reverse", rule: ClauseRule::Flexible },
104 Reproducible => { name: "reproducible", rule: ClauseRule::Bare },
105 Safelen => { name: "safelen", rule: ClauseRule::Parenthesized },
106 Schedule => { name: "schedule", rule: ClauseRule::Parenthesized },
107 SeqCst => { name: "seq_cst", rule: ClauseRule::Bare },
108 Shared => { name: "shared", rule: ClauseRule::Parenthesized },
109 Simdlen => { name: "simdlen", rule: ClauseRule::Parenthesized },
110 Sizes => { name: "sizes", rule: ClauseRule::Parenthesized },
111 TaskReduction => { name: "task_reduction", rule: ClauseRule::Parenthesized },
112 ThreadLimit => { name: "thread_limit", rule: ClauseRule::Parenthesized },
113 Tile => { name: "tile", rule: ClauseRule::Parenthesized },
114 To => { name: "to", rule: ClauseRule::Parenthesized },
115 UnifiedAddress => { name: "unified_address", rule: ClauseRule::Flexible },
116 UnifiedSharedMemory => { name: "unified_shared_memory", rule: ClauseRule::Flexible },
117 Unroll => { name: "unroll", rule: ClauseRule::Flexible },
118 Untied => { name: "untied", rule: ClauseRule::Bare },
119 Update => { name: "update", rule: ClauseRule::Flexible },
120 UseDeviceAddr => { name: "use_device_addr", rule: ClauseRule::Parenthesized },
121 UseDevicePtr => { name: "use_device_ptr", rule: ClauseRule::Parenthesized },
122 UsesAllocators => { name: "uses_allocators", rule: ClauseRule::Parenthesized },
123 Weak => { name: "weak", rule: ClauseRule::Flexible },
124 When => { name: "when", rule: ClauseRule::Parenthesized },
125}
126
127macro_rules! openmp_directives {
128 ($( $variant:ident => $name:literal ),+ $(,)?) => {
129 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
130 pub enum OpenMpDirective {
131 $( $variant, )+
132 }
133
134 impl OpenMpDirective {
135 pub const ALL: &'static [OpenMpDirective] = &[ $( OpenMpDirective::$variant, )+ ];
136
137 pub const fn as_str(self) -> &'static str {
138 match self {
139 $( OpenMpDirective::$variant => $name, )+
140 }
141 }
142 }
143 };
144}
145
146openmp_directives! {
147 Assume => "assume",
148 Atomic => "atomic",
149 AtomicCapture => "atomic capture",
150 AtomicCompareCapture => "atomic compare capture",
151 AtomicRead => "atomic read",
152 AtomicUpdate => "atomic update",
153 AtomicWrite => "atomic write",
154 Barrier => "barrier",
155 BeginDeclareTarget => "begin declare target",
156 Cancel => "cancel",
157 CancellationPoint => "cancellation point",
158 Critical => "critical",
159 DeclareMapper => "declare mapper",
160 DeclareReduction => "declare reduction",
161 DeclareSimd => "declare simd",
162 DeclareTarget => "declare target",
163 DeclareVariant => "declare variant",
164 Depobj => "depobj",
165 Dispatch => "dispatch",
166 Distribute => "distribute",
167 DistributeParallelFor => "distribute parallel for",
168 DistributeParallelForSimd => "distribute parallel for simd",
169 DistributeParallelLoop => "distribute parallel loop",
170 DistributeParallelLoopSimd => "distribute parallel loop simd",
171 DistributeSimd => "distribute simd",
172 DistributeParallelDo => "distribute parallel do", DistributeParallelDoSimd => "distribute parallel do simd", Do => "do", DoSimd => "do simd", EndDeclareTarget => "end declare target",
178 Error => "error",
179 Flush => "flush",
180 For => "for",
181 ForSimd => "for simd",
182 Interop => "interop",
183 Loop => "loop",
184 Masked => "masked",
185 MaskedTaskloop => "masked taskloop",
186 MaskedTaskloopSimd => "masked taskloop simd",
187 Master => "master",
188 Metadirective => "metadirective",
189 Nothing => "nothing",
190 Ordered => "ordered",
191 Parallel => "parallel",
192 ParallelDo => "parallel do", ParallelDoSimd => "parallel do simd", ParallelFor => "parallel for",
195 ParallelForSimd => "parallel for simd",
196 ParallelLoop => "parallel loop",
197 ParallelLoopSimd => "parallel loop simd",
198 ParallelMasked => "parallel masked",
199 ParallelMaskedTaskloop => "parallel masked taskloop",
200 ParallelMaskedTaskloopSimd => "parallel masked taskloop simd",
201 ParallelMaster => "parallel master",
202 ParallelMasterTaskloop => "parallel master taskloop",
203 ParallelMasterTaskloopSimd => "parallel master taskloop simd",
204 ParallelSections => "parallel sections",
205 Requires => "requires",
206 Scope => "scope",
207 Sections => "sections",
208 Simd => "simd",
209 Single => "single",
210 Target => "target",
211 TargetData => "target data",
212 TargetEnterData => "target enter data",
213 TargetExitData => "target exit data",
214 TargetLoop => "target loop",
215 TargetLoopSimd => "target loop simd",
216 TargetParallel => "target parallel",
217 TargetParallelDo => "target parallel do", TargetParallelDoSimd => "target parallel do simd", TargetParallelFor => "target parallel for",
220 TargetParallelForSimd => "target parallel for simd",
221 TargetParallelLoop => "target parallel loop",
222 TargetParallelLoopSimd => "target parallel loop simd",
223 TargetSimd => "target simd",
224 TargetTeams => "target teams",
225 TargetTeamsDistribute => "target teams distribute",
226 TargetTeamsDistributeParallelDo => "target teams distribute parallel do", TargetTeamsDistributeParallelDoSimd => "target teams distribute parallel do simd", TargetTeamsDistributeParallelFor => "target teams distribute parallel for",
229 TargetTeamsDistributeParallelForSimd => "target teams distribute parallel for simd",
230 TargetTeamsDistributeParallelLoop => "target teams distribute parallel loop",
231 TargetTeamsDistributeParallelLoopSimd => "target teams distribute parallel loop simd",
232 TargetTeamsDistributeSimd => "target teams distribute simd",
233 TargetTeamsLoop => "target teams loop",
234 TargetTeamsLoopSimd => "target teams loop simd",
235 TargetUpdate => "target update",
236 Task => "task",
237 Taskgroup => "taskgroup",
238 Taskgraph => "taskgraph",
239 Taskloop => "taskloop",
240 TaskloopSimd => "taskloop simd",
241 Taskwait => "taskwait",
242 Taskyield => "taskyield",
243 Teams => "teams",
244 TeamsDistribute => "teams distribute",
245 TeamsDistributeParallelDo => "teams distribute parallel do", TeamsDistributeParallelDoSimd => "teams distribute parallel do simd", TeamsDistributeParallelFor => "teams distribute parallel for",
248 TeamsDistributeParallelForSimd => "teams distribute parallel for simd",
249 TeamsDistributeParallelLoop => "teams distribute parallel loop",
250 TeamsDistributeParallelLoopSimd => "teams distribute parallel loop simd",
251 TeamsDistributeSimd => "teams distribute simd",
252 TeamsLoop => "teams loop",
253 TeamsLoopSimd => "teams loop simd",
254 Threadprivate => "threadprivate",
255}
256
257pub fn clause_registry() -> ClauseRegistry {
258 let mut builder = ClauseRegistryBuilder::new().with_default_rule(OPENMP_DEFAULT_CLAUSE_RULE);
259
260 for clause in OpenMpClause::ALL {
261 builder.register_with_rule_mut(clause.name(), clause.rule());
262 }
263
264 builder.build()
265}
266
267pub fn directive_registry() -> DirectiveRegistry {
268 let mut builder = DirectiveRegistryBuilder::new();
269
270 for directive in OpenMpDirective::ALL {
271 builder = builder.register_generic(directive.as_str());
272 }
273
274 builder.build()
275}
276
277pub fn parser() -> Parser {
278 Parser::new(directive_registry(), clause_registry())
279}