xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaOpenACC.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenACC constructs and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Sema/SemaOpenACC.h"
15 #include "clang/AST/StmtOpenACC.h"
16 #include "clang/Basic/DiagnosticSema.h"
17 #include "clang/Basic/OpenACCKinds.h"
18 #include "clang/Sema/Sema.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/Support/Casting.h"
21 
22 using namespace clang;
23 
24 namespace {
diagnoseConstructAppertainment(SemaOpenACC & S,OpenACCDirectiveKind K,SourceLocation StartLoc,bool IsStmt)25 bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
26                                     SourceLocation StartLoc, bool IsStmt) {
27   switch (K) {
28   default:
29   case OpenACCDirectiveKind::Invalid:
30     // Nothing to do here, both invalid and unimplemented don't really need to
31     // do anything.
32     break;
33   case OpenACCDirectiveKind::Parallel:
34   case OpenACCDirectiveKind::Serial:
35   case OpenACCDirectiveKind::Kernels:
36   case OpenACCDirectiveKind::Loop:
37     if (!IsStmt)
38       return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
39     break;
40   }
41   return false;
42 }
43 
doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,OpenACCClauseKind ClauseKind)44 bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind,
45                                 OpenACCClauseKind ClauseKind) {
46   switch (ClauseKind) {
47     // FIXME: For each clause as we implement them, we can add the
48     // 'legalization' list here.
49   case OpenACCClauseKind::Default:
50     switch (DirectiveKind) {
51     case OpenACCDirectiveKind::Parallel:
52     case OpenACCDirectiveKind::Serial:
53     case OpenACCDirectiveKind::Kernels:
54     case OpenACCDirectiveKind::ParallelLoop:
55     case OpenACCDirectiveKind::SerialLoop:
56     case OpenACCDirectiveKind::KernelsLoop:
57     case OpenACCDirectiveKind::Data:
58       return true;
59     default:
60       return false;
61     }
62   case OpenACCClauseKind::If:
63     switch (DirectiveKind) {
64     case OpenACCDirectiveKind::Parallel:
65     case OpenACCDirectiveKind::Serial:
66     case OpenACCDirectiveKind::Kernels:
67     case OpenACCDirectiveKind::Data:
68     case OpenACCDirectiveKind::EnterData:
69     case OpenACCDirectiveKind::ExitData:
70     case OpenACCDirectiveKind::HostData:
71     case OpenACCDirectiveKind::Init:
72     case OpenACCDirectiveKind::Shutdown:
73     case OpenACCDirectiveKind::Set:
74     case OpenACCDirectiveKind::Update:
75     case OpenACCDirectiveKind::Wait:
76     case OpenACCDirectiveKind::ParallelLoop:
77     case OpenACCDirectiveKind::SerialLoop:
78     case OpenACCDirectiveKind::KernelsLoop:
79       return true;
80     default:
81       return false;
82     }
83   case OpenACCClauseKind::Self:
84     switch (DirectiveKind) {
85     case OpenACCDirectiveKind::Parallel:
86     case OpenACCDirectiveKind::Serial:
87     case OpenACCDirectiveKind::Kernels:
88     case OpenACCDirectiveKind::Update:
89     case OpenACCDirectiveKind::ParallelLoop:
90     case OpenACCDirectiveKind::SerialLoop:
91     case OpenACCDirectiveKind::KernelsLoop:
92       return true;
93     default:
94       return false;
95     }
96   case OpenACCClauseKind::NumGangs:
97   case OpenACCClauseKind::NumWorkers:
98   case OpenACCClauseKind::VectorLength:
99     switch (DirectiveKind) {
100     case OpenACCDirectiveKind::Parallel:
101     case OpenACCDirectiveKind::Kernels:
102     case OpenACCDirectiveKind::ParallelLoop:
103     case OpenACCDirectiveKind::KernelsLoop:
104       return true;
105     default:
106       return false;
107     }
108   case OpenACCClauseKind::FirstPrivate:
109     switch (DirectiveKind) {
110     case OpenACCDirectiveKind::Parallel:
111     case OpenACCDirectiveKind::Serial:
112     case OpenACCDirectiveKind::ParallelLoop:
113     case OpenACCDirectiveKind::SerialLoop:
114       return true;
115     default:
116       return false;
117     }
118   case OpenACCClauseKind::Private:
119     switch (DirectiveKind) {
120     case OpenACCDirectiveKind::Parallel:
121     case OpenACCDirectiveKind::Serial:
122     case OpenACCDirectiveKind::Loop:
123     case OpenACCDirectiveKind::ParallelLoop:
124     case OpenACCDirectiveKind::SerialLoop:
125     case OpenACCDirectiveKind::KernelsLoop:
126       return true;
127     default:
128       return false;
129     }
130   case OpenACCClauseKind::NoCreate:
131     switch (DirectiveKind) {
132     case OpenACCDirectiveKind::Parallel:
133     case OpenACCDirectiveKind::Serial:
134     case OpenACCDirectiveKind::Kernels:
135     case OpenACCDirectiveKind::Data:
136     case OpenACCDirectiveKind::ParallelLoop:
137     case OpenACCDirectiveKind::SerialLoop:
138     case OpenACCDirectiveKind::KernelsLoop:
139       return true;
140     default:
141       return false;
142     }
143   case OpenACCClauseKind::Present:
144     switch (DirectiveKind) {
145     case OpenACCDirectiveKind::Parallel:
146     case OpenACCDirectiveKind::Serial:
147     case OpenACCDirectiveKind::Kernels:
148     case OpenACCDirectiveKind::Data:
149     case OpenACCDirectiveKind::Declare:
150     case OpenACCDirectiveKind::ParallelLoop:
151     case OpenACCDirectiveKind::SerialLoop:
152     case OpenACCDirectiveKind::KernelsLoop:
153       return true;
154     default:
155       return false;
156     }
157 
158   case OpenACCClauseKind::Copy:
159   case OpenACCClauseKind::PCopy:
160   case OpenACCClauseKind::PresentOrCopy:
161     switch (DirectiveKind) {
162     case OpenACCDirectiveKind::Parallel:
163     case OpenACCDirectiveKind::Serial:
164     case OpenACCDirectiveKind::Kernels:
165     case OpenACCDirectiveKind::Data:
166     case OpenACCDirectiveKind::Declare:
167     case OpenACCDirectiveKind::ParallelLoop:
168     case OpenACCDirectiveKind::SerialLoop:
169     case OpenACCDirectiveKind::KernelsLoop:
170       return true;
171     default:
172       return false;
173     }
174   case OpenACCClauseKind::CopyIn:
175   case OpenACCClauseKind::PCopyIn:
176   case OpenACCClauseKind::PresentOrCopyIn:
177     switch (DirectiveKind) {
178     case OpenACCDirectiveKind::Parallel:
179     case OpenACCDirectiveKind::Serial:
180     case OpenACCDirectiveKind::Kernels:
181     case OpenACCDirectiveKind::Data:
182     case OpenACCDirectiveKind::EnterData:
183     case OpenACCDirectiveKind::Declare:
184     case OpenACCDirectiveKind::ParallelLoop:
185     case OpenACCDirectiveKind::SerialLoop:
186     case OpenACCDirectiveKind::KernelsLoop:
187       return true;
188     default:
189       return false;
190     }
191   case OpenACCClauseKind::CopyOut:
192   case OpenACCClauseKind::PCopyOut:
193   case OpenACCClauseKind::PresentOrCopyOut:
194     switch (DirectiveKind) {
195     case OpenACCDirectiveKind::Parallel:
196     case OpenACCDirectiveKind::Serial:
197     case OpenACCDirectiveKind::Kernels:
198     case OpenACCDirectiveKind::Data:
199     case OpenACCDirectiveKind::ExitData:
200     case OpenACCDirectiveKind::Declare:
201     case OpenACCDirectiveKind::ParallelLoop:
202     case OpenACCDirectiveKind::SerialLoop:
203     case OpenACCDirectiveKind::KernelsLoop:
204       return true;
205     default:
206       return false;
207     }
208   case OpenACCClauseKind::Create:
209   case OpenACCClauseKind::PCreate:
210   case OpenACCClauseKind::PresentOrCreate:
211     switch (DirectiveKind) {
212     case OpenACCDirectiveKind::Parallel:
213     case OpenACCDirectiveKind::Serial:
214     case OpenACCDirectiveKind::Kernels:
215     case OpenACCDirectiveKind::Data:
216     case OpenACCDirectiveKind::EnterData:
217     case OpenACCDirectiveKind::ParallelLoop:
218     case OpenACCDirectiveKind::SerialLoop:
219     case OpenACCDirectiveKind::KernelsLoop:
220       return true;
221     default:
222       return false;
223     }
224 
225   case OpenACCClauseKind::Attach:
226     switch (DirectiveKind) {
227     case OpenACCDirectiveKind::Parallel:
228     case OpenACCDirectiveKind::Serial:
229     case OpenACCDirectiveKind::Kernels:
230     case OpenACCDirectiveKind::Data:
231     case OpenACCDirectiveKind::EnterData:
232     case OpenACCDirectiveKind::ParallelLoop:
233     case OpenACCDirectiveKind::SerialLoop:
234     case OpenACCDirectiveKind::KernelsLoop:
235       return true;
236     default:
237       return false;
238     }
239   case OpenACCClauseKind::DevicePtr:
240     switch (DirectiveKind) {
241     case OpenACCDirectiveKind::Parallel:
242     case OpenACCDirectiveKind::Serial:
243     case OpenACCDirectiveKind::Kernels:
244     case OpenACCDirectiveKind::Data:
245     case OpenACCDirectiveKind::Declare:
246     case OpenACCDirectiveKind::ParallelLoop:
247     case OpenACCDirectiveKind::SerialLoop:
248     case OpenACCDirectiveKind::KernelsLoop:
249       return true;
250     default:
251       return false;
252     }
253   case OpenACCClauseKind::Async:
254     switch (DirectiveKind) {
255     case OpenACCDirectiveKind::Parallel:
256     case OpenACCDirectiveKind::Serial:
257     case OpenACCDirectiveKind::Kernels:
258     case OpenACCDirectiveKind::Data:
259     case OpenACCDirectiveKind::EnterData:
260     case OpenACCDirectiveKind::ExitData:
261     case OpenACCDirectiveKind::Set:
262     case OpenACCDirectiveKind::Update:
263     case OpenACCDirectiveKind::Wait:
264     case OpenACCDirectiveKind::ParallelLoop:
265     case OpenACCDirectiveKind::SerialLoop:
266     case OpenACCDirectiveKind::KernelsLoop:
267       return true;
268     default:
269       return false;
270     }
271   case OpenACCClauseKind::Wait:
272     switch (DirectiveKind) {
273     case OpenACCDirectiveKind::Parallel:
274     case OpenACCDirectiveKind::Serial:
275     case OpenACCDirectiveKind::Kernels:
276     case OpenACCDirectiveKind::Data:
277     case OpenACCDirectiveKind::EnterData:
278     case OpenACCDirectiveKind::ExitData:
279     case OpenACCDirectiveKind::Update:
280     case OpenACCDirectiveKind::ParallelLoop:
281     case OpenACCDirectiveKind::SerialLoop:
282     case OpenACCDirectiveKind::KernelsLoop:
283       return true;
284     default:
285       return false;
286     }
287 
288   case OpenACCClauseKind::Seq:
289     switch (DirectiveKind) {
290     case OpenACCDirectiveKind::Loop:
291     case OpenACCDirectiveKind::Routine:
292     case OpenACCDirectiveKind::ParallelLoop:
293     case OpenACCDirectiveKind::SerialLoop:
294     case OpenACCDirectiveKind::KernelsLoop:
295       return true;
296     default:
297       return false;
298     }
299 
300   case OpenACCClauseKind::Independent:
301   case OpenACCClauseKind::Auto:
302     switch (DirectiveKind) {
303     case OpenACCDirectiveKind::Loop:
304     case OpenACCDirectiveKind::ParallelLoop:
305     case OpenACCDirectiveKind::SerialLoop:
306     case OpenACCDirectiveKind::KernelsLoop:
307       return true;
308     default:
309       return false;
310     }
311 
312   case OpenACCClauseKind::Reduction:
313     switch (DirectiveKind) {
314     case OpenACCDirectiveKind::Parallel:
315     case OpenACCDirectiveKind::Serial:
316     case OpenACCDirectiveKind::Loop:
317     case OpenACCDirectiveKind::ParallelLoop:
318     case OpenACCDirectiveKind::SerialLoop:
319     case OpenACCDirectiveKind::KernelsLoop:
320       return true;
321     default:
322       return false;
323     }
324 
325   case OpenACCClauseKind::DeviceType:
326   case OpenACCClauseKind::DType:
327     switch (DirectiveKind) {
328     case OpenACCDirectiveKind::Parallel:
329     case OpenACCDirectiveKind::Serial:
330     case OpenACCDirectiveKind::Kernels:
331     case OpenACCDirectiveKind::Data:
332     case OpenACCDirectiveKind::Init:
333     case OpenACCDirectiveKind::Shutdown:
334     case OpenACCDirectiveKind::Set:
335     case OpenACCDirectiveKind::Update:
336     case OpenACCDirectiveKind::Loop:
337     case OpenACCDirectiveKind::Routine:
338     case OpenACCDirectiveKind::ParallelLoop:
339     case OpenACCDirectiveKind::SerialLoop:
340     case OpenACCDirectiveKind::KernelsLoop:
341       return true;
342     default:
343       return false;
344     }
345 
346   default:
347     // Do nothing so we can go to the 'unimplemented' diagnostic instead.
348     return true;
349   }
350   llvm_unreachable("Invalid clause kind");
351 }
352 
checkAlreadyHasClauseOfKind(SemaOpenACC & S,ArrayRef<const OpenACCClause * > ExistingClauses,SemaOpenACC::OpenACCParsedClause & Clause)353 bool checkAlreadyHasClauseOfKind(
354     SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses,
355     SemaOpenACC::OpenACCParsedClause &Clause) {
356   const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) {
357     return C->getClauseKind() == Clause.getClauseKind();
358   });
359   if (Itr != ExistingClauses.end()) {
360     S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed)
361         << Clause.getDirectiveKind() << Clause.getClauseKind();
362     S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
363     return true;
364   }
365   return false;
366 }
367 
checkValidAfterDeviceType(SemaOpenACC & S,const OpenACCDeviceTypeClause & DeviceTypeClause,const SemaOpenACC::OpenACCParsedClause & NewClause)368 bool checkValidAfterDeviceType(
369     SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
370     const SemaOpenACC::OpenACCParsedClause &NewClause) {
371   // This is only a requirement on compute and loop constructs so far, so this
372   // is fine otherwise.
373   if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) &&
374       NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
375     return false;
376 
377   // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
378   // default clauses.  Clauses that follow a device_type clause up to the end of
379   // the directive or up to the next device_type clause are device-specific
380   // clauses for the device types specified in the device_type argument.
381   //
382   // The above implies that despite what the individual text says, these are
383   // valid.
384   if (NewClause.getClauseKind() == OpenACCClauseKind::DType ||
385       NewClause.getClauseKind() == OpenACCClauseKind::DeviceType)
386     return false;
387 
388   // Implement check from OpenACC3.3: section 2.5.4:
389   // Only the async, wait, num_gangs, num_workers, and vector_length clauses may
390   // follow a device_type clause.
391   if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) {
392     switch (NewClause.getClauseKind()) {
393     case OpenACCClauseKind::Async:
394     case OpenACCClauseKind::Wait:
395     case OpenACCClauseKind::NumGangs:
396     case OpenACCClauseKind::NumWorkers:
397     case OpenACCClauseKind::VectorLength:
398       return false;
399     default:
400       break;
401     }
402   } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) {
403     // Implement check from OpenACC3.3: section 2.9:
404     // Only the collapse, gang, worker, vector, seq, independent, auto, and tile
405     // clauses may follow a device_type clause.
406     switch (NewClause.getClauseKind()) {
407     case OpenACCClauseKind::Collapse:
408     case OpenACCClauseKind::Gang:
409     case OpenACCClauseKind::Worker:
410     case OpenACCClauseKind::Vector:
411     case OpenACCClauseKind::Seq:
412     case OpenACCClauseKind::Independent:
413     case OpenACCClauseKind::Auto:
414     case OpenACCClauseKind::Tile:
415       return false;
416     default:
417       break;
418     }
419   }
420   S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
421       << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
422       << isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())
423       << NewClause.getDirectiveKind();
424   S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here);
425   return true;
426 }
427 
428 class SemaOpenACCClauseVisitor {
429   SemaOpenACC &SemaRef;
430   ASTContext &Ctx;
431   ArrayRef<const OpenACCClause *> ExistingClauses;
432   bool NotImplemented = false;
433 
isNotImplemented()434   OpenACCClause *isNotImplemented() {
435     NotImplemented = true;
436     return nullptr;
437   }
438 
439 public:
SemaOpenACCClauseVisitor(SemaOpenACC & S,ArrayRef<const OpenACCClause * > ExistingClauses)440   SemaOpenACCClauseVisitor(SemaOpenACC &S,
441                            ArrayRef<const OpenACCClause *> ExistingClauses)
442       : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {}
443   // Once we've implemented everything, we shouldn't need this infrastructure.
444   // But in the meantime, we use this to help decide whether the clause was
445   // handled for this directive.
diagNotImplemented()446   bool diagNotImplemented() { return NotImplemented; }
447 
Visit(SemaOpenACC::OpenACCParsedClause & Clause)448   OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) {
449     switch (Clause.getClauseKind()) {
450   case OpenACCClauseKind::Gang:
451   case OpenACCClauseKind::Worker:
452   case OpenACCClauseKind::Vector: {
453     // TODO OpenACC: These are only implemented enough for the 'seq' diagnostic,
454     // otherwise treats itself as unimplemented.  When we implement these, we
455     // can remove them from here.
456 
457     // OpenACC 3.3 2.9:
458     // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
459     // appears.
460     const auto *Itr =
461         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
462 
463     if (Itr != ExistingClauses.end()) {
464       SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
465           << Clause.getClauseKind() << (*Itr)->getClauseKind();
466       SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
467     }
468     return isNotImplemented();
469   }
470 
471 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
472   case OpenACCClauseKind::CLAUSE_NAME:                                         \
473     return Visit##CLAUSE_NAME##Clause(Clause);
474 #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED)                           \
475   case OpenACCClauseKind::ALIAS:                                               \
476   if (DEPRECATED)                                                              \
477     SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)   \
478         << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME;           \
479   return Visit##CLAUSE_NAME##Clause(Clause);
480 #include "clang/Basic/OpenACCClauses.def"
481     default:
482       return isNotImplemented();
483     }
484     llvm_unreachable("Invalid clause kind");
485   }
486 
487 #define VISIT_CLAUSE(CLAUSE_NAME)                                              \
488   OpenACCClause *Visit##CLAUSE_NAME##Clause(                                   \
489       SemaOpenACC::OpenACCParsedClause &Clause);
490 #include "clang/Basic/OpenACCClauses.def"
491 };
492 
VisitDefaultClause(SemaOpenACC::OpenACCParsedClause & Clause)493 OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause(
494     SemaOpenACC::OpenACCParsedClause &Clause) {
495   // Restrictions only properly implemented on 'compute' constructs, and
496   // 'compute' constructs are the only construct that can do anything with
497   // this yet, so skip/treat as unimplemented in this case.
498   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
499     return isNotImplemented();
500 
501   // Don't add an invalid clause to the AST.
502   if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid)
503     return nullptr;
504 
505   // OpenACC 3.3, Section 2.5.4:
506   // At most one 'default' clause may appear, and it must have a value of
507   // either 'none' or 'present'.
508   // Second half of the sentence is diagnosed during parsing.
509   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
510     return nullptr;
511 
512   return OpenACCDefaultClause::Create(
513       Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(),
514       Clause.getLParenLoc(), Clause.getEndLoc());
515 }
516 
VisitIfClause(SemaOpenACC::OpenACCParsedClause & Clause)517 OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
518     SemaOpenACC::OpenACCParsedClause &Clause) {
519   // Restrictions only properly implemented on 'compute' constructs, and
520   // 'compute' constructs are the only construct that can do anything with
521   // this yet, so skip/treat as unimplemented in this case.
522   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
523     return isNotImplemented();
524 
525   // There is no prose in the standard that says duplicates aren't allowed,
526   // but this diagnostic is present in other compilers, as well as makes
527   // sense.
528   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
529     return nullptr;
530 
531   // The parser has ensured that we have a proper condition expr, so there
532   // isn't really much to do here.
533 
534   // If the 'if' clause is true, it makes the 'self' clause have no effect,
535   // diagnose that here.
536   // TODO OpenACC: When we add these two to other constructs, we might not
537   // want to warn on this (for example, 'update').
538   const auto *Itr =
539       llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>);
540   if (Itr != ExistingClauses.end()) {
541     SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
542     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
543   }
544 
545   return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(),
546                                  Clause.getLParenLoc(),
547                                  Clause.getConditionExpr(), Clause.getEndLoc());
548 }
549 
VisitSelfClause(SemaOpenACC::OpenACCParsedClause & Clause)550 OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause(
551     SemaOpenACC::OpenACCParsedClause &Clause) {
552   // Restrictions only properly implemented on 'compute' constructs, and
553   // 'compute' constructs are the only construct that can do anything with
554   // this yet, so skip/treat as unimplemented in this case.
555   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
556     return isNotImplemented();
557 
558   // TODO OpenACC: When we implement this for 'update', this takes a
559   // 'var-list' instead of a condition expression, so semantics/handling has
560   // to happen differently here.
561 
562   // There is no prose in the standard that says duplicates aren't allowed,
563   // but this diagnostic is present in other compilers, as well as makes
564   // sense.
565   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
566     return nullptr;
567 
568   // If the 'if' clause is true, it makes the 'self' clause have no effect,
569   // diagnose that here.
570   // TODO OpenACC: When we add these two to other constructs, we might not
571   // want to warn on this (for example, 'update').
572   const auto *Itr =
573       llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>);
574   if (Itr != ExistingClauses.end()) {
575     SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict);
576     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
577   }
578   return OpenACCSelfClause::Create(
579       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
580       Clause.getConditionExpr(), Clause.getEndLoc());
581 }
582 
VisitNumGangsClause(SemaOpenACC::OpenACCParsedClause & Clause)583 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause(
584     SemaOpenACC::OpenACCParsedClause &Clause) {
585   // Restrictions only properly implemented on 'compute' constructs, and
586   // 'compute' constructs are the only construct that can do anything with
587   // this yet, so skip/treat as unimplemented in this case.
588   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
589     return isNotImplemented();
590 
591   // There is no prose in the standard that says duplicates aren't allowed,
592   // but this diagnostic is present in other compilers, as well as makes
593   // sense.
594   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
595     return nullptr;
596 
597   // num_gangs requires at least 1 int expr in all forms.  Diagnose here, but
598   // allow us to continue, an empty clause might be useful for future
599   // diagnostics.
600   if (Clause.getIntExprs().empty())
601     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
602         << /*NoArgs=*/0;
603 
604   unsigned MaxArgs =
605       (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel ||
606        Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop)
607           ? 3
608           : 1;
609   // The max number of args differs between parallel and other constructs.
610   // Again, allow us to continue for the purposes of future diagnostics.
611   if (Clause.getIntExprs().size() > MaxArgs)
612     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args)
613         << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs
614         << Clause.getIntExprs().size();
615 
616   // OpenACC 3.3 Section 2.5.4:
617   // A reduction clause may not appear on a parallel construct with a
618   // num_gangs clause that has more than one argument.
619   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel &&
620       Clause.getIntExprs().size() > 1) {
621     auto *Parallel =
622         llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>);
623 
624     if (Parallel != ExistingClauses.end()) {
625       SemaRef.Diag(Clause.getBeginLoc(),
626                    diag::err_acc_reduction_num_gangs_conflict)
627           << Clause.getIntExprs().size();
628       SemaRef.Diag((*Parallel)->getBeginLoc(),
629                    diag::note_acc_previous_clause_here);
630       return nullptr;
631     }
632   }
633   return OpenACCNumGangsClause::Create(
634       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(),
635       Clause.getEndLoc());
636 }
637 
VisitNumWorkersClause(SemaOpenACC::OpenACCParsedClause & Clause)638 OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause(
639     SemaOpenACC::OpenACCParsedClause &Clause) {
640   // Restrictions only properly implemented on 'compute' constructs, and
641   // 'compute' constructs are the only construct that can do anything with
642   // this yet, so skip/treat as unimplemented in this case.
643   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
644     return isNotImplemented();
645 
646   // There is no prose in the standard that says duplicates aren't allowed,
647   // but this diagnostic is present in other compilers, as well as makes
648   // sense.
649   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
650     return nullptr;
651 
652   assert(Clause.getIntExprs().size() == 1 &&
653          "Invalid number of expressions for NumWorkers");
654   return OpenACCNumWorkersClause::Create(
655       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
656       Clause.getEndLoc());
657 }
658 
VisitVectorLengthClause(SemaOpenACC::OpenACCParsedClause & Clause)659 OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
660     SemaOpenACC::OpenACCParsedClause &Clause) {
661   // Restrictions only properly implemented on 'compute' constructs, and
662   // 'compute' constructs are the only construct that can do anything with
663   // this yet, so skip/treat as unimplemented in this case.
664   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
665     return isNotImplemented();
666 
667   // There is no prose in the standard that says duplicates aren't allowed,
668   // but this diagnostic is present in other compilers, as well as makes
669   // sense.
670   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
671     return nullptr;
672 
673   assert(Clause.getIntExprs().size() == 1 &&
674          "Invalid number of expressions for NumWorkers");
675   return OpenACCVectorLengthClause::Create(
676       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0],
677       Clause.getEndLoc());
678 }
679 
VisitAsyncClause(SemaOpenACC::OpenACCParsedClause & Clause)680 OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
681     SemaOpenACC::OpenACCParsedClause &Clause) {
682   // Restrictions only properly implemented on 'compute' constructs, and
683   // 'compute' constructs are the only construct that can do anything with
684   // this yet, so skip/treat as unimplemented in this case.
685   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
686     return isNotImplemented();
687 
688   // There is no prose in the standard that says duplicates aren't allowed,
689   // but this diagnostic is present in other compilers, as well as makes
690   // sense.
691   if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
692     return nullptr;
693 
694   assert(Clause.getNumIntExprs() < 2 &&
695          "Invalid number of expressions for Async");
696   return OpenACCAsyncClause::Create(
697       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(),
698       Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr,
699       Clause.getEndLoc());
700 }
701 
VisitPrivateClause(SemaOpenACC::OpenACCParsedClause & Clause)702 OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause(
703     SemaOpenACC::OpenACCParsedClause &Clause) {
704   // Restrictions only properly implemented on 'compute' and 'loop'
705   // constructs, and 'compute'/'loop' constructs are the only construct that
706   // can do anything with this yet, so skip/treat as unimplemented in this
707   // case.
708   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
709       Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
710     return isNotImplemented();
711 
712   // ActOnVar ensured that everything is a valid variable reference, so there
713   // really isn't anything to do here. GCC does some duplicate-finding, though
714   // it isn't apparent in the standard where this is justified.
715 
716   return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(),
717                                       Clause.getLParenLoc(),
718                                       Clause.getVarList(), Clause.getEndLoc());
719 }
720 
VisitFirstPrivateClause(SemaOpenACC::OpenACCParsedClause & Clause)721 OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause(
722     SemaOpenACC::OpenACCParsedClause &Clause) {
723   // Restrictions only properly implemented on 'compute' constructs, and
724   // 'compute' constructs are the only construct that can do anything with
725   // this yet, so skip/treat as unimplemented in this case.
726   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
727     return isNotImplemented();
728 
729   // ActOnVar ensured that everything is a valid variable reference, so there
730   // really isn't anything to do here. GCC does some duplicate-finding, though
731   // it isn't apparent in the standard where this is justified.
732 
733   return OpenACCFirstPrivateClause::Create(
734       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
735       Clause.getEndLoc());
736 }
737 
VisitNoCreateClause(SemaOpenACC::OpenACCParsedClause & Clause)738 OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
739     SemaOpenACC::OpenACCParsedClause &Clause) {
740   // Restrictions only properly implemented on 'compute' constructs, and
741   // 'compute' constructs are the only construct that can do anything with
742   // this yet, so skip/treat as unimplemented in this case.
743   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
744     return isNotImplemented();
745   // ActOnVar ensured that everything is a valid variable reference, so there
746   // really isn't anything to do here. GCC does some duplicate-finding, though
747   // it isn't apparent in the standard where this is justified.
748 
749   return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(),
750                                        Clause.getLParenLoc(),
751                                        Clause.getVarList(), Clause.getEndLoc());
752 }
753 
VisitPresentClause(SemaOpenACC::OpenACCParsedClause & Clause)754 OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
755     SemaOpenACC::OpenACCParsedClause &Clause) {
756   // Restrictions only properly implemented on 'compute' constructs, and
757   // 'compute' constructs are the only construct that can do anything with
758   // this yet, so skip/treat as unimplemented in this case.
759   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
760     return isNotImplemented();
761   // ActOnVar ensured that everything is a valid variable reference, so there
762   // really isn't anything to do here. GCC does some duplicate-finding, though
763   // it isn't apparent in the standard where this is justified.
764 
765   return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(),
766                                       Clause.getLParenLoc(),
767                                       Clause.getVarList(), Clause.getEndLoc());
768 }
769 
VisitCopyClause(SemaOpenACC::OpenACCParsedClause & Clause)770 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause(
771     SemaOpenACC::OpenACCParsedClause &Clause) {
772   // Restrictions only properly implemented on 'compute' constructs, and
773   // 'compute' constructs are the only construct that can do anything with
774   // this yet, so skip/treat as unimplemented in this case.
775   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
776     return isNotImplemented();
777   // ActOnVar ensured that everything is a valid variable reference, so there
778   // really isn't anything to do here. GCC does some duplicate-finding, though
779   // it isn't apparent in the standard where this is justified.
780 
781   return OpenACCCopyClause::Create(
782       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
783       Clause.getVarList(), Clause.getEndLoc());
784 }
785 
VisitCopyInClause(SemaOpenACC::OpenACCParsedClause & Clause)786 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause(
787     SemaOpenACC::OpenACCParsedClause &Clause) {
788   // Restrictions only properly implemented on 'compute' constructs, and
789   // 'compute' constructs are the only construct that can do anything with
790   // this yet, so skip/treat as unimplemented in this case.
791   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
792     return isNotImplemented();
793   // ActOnVar ensured that everything is a valid variable reference, so there
794   // really isn't anything to do here. GCC does some duplicate-finding, though
795   // it isn't apparent in the standard where this is justified.
796 
797   return OpenACCCopyInClause::Create(
798       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
799       Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc());
800 }
801 
VisitCopyOutClause(SemaOpenACC::OpenACCParsedClause & Clause)802 OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause(
803     SemaOpenACC::OpenACCParsedClause &Clause) {
804   // Restrictions only properly implemented on 'compute' constructs, and
805   // 'compute' constructs are the only construct that can do anything with
806   // this yet, so skip/treat as unimplemented in this case.
807   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
808     return isNotImplemented();
809   // ActOnVar ensured that everything is a valid variable reference, so there
810   // really isn't anything to do here. GCC does some duplicate-finding, though
811   // it isn't apparent in the standard where this is justified.
812 
813   return OpenACCCopyOutClause::Create(
814       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
815       Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
816 }
817 
VisitCreateClause(SemaOpenACC::OpenACCParsedClause & Clause)818 OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause(
819     SemaOpenACC::OpenACCParsedClause &Clause) {
820   // Restrictions only properly implemented on 'compute' constructs, and
821   // 'compute' constructs are the only construct that can do anything with
822   // this yet, so skip/treat as unimplemented in this case.
823   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
824     return isNotImplemented();
825   // ActOnVar ensured that everything is a valid variable reference, so there
826   // really isn't anything to do here. GCC does some duplicate-finding, though
827   // it isn't apparent in the standard where this is justified.
828 
829   return OpenACCCreateClause::Create(
830       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
831       Clause.isZero(), Clause.getVarList(), Clause.getEndLoc());
832 }
833 
VisitAttachClause(SemaOpenACC::OpenACCParsedClause & Clause)834 OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause(
835     SemaOpenACC::OpenACCParsedClause &Clause) {
836   // Restrictions only properly implemented on 'compute' constructs, and
837   // 'compute' constructs are the only construct that can do anything with
838   // this yet, so skip/treat as unimplemented in this case.
839   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
840     return isNotImplemented();
841 
842   // ActOnVar ensured that everything is a valid variable reference, but we
843   // still have to make sure it is a pointer type.
844   llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
845   llvm::erase_if(VarList, [&](Expr *E) {
846     return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E);
847   });
848   Clause.setVarListDetails(VarList,
849                            /*IsReadOnly=*/false, /*IsZero=*/false);
850   return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(),
851                                      Clause.getLParenLoc(), Clause.getVarList(),
852                                      Clause.getEndLoc());
853 }
854 
VisitDevicePtrClause(SemaOpenACC::OpenACCParsedClause & Clause)855 OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
856     SemaOpenACC::OpenACCParsedClause &Clause) {
857   // Restrictions only properly implemented on 'compute' constructs, and
858   // 'compute' constructs are the only construct that can do anything with
859   // this yet, so skip/treat as unimplemented in this case.
860   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
861     return isNotImplemented();
862 
863   // ActOnVar ensured that everything is a valid variable reference, but we
864   // still have to make sure it is a pointer type.
865   llvm::SmallVector<Expr *> VarList{Clause.getVarList()};
866   llvm::erase_if(VarList, [&](Expr *E) {
867     return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E);
868   });
869   Clause.setVarListDetails(VarList,
870                            /*IsReadOnly=*/false, /*IsZero=*/false);
871 
872   return OpenACCDevicePtrClause::Create(
873       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(),
874       Clause.getEndLoc());
875 }
876 
VisitWaitClause(SemaOpenACC::OpenACCParsedClause & Clause)877 OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
878     SemaOpenACC::OpenACCParsedClause &Clause) {
879   // Restrictions only properly implemented on 'compute' constructs, and
880   // 'compute' constructs are the only construct that can do anything with
881   // this yet, so skip/treat as unimplemented in this case.
882   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
883     return isNotImplemented();
884 
885   return OpenACCWaitClause::Create(
886       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
887       Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
888 }
889 
VisitDeviceTypeClause(SemaOpenACC::OpenACCParsedClause & Clause)890 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
891     SemaOpenACC::OpenACCParsedClause &Clause) {
892   // Restrictions only properly implemented on 'compute' and 'loop'
893   // constructs, and 'compute'/'loop' constructs are the only construct that
894   // can do anything with this yet, so skip/treat as unimplemented in this
895   // case.
896   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
897       Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
898     return isNotImplemented();
899 
900   // TODO OpenACC: Once we get enough of the CodeGen implemented that we have
901   // a source for the list of valid architectures, we need to warn on unknown
902   // identifiers here.
903 
904   return OpenACCDeviceTypeClause::Create(
905       Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(),
906       Clause.getDeviceTypeArchitectures(), Clause.getEndLoc());
907 }
908 
VisitAutoClause(SemaOpenACC::OpenACCParsedClause & Clause)909 OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause(
910     SemaOpenACC::OpenACCParsedClause &Clause) {
911   // Restrictions only properly implemented on 'loop' constructs, and it is
912   // the only construct that can do anything with this, so skip/treat as
913   // unimplemented for the combined constructs.
914   if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
915     return isNotImplemented();
916 
917   // OpenACC 3.3 2.9:
918   // Only one of the seq, independent, and auto clauses may appear.
919   const auto *Itr =
920       llvm::find_if(ExistingClauses,
921                     llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>);
922   if (Itr != ExistingClauses.end()) {
923     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
924         << Clause.getClauseKind() << Clause.getDirectiveKind();
925     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
926     return nullptr;
927   }
928 
929   return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(),
930                                    Clause.getEndLoc());
931 }
932 
VisitIndependentClause(SemaOpenACC::OpenACCParsedClause & Clause)933 OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause(
934     SemaOpenACC::OpenACCParsedClause &Clause) {
935   // Restrictions only properly implemented on 'loop' constructs, and it is
936   // the only construct that can do anything with this, so skip/treat as
937   // unimplemented for the combined constructs.
938   if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
939     return isNotImplemented();
940 
941   // OpenACC 3.3 2.9:
942   // Only one of the seq, independent, and auto clauses may appear.
943   const auto *Itr = llvm::find_if(
944       ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>);
945   if (Itr != ExistingClauses.end()) {
946     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
947         << Clause.getClauseKind() << Clause.getDirectiveKind();
948     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
949     return nullptr;
950   }
951 
952   return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(),
953                                           Clause.getEndLoc());
954 }
955 
VisitSeqClause(SemaOpenACC::OpenACCParsedClause & Clause)956 OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause(
957     SemaOpenACC::OpenACCParsedClause &Clause) {
958   // Restrictions only properly implemented on 'loop' constructs, and it is
959   // the only construct that can do anything with this, so skip/treat as
960   // unimplemented for the combined constructs.
961   if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop)
962     return isNotImplemented();
963 
964   // OpenACC 3.3 2.9:
965   // Only one of the seq, independent, and auto clauses may appear.
966   const auto *Itr =
967       llvm::find_if(ExistingClauses,
968                     llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>);
969   if (Itr != ExistingClauses.end()) {
970     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict)
971         << Clause.getClauseKind() << Clause.getDirectiveKind();
972     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
973     return nullptr;
974   }
975 
976   // OpenACC 3.3 2.9:
977   // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
978   // appears.
979   Itr = llvm::find_if(ExistingClauses,
980                       llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause,
981                                     OpenACCVectorClause>);
982 
983   if (Itr != ExistingClauses.end()) {
984     SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
985         << Clause.getClauseKind() << (*Itr)->getClauseKind();
986     SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
987     return nullptr;
988   }
989 
990   // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
991   // restrictions when there is a 'seq' clause in place. We probably need to
992   // implement that.
993   return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(),
994                                   Clause.getEndLoc());
995 }
996 
VisitReductionClause(SemaOpenACC::OpenACCParsedClause & Clause)997 OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause(
998     SemaOpenACC::OpenACCParsedClause &Clause) {
999   // Restrictions only properly implemented on 'compute' constructs, and
1000   // 'compute' constructs are the only construct that can do anything with
1001   // this yet, so skip/treat as unimplemented in this case.
1002   if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
1003     return isNotImplemented();
1004 
1005   // OpenACC 3.3 Section 2.5.4:
1006   // A reduction clause may not appear on a parallel construct with a
1007   // num_gangs clause that has more than one argument.
1008   if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) {
1009     auto NumGangsClauses = llvm::make_filter_range(
1010         ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>);
1011 
1012     for (auto *NGC : NumGangsClauses) {
1013       unsigned NumExprs =
1014           cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size();
1015 
1016       if (NumExprs > 1) {
1017         SemaRef.Diag(Clause.getBeginLoc(),
1018                      diag::err_acc_reduction_num_gangs_conflict)
1019             << NumExprs;
1020         SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here);
1021         return nullptr;
1022       }
1023     }
1024   }
1025 
1026   SmallVector<Expr *> ValidVars;
1027 
1028   for (Expr *Var : Clause.getVarList()) {
1029     ExprResult Res = SemaRef.CheckReductionVar(Var);
1030 
1031     if (Res.isUsable())
1032       ValidVars.push_back(Res.get());
1033   }
1034 
1035   return OpenACCReductionClause::Create(
1036       Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getReductionOp(),
1037       ValidVars, Clause.getEndLoc());
1038 }
1039 
1040 } // namespace
1041 
SemaOpenACC(Sema & S)1042 SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {}
1043 
AssociatedStmtRAII(SemaOpenACC & S,OpenACCDirectiveKind DK)1044 SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(SemaOpenACC &S,
1045                                                     OpenACCDirectiveKind DK)
1046     : SemaRef(S), WasInsideComputeConstruct(S.InsideComputeConstruct),
1047       DirKind(DK) {
1048   // Compute constructs end up taking their 'loop'.
1049   if (DirKind == OpenACCDirectiveKind::Parallel ||
1050       DirKind == OpenACCDirectiveKind::Serial ||
1051       DirKind == OpenACCDirectiveKind::Kernels) {
1052     SemaRef.InsideComputeConstruct = true;
1053     SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs);
1054   }
1055 }
1056 
~AssociatedStmtRAII()1057 SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() {
1058   SemaRef.InsideComputeConstruct = WasInsideComputeConstruct;
1059   if (DirKind == OpenACCDirectiveKind::Parallel ||
1060       DirKind == OpenACCDirectiveKind::Serial ||
1061       DirKind == OpenACCDirectiveKind::Kernels) {
1062     assert(SemaRef.ParentlessLoopConstructs.empty() &&
1063            "Didn't consume loop construct list?");
1064     SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs);
1065   }
1066 }
1067 
1068 OpenACCClause *
ActOnClause(ArrayRef<const OpenACCClause * > ExistingClauses,OpenACCParsedClause & Clause)1069 SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses,
1070                          OpenACCParsedClause &Clause) {
1071   if (Clause.getClauseKind() == OpenACCClauseKind::Invalid)
1072     return nullptr;
1073 
1074   // Diagnose that we don't support this clause on this directive.
1075   if (!doesClauseApplyToDirective(Clause.getDirectiveKind(),
1076                                   Clause.getClauseKind())) {
1077     Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment)
1078         << Clause.getDirectiveKind() << Clause.getClauseKind();
1079     return nullptr;
1080   }
1081 
1082   if (const auto *DevTypeClause =
1083           llvm::find_if(ExistingClauses,
1084                         [&](const OpenACCClause *C) {
1085                           return isa<OpenACCDeviceTypeClause>(C);
1086                         });
1087       DevTypeClause != ExistingClauses.end()) {
1088     if (checkValidAfterDeviceType(
1089             *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause))
1090       return nullptr;
1091   }
1092 
1093   SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses};
1094   OpenACCClause *Result = Visitor.Visit(Clause);
1095   assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) &&
1096          "Created wrong clause?");
1097 
1098   if (Visitor.diagNotImplemented())
1099     Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented)
1100         << Clause.getClauseKind();
1101 
1102   return Result;
1103 
1104   //  switch (Clause.getClauseKind()) {
1105   //  case OpenACCClauseKind::PresentOrCopy:
1106   //  case OpenACCClauseKind::PCopy:
1107   //    Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
1108   //        << Clause.getClauseKind() << OpenACCClauseKind::Copy;
1109   //    LLVM_FALLTHROUGH;
1110   //  case OpenACCClauseKind::PresentOrCreate:
1111   //  case OpenACCClauseKind::PCreate:
1112   //    Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name)
1113   //        << Clause.getClauseKind() << OpenACCClauseKind::Create;
1114   //    LLVM_FALLTHROUGH;
1115   //
1116   //
1117   //
1118   //
1119   //  case OpenACCClauseKind::DType:
1120   //
1121   //
1122   //
1123   //
1124   //
1125   //
1126   //
1127   //
1128   //  case OpenACCClauseKind::Gang:
1129   //  case OpenACCClauseKind::Worker:
1130   //  case OpenACCClauseKind::Vector: {
1131   //    // OpenACC 3.3 2.9:
1132   //    // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq'
1133   //    clause
1134   //    // appears.
1135   //    const auto *Itr =
1136   //        llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
1137   //
1138   //    if (Itr != ExistingClauses.end()) {
1139   //      Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine)
1140   //          << Clause.getClauseKind() << (*Itr)->getClauseKind();
1141   //      Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here);
1142   //    }
1143   //    // Not yet implemented, so immediately drop to the 'not yet implemented'
1144   //    // diagnostic.
1145   //    break;
1146   //  }
1147   //  */
1148 
1149 }
1150 
1151 /// OpenACC 3.3 section 2.5.15:
1152 /// At a mininmum, the supported data types include ... the numerical data types
1153 /// in C, C++, and Fortran.
1154 ///
1155 /// If the reduction var is a composite variable, each
1156 /// member of the composite variable must be a supported datatype for the
1157 /// reduction operation.
CheckReductionVar(Expr * VarExpr)1158 ExprResult SemaOpenACC::CheckReductionVar(Expr *VarExpr) {
1159   VarExpr = VarExpr->IgnoreParenCasts();
1160 
1161   auto TypeIsValid = [](QualType Ty) {
1162     return Ty->isDependentType() || Ty->isScalarType();
1163   };
1164 
1165   if (isa<ArraySectionExpr>(VarExpr)) {
1166     Expr *ASExpr = VarExpr;
1167     QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr);
1168     QualType EltTy = getASTContext().getBaseElementType(BaseTy);
1169 
1170     if (!TypeIsValid(EltTy)) {
1171       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
1172           << EltTy << /*Sub array base type*/ 1;
1173       return ExprError();
1174     }
1175   } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) {
1176     if (!RD->isStruct() && !RD->isClass()) {
1177       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
1178           << /*not class or struct*/ 0 << VarExpr->getType();
1179       return ExprError();
1180     }
1181 
1182     if (!RD->isCompleteDefinition()) {
1183       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
1184           << /*incomplete*/ 1 << VarExpr->getType();
1185       return ExprError();
1186     }
1187     if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1188         CXXRD && !CXXRD->isAggregate()) {
1189       Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type)
1190           << /*aggregate*/ 2 << VarExpr->getType();
1191       return ExprError();
1192     }
1193 
1194     for (FieldDecl *FD : RD->fields()) {
1195       if (!TypeIsValid(FD->getType())) {
1196         Diag(VarExpr->getExprLoc(),
1197              diag::err_acc_reduction_composite_member_type);
1198         Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc);
1199         return ExprError();
1200       }
1201     }
1202   } else if (!TypeIsValid(VarExpr->getType())) {
1203     Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type)
1204         << VarExpr->getType() << /*Sub array base type*/ 0;
1205     return ExprError();
1206   }
1207 
1208   return VarExpr;
1209 }
1210 
ActOnConstruct(OpenACCDirectiveKind K,SourceLocation DirLoc)1211 void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
1212                                  SourceLocation DirLoc) {
1213   switch (K) {
1214   case OpenACCDirectiveKind::Invalid:
1215     // Nothing to do here, an invalid kind has nothing we can check here.  We
1216     // want to continue parsing clauses as far as we can, so we will just
1217     // ensure that we can still work and don't check any construct-specific
1218     // rules anywhere.
1219     break;
1220   case OpenACCDirectiveKind::Parallel:
1221   case OpenACCDirectiveKind::Serial:
1222   case OpenACCDirectiveKind::Kernels:
1223   case OpenACCDirectiveKind::Loop:
1224     // Nothing to do here, there is no real legalization that needs to happen
1225     // here as these constructs do not take any arguments.
1226     break;
1227   default:
1228     Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K;
1229     break;
1230   }
1231 }
1232 
ActOnIntExpr(OpenACCDirectiveKind DK,OpenACCClauseKind CK,SourceLocation Loc,Expr * IntExpr)1233 ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK,
1234                                      OpenACCClauseKind CK, SourceLocation Loc,
1235                                      Expr *IntExpr) {
1236 
1237   assert(((DK != OpenACCDirectiveKind::Invalid &&
1238            CK == OpenACCClauseKind::Invalid) ||
1239           (DK == OpenACCDirectiveKind::Invalid &&
1240            CK != OpenACCClauseKind::Invalid) ||
1241           (DK == OpenACCDirectiveKind::Invalid &&
1242            CK == OpenACCClauseKind::Invalid)) &&
1243          "Only one of directive or clause kind should be provided");
1244 
1245   class IntExprConverter : public Sema::ICEConvertDiagnoser {
1246     OpenACCDirectiveKind DirectiveKind;
1247     OpenACCClauseKind ClauseKind;
1248     Expr *IntExpr;
1249 
1250     // gets the index into the diagnostics so we can use this for clauses,
1251     // directives, and sub array.s
1252     unsigned getDiagKind() const {
1253       if (ClauseKind != OpenACCClauseKind::Invalid)
1254         return 0;
1255       if (DirectiveKind != OpenACCDirectiveKind::Invalid)
1256         return 1;
1257       return 2;
1258     }
1259 
1260   public:
1261     IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
1262                      Expr *IntExpr)
1263         : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false,
1264                               /*Suppress=*/false,
1265                               /*SuppressConversion=*/true),
1266           DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {}
1267 
1268     bool match(QualType T) override {
1269       // OpenACC spec just calls this 'integer expression' as having an
1270       // 'integer type', so fall back on C99's 'integer type'.
1271       return T->isIntegerType();
1272     }
1273     SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
1274                                                    QualType T) override {
1275       return S.Diag(Loc, diag::err_acc_int_expr_requires_integer)
1276              << getDiagKind() << ClauseKind << DirectiveKind << T;
1277     }
1278 
1279     SemaBase::SemaDiagnosticBuilder
1280     diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override {
1281       return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type)
1282              << T << IntExpr->getSourceRange();
1283     }
1284 
1285     SemaBase::SemaDiagnosticBuilder
1286     diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T,
1287                          QualType ConvTy) override {
1288       return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion)
1289              << T << ConvTy;
1290     }
1291 
1292     SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S,
1293                                                      CXXConversionDecl *Conv,
1294                                                      QualType ConvTy) override {
1295       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
1296              << ConvTy->isEnumeralType() << ConvTy;
1297     }
1298 
1299     SemaBase::SemaDiagnosticBuilder
1300     diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override {
1301       return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T;
1302     }
1303 
1304     SemaBase::SemaDiagnosticBuilder
1305     noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
1306       return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion)
1307              << ConvTy->isEnumeralType() << ConvTy;
1308     }
1309 
1310     SemaBase::SemaDiagnosticBuilder
1311     diagnoseConversion(Sema &S, SourceLocation Loc, QualType T,
1312                        QualType ConvTy) override {
1313       llvm_unreachable("conversion functions are permitted");
1314     }
1315   } IntExprDiagnoser(DK, CK, IntExpr);
1316 
1317   ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion(
1318       Loc, IntExpr, IntExprDiagnoser);
1319   if (IntExprResult.isInvalid())
1320     return ExprError();
1321 
1322   IntExpr = IntExprResult.get();
1323   if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType())
1324     return ExprError();
1325 
1326   // TODO OpenACC: Do we want to perform usual unary conversions here? When
1327   // doing codegen we might find that is necessary, but skip it for now.
1328   return IntExpr;
1329 }
1330 
CheckVarIsPointerType(OpenACCClauseKind ClauseKind,Expr * VarExpr)1331 bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind,
1332                                         Expr *VarExpr) {
1333   // We already know that VarExpr is a proper reference to a variable, so we
1334   // should be able to just take the type of the expression to get the type of
1335   // the referenced variable.
1336 
1337   // We've already seen an error, don't diagnose anything else.
1338   if (!VarExpr || VarExpr->containsErrors())
1339     return false;
1340 
1341   if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) ||
1342       VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) {
1343     Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0;
1344     Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var);
1345     return true;
1346   }
1347 
1348   QualType Ty = VarExpr->getType();
1349   Ty = Ty.getNonReferenceType().getUnqualifiedType();
1350 
1351   // Nothing we can do if this is a dependent type.
1352   if (Ty->isDependentType())
1353     return false;
1354 
1355   if (!Ty->isPointerType())
1356     return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type)
1357            << ClauseKind << Ty;
1358   return false;
1359 }
1360 
ActOnVar(OpenACCClauseKind CK,Expr * VarExpr)1361 ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) {
1362   Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts();
1363 
1364   // Sub-arrays/subscript-exprs are fine as long as the base is a
1365   // VarExpr/MemberExpr. So strip all of those off.
1366   while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
1367     if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr))
1368       CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts();
1369     else
1370       CurVarExpr =
1371           cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts();
1372   }
1373 
1374   // References to a VarDecl are fine.
1375   if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) {
1376     if (isa<VarDecl, NonTypeTemplateParmDecl>(
1377             DRE->getFoundDecl()->getCanonicalDecl()))
1378       return VarExpr;
1379   }
1380 
1381   // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a
1382   // reduction clause must be a scalar variable name, an aggregate variable
1383   // name, an array element, or a subarray.
1384   // A MemberExpr that references a Field is valid.
1385   if (CK != OpenACCClauseKind::Reduction) {
1386     if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) {
1387       if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl()))
1388         return VarExpr;
1389     }
1390   }
1391 
1392   // Referring to 'this' is always OK.
1393   if (isa<CXXThisExpr>(CurVarExpr))
1394     return VarExpr;
1395 
1396   // Nothing really we can do here, as these are dependent.  So just return they
1397   // are valid.
1398   if (isa<DependentScopeDeclRefExpr>(CurVarExpr) ||
1399       (CK != OpenACCClauseKind::Reduction &&
1400        isa<CXXDependentScopeMemberExpr>(CurVarExpr)))
1401     return VarExpr;
1402 
1403   // There isn't really anything we can do in the case of a recovery expr, so
1404   // skip the diagnostic rather than produce a confusing diagnostic.
1405   if (isa<RecoveryExpr>(CurVarExpr))
1406     return ExprError();
1407 
1408   Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref)
1409       << (CK != OpenACCClauseKind::Reduction);
1410   return ExprError();
1411 }
1412 
ActOnArraySectionExpr(Expr * Base,SourceLocation LBLoc,Expr * LowerBound,SourceLocation ColonLoc,Expr * Length,SourceLocation RBLoc)1413 ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc,
1414                                               Expr *LowerBound,
1415                                               SourceLocation ColonLoc,
1416                                               Expr *Length,
1417                                               SourceLocation RBLoc) {
1418   ASTContext &Context = getASTContext();
1419 
1420   // Handle placeholders.
1421   if (Base->hasPlaceholderType() &&
1422       !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
1423     ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
1424     if (Result.isInvalid())
1425       return ExprError();
1426     Base = Result.get();
1427   }
1428   if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
1429     ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound);
1430     if (Result.isInvalid())
1431       return ExprError();
1432     Result = SemaRef.DefaultLvalueConversion(Result.get());
1433     if (Result.isInvalid())
1434       return ExprError();
1435     LowerBound = Result.get();
1436   }
1437   if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
1438     ExprResult Result = SemaRef.CheckPlaceholderExpr(Length);
1439     if (Result.isInvalid())
1440       return ExprError();
1441     Result = SemaRef.DefaultLvalueConversion(Result.get());
1442     if (Result.isInvalid())
1443       return ExprError();
1444     Length = Result.get();
1445   }
1446 
1447   // Check the 'base' value, it must be an array or pointer type, and not to/of
1448   // a function type.
1449   QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base);
1450   QualType ResultTy;
1451   if (!Base->isTypeDependent()) {
1452     if (OriginalBaseTy->isAnyPointerType()) {
1453       ResultTy = OriginalBaseTy->getPointeeType();
1454     } else if (OriginalBaseTy->isArrayType()) {
1455       ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType();
1456     } else {
1457       return ExprError(
1458           Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value)
1459           << Base->getSourceRange());
1460     }
1461 
1462     if (ResultTy->isFunctionType()) {
1463       Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type)
1464           << ResultTy << Base->getSourceRange();
1465       return ExprError();
1466     }
1467 
1468     if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
1469                                     diag::err_acc_subarray_incomplete_type,
1470                                     Base))
1471       return ExprError();
1472 
1473     if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
1474       ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base);
1475       if (Result.isInvalid())
1476         return ExprError();
1477       Base = Result.get();
1478     }
1479   }
1480 
1481   auto GetRecovery = [&](Expr *E, QualType Ty) {
1482     ExprResult Recovery =
1483         SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty);
1484     return Recovery.isUsable() ? Recovery.get() : nullptr;
1485   };
1486 
1487   // Ensure both of the expressions are int-exprs.
1488   if (LowerBound && !LowerBound->isTypeDependent()) {
1489     ExprResult LBRes =
1490         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
1491                      LowerBound->getExprLoc(), LowerBound);
1492 
1493     if (LBRes.isUsable())
1494       LBRes = SemaRef.DefaultLvalueConversion(LBRes.get());
1495     LowerBound =
1496         LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy);
1497   }
1498 
1499   if (Length && !Length->isTypeDependent()) {
1500     ExprResult LenRes =
1501         ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid,
1502                      Length->getExprLoc(), Length);
1503 
1504     if (LenRes.isUsable())
1505       LenRes = SemaRef.DefaultLvalueConversion(LenRes.get());
1506     Length =
1507         LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy);
1508   }
1509 
1510   // Length is required if the base type is not an array of known bounds.
1511   if (!Length && (OriginalBaseTy.isNull() ||
1512                   (!OriginalBaseTy->isDependentType() &&
1513                    !OriginalBaseTy->isConstantArrayType() &&
1514                    !OriginalBaseTy->isDependentSizedArrayType()))) {
1515     bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType();
1516     Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray;
1517     // Fill in a dummy 'length' so that when we instantiate this we don't
1518     // double-diagnose here.
1519     ExprResult Recovery = SemaRef.CreateRecoveryExpr(
1520         ColonLoc, SourceLocation(), ArrayRef<Expr *>{std::nullopt},
1521         Context.IntTy);
1522     Length = Recovery.isUsable() ? Recovery.get() : nullptr;
1523   }
1524 
1525   // Check the values of each of the arguments, they cannot be negative(we
1526   // assume), and if the array bound is known, must be within range. As we do
1527   // so, do our best to continue with evaluation, we can set the
1528   // value/expression to nullptr/nullopt if they are invalid, and treat them as
1529   // not present for the rest of evaluation.
1530 
1531   // We don't have to check for dependence, because the dependent size is
1532   // represented as a different AST node.
1533   std::optional<llvm::APSInt> BaseSize;
1534   if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) {
1535     const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy);
1536     BaseSize = ArrayTy->getSize();
1537   }
1538 
1539   auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> {
1540     if (!E || E->isInstantiationDependent())
1541       return std::nullopt;
1542 
1543     Expr::EvalResult Res;
1544     if (!E->EvaluateAsInt(Res, Context))
1545       return std::nullopt;
1546     return Res.Val.getInt();
1547   };
1548 
1549   std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound);
1550   std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length);
1551 
1552   // Check lower bound for negative or out of range.
1553   if (LowerBoundValue.has_value()) {
1554     if (LowerBoundValue->isNegative()) {
1555       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative)
1556           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10);
1557       LowerBoundValue.reset();
1558       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1559     } else if (BaseSize.has_value() &&
1560                llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) {
1561       // Lower bound (start index) must be less than the size of the array.
1562       Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range)
1563           << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10)
1564           << toString(*BaseSize, /*Radix=*/10);
1565       LowerBoundValue.reset();
1566       LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1567     }
1568   }
1569 
1570   // Check length for negative or out of range.
1571   if (LengthValue.has_value()) {
1572     if (LengthValue->isNegative()) {
1573       Diag(Length->getExprLoc(), diag::err_acc_subarray_negative)
1574           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10);
1575       LengthValue.reset();
1576       Length = GetRecovery(Length, Length->getType());
1577     } else if (BaseSize.has_value() &&
1578                llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) {
1579       // Length must be lessthan or EQUAL to the size of the array.
1580       Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range)
1581           << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10)
1582           << toString(*BaseSize, /*Radix=*/10);
1583       LengthValue.reset();
1584       Length = GetRecovery(Length, Length->getType());
1585     }
1586   }
1587 
1588   // Adding two APSInts requires matching sign, so extract that here.
1589   auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt {
1590     if (LHS.isSigned() == RHS.isSigned())
1591       return LHS + RHS;
1592 
1593     unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1;
1594     return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true);
1595   };
1596 
1597   // If we know all 3 values, we can diagnose that the total value would be out
1598   // of range.
1599   if (BaseSize.has_value() && LowerBoundValue.has_value() &&
1600       LengthValue.has_value() &&
1601       llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue),
1602                                   *BaseSize) > 0) {
1603     Diag(Base->getExprLoc(),
1604          diag::err_acc_subarray_base_plus_length_out_of_range)
1605         << toString(*LowerBoundValue, /*Radix=*/10)
1606         << toString(*LengthValue, /*Radix=*/10)
1607         << toString(*BaseSize, /*Radix=*/10);
1608 
1609     LowerBoundValue.reset();
1610     LowerBound = GetRecovery(LowerBound, LowerBound->getType());
1611     LengthValue.reset();
1612     Length = GetRecovery(Length, Length->getType());
1613   }
1614 
1615   // If any part of the expression is dependent, return a dependent sub-array.
1616   QualType ArrayExprTy = Context.ArraySectionTy;
1617   if (Base->isTypeDependent() ||
1618       (LowerBound && LowerBound->isInstantiationDependent()) ||
1619       (Length && Length->isInstantiationDependent()))
1620     ArrayExprTy = Context.DependentTy;
1621 
1622   return new (Context)
1623       ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue,
1624                        OK_Ordinary, ColonLoc, RBLoc);
1625 }
1626 
ActOnStartStmtDirective(OpenACCDirectiveKind K,SourceLocation StartLoc)1627 bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
1628                                           SourceLocation StartLoc) {
1629   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
1630 }
1631 
ActOnEndStmtDirective(OpenACCDirectiveKind K,SourceLocation StartLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<OpenACCClause * > Clauses,StmtResult AssocStmt)1632 StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K,
1633                                               SourceLocation StartLoc,
1634                                               SourceLocation DirLoc,
1635                                               SourceLocation EndLoc,
1636                                               ArrayRef<OpenACCClause *> Clauses,
1637                                               StmtResult AssocStmt) {
1638   switch (K) {
1639   default:
1640     return StmtEmpty();
1641   case OpenACCDirectiveKind::Invalid:
1642     return StmtError();
1643   case OpenACCDirectiveKind::Parallel:
1644   case OpenACCDirectiveKind::Serial:
1645   case OpenACCDirectiveKind::Kernels: {
1646     auto *ComputeConstruct = OpenACCComputeConstruct::Create(
1647         getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses,
1648         AssocStmt.isUsable() ? AssocStmt.get() : nullptr,
1649         ParentlessLoopConstructs);
1650 
1651     ParentlessLoopConstructs.clear();
1652     return ComputeConstruct;
1653   }
1654   case OpenACCDirectiveKind::Loop: {
1655     auto *LoopConstruct = OpenACCLoopConstruct::Create(
1656         getASTContext(), StartLoc, DirLoc, EndLoc, Clauses,
1657         AssocStmt.isUsable() ? AssocStmt.get() : nullptr);
1658 
1659     // If we are in the scope of a compute construct, add this to the list of
1660     // loop constructs that need assigning to the next closing compute
1661     // construct.
1662     if (InsideComputeConstruct)
1663       ParentlessLoopConstructs.push_back(LoopConstruct);
1664 
1665     return LoopConstruct;
1666   }
1667   }
1668   llvm_unreachable("Unhandled case in directive handling?");
1669 }
1670 
ActOnAssociatedStmt(SourceLocation DirectiveLoc,OpenACCDirectiveKind K,StmtResult AssocStmt)1671 StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc,
1672                                             OpenACCDirectiveKind K,
1673                                             StmtResult AssocStmt) {
1674   switch (K) {
1675   default:
1676     llvm_unreachable("Unimplemented associated statement application");
1677   case OpenACCDirectiveKind::Parallel:
1678   case OpenACCDirectiveKind::Serial:
1679   case OpenACCDirectiveKind::Kernels:
1680     // There really isn't any checking here that could happen. As long as we
1681     // have a statement to associate, this should be fine.
1682     // OpenACC 3.3 Section 6:
1683     // Structured Block: in C or C++, an executable statement, possibly
1684     // compound, with a single entry at the top and a single exit at the
1685     // bottom.
1686     // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and
1687     // an interpretation of it is to allow this and treat the initializer as
1688     // the 'structured block'.
1689     return AssocStmt;
1690   case OpenACCDirectiveKind::Loop:
1691     if (AssocStmt.isUsable() &&
1692         !isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) {
1693       Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop);
1694       Diag(DirectiveLoc, diag::note_acc_construct_here) << K;
1695       return StmtError();
1696     }
1697     // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some
1698     // restrictions when there is a 'seq' clause in place. We probably need to
1699     // implement that, including piping in the clauses here.
1700     return AssocStmt;
1701   }
1702   llvm_unreachable("Invalid associated statement application");
1703 }
1704 
ActOnStartDeclDirective(OpenACCDirectiveKind K,SourceLocation StartLoc)1705 bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
1706                                           SourceLocation StartLoc) {
1707   return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
1708 }
1709 
ActOnEndDeclDirective()1710 DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
1711