1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP 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 OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallSet.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Frontend/OpenMP/OMPAssume.h"
41 #include "llvm/Frontend/OpenMP/OMPConstants.h"
42 #include <set>
43
44 using namespace clang;
45 using namespace llvm::omp;
46
47 //===----------------------------------------------------------------------===//
48 // Stack of data-sharing attributes for variables
49 //===----------------------------------------------------------------------===//
50
51 static const Expr *checkMapClauseExpressionBase(
52 Sema &SemaRef, Expr *E,
53 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
54 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
55
56 namespace {
57 /// Default data sharing attributes, which can be applied to directive.
58 enum DefaultDataSharingAttributes {
59 DSA_unspecified = 0, /// Data sharing attribute not specified.
60 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
61 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
62 DSA_private = 1 << 2, /// Default data sharing attribute 'private'.
63 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
64 };
65
66 /// Stack for tracking declarations used in OpenMP directives and
67 /// clauses and their data-sharing attributes.
68 class DSAStackTy {
69 public:
70 struct DSAVarData {
71 OpenMPDirectiveKind DKind = OMPD_unknown;
72 OpenMPClauseKind CKind = OMPC_unknown;
73 unsigned Modifier = 0;
74 const Expr *RefExpr = nullptr;
75 DeclRefExpr *PrivateCopy = nullptr;
76 SourceLocation ImplicitDSALoc;
77 bool AppliedToPointee = false;
78 DSAVarData() = default;
DSAVarData__anon296aa5740111::DSAStackTy::DSAVarData79 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
80 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
81 SourceLocation ImplicitDSALoc, unsigned Modifier,
82 bool AppliedToPointee)
83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
85 AppliedToPointee(AppliedToPointee) {}
86 };
87 using OperatorOffsetTy =
88 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
89 using DoacrossDependMapTy =
90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
91 /// Kind of the declaration used in the uses_allocators clauses.
92 enum class UsesAllocatorsDeclKind {
93 /// Predefined allocator
94 PredefinedAllocator,
95 /// User-defined allocator
96 UserDefinedAllocator,
97 /// The declaration that represent allocator trait
98 AllocatorTrait,
99 };
100
101 private:
102 struct DSAInfo {
103 OpenMPClauseKind Attributes = OMPC_unknown;
104 unsigned Modifier = 0;
105 /// Pointer to a reference expression and a flag which shows that the
106 /// variable is marked as lastprivate(true) or not (false).
107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
108 DeclRefExpr *PrivateCopy = nullptr;
109 /// true if the attribute is applied to the pointee, not the variable
110 /// itself.
111 bool AppliedToPointee = false;
112 };
113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
115 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
116 using LoopControlVariablesMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
118 /// Struct that associates a component with the clause kind where they are
119 /// found.
120 struct MappedExprComponentTy {
121 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
122 OpenMPClauseKind Kind = OMPC_unknown;
123 };
124 using MappedExprComponentsTy =
125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
126 using CriticalsWithHintsTy =
127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
128 struct ReductionData {
129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
130 SourceRange ReductionRange;
131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
132 ReductionData() = default;
set__anon296aa5740111::DSAStackTy::ReductionData133 void set(BinaryOperatorKind BO, SourceRange RR) {
134 ReductionRange = RR;
135 ReductionOp = BO;
136 }
set__anon296aa5740111::DSAStackTy::ReductionData137 void set(const Expr *RefExpr, SourceRange RR) {
138 ReductionRange = RR;
139 ReductionOp = RefExpr;
140 }
141 };
142 using DeclReductionMapTy =
143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
144 struct DefaultmapInfo {
145 OpenMPDefaultmapClauseModifier ImplicitBehavior =
146 OMPC_DEFAULTMAP_MODIFIER_unknown;
147 SourceLocation SLoc;
148 DefaultmapInfo() = default;
DefaultmapInfo__anon296aa5740111::DSAStackTy::DefaultmapInfo149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
150 : ImplicitBehavior(M), SLoc(Loc) {}
151 };
152
153 struct SharingMapTy {
154 DeclSAMapTy SharingMap;
155 DeclReductionMapTy ReductionMap;
156 UsedRefMapTy AlignedMap;
157 UsedRefMapTy NontemporalMap;
158 MappedExprComponentsTy MappedExprComponents;
159 LoopControlVariablesMapTy LCVMap;
160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
161 SourceLocation DefaultAttrLoc;
162 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
163 OpenMPDirectiveKind Directive = OMPD_unknown;
164 DeclarationNameInfo DirectiveName;
165 Scope *CurScope = nullptr;
166 DeclContext *Context = nullptr;
167 SourceLocation ConstructLoc;
168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
169 /// get the data (loop counters etc.) about enclosing loop-based construct.
170 /// This data is required during codegen.
171 DoacrossDependMapTy DoacrossDepends;
172 /// First argument (Expr *) contains optional argument of the
173 /// 'ordered' clause, the second one is true if the regions has 'ordered'
174 /// clause, false otherwise.
175 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
176 unsigned AssociatedLoops = 1;
177 bool HasMutipleLoops = false;
178 const Decl *PossiblyLoopCounter = nullptr;
179 bool NowaitRegion = false;
180 bool UntiedRegion = false;
181 bool CancelRegion = false;
182 bool LoopStart = false;
183 bool BodyComplete = false;
184 SourceLocation PrevScanLocation;
185 SourceLocation PrevOrderedLocation;
186 SourceLocation InnerTeamsRegionLoc;
187 /// Reference to the taskgroup task_reduction reference expression.
188 Expr *TaskgroupReductionRef = nullptr;
189 llvm::DenseSet<QualType> MappedClassesQualTypes;
190 SmallVector<Expr *, 4> InnerUsedAllocators;
191 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
192 /// List of globals marked as declare target link in this target region
193 /// (isOpenMPTargetExecutionDirective(Directive) == true).
194 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
195 /// List of decls used in inclusive/exclusive clauses of the scan directive.
196 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
198 UsesAllocatorsDecls;
199 /// Data is required on creating capture fields for implicit
200 /// default first|private clause.
201 struct ImplicitDefaultFDInfoTy {
202 /// Field decl.
203 const FieldDecl *FD = nullptr;
204 /// Nesting stack level
205 size_t StackLevel = 0;
206 /// Capture variable decl.
207 VarDecl *VD = nullptr;
ImplicitDefaultFDInfoTy__anon296aa5740111::DSAStackTy::SharingMapTy::ImplicitDefaultFDInfoTy208 ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
209 VarDecl *VD)
210 : FD(FD), StackLevel(StackLevel), VD(VD) {}
211 };
212 /// List of captured fields
213 llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
214 ImplicitDefaultFirstprivateFDs;
215 Expr *DeclareMapperVar = nullptr;
SharingMapTy__anon296aa5740111::DSAStackTy::SharingMapTy216 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
217 Scope *CurScope, SourceLocation Loc)
218 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
219 ConstructLoc(Loc) {}
220 SharingMapTy() = default;
221 };
222
223 using StackTy = SmallVector<SharingMapTy, 4>;
224
225 /// Stack of used declaration and their data-sharing attributes.
226 DeclSAMapTy Threadprivates;
227 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
228 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
229 /// true, if check for DSA must be from parent directive, false, if
230 /// from current directive.
231 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
232 Sema &SemaRef;
233 bool ForceCapturing = false;
234 /// true if all the variables in the target executable directives must be
235 /// captured by reference.
236 bool ForceCaptureByReferenceInTargetExecutable = false;
237 CriticalsWithHintsTy Criticals;
238 unsigned IgnoredStackElements = 0;
239
240 /// Iterators over the stack iterate in order from innermost to outermost
241 /// directive.
242 using const_iterator = StackTy::const_reverse_iterator;
begin() const243 const_iterator begin() const {
244 return Stack.empty() ? const_iterator()
245 : Stack.back().first.rbegin() + IgnoredStackElements;
246 }
end() const247 const_iterator end() const {
248 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
249 }
250 using iterator = StackTy::reverse_iterator;
begin()251 iterator begin() {
252 return Stack.empty() ? iterator()
253 : Stack.back().first.rbegin() + IgnoredStackElements;
254 }
end()255 iterator end() {
256 return Stack.empty() ? iterator() : Stack.back().first.rend();
257 }
258
259 // Convenience operations to get at the elements of the stack.
260
isStackEmpty() const261 bool isStackEmpty() const {
262 return Stack.empty() ||
263 Stack.back().second != CurrentNonCapturingFunctionScope ||
264 Stack.back().first.size() <= IgnoredStackElements;
265 }
getStackSize() const266 size_t getStackSize() const {
267 return isStackEmpty() ? 0
268 : Stack.back().first.size() - IgnoredStackElements;
269 }
270
getTopOfStackOrNull()271 SharingMapTy *getTopOfStackOrNull() {
272 size_t Size = getStackSize();
273 if (Size == 0)
274 return nullptr;
275 return &Stack.back().first[Size - 1];
276 }
getTopOfStackOrNull() const277 const SharingMapTy *getTopOfStackOrNull() const {
278 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
279 }
getTopOfStack()280 SharingMapTy &getTopOfStack() {
281 assert(!isStackEmpty() && "no current directive");
282 return *getTopOfStackOrNull();
283 }
getTopOfStack() const284 const SharingMapTy &getTopOfStack() const {
285 return const_cast<DSAStackTy &>(*this).getTopOfStack();
286 }
287
getSecondOnStackOrNull()288 SharingMapTy *getSecondOnStackOrNull() {
289 size_t Size = getStackSize();
290 if (Size <= 1)
291 return nullptr;
292 return &Stack.back().first[Size - 2];
293 }
getSecondOnStackOrNull() const294 const SharingMapTy *getSecondOnStackOrNull() const {
295 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
296 }
297
298 /// Get the stack element at a certain level (previously returned by
299 /// \c getNestingLevel).
300 ///
301 /// Note that nesting levels count from outermost to innermost, and this is
302 /// the reverse of our iteration order where new inner levels are pushed at
303 /// the front of the stack.
getStackElemAtLevel(unsigned Level)304 SharingMapTy &getStackElemAtLevel(unsigned Level) {
305 assert(Level < getStackSize() && "no such stack element");
306 return Stack.back().first[Level];
307 }
getStackElemAtLevel(unsigned Level) const308 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
309 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
310 }
311
312 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
313
314 /// Checks if the variable is a local for OpenMP region.
315 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
316
317 /// Vector of previously declared requires directives
318 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
319 /// omp_allocator_handle_t type.
320 QualType OMPAllocatorHandleT;
321 /// omp_depend_t type.
322 QualType OMPDependT;
323 /// omp_event_handle_t type.
324 QualType OMPEventHandleT;
325 /// omp_alloctrait_t type.
326 QualType OMPAlloctraitT;
327 /// Expression for the predefined allocators.
328 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
329 nullptr};
330 /// Vector of previously encountered target directives
331 SmallVector<SourceLocation, 2> TargetLocations;
332 SourceLocation AtomicLocation;
333 /// Vector of declare variant construct traits.
334 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
335
336 public:
DSAStackTy(Sema & S)337 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
338
339 /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)340 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
341 /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const342 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
343 /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)344 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
345 /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const346 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
347 /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)348 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
349 Expr *Allocator) {
350 OMPPredefinedAllocators[AllocatorKind] = Allocator;
351 }
352 /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const353 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
354 return OMPPredefinedAllocators[AllocatorKind];
355 }
356 /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)357 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
358 /// Gets omp_depend_t type.
getOMPDependT() const359 QualType getOMPDependT() const { return OMPDependT; }
360
361 /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)362 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
363 /// Gets omp_event_handle_t type.
getOMPEventHandleT() const364 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
365
isClauseParsingMode() const366 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const367 OpenMPClauseKind getClauseParsingMode() const {
368 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
369 return ClauseKindMode;
370 }
setClauseParsingMode(OpenMPClauseKind K)371 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
372
isBodyComplete() const373 bool isBodyComplete() const {
374 const SharingMapTy *Top = getTopOfStackOrNull();
375 return Top && Top->BodyComplete;
376 }
setBodyComplete()377 void setBodyComplete() { getTopOfStack().BodyComplete = true; }
378
isForceVarCapturing() const379 bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)380 void setForceVarCapturing(bool V) { ForceCapturing = V; }
381
setForceCaptureByReferenceInTargetExecutable(bool V)382 void setForceCaptureByReferenceInTargetExecutable(bool V) {
383 ForceCaptureByReferenceInTargetExecutable = V;
384 }
isForceCaptureByReferenceInTargetExecutable() const385 bool isForceCaptureByReferenceInTargetExecutable() const {
386 return ForceCaptureByReferenceInTargetExecutable;
387 }
388
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)389 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
390 Scope *CurScope, SourceLocation Loc) {
391 assert(!IgnoredStackElements &&
392 "cannot change stack while ignoring elements");
393 if (Stack.empty() ||
394 Stack.back().second != CurrentNonCapturingFunctionScope)
395 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
396 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
397 Stack.back().first.back().DefaultAttrLoc = Loc;
398 }
399
pop()400 void pop() {
401 assert(!IgnoredStackElements &&
402 "cannot change stack while ignoring elements");
403 assert(!Stack.back().first.empty() &&
404 "Data-sharing attributes stack is empty!");
405 Stack.back().first.pop_back();
406 }
407
408 /// RAII object to temporarily leave the scope of a directive when we want to
409 /// logically operate in its parent.
410 class ParentDirectiveScope {
411 DSAStackTy &Self;
412 bool Active;
413
414 public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)415 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
416 : Self(Self), Active(false) {
417 if (Activate)
418 enable();
419 }
~ParentDirectiveScope()420 ~ParentDirectiveScope() { disable(); }
disable()421 void disable() {
422 if (Active) {
423 --Self.IgnoredStackElements;
424 Active = false;
425 }
426 }
enable()427 void enable() {
428 if (!Active) {
429 ++Self.IgnoredStackElements;
430 Active = true;
431 }
432 }
433 };
434
435 /// Marks that we're started loop parsing.
loopInit()436 void loopInit() {
437 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
438 "Expected loop-based directive.");
439 getTopOfStack().LoopStart = true;
440 }
441 /// Start capturing of the variables in the loop context.
loopStart()442 void loopStart() {
443 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
444 "Expected loop-based directive.");
445 getTopOfStack().LoopStart = false;
446 }
447 /// true, if variables are captured, false otherwise.
isLoopStarted() const448 bool isLoopStarted() const {
449 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
450 "Expected loop-based directive.");
451 return !getTopOfStack().LoopStart;
452 }
453 /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)454 void resetPossibleLoopCounter(const Decl *D = nullptr) {
455 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
456 }
457 /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const458 const Decl *getPossiblyLoopCunter() const {
459 return getTopOfStack().PossiblyLoopCounter;
460 }
461 /// Start new OpenMP region stack in new non-capturing function.
pushFunction()462 void pushFunction() {
463 assert(!IgnoredStackElements &&
464 "cannot change stack while ignoring elements");
465 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
466 assert(!isa<CapturingScopeInfo>(CurFnScope));
467 CurrentNonCapturingFunctionScope = CurFnScope;
468 }
469 /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)470 void popFunction(const FunctionScopeInfo *OldFSI) {
471 assert(!IgnoredStackElements &&
472 "cannot change stack while ignoring elements");
473 if (!Stack.empty() && Stack.back().second == OldFSI) {
474 assert(Stack.back().first.empty());
475 Stack.pop_back();
476 }
477 CurrentNonCapturingFunctionScope = nullptr;
478 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
479 if (!isa<CapturingScopeInfo>(FSI)) {
480 CurrentNonCapturingFunctionScope = FSI;
481 break;
482 }
483 }
484 }
485
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)486 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
487 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
488 }
489 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const490 getCriticalWithHint(const DeclarationNameInfo &Name) const {
491 auto I = Criticals.find(Name.getAsString());
492 if (I != Criticals.end())
493 return I->second;
494 return std::make_pair(nullptr, llvm::APSInt());
495 }
496 /// If 'aligned' declaration for given variable \a D was not seen yet,
497 /// add it and return NULL; otherwise return previous occurrence's expression
498 /// for diagnostics.
499 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
500 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
501 /// add it and return NULL; otherwise return previous occurrence's expression
502 /// for diagnostics.
503 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
504
505 /// Register specified variable as loop control variable.
506 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
507 /// Check if the specified variable is a loop control variable for
508 /// current region.
509 /// \return The index of the loop control variable in the list of associated
510 /// for-loops (from outer to inner).
511 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
512 /// Check if the specified variable is a loop control variable for
513 /// parent region.
514 /// \return The index of the loop control variable in the list of associated
515 /// for-loops (from outer to inner).
516 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
517 /// Check if the specified variable is a loop control variable for
518 /// current region.
519 /// \return The index of the loop control variable in the list of associated
520 /// for-loops (from outer to inner).
521 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
522 unsigned Level) const;
523 /// Get the loop control variable for the I-th loop (or nullptr) in
524 /// parent directive.
525 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
526
527 /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)528 void markDeclAsUsedInScanDirective(ValueDecl *D) {
529 if (SharingMapTy *Stack = getSecondOnStackOrNull())
530 Stack->UsedInScanDirective.insert(D);
531 }
532
533 /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const534 bool isUsedInScanDirective(ValueDecl *D) const {
535 if (const SharingMapTy *Stack = getTopOfStackOrNull())
536 return Stack->UsedInScanDirective.contains(D);
537 return false;
538 }
539
540 /// Adds explicit data sharing attribute to the specified declaration.
541 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
542 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
543 bool AppliedToPointee = false);
544
545 /// Adds additional information for the reduction items with the reduction id
546 /// represented as an operator.
547 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
548 BinaryOperatorKind BOK);
549 /// Adds additional information for the reduction items with the reduction id
550 /// represented as reduction identifier.
551 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
552 const Expr *ReductionRef);
553 /// Returns the location and reduction operation from the innermost parent
554 /// region for the given \p D.
555 const DSAVarData
556 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
557 BinaryOperatorKind &BOK,
558 Expr *&TaskgroupDescriptor) const;
559 /// Returns the location and reduction operation from the innermost parent
560 /// region for the given \p D.
561 const DSAVarData
562 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
563 const Expr *&ReductionRef,
564 Expr *&TaskgroupDescriptor) const;
565 /// Return reduction reference expression for the current taskgroup or
566 /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const567 Expr *getTaskgroupReductionRef() const {
568 assert((getTopOfStack().Directive == OMPD_taskgroup ||
569 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
570 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
571 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
572 "taskgroup reference expression requested for non taskgroup or "
573 "parallel/worksharing directive.");
574 return getTopOfStack().TaskgroupReductionRef;
575 }
576 /// Checks if the given \p VD declaration is actually a taskgroup reduction
577 /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const578 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
579 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
580 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
581 ->getDecl() == VD;
582 }
583
584 /// Returns data sharing attributes from top of the stack for the
585 /// specified declaration.
586 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
587 /// Returns data-sharing attributes for the specified declaration.
588 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
589 /// Returns data-sharing attributes for the specified declaration.
590 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
591 /// Checks if the specified variables has data-sharing attributes which
592 /// match specified \a CPred predicate in any directive which matches \a DPred
593 /// predicate.
594 const DSAVarData
595 hasDSA(ValueDecl *D,
596 const llvm::function_ref<bool(OpenMPClauseKind, bool,
597 DefaultDataSharingAttributes)>
598 CPred,
599 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
600 bool FromParent) const;
601 /// Checks if the specified variables has data-sharing attributes which
602 /// match specified \a CPred predicate in any innermost directive which
603 /// matches \a DPred predicate.
604 const DSAVarData
605 hasInnermostDSA(ValueDecl *D,
606 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
607 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
608 bool FromParent) const;
609 /// Checks if the specified variables has explicit data-sharing
610 /// attributes which match specified \a CPred predicate at the specified
611 /// OpenMP region.
612 bool
613 hasExplicitDSA(const ValueDecl *D,
614 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
615 unsigned Level, bool NotLastprivate = false) const;
616
617 /// Returns true if the directive at level \Level matches in the
618 /// specified \a DPred predicate.
619 bool hasExplicitDirective(
620 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
621 unsigned Level) const;
622
623 /// Finds a directive which matches specified \a DPred predicate.
624 bool hasDirective(
625 const llvm::function_ref<bool(
626 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
627 DPred,
628 bool FromParent) const;
629
630 /// Returns currently analyzed directive.
getCurrentDirective() const631 OpenMPDirectiveKind getCurrentDirective() const {
632 const SharingMapTy *Top = getTopOfStackOrNull();
633 return Top ? Top->Directive : OMPD_unknown;
634 }
635 /// Returns directive kind at specified level.
getDirective(unsigned Level) const636 OpenMPDirectiveKind getDirective(unsigned Level) const {
637 assert(!isStackEmpty() && "No directive at specified level.");
638 return getStackElemAtLevel(Level).Directive;
639 }
640 /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const641 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
642 unsigned OpenMPCaptureLevel) const {
643 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
644 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
645 return CaptureRegions[OpenMPCaptureLevel];
646 }
647 /// Returns parent directive.
getParentDirective() const648 OpenMPDirectiveKind getParentDirective() const {
649 const SharingMapTy *Parent = getSecondOnStackOrNull();
650 return Parent ? Parent->Directive : OMPD_unknown;
651 }
652
653 /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)654 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
655
656 /// Checks if the defined 'requires' directive has specified type of clause.
hasRequiresDeclWithClause() const657 template <typename ClauseType> bool hasRequiresDeclWithClause() const {
658 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
659 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
660 return isa<ClauseType>(C);
661 });
662 });
663 }
664
665 /// Checks for a duplicate clause amongst previously declared requires
666 /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const667 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
668 bool IsDuplicate = false;
669 for (OMPClause *CNew : ClauseList) {
670 for (const OMPRequiresDecl *D : RequiresDecls) {
671 for (const OMPClause *CPrev : D->clauselists()) {
672 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
673 SemaRef.Diag(CNew->getBeginLoc(),
674 diag::err_omp_requires_clause_redeclaration)
675 << getOpenMPClauseName(CNew->getClauseKind());
676 SemaRef.Diag(CPrev->getBeginLoc(),
677 diag::note_omp_requires_previous_clause)
678 << getOpenMPClauseName(CPrev->getClauseKind());
679 IsDuplicate = true;
680 }
681 }
682 }
683 }
684 return IsDuplicate;
685 }
686
687 /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)688 void addTargetDirLocation(SourceLocation LocStart) {
689 TargetLocations.push_back(LocStart);
690 }
691
692 /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)693 void addAtomicDirectiveLoc(SourceLocation Loc) {
694 if (AtomicLocation.isInvalid())
695 AtomicLocation = Loc;
696 }
697
698 /// Returns the location of the first encountered atomic directive in the
699 /// module.
getAtomicDirectiveLoc() const700 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
701
702 // Return previously encountered target region locations.
getEncounteredTargetLocs() const703 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
704 return TargetLocations;
705 }
706
707 /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)708 void setDefaultDSANone(SourceLocation Loc) {
709 getTopOfStack().DefaultAttr = DSA_none;
710 getTopOfStack().DefaultAttrLoc = Loc;
711 }
712 /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)713 void setDefaultDSAShared(SourceLocation Loc) {
714 getTopOfStack().DefaultAttr = DSA_shared;
715 getTopOfStack().DefaultAttrLoc = Loc;
716 }
717 /// Set default data sharing attribute to private.
setDefaultDSAPrivate(SourceLocation Loc)718 void setDefaultDSAPrivate(SourceLocation Loc) {
719 getTopOfStack().DefaultAttr = DSA_private;
720 getTopOfStack().DefaultAttrLoc = Loc;
721 }
722 /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)723 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
724 getTopOfStack().DefaultAttr = DSA_firstprivate;
725 getTopOfStack().DefaultAttrLoc = Loc;
726 }
727 /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)728 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
729 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
730 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
731 DMI.ImplicitBehavior = M;
732 DMI.SLoc = Loc;
733 }
734 /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)735 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
736 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
737 return getTopOfStack()
738 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
739 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
740 getTopOfStack()
741 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
742 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
743 getTopOfStack()
744 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
745 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
746 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
747 OMPC_DEFAULTMAP_MODIFIER_unknown;
748 }
749
getConstructTraits()750 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
751 return ConstructTraits;
752 }
handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,bool ScopeEntry)753 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
754 bool ScopeEntry) {
755 if (ScopeEntry)
756 ConstructTraits.append(Traits.begin(), Traits.end());
757 else
758 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
759 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
760 assert(Top == Trait && "Something left a trait on the stack!");
761 (void)Trait;
762 (void)Top;
763 }
764 }
765
getDefaultDSA(unsigned Level) const766 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
767 return getStackSize() <= Level ? DSA_unspecified
768 : getStackElemAtLevel(Level).DefaultAttr;
769 }
getDefaultDSA() const770 DefaultDataSharingAttributes getDefaultDSA() const {
771 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
772 }
getDefaultDSALocation() const773 SourceLocation getDefaultDSALocation() const {
774 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
775 }
776 OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const777 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
778 return isStackEmpty()
779 ? OMPC_DEFAULTMAP_MODIFIER_unknown
780 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
781 }
782 OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const783 getDefaultmapModifierAtLevel(unsigned Level,
784 OpenMPDefaultmapClauseKind Kind) const {
785 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
786 }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const787 bool isDefaultmapCapturedByRef(unsigned Level,
788 OpenMPDefaultmapClauseKind Kind) const {
789 OpenMPDefaultmapClauseModifier M =
790 getDefaultmapModifierAtLevel(Level, Kind);
791 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
792 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
793 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
794 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
795 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
796 }
797 return true;
798 }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)799 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
800 OpenMPDefaultmapClauseKind Kind) {
801 switch (Kind) {
802 case OMPC_DEFAULTMAP_scalar:
803 case OMPC_DEFAULTMAP_pointer:
804 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
805 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
806 (M == OMPC_DEFAULTMAP_MODIFIER_default);
807 case OMPC_DEFAULTMAP_aggregate:
808 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
809 default:
810 break;
811 }
812 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
813 }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const814 bool mustBeFirstprivateAtLevel(unsigned Level,
815 OpenMPDefaultmapClauseKind Kind) const {
816 OpenMPDefaultmapClauseModifier M =
817 getDefaultmapModifierAtLevel(Level, Kind);
818 return mustBeFirstprivateBase(M, Kind);
819 }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const820 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
821 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
822 return mustBeFirstprivateBase(M, Kind);
823 }
824
825 /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)826 bool isThreadPrivate(VarDecl *D) {
827 const DSAVarData DVar = getTopDSA(D, false);
828 return isOpenMPThreadPrivate(DVar.CKind);
829 }
830
831 /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)832 void setOrderedRegion(bool IsOrdered, const Expr *Param,
833 OMPOrderedClause *Clause) {
834 if (IsOrdered)
835 getTopOfStack().OrderedRegion.emplace(Param, Clause);
836 else
837 getTopOfStack().OrderedRegion.reset();
838 }
839 /// Returns true, if region is ordered (has associated 'ordered' clause),
840 /// false - otherwise.
isOrderedRegion() const841 bool isOrderedRegion() const {
842 if (const SharingMapTy *Top = getTopOfStackOrNull())
843 return Top->OrderedRegion.has_value();
844 return false;
845 }
846 /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const847 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
848 if (const SharingMapTy *Top = getTopOfStackOrNull())
849 if (Top->OrderedRegion)
850 return Top->OrderedRegion.value();
851 return std::make_pair(nullptr, nullptr);
852 }
853 /// Returns true, if parent region is ordered (has associated
854 /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const855 bool isParentOrderedRegion() const {
856 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
857 return Parent->OrderedRegion.has_value();
858 return false;
859 }
860 /// Returns optional parameter for the ordered region.
861 std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const862 getParentOrderedRegionParam() const {
863 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
864 if (Parent->OrderedRegion)
865 return Parent->OrderedRegion.value();
866 return std::make_pair(nullptr, nullptr);
867 }
868 /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)869 void setNowaitRegion(bool IsNowait = true) {
870 getTopOfStack().NowaitRegion = IsNowait;
871 }
872 /// Returns true, if parent region is nowait (has associated
873 /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const874 bool isParentNowaitRegion() const {
875 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
876 return Parent->NowaitRegion;
877 return false;
878 }
879 /// Marks current region as untied (it has a 'untied' clause).
setUntiedRegion(bool IsUntied=true)880 void setUntiedRegion(bool IsUntied = true) {
881 getTopOfStack().UntiedRegion = IsUntied;
882 }
883 /// Return true if current region is untied.
isUntiedRegion() const884 bool isUntiedRegion() const {
885 const SharingMapTy *Top = getTopOfStackOrNull();
886 return Top ? Top->UntiedRegion : false;
887 }
888 /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)889 void setParentCancelRegion(bool Cancel = true) {
890 if (SharingMapTy *Parent = getSecondOnStackOrNull())
891 Parent->CancelRegion |= Cancel;
892 }
893 /// Return true if current region has inner cancel construct.
isCancelRegion() const894 bool isCancelRegion() const {
895 const SharingMapTy *Top = getTopOfStackOrNull();
896 return Top ? Top->CancelRegion : false;
897 }
898
899 /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)900 void setParentHasScanDirective(SourceLocation Loc) {
901 if (SharingMapTy *Parent = getSecondOnStackOrNull())
902 Parent->PrevScanLocation = Loc;
903 }
904 /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const905 bool doesParentHasScanDirective() const {
906 const SharingMapTy *Top = getSecondOnStackOrNull();
907 return Top ? Top->PrevScanLocation.isValid() : false;
908 }
909 /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const910 SourceLocation getParentScanDirectiveLoc() const {
911 const SharingMapTy *Top = getSecondOnStackOrNull();
912 return Top ? Top->PrevScanLocation : SourceLocation();
913 }
914 /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)915 void setParentHasOrderedDirective(SourceLocation Loc) {
916 if (SharingMapTy *Parent = getSecondOnStackOrNull())
917 Parent->PrevOrderedLocation = Loc;
918 }
919 /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const920 bool doesParentHasOrderedDirective() const {
921 const SharingMapTy *Top = getSecondOnStackOrNull();
922 return Top ? Top->PrevOrderedLocation.isValid() : false;
923 }
924 /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const925 SourceLocation getParentOrderedDirectiveLoc() const {
926 const SharingMapTy *Top = getSecondOnStackOrNull();
927 return Top ? Top->PrevOrderedLocation : SourceLocation();
928 }
929
930 /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)931 void setAssociatedLoops(unsigned Val) {
932 getTopOfStack().AssociatedLoops = Val;
933 if (Val > 1)
934 getTopOfStack().HasMutipleLoops = true;
935 }
936 /// Return collapse value for region.
getAssociatedLoops() const937 unsigned getAssociatedLoops() const {
938 const SharingMapTy *Top = getTopOfStackOrNull();
939 return Top ? Top->AssociatedLoops : 0;
940 }
941 /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const942 bool hasMutipleLoops() const {
943 const SharingMapTy *Top = getTopOfStackOrNull();
944 return Top ? Top->HasMutipleLoops : false;
945 }
946
947 /// Marks current target region as one with closely nested teams
948 /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)949 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
950 if (SharingMapTy *Parent = getSecondOnStackOrNull())
951 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
952 }
953 /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const954 bool hasInnerTeamsRegion() const {
955 return getInnerTeamsRegionLoc().isValid();
956 }
957 /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const958 SourceLocation getInnerTeamsRegionLoc() const {
959 const SharingMapTy *Top = getTopOfStackOrNull();
960 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
961 }
962
getCurScope() const963 Scope *getCurScope() const {
964 const SharingMapTy *Top = getTopOfStackOrNull();
965 return Top ? Top->CurScope : nullptr;
966 }
setContext(DeclContext * DC)967 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const968 SourceLocation getConstructLoc() const {
969 const SharingMapTy *Top = getTopOfStackOrNull();
970 return Top ? Top->ConstructLoc : SourceLocation();
971 }
972
973 /// Do the check specified in \a Check to all component lists and return true
974 /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const975 bool checkMappableExprComponentListsForDecl(
976 const ValueDecl *VD, bool CurrentRegionOnly,
977 const llvm::function_ref<
978 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
979 OpenMPClauseKind)>
980 Check) const {
981 if (isStackEmpty())
982 return false;
983 auto SI = begin();
984 auto SE = end();
985
986 if (SI == SE)
987 return false;
988
989 if (CurrentRegionOnly)
990 SE = std::next(SI);
991 else
992 std::advance(SI, 1);
993
994 for (; SI != SE; ++SI) {
995 auto MI = SI->MappedExprComponents.find(VD);
996 if (MI != SI->MappedExprComponents.end())
997 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
998 MI->second.Components)
999 if (Check(L, MI->second.Kind))
1000 return true;
1001 }
1002 return false;
1003 }
1004
1005 /// Do the check specified in \a Check to all component lists at a given level
1006 /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const1007 bool checkMappableExprComponentListsForDeclAtLevel(
1008 const ValueDecl *VD, unsigned Level,
1009 const llvm::function_ref<
1010 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1011 OpenMPClauseKind)>
1012 Check) const {
1013 if (getStackSize() <= Level)
1014 return false;
1015
1016 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1017 auto MI = StackElem.MappedExprComponents.find(VD);
1018 if (MI != StackElem.MappedExprComponents.end())
1019 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1020 MI->second.Components)
1021 if (Check(L, MI->second.Kind))
1022 return true;
1023 return false;
1024 }
1025
1026 /// Create a new mappable expression component list associated with a given
1027 /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)1028 void addMappableExpressionComponents(
1029 const ValueDecl *VD,
1030 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1031 OpenMPClauseKind WhereFoundClauseKind) {
1032 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1033 // Create new entry and append the new components there.
1034 MEC.Components.resize(MEC.Components.size() + 1);
1035 MEC.Components.back().append(Components.begin(), Components.end());
1036 MEC.Kind = WhereFoundClauseKind;
1037 }
1038
getNestingLevel() const1039 unsigned getNestingLevel() const {
1040 assert(!isStackEmpty());
1041 return getStackSize() - 1;
1042 }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)1043 void addDoacrossDependClause(OMPDependClause *C,
1044 const OperatorOffsetTy &OpsOffs) {
1045 SharingMapTy *Parent = getSecondOnStackOrNull();
1046 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1047 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1048 }
1049 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1050 getDoacrossDependClauses() const {
1051 const SharingMapTy &StackElem = getTopOfStack();
1052 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1053 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1054 return llvm::make_range(Ref.begin(), Ref.end());
1055 }
1056 return llvm::make_range(StackElem.DoacrossDepends.end(),
1057 StackElem.DoacrossDepends.end());
1058 }
1059
1060 // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1061 void addMappedClassesQualTypes(QualType QT) {
1062 SharingMapTy &StackElem = getTopOfStack();
1063 StackElem.MappedClassesQualTypes.insert(QT);
1064 }
1065
1066 // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1067 bool isClassPreviouslyMapped(QualType QT) const {
1068 const SharingMapTy &StackElem = getTopOfStack();
1069 return StackElem.MappedClassesQualTypes.contains(QT);
1070 }
1071
1072 /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1073 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1074 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1075 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1076 "Expected declare target link global.");
1077 for (auto &Elem : *this) {
1078 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1079 Elem.DeclareTargetLinkVarDecls.push_back(E);
1080 return;
1081 }
1082 }
1083 }
1084
1085 /// Returns the list of globals with declare target link if current directive
1086 /// is target.
getLinkGlobals() const1087 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1088 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1089 "Expected target executable directive.");
1090 return getTopOfStack().DeclareTargetLinkVarDecls;
1091 }
1092
1093 /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1094 void addInnerAllocatorExpr(Expr *E) {
1095 getTopOfStack().InnerUsedAllocators.push_back(E);
1096 }
1097 /// Return list of used allocators.
getInnerAllocators() const1098 ArrayRef<Expr *> getInnerAllocators() const {
1099 return getTopOfStack().InnerUsedAllocators;
1100 }
1101 /// Marks the declaration as implicitly firstprivate nin the task-based
1102 /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1103 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1104 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1105 }
1106 /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1107 bool isImplicitTaskFirstprivate(Decl *D) const {
1108 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1109 }
1110
1111 /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1112 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1113 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1114 }
1115 /// Checks if specified decl is used in uses allocator clause as the
1116 /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1117 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1118 const Decl *D) const {
1119 const SharingMapTy &StackElem = getTopOfStack();
1120 auto I = StackElem.UsesAllocatorsDecls.find(D);
1121 if (I == StackElem.UsesAllocatorsDecls.end())
1122 return None;
1123 return I->getSecond();
1124 }
isUsesAllocatorsDecl(const Decl * D) const1125 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1126 const SharingMapTy &StackElem = getTopOfStack();
1127 auto I = StackElem.UsesAllocatorsDecls.find(D);
1128 if (I == StackElem.UsesAllocatorsDecls.end())
1129 return None;
1130 return I->getSecond();
1131 }
1132
addDeclareMapperVarRef(Expr * Ref)1133 void addDeclareMapperVarRef(Expr *Ref) {
1134 SharingMapTy &StackElem = getTopOfStack();
1135 StackElem.DeclareMapperVar = Ref;
1136 }
getDeclareMapperVarRef() const1137 const Expr *getDeclareMapperVarRef() const {
1138 const SharingMapTy *Top = getTopOfStackOrNull();
1139 return Top ? Top->DeclareMapperVar : nullptr;
1140 }
1141 /// get captured field from ImplicitDefaultFirstprivateFDs
getImplicitFDCapExprDecl(const FieldDecl * FD) const1142 VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1143 const_iterator I = begin();
1144 const_iterator EndI = end();
1145 size_t StackLevel = getStackSize();
1146 for (; I != EndI; ++I) {
1147 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1148 break;
1149 StackLevel--;
1150 }
1151 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1152 if (I == EndI)
1153 return nullptr;
1154 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1155 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1156 return IFD.VD;
1157 return nullptr;
1158 }
1159 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
isImplicitDefaultFirstprivateFD(VarDecl * VD) const1160 bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1161 const_iterator I = begin();
1162 const_iterator EndI = end();
1163 for (; I != EndI; ++I)
1164 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1165 break;
1166 if (I == EndI)
1167 return false;
1168 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1169 if (IFD.VD == VD)
1170 return true;
1171 return false;
1172 }
1173 /// Store capture FD info in ImplicitDefaultFirstprivateFDs
addImplicitDefaultFirstprivateFD(const FieldDecl * FD,VarDecl * VD)1174 void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1175 iterator I = begin();
1176 const_iterator EndI = end();
1177 size_t StackLevel = getStackSize();
1178 for (; I != EndI; ++I) {
1179 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1180 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1181 break;
1182 }
1183 StackLevel--;
1184 }
1185 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1186 }
1187 };
1188
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1189 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1190 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1191 }
1192
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1193 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1194 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1195 DKind == OMPD_unknown;
1196 }
1197
1198 } // namespace
1199
getExprAsWritten(const Expr * E)1200 static const Expr *getExprAsWritten(const Expr *E) {
1201 if (const auto *FE = dyn_cast<FullExpr>(E))
1202 E = FE->getSubExpr();
1203
1204 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1205 E = MTE->getSubExpr();
1206
1207 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1208 E = Binder->getSubExpr();
1209
1210 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1211 E = ICE->getSubExprAsWritten();
1212 return E->IgnoreParens();
1213 }
1214
getExprAsWritten(Expr * E)1215 static Expr *getExprAsWritten(Expr *E) {
1216 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1217 }
1218
getCanonicalDecl(const ValueDecl * D)1219 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1220 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1221 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1222 D = ME->getMemberDecl();
1223 const auto *VD = dyn_cast<VarDecl>(D);
1224 const auto *FD = dyn_cast<FieldDecl>(D);
1225 if (VD != nullptr) {
1226 VD = VD->getCanonicalDecl();
1227 D = VD;
1228 } else {
1229 assert(FD);
1230 FD = FD->getCanonicalDecl();
1231 D = FD;
1232 }
1233 return D;
1234 }
1235
getCanonicalDecl(ValueDecl * D)1236 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1237 return const_cast<ValueDecl *>(
1238 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1239 }
1240
getDSA(const_iterator & Iter,ValueDecl * D) const1241 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1242 ValueDecl *D) const {
1243 D = getCanonicalDecl(D);
1244 auto *VD = dyn_cast<VarDecl>(D);
1245 const auto *FD = dyn_cast<FieldDecl>(D);
1246 DSAVarData DVar;
1247 if (Iter == end()) {
1248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1249 // in a region but not in construct]
1250 // File-scope or namespace-scope variables referenced in called routines
1251 // in the region are shared unless they appear in a threadprivate
1252 // directive.
1253 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1254 DVar.CKind = OMPC_shared;
1255
1256 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1257 // in a region but not in construct]
1258 // Variables with static storage duration that are declared in called
1259 // routines in the region are shared.
1260 if (VD && VD->hasGlobalStorage())
1261 DVar.CKind = OMPC_shared;
1262
1263 // Non-static data members are shared by default.
1264 if (FD)
1265 DVar.CKind = OMPC_shared;
1266
1267 return DVar;
1268 }
1269
1270 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1271 // in a Construct, C/C++, predetermined, p.1]
1272 // Variables with automatic storage duration that are declared in a scope
1273 // inside the construct are private.
1274 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1275 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1276 DVar.CKind = OMPC_private;
1277 return DVar;
1278 }
1279
1280 DVar.DKind = Iter->Directive;
1281 // Explicitly specified attributes and local variables with predetermined
1282 // attributes.
1283 if (Iter->SharingMap.count(D)) {
1284 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1285 DVar.RefExpr = Data.RefExpr.getPointer();
1286 DVar.PrivateCopy = Data.PrivateCopy;
1287 DVar.CKind = Data.Attributes;
1288 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1289 DVar.Modifier = Data.Modifier;
1290 DVar.AppliedToPointee = Data.AppliedToPointee;
1291 return DVar;
1292 }
1293
1294 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1295 // in a Construct, C/C++, implicitly determined, p.1]
1296 // In a parallel or task construct, the data-sharing attributes of these
1297 // variables are determined by the default clause, if present.
1298 switch (Iter->DefaultAttr) {
1299 case DSA_shared:
1300 DVar.CKind = OMPC_shared;
1301 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1302 return DVar;
1303 case DSA_none:
1304 return DVar;
1305 case DSA_firstprivate:
1306 if (VD && VD->getStorageDuration() == SD_Static &&
1307 VD->getDeclContext()->isFileContext()) {
1308 DVar.CKind = OMPC_unknown;
1309 } else {
1310 DVar.CKind = OMPC_firstprivate;
1311 }
1312 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1313 return DVar;
1314 case DSA_private:
1315 // each variable with static storage duration that is declared
1316 // in a namespace or global scope and referenced in the construct,
1317 // and that does not have a predetermined data-sharing attribute
1318 if (VD && VD->getStorageDuration() == SD_Static &&
1319 VD->getDeclContext()->isFileContext()) {
1320 DVar.CKind = OMPC_unknown;
1321 } else {
1322 DVar.CKind = OMPC_private;
1323 }
1324 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1325 return DVar;
1326 case DSA_unspecified:
1327 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1328 // in a Construct, implicitly determined, p.2]
1329 // In a parallel construct, if no default clause is present, these
1330 // variables are shared.
1331 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1332 if ((isOpenMPParallelDirective(DVar.DKind) &&
1333 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1334 isOpenMPTeamsDirective(DVar.DKind)) {
1335 DVar.CKind = OMPC_shared;
1336 return DVar;
1337 }
1338
1339 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1340 // in a Construct, implicitly determined, p.4]
1341 // In a task construct, if no default clause is present, a variable that in
1342 // the enclosing context is determined to be shared by all implicit tasks
1343 // bound to the current team is shared.
1344 if (isOpenMPTaskingDirective(DVar.DKind)) {
1345 DSAVarData DVarTemp;
1346 const_iterator I = Iter, E = end();
1347 do {
1348 ++I;
1349 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1350 // Referenced in a Construct, implicitly determined, p.6]
1351 // In a task construct, if no default clause is present, a variable
1352 // whose data-sharing attribute is not determined by the rules above is
1353 // firstprivate.
1354 DVarTemp = getDSA(I, D);
1355 if (DVarTemp.CKind != OMPC_shared) {
1356 DVar.RefExpr = nullptr;
1357 DVar.CKind = OMPC_firstprivate;
1358 return DVar;
1359 }
1360 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1361 DVar.CKind =
1362 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1363 return DVar;
1364 }
1365 }
1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1367 // in a Construct, implicitly determined, p.3]
1368 // For constructs other than task, if no default clause is present, these
1369 // variables inherit their data-sharing attributes from the enclosing
1370 // context.
1371 return getDSA(++Iter, D);
1372 }
1373
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1374 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1375 const Expr *NewDE) {
1376 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1377 D = getCanonicalDecl(D);
1378 SharingMapTy &StackElem = getTopOfStack();
1379 auto It = StackElem.AlignedMap.find(D);
1380 if (It == StackElem.AlignedMap.end()) {
1381 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1382 StackElem.AlignedMap[D] = NewDE;
1383 return nullptr;
1384 }
1385 assert(It->second && "Unexpected nullptr expr in the aligned map");
1386 return It->second;
1387 }
1388
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1389 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1390 const Expr *NewDE) {
1391 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1392 D = getCanonicalDecl(D);
1393 SharingMapTy &StackElem = getTopOfStack();
1394 auto It = StackElem.NontemporalMap.find(D);
1395 if (It == StackElem.NontemporalMap.end()) {
1396 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1397 StackElem.NontemporalMap[D] = NewDE;
1398 return nullptr;
1399 }
1400 assert(It->second && "Unexpected nullptr expr in the aligned map");
1401 return It->second;
1402 }
1403
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1404 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1405 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1406 D = getCanonicalDecl(D);
1407 SharingMapTy &StackElem = getTopOfStack();
1408 StackElem.LCVMap.try_emplace(
1409 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1410 }
1411
1412 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1413 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1414 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1415 D = getCanonicalDecl(D);
1416 const SharingMapTy &StackElem = getTopOfStack();
1417 auto It = StackElem.LCVMap.find(D);
1418 if (It != StackElem.LCVMap.end())
1419 return It->second;
1420 return {0, nullptr};
1421 }
1422
1423 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1424 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1425 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1426 D = getCanonicalDecl(D);
1427 for (unsigned I = Level + 1; I > 0; --I) {
1428 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1429 auto It = StackElem.LCVMap.find(D);
1430 if (It != StackElem.LCVMap.end())
1431 return It->second;
1432 }
1433 return {0, nullptr};
1434 }
1435
1436 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1437 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1438 const SharingMapTy *Parent = getSecondOnStackOrNull();
1439 assert(Parent && "Data-sharing attributes stack is empty");
1440 D = getCanonicalDecl(D);
1441 auto It = Parent->LCVMap.find(D);
1442 if (It != Parent->LCVMap.end())
1443 return It->second;
1444 return {0, nullptr};
1445 }
1446
getParentLoopControlVariable(unsigned I) const1447 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1448 const SharingMapTy *Parent = getSecondOnStackOrNull();
1449 assert(Parent && "Data-sharing attributes stack is empty");
1450 if (Parent->LCVMap.size() < I)
1451 return nullptr;
1452 for (const auto &Pair : Parent->LCVMap)
1453 if (Pair.second.first == I)
1454 return Pair.first;
1455 return nullptr;
1456 }
1457
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1458 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1459 DeclRefExpr *PrivateCopy, unsigned Modifier,
1460 bool AppliedToPointee) {
1461 D = getCanonicalDecl(D);
1462 if (A == OMPC_threadprivate) {
1463 DSAInfo &Data = Threadprivates[D];
1464 Data.Attributes = A;
1465 Data.RefExpr.setPointer(E);
1466 Data.PrivateCopy = nullptr;
1467 Data.Modifier = Modifier;
1468 } else {
1469 DSAInfo &Data = getTopOfStack().SharingMap[D];
1470 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1471 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1472 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1473 (isLoopControlVariable(D).first && A == OMPC_private));
1474 Data.Modifier = Modifier;
1475 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1476 Data.RefExpr.setInt(/*IntVal=*/true);
1477 return;
1478 }
1479 const bool IsLastprivate =
1480 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1481 Data.Attributes = A;
1482 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1483 Data.PrivateCopy = PrivateCopy;
1484 Data.AppliedToPointee = AppliedToPointee;
1485 if (PrivateCopy) {
1486 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1487 Data.Modifier = Modifier;
1488 Data.Attributes = A;
1489 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1490 Data.PrivateCopy = nullptr;
1491 Data.AppliedToPointee = AppliedToPointee;
1492 }
1493 }
1494 }
1495
1496 /// Build a variable declaration for OpenMP loop iteration variable.
buildVarDecl(Sema & SemaRef,SourceLocation Loc,QualType Type,StringRef Name,const AttrVec * Attrs=nullptr,DeclRefExpr * OrigRef=nullptr)1497 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1498 StringRef Name, const AttrVec *Attrs = nullptr,
1499 DeclRefExpr *OrigRef = nullptr) {
1500 DeclContext *DC = SemaRef.CurContext;
1501 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1502 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1503 auto *Decl =
1504 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1505 if (Attrs) {
1506 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1507 I != E; ++I)
1508 Decl->addAttr(*I);
1509 }
1510 Decl->setImplicit();
1511 if (OrigRef) {
1512 Decl->addAttr(
1513 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1514 }
1515 return Decl;
1516 }
1517
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1518 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1519 SourceLocation Loc,
1520 bool RefersToCapture = false) {
1521 D->setReferenced();
1522 D->markUsed(S.Context);
1523 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1524 SourceLocation(), D, RefersToCapture, Loc, Ty,
1525 VK_LValue);
1526 }
1527
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1528 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1529 BinaryOperatorKind BOK) {
1530 D = getCanonicalDecl(D);
1531 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1532 assert(
1533 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1534 "Additional reduction info may be specified only for reduction items.");
1535 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1536 assert(ReductionData.ReductionRange.isInvalid() &&
1537 (getTopOfStack().Directive == OMPD_taskgroup ||
1538 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1539 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1540 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1541 "Additional reduction info may be specified only once for reduction "
1542 "items.");
1543 ReductionData.set(BOK, SR);
1544 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1545 if (!TaskgroupReductionRef) {
1546 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1547 SemaRef.Context.VoidPtrTy, ".task_red.");
1548 TaskgroupReductionRef =
1549 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1550 }
1551 }
1552
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1553 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1554 const Expr *ReductionRef) {
1555 D = getCanonicalDecl(D);
1556 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1557 assert(
1558 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1559 "Additional reduction info may be specified only for reduction items.");
1560 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1561 assert(ReductionData.ReductionRange.isInvalid() &&
1562 (getTopOfStack().Directive == OMPD_taskgroup ||
1563 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1564 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1565 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1566 "Additional reduction info may be specified only once for reduction "
1567 "items.");
1568 ReductionData.set(ReductionRef, SR);
1569 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1570 if (!TaskgroupReductionRef) {
1571 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1572 SemaRef.Context.VoidPtrTy, ".task_red.");
1573 TaskgroupReductionRef =
1574 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1575 }
1576 }
1577
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1578 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1579 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1580 Expr *&TaskgroupDescriptor) const {
1581 D = getCanonicalDecl(D);
1582 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1583 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1584 const DSAInfo &Data = I->SharingMap.lookup(D);
1585 if (Data.Attributes != OMPC_reduction ||
1586 Data.Modifier != OMPC_REDUCTION_task)
1587 continue;
1588 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1589 if (!ReductionData.ReductionOp ||
1590 ReductionData.ReductionOp.is<const Expr *>())
1591 return DSAVarData();
1592 SR = ReductionData.ReductionRange;
1593 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1594 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1595 "expression for the descriptor is not "
1596 "set.");
1597 TaskgroupDescriptor = I->TaskgroupReductionRef;
1598 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1599 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1600 /*AppliedToPointee=*/false);
1601 }
1602 return DSAVarData();
1603 }
1604
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1605 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1606 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1607 Expr *&TaskgroupDescriptor) const {
1608 D = getCanonicalDecl(D);
1609 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1610 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1611 const DSAInfo &Data = I->SharingMap.lookup(D);
1612 if (Data.Attributes != OMPC_reduction ||
1613 Data.Modifier != OMPC_REDUCTION_task)
1614 continue;
1615 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1616 if (!ReductionData.ReductionOp ||
1617 !ReductionData.ReductionOp.is<const Expr *>())
1618 return DSAVarData();
1619 SR = ReductionData.ReductionRange;
1620 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1621 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1622 "expression for the descriptor is not "
1623 "set.");
1624 TaskgroupDescriptor = I->TaskgroupReductionRef;
1625 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1626 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1627 /*AppliedToPointee=*/false);
1628 }
1629 return DSAVarData();
1630 }
1631
isOpenMPLocal(VarDecl * D,const_iterator I) const1632 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1633 D = D->getCanonicalDecl();
1634 for (const_iterator E = end(); I != E; ++I) {
1635 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1636 isOpenMPTargetExecutionDirective(I->Directive)) {
1637 if (I->CurScope) {
1638 Scope *TopScope = I->CurScope->getParent();
1639 Scope *CurScope = getCurScope();
1640 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1641 CurScope = CurScope->getParent();
1642 return CurScope != TopScope;
1643 }
1644 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1645 if (I->Context == DC)
1646 return true;
1647 return false;
1648 }
1649 }
1650 return false;
1651 }
1652
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1653 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1654 bool AcceptIfMutable = true,
1655 bool *IsClassType = nullptr) {
1656 ASTContext &Context = SemaRef.getASTContext();
1657 Type = Type.getNonReferenceType().getCanonicalType();
1658 bool IsConstant = Type.isConstant(Context);
1659 Type = Context.getBaseElementType(Type);
1660 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1661 ? Type->getAsCXXRecordDecl()
1662 : nullptr;
1663 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1664 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1665 RD = CTD->getTemplatedDecl();
1666 if (IsClassType)
1667 *IsClassType = RD;
1668 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1669 RD->hasDefinition() && RD->hasMutableFields());
1670 }
1671
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1672 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1673 QualType Type, OpenMPClauseKind CKind,
1674 SourceLocation ELoc,
1675 bool AcceptIfMutable = true,
1676 bool ListItemNotVar = false) {
1677 ASTContext &Context = SemaRef.getASTContext();
1678 bool IsClassType;
1679 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1680 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1681 : IsClassType ? diag::err_omp_const_not_mutable_variable
1682 : diag::err_omp_const_variable;
1683 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1684 if (!ListItemNotVar && D) {
1685 const VarDecl *VD = dyn_cast<VarDecl>(D);
1686 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1687 VarDecl::DeclarationOnly;
1688 SemaRef.Diag(D->getLocation(),
1689 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1690 << D;
1691 }
1692 return true;
1693 }
1694 return false;
1695 }
1696
getTopDSA(ValueDecl * D,bool FromParent)1697 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1698 bool FromParent) {
1699 D = getCanonicalDecl(D);
1700 DSAVarData DVar;
1701
1702 auto *VD = dyn_cast<VarDecl>(D);
1703 auto TI = Threadprivates.find(D);
1704 if (TI != Threadprivates.end()) {
1705 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1706 DVar.CKind = OMPC_threadprivate;
1707 DVar.Modifier = TI->getSecond().Modifier;
1708 return DVar;
1709 }
1710 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1711 DVar.RefExpr = buildDeclRefExpr(
1712 SemaRef, VD, D->getType().getNonReferenceType(),
1713 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1714 DVar.CKind = OMPC_threadprivate;
1715 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1716 return DVar;
1717 }
1718 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1719 // in a Construct, C/C++, predetermined, p.1]
1720 // Variables appearing in threadprivate directives are threadprivate.
1721 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1722 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1723 SemaRef.getLangOpts().OpenMPUseTLS &&
1724 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1725 (VD && VD->getStorageClass() == SC_Register &&
1726 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1727 DVar.RefExpr = buildDeclRefExpr(
1728 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1729 DVar.CKind = OMPC_threadprivate;
1730 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1731 return DVar;
1732 }
1733 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1734 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1735 !isLoopControlVariable(D).first) {
1736 const_iterator IterTarget =
1737 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1738 return isOpenMPTargetExecutionDirective(Data.Directive);
1739 });
1740 if (IterTarget != end()) {
1741 const_iterator ParentIterTarget = IterTarget + 1;
1742 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1743 if (isOpenMPLocal(VD, Iter)) {
1744 DVar.RefExpr =
1745 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1746 D->getLocation());
1747 DVar.CKind = OMPC_threadprivate;
1748 return DVar;
1749 }
1750 }
1751 if (!isClauseParsingMode() || IterTarget != begin()) {
1752 auto DSAIter = IterTarget->SharingMap.find(D);
1753 if (DSAIter != IterTarget->SharingMap.end() &&
1754 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1755 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1756 DVar.CKind = OMPC_threadprivate;
1757 return DVar;
1758 }
1759 const_iterator End = end();
1760 if (!SemaRef.isOpenMPCapturedByRef(D,
1761 std::distance(ParentIterTarget, End),
1762 /*OpenMPCaptureLevel=*/0)) {
1763 DVar.RefExpr =
1764 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1765 IterTarget->ConstructLoc);
1766 DVar.CKind = OMPC_threadprivate;
1767 return DVar;
1768 }
1769 }
1770 }
1771 }
1772
1773 if (isStackEmpty())
1774 // Not in OpenMP execution region and top scope was already checked.
1775 return DVar;
1776
1777 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1778 // in a Construct, C/C++, predetermined, p.4]
1779 // Static data members are shared.
1780 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1781 // in a Construct, C/C++, predetermined, p.7]
1782 // Variables with static storage duration that are declared in a scope
1783 // inside the construct are shared.
1784 if (VD && VD->isStaticDataMember()) {
1785 // Check for explicitly specified attributes.
1786 const_iterator I = begin();
1787 const_iterator EndI = end();
1788 if (FromParent && I != EndI)
1789 ++I;
1790 if (I != EndI) {
1791 auto It = I->SharingMap.find(D);
1792 if (It != I->SharingMap.end()) {
1793 const DSAInfo &Data = It->getSecond();
1794 DVar.RefExpr = Data.RefExpr.getPointer();
1795 DVar.PrivateCopy = Data.PrivateCopy;
1796 DVar.CKind = Data.Attributes;
1797 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1798 DVar.DKind = I->Directive;
1799 DVar.Modifier = Data.Modifier;
1800 DVar.AppliedToPointee = Data.AppliedToPointee;
1801 return DVar;
1802 }
1803 }
1804
1805 DVar.CKind = OMPC_shared;
1806 return DVar;
1807 }
1808
1809 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1810 // The predetermined shared attribute for const-qualified types having no
1811 // mutable members was removed after OpenMP 3.1.
1812 if (SemaRef.LangOpts.OpenMP <= 31) {
1813 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1814 // in a Construct, C/C++, predetermined, p.6]
1815 // Variables with const qualified type having no mutable member are
1816 // shared.
1817 if (isConstNotMutableType(SemaRef, D->getType())) {
1818 // Variables with const-qualified type having no mutable member may be
1819 // listed in a firstprivate clause, even if they are static data members.
1820 DSAVarData DVarTemp = hasInnermostDSA(
1821 D,
1822 [](OpenMPClauseKind C, bool) {
1823 return C == OMPC_firstprivate || C == OMPC_shared;
1824 },
1825 MatchesAlways, FromParent);
1826 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1827 return DVarTemp;
1828
1829 DVar.CKind = OMPC_shared;
1830 return DVar;
1831 }
1832 }
1833
1834 // Explicitly specified attributes and local variables with predetermined
1835 // attributes.
1836 const_iterator I = begin();
1837 const_iterator EndI = end();
1838 if (FromParent && I != EndI)
1839 ++I;
1840 if (I == EndI)
1841 return DVar;
1842 auto It = I->SharingMap.find(D);
1843 if (It != I->SharingMap.end()) {
1844 const DSAInfo &Data = It->getSecond();
1845 DVar.RefExpr = Data.RefExpr.getPointer();
1846 DVar.PrivateCopy = Data.PrivateCopy;
1847 DVar.CKind = Data.Attributes;
1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849 DVar.DKind = I->Directive;
1850 DVar.Modifier = Data.Modifier;
1851 DVar.AppliedToPointee = Data.AppliedToPointee;
1852 }
1853
1854 return DVar;
1855 }
1856
getImplicitDSA(ValueDecl * D,bool FromParent) const1857 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1858 bool FromParent) const {
1859 if (isStackEmpty()) {
1860 const_iterator I;
1861 return getDSA(I, D);
1862 }
1863 D = getCanonicalDecl(D);
1864 const_iterator StartI = begin();
1865 const_iterator EndI = end();
1866 if (FromParent && StartI != EndI)
1867 ++StartI;
1868 return getDSA(StartI, D);
1869 }
1870
getImplicitDSA(ValueDecl * D,unsigned Level) const1871 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1872 unsigned Level) const {
1873 if (getStackSize() <= Level)
1874 return DSAVarData();
1875 D = getCanonicalDecl(D);
1876 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1877 return getDSA(StartI, D);
1878 }
1879
1880 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool,DefaultDataSharingAttributes)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1881 DSAStackTy::hasDSA(ValueDecl *D,
1882 const llvm::function_ref<bool(OpenMPClauseKind, bool,
1883 DefaultDataSharingAttributes)>
1884 CPred,
1885 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1886 bool FromParent) const {
1887 if (isStackEmpty())
1888 return {};
1889 D = getCanonicalDecl(D);
1890 const_iterator I = begin();
1891 const_iterator EndI = end();
1892 if (FromParent && I != EndI)
1893 ++I;
1894 for (; I != EndI; ++I) {
1895 if (!DPred(I->Directive) &&
1896 !isImplicitOrExplicitTaskingRegion(I->Directive))
1897 continue;
1898 const_iterator NewI = I;
1899 DSAVarData DVar = getDSA(NewI, D);
1900 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1901 return DVar;
1902 }
1903 return {};
1904 }
1905
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1906 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1907 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1908 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1909 bool FromParent) const {
1910 if (isStackEmpty())
1911 return {};
1912 D = getCanonicalDecl(D);
1913 const_iterator StartI = begin();
1914 const_iterator EndI = end();
1915 if (FromParent && StartI != EndI)
1916 ++StartI;
1917 if (StartI == EndI || !DPred(StartI->Directive))
1918 return {};
1919 const_iterator NewI = StartI;
1920 DSAVarData DVar = getDSA(NewI, D);
1921 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1922 ? DVar
1923 : DSAVarData();
1924 }
1925
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1926 bool DSAStackTy::hasExplicitDSA(
1927 const ValueDecl *D,
1928 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1929 unsigned Level, bool NotLastprivate) const {
1930 if (getStackSize() <= Level)
1931 return false;
1932 D = getCanonicalDecl(D);
1933 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1934 auto I = StackElem.SharingMap.find(D);
1935 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1936 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1937 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1938 return true;
1939 // Check predetermined rules for the loop control variables.
1940 auto LI = StackElem.LCVMap.find(D);
1941 if (LI != StackElem.LCVMap.end())
1942 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1943 return false;
1944 }
1945
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1946 bool DSAStackTy::hasExplicitDirective(
1947 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1948 unsigned Level) const {
1949 if (getStackSize() <= Level)
1950 return false;
1951 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1952 return DPred(StackElem.Directive);
1953 }
1954
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1955 bool DSAStackTy::hasDirective(
1956 const llvm::function_ref<bool(OpenMPDirectiveKind,
1957 const DeclarationNameInfo &, SourceLocation)>
1958 DPred,
1959 bool FromParent) const {
1960 // We look only in the enclosing region.
1961 size_t Skip = FromParent ? 2 : 1;
1962 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1963 I != E; ++I) {
1964 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1965 return true;
1966 }
1967 return false;
1968 }
1969
InitDataSharingAttributesStack()1970 void Sema::InitDataSharingAttributesStack() {
1971 VarDataSharingAttributesStack = new DSAStackTy(*this);
1972 }
1973
1974 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1975
pushOpenMPFunctionRegion()1976 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
1977
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1978 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1979 DSAStack->popFunction(OldFSI);
1980 }
1981
isOpenMPDeviceDelayedContext(Sema & S)1982 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1983 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1984 "Expected OpenMP device compilation.");
1985 return !S.isInOpenMPTargetExecutionDirective();
1986 }
1987
1988 namespace {
1989 /// Status of the function emission on the host/device.
1990 enum class FunctionEmissionStatus {
1991 Emitted,
1992 Discarded,
1993 Unknown,
1994 };
1995 } // anonymous namespace
1996
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1997 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1998 unsigned DiagID,
1999 FunctionDecl *FD) {
2000 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
2001 "Expected OpenMP device compilation.");
2002
2003 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2004 if (FD) {
2005 FunctionEmissionStatus FES = getEmissionStatus(FD);
2006 switch (FES) {
2007 case FunctionEmissionStatus::Emitted:
2008 Kind = SemaDiagnosticBuilder::K_Immediate;
2009 break;
2010 case FunctionEmissionStatus::Unknown:
2011 // TODO: We should always delay diagnostics here in case a target
2012 // region is in a function we do not emit. However, as the
2013 // current diagnostics are associated with the function containing
2014 // the target region and we do not emit that one, we would miss out
2015 // on diagnostics for the target region itself. We need to anchor
2016 // the diagnostics with the new generated function *or* ensure we
2017 // emit diagnostics associated with the surrounding function.
2018 Kind = isOpenMPDeviceDelayedContext(*this)
2019 ? SemaDiagnosticBuilder::K_Deferred
2020 : SemaDiagnosticBuilder::K_Immediate;
2021 break;
2022 case FunctionEmissionStatus::TemplateDiscarded:
2023 case FunctionEmissionStatus::OMPDiscarded:
2024 Kind = SemaDiagnosticBuilder::K_Nop;
2025 break;
2026 case FunctionEmissionStatus::CUDADiscarded:
2027 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2028 break;
2029 }
2030 }
2031
2032 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2033 }
2034
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)2035 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2036 unsigned DiagID,
2037 FunctionDecl *FD) {
2038 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
2039 "Expected OpenMP host compilation.");
2040
2041 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2042 if (FD) {
2043 FunctionEmissionStatus FES = getEmissionStatus(FD);
2044 switch (FES) {
2045 case FunctionEmissionStatus::Emitted:
2046 Kind = SemaDiagnosticBuilder::K_Immediate;
2047 break;
2048 case FunctionEmissionStatus::Unknown:
2049 Kind = SemaDiagnosticBuilder::K_Deferred;
2050 break;
2051 case FunctionEmissionStatus::TemplateDiscarded:
2052 case FunctionEmissionStatus::OMPDiscarded:
2053 case FunctionEmissionStatus::CUDADiscarded:
2054 Kind = SemaDiagnosticBuilder::K_Nop;
2055 break;
2056 }
2057 }
2058
2059 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2060 }
2061
2062 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)2063 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2064 if (LO.OpenMP <= 45) {
2065 if (VD->getType().getNonReferenceType()->isScalarType())
2066 return OMPC_DEFAULTMAP_scalar;
2067 return OMPC_DEFAULTMAP_aggregate;
2068 }
2069 if (VD->getType().getNonReferenceType()->isAnyPointerType())
2070 return OMPC_DEFAULTMAP_pointer;
2071 if (VD->getType().getNonReferenceType()->isScalarType())
2072 return OMPC_DEFAULTMAP_scalar;
2073 return OMPC_DEFAULTMAP_aggregate;
2074 }
2075
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const2076 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2077 unsigned OpenMPCaptureLevel) const {
2078 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2079
2080 ASTContext &Ctx = getASTContext();
2081 bool IsByRef = true;
2082
2083 // Find the directive that is associated with the provided scope.
2084 D = cast<ValueDecl>(D->getCanonicalDecl());
2085 QualType Ty = D->getType();
2086
2087 bool IsVariableUsedInMapClause = false;
2088 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2089 // This table summarizes how a given variable should be passed to the device
2090 // given its type and the clauses where it appears. This table is based on
2091 // the description in OpenMP 4.5 [2.10.4, target Construct] and
2092 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2093 //
2094 // =========================================================================
2095 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2096 // | |(tofrom:scalar)| | pvt | | | |
2097 // =========================================================================
2098 // | scl | | | | - | | bycopy|
2099 // | scl | | - | x | - | - | bycopy|
2100 // | scl | | x | - | - | - | null |
2101 // | scl | x | | | - | | byref |
2102 // | scl | x | - | x | - | - | bycopy|
2103 // | scl | x | x | - | - | - | null |
2104 // | scl | | - | - | - | x | byref |
2105 // | scl | x | - | - | - | x | byref |
2106 //
2107 // | agg | n.a. | | | - | | byref |
2108 // | agg | n.a. | - | x | - | - | byref |
2109 // | agg | n.a. | x | - | - | - | null |
2110 // | agg | n.a. | - | - | - | x | byref |
2111 // | agg | n.a. | - | - | - | x[] | byref |
2112 //
2113 // | ptr | n.a. | | | - | | bycopy|
2114 // | ptr | n.a. | - | x | - | - | bycopy|
2115 // | ptr | n.a. | x | - | - | - | null |
2116 // | ptr | n.a. | - | - | - | x | byref |
2117 // | ptr | n.a. | - | - | - | x[] | bycopy|
2118 // | ptr | n.a. | - | - | x | | bycopy|
2119 // | ptr | n.a. | - | - | x | x | bycopy|
2120 // | ptr | n.a. | - | - | x | x[] | bycopy|
2121 // =========================================================================
2122 // Legend:
2123 // scl - scalar
2124 // ptr - pointer
2125 // agg - aggregate
2126 // x - applies
2127 // - - invalid in this combination
2128 // [] - mapped with an array section
2129 // byref - should be mapped by reference
2130 // byval - should be mapped by value
2131 // null - initialize a local variable to null on the device
2132 //
2133 // Observations:
2134 // - All scalar declarations that show up in a map clause have to be passed
2135 // by reference, because they may have been mapped in the enclosing data
2136 // environment.
2137 // - If the scalar value does not fit the size of uintptr, it has to be
2138 // passed by reference, regardless the result in the table above.
2139 // - For pointers mapped by value that have either an implicit map or an
2140 // array section, the runtime library may pass the NULL value to the
2141 // device instead of the value passed to it by the compiler.
2142
2143 if (Ty->isReferenceType())
2144 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2145
2146 // Locate map clauses and see if the variable being captured is referred to
2147 // in any of those clauses. Here we only care about variables, not fields,
2148 // because fields are part of aggregates.
2149 bool IsVariableAssociatedWithSection = false;
2150
2151 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2152 D, Level,
2153 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2154 D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2155 MapExprComponents,
2156 OpenMPClauseKind WhereFoundClauseKind) {
2157 // Only the map clause information influences how a variable is
2158 // captured. E.g. is_device_ptr does not require changing the default
2159 // behavior.
2160 if (WhereFoundClauseKind != OMPC_map)
2161 return false;
2162
2163 auto EI = MapExprComponents.rbegin();
2164 auto EE = MapExprComponents.rend();
2165
2166 assert(EI != EE && "Invalid map expression!");
2167
2168 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2169 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2170
2171 ++EI;
2172 if (EI == EE)
2173 return false;
2174
2175 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2176 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2177 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2178 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2179 IsVariableAssociatedWithSection = true;
2180 // There is nothing more we need to know about this variable.
2181 return true;
2182 }
2183
2184 // Keep looking for more map info.
2185 return false;
2186 });
2187
2188 if (IsVariableUsedInMapClause) {
2189 // If variable is identified in a map clause it is always captured by
2190 // reference except if it is a pointer that is dereferenced somehow.
2191 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2192 } else {
2193 // By default, all the data that has a scalar type is mapped by copy
2194 // (except for reduction variables).
2195 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2196 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2197 !Ty->isAnyPointerType()) ||
2198 !Ty->isScalarType() ||
2199 DSAStack->isDefaultmapCapturedByRef(
2200 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2201 DSAStack->hasExplicitDSA(
2202 D,
2203 [](OpenMPClauseKind K, bool AppliedToPointee) {
2204 return K == OMPC_reduction && !AppliedToPointee;
2205 },
2206 Level);
2207 }
2208 }
2209
2210 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2211 IsByRef =
2212 ((IsVariableUsedInMapClause &&
2213 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2214 OMPD_target) ||
2215 !(DSAStack->hasExplicitDSA(
2216 D,
2217 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2218 return K == OMPC_firstprivate ||
2219 (K == OMPC_reduction && AppliedToPointee);
2220 },
2221 Level, /*NotLastprivate=*/true) ||
2222 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2223 // If the variable is artificial and must be captured by value - try to
2224 // capture by value.
2225 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2226 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2227 // If the variable is implicitly firstprivate and scalar - capture by
2228 // copy
2229 !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2230 DSAStack->getDefaultDSA() == DSA_private) &&
2231 !DSAStack->hasExplicitDSA(
2232 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2233 Level) &&
2234 !DSAStack->isLoopControlVariable(D, Level).first);
2235 }
2236
2237 // When passing data by copy, we need to make sure it fits the uintptr size
2238 // and alignment, because the runtime library only deals with uintptr types.
2239 // If it does not fit the uintptr size, we need to pass the data by reference
2240 // instead.
2241 if (!IsByRef &&
2242 (Ctx.getTypeSizeInChars(Ty) >
2243 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2244 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2245 IsByRef = true;
2246 }
2247
2248 return IsByRef;
2249 }
2250
getOpenMPNestingLevel() const2251 unsigned Sema::getOpenMPNestingLevel() const {
2252 assert(getLangOpts().OpenMP);
2253 return DSAStack->getNestingLevel();
2254 }
2255
isInOpenMPTaskUntiedContext() const2256 bool Sema::isInOpenMPTaskUntiedContext() const {
2257 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2258 DSAStack->isUntiedRegion();
2259 }
2260
isInOpenMPTargetExecutionDirective() const2261 bool Sema::isInOpenMPTargetExecutionDirective() const {
2262 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2263 !DSAStack->isClauseParsingMode()) ||
2264 DSAStack->hasDirective(
2265 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2266 SourceLocation) -> bool {
2267 return isOpenMPTargetExecutionDirective(K);
2268 },
2269 false);
2270 }
2271
isOpenMPRebuildMemberExpr(ValueDecl * D)2272 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2273 // Only rebuild for Field.
2274 if (!dyn_cast<FieldDecl>(D))
2275 return false;
2276 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2277 D,
2278 [](OpenMPClauseKind C, bool AppliedToPointee,
2279 DefaultDataSharingAttributes DefaultAttr) {
2280 return isOpenMPPrivate(C) && !AppliedToPointee &&
2281 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2282 },
2283 [](OpenMPDirectiveKind) { return true; },
2284 DSAStack->isClauseParsingMode());
2285 if (DVarPrivate.CKind != OMPC_unknown)
2286 return true;
2287 return false;
2288 }
2289
2290 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2291 Expr *CaptureExpr, bool WithInit,
2292 DeclContext *CurContext,
2293 bool AsExpression);
2294
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2295 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2296 unsigned StopAt) {
2297 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2298 D = getCanonicalDecl(D);
2299
2300 auto *VD = dyn_cast<VarDecl>(D);
2301 // Do not capture constexpr variables.
2302 if (VD && VD->isConstexpr())
2303 return nullptr;
2304
2305 // If we want to determine whether the variable should be captured from the
2306 // perspective of the current capturing scope, and we've already left all the
2307 // capturing scopes of the top directive on the stack, check from the
2308 // perspective of its parent directive (if any) instead.
2309 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2310 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2311
2312 // If we are attempting to capture a global variable in a directive with
2313 // 'target' we return true so that this global is also mapped to the device.
2314 //
2315 if (VD && !VD->hasLocalStorage() &&
2316 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2317 if (isInOpenMPTargetExecutionDirective()) {
2318 DSAStackTy::DSAVarData DVarTop =
2319 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2320 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2321 return VD;
2322 // If the declaration is enclosed in a 'declare target' directive,
2323 // then it should not be captured.
2324 //
2325 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2326 return nullptr;
2327 CapturedRegionScopeInfo *CSI = nullptr;
2328 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2329 llvm::reverse(FunctionScopes),
2330 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2331 if (!isa<CapturingScopeInfo>(FSI))
2332 return nullptr;
2333 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2334 if (RSI->CapRegionKind == CR_OpenMP) {
2335 CSI = RSI;
2336 break;
2337 }
2338 }
2339 assert(CSI && "Failed to find CapturedRegionScopeInfo");
2340 SmallVector<OpenMPDirectiveKind, 4> Regions;
2341 getOpenMPCaptureRegions(Regions,
2342 DSAStack->getDirective(CSI->OpenMPLevel));
2343 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2344 return VD;
2345 }
2346 if (isInOpenMPDeclareTargetContext()) {
2347 // Try to mark variable as declare target if it is used in capturing
2348 // regions.
2349 if (LangOpts.OpenMP <= 45 &&
2350 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2351 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2352 return nullptr;
2353 }
2354 }
2355
2356 if (CheckScopeInfo) {
2357 bool OpenMPFound = false;
2358 for (unsigned I = StopAt + 1; I > 0; --I) {
2359 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2360 if (!isa<CapturingScopeInfo>(FSI))
2361 return nullptr;
2362 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2363 if (RSI->CapRegionKind == CR_OpenMP) {
2364 OpenMPFound = true;
2365 break;
2366 }
2367 }
2368 if (!OpenMPFound)
2369 return nullptr;
2370 }
2371
2372 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2373 (!DSAStack->isClauseParsingMode() ||
2374 DSAStack->getParentDirective() != OMPD_unknown)) {
2375 auto &&Info = DSAStack->isLoopControlVariable(D);
2376 if (Info.first ||
2377 (VD && VD->hasLocalStorage() &&
2378 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2379 (VD && DSAStack->isForceVarCapturing()))
2380 return VD ? VD : Info.second;
2381 DSAStackTy::DSAVarData DVarTop =
2382 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2383 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2384 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2385 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2386 // Threadprivate variables must not be captured.
2387 if (isOpenMPThreadPrivate(DVarTop.CKind))
2388 return nullptr;
2389 // The variable is not private or it is the variable in the directive with
2390 // default(none) clause and not used in any clause.
2391 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2392 D,
2393 [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2394 return isOpenMPPrivate(C) && !AppliedToPointee;
2395 },
2396 [](OpenMPDirectiveKind) { return true; },
2397 DSAStack->isClauseParsingMode());
2398 // Global shared must not be captured.
2399 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2400 ((DSAStack->getDefaultDSA() != DSA_none &&
2401 DSAStack->getDefaultDSA() != DSA_private &&
2402 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2403 DVarTop.CKind == OMPC_shared))
2404 return nullptr;
2405 auto *FD = dyn_cast<FieldDecl>(D);
2406 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2407 !DVarPrivate.PrivateCopy) {
2408 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2409 D,
2410 [](OpenMPClauseKind C, bool AppliedToPointee,
2411 DefaultDataSharingAttributes DefaultAttr) {
2412 return isOpenMPPrivate(C) && !AppliedToPointee &&
2413 (DefaultAttr == DSA_firstprivate ||
2414 DefaultAttr == DSA_private);
2415 },
2416 [](OpenMPDirectiveKind) { return true; },
2417 DSAStack->isClauseParsingMode());
2418 if (DVarPrivate.CKind == OMPC_unknown)
2419 return nullptr;
2420
2421 VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2422 if (VD)
2423 return VD;
2424 if (getCurrentThisType().isNull())
2425 return nullptr;
2426 Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2427 /*IsImplicit=*/true);
2428 const CXXScopeSpec CS = CXXScopeSpec();
2429 Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2430 NestedNameSpecifierLoc(), SourceLocation(), FD,
2431 DeclAccessPair::make(FD, FD->getAccess()),
2432 /*HadMultipleCandidates=*/false,
2433 DeclarationNameInfo(), FD->getType(),
2434 VK_LValue, OK_Ordinary);
2435 OMPCapturedExprDecl *CD = buildCaptureDecl(
2436 *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2437 CurContext->getParent(), /*AsExpression=*/false);
2438 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2439 *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2440 VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2441 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2442 return VD;
2443 }
2444 if (DVarPrivate.CKind != OMPC_unknown ||
2445 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2446 DSAStack->getDefaultDSA() == DSA_private ||
2447 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2448 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2449 }
2450 return nullptr;
2451 }
2452
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2453 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2454 unsigned Level) const {
2455 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2456 }
2457
startOpenMPLoop()2458 void Sema::startOpenMPLoop() {
2459 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2460 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2461 DSAStack->loopInit();
2462 }
2463
startOpenMPCXXRangeFor()2464 void Sema::startOpenMPCXXRangeFor() {
2465 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2466 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2467 DSAStack->resetPossibleLoopCounter();
2468 DSAStack->loopStart();
2469 }
2470 }
2471
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2472 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2473 unsigned CapLevel) const {
2474 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2475 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2476 (!DSAStack->isClauseParsingMode() ||
2477 DSAStack->getParentDirective() != OMPD_unknown)) {
2478 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2479 D,
2480 [](OpenMPClauseKind C, bool AppliedToPointee,
2481 DefaultDataSharingAttributes DefaultAttr) {
2482 return isOpenMPPrivate(C) && !AppliedToPointee &&
2483 DefaultAttr == DSA_private;
2484 },
2485 [](OpenMPDirectiveKind) { return true; },
2486 DSAStack->isClauseParsingMode());
2487 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2488 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2489 !DSAStack->isLoopControlVariable(D).first)
2490 return OMPC_private;
2491 }
2492 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2493 bool IsTriviallyCopyable =
2494 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2495 !D->getType()
2496 .getNonReferenceType()
2497 .getCanonicalType()
2498 ->getAsCXXRecordDecl();
2499 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2500 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2501 getOpenMPCaptureRegions(CaptureRegions, DKind);
2502 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2503 (IsTriviallyCopyable ||
2504 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2505 if (DSAStack->hasExplicitDSA(
2506 D,
2507 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2508 Level, /*NotLastprivate=*/true))
2509 return OMPC_firstprivate;
2510 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2511 if (DVar.CKind != OMPC_shared &&
2512 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2513 DSAStack->addImplicitTaskFirstprivate(Level, D);
2514 return OMPC_firstprivate;
2515 }
2516 }
2517 }
2518 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2519 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2520 DSAStack->resetPossibleLoopCounter(D);
2521 DSAStack->loopStart();
2522 return OMPC_private;
2523 }
2524 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2525 DSAStack->isLoopControlVariable(D).first) &&
2526 !DSAStack->hasExplicitDSA(
2527 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2528 Level) &&
2529 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2530 return OMPC_private;
2531 }
2532 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2533 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2534 DSAStack->isForceVarCapturing() &&
2535 !DSAStack->hasExplicitDSA(
2536 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2537 Level))
2538 return OMPC_private;
2539 }
2540 // User-defined allocators are private since they must be defined in the
2541 // context of target region.
2542 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2543 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2544 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2545 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2546 return OMPC_private;
2547 return (DSAStack->hasExplicitDSA(
2548 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2549 Level) ||
2550 (DSAStack->isClauseParsingMode() &&
2551 DSAStack->getClauseParsingMode() == OMPC_private) ||
2552 // Consider taskgroup reduction descriptor variable a private
2553 // to avoid possible capture in the region.
2554 (DSAStack->hasExplicitDirective(
2555 [](OpenMPDirectiveKind K) {
2556 return K == OMPD_taskgroup ||
2557 ((isOpenMPParallelDirective(K) ||
2558 isOpenMPWorksharingDirective(K)) &&
2559 !isOpenMPSimdDirective(K));
2560 },
2561 Level) &&
2562 DSAStack->isTaskgroupReductionRef(D, Level)))
2563 ? OMPC_private
2564 : OMPC_unknown;
2565 }
2566
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2567 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2568 unsigned Level) {
2569 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2570 D = getCanonicalDecl(D);
2571 OpenMPClauseKind OMPC = OMPC_unknown;
2572 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2573 const unsigned NewLevel = I - 1;
2574 if (DSAStack->hasExplicitDSA(
2575 D,
2576 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2577 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2578 OMPC = K;
2579 return true;
2580 }
2581 return false;
2582 },
2583 NewLevel))
2584 break;
2585 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2586 D, NewLevel,
2587 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2588 OpenMPClauseKind) { return true; })) {
2589 OMPC = OMPC_map;
2590 break;
2591 }
2592 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2593 NewLevel)) {
2594 OMPC = OMPC_map;
2595 if (DSAStack->mustBeFirstprivateAtLevel(
2596 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2597 OMPC = OMPC_firstprivate;
2598 break;
2599 }
2600 }
2601 if (OMPC != OMPC_unknown)
2602 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2603 }
2604
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2605 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2606 unsigned CaptureLevel) const {
2607 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2608 // Return true if the current level is no longer enclosed in a target region.
2609
2610 SmallVector<OpenMPDirectiveKind, 4> Regions;
2611 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2612 const auto *VD = dyn_cast<VarDecl>(D);
2613 return VD && !VD->hasLocalStorage() &&
2614 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2615 Level) &&
2616 Regions[CaptureLevel] != OMPD_task;
2617 }
2618
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2619 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2620 unsigned CaptureLevel) const {
2621 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2622 // Return true if the current level is no longer enclosed in a target region.
2623
2624 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2625 if (!VD->hasLocalStorage()) {
2626 if (isInOpenMPTargetExecutionDirective())
2627 return true;
2628 DSAStackTy::DSAVarData TopDVar =
2629 DSAStack->getTopDSA(D, /*FromParent=*/false);
2630 unsigned NumLevels =
2631 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2632 if (Level == 0)
2633 // non-file scope static variale with default(firstprivate)
2634 // should be gloabal captured.
2635 return (NumLevels == CaptureLevel + 1 &&
2636 (TopDVar.CKind != OMPC_shared ||
2637 DSAStack->getDefaultDSA() == DSA_firstprivate));
2638 do {
2639 --Level;
2640 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2641 if (DVar.CKind != OMPC_shared)
2642 return true;
2643 } while (Level > 0);
2644 }
2645 }
2646 return true;
2647 }
2648
DestroyDataSharingAttributesStack()2649 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2650
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2651 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2652 OMPTraitInfo &TI) {
2653 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2654 }
2655
ActOnOpenMPEndDeclareVariant()2656 void Sema::ActOnOpenMPEndDeclareVariant() {
2657 assert(isInOpenMPDeclareVariantScope() &&
2658 "Not in OpenMP declare variant scope!");
2659
2660 OMPDeclareVariantScopes.pop_back();
2661 }
2662
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2663 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2664 const FunctionDecl *Callee,
2665 SourceLocation Loc) {
2666 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2667 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2668 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2669 // Ignore host functions during device analyzis.
2670 if (LangOpts.OpenMPIsDevice &&
2671 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2672 return;
2673 // Ignore nohost functions during host analyzis.
2674 if (!LangOpts.OpenMPIsDevice && DevTy &&
2675 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2676 return;
2677 const FunctionDecl *FD = Callee->getMostRecentDecl();
2678 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2679 if (LangOpts.OpenMPIsDevice && DevTy &&
2680 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2681 // Diagnose host function called during device codegen.
2682 StringRef HostDevTy =
2683 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2684 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2685 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2686 diag::note_omp_marked_device_type_here)
2687 << HostDevTy;
2688 return;
2689 }
2690 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2691 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2692 // Diagnose nohost function called during host codegen.
2693 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2694 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2695 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2696 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2697 diag::note_omp_marked_device_type_here)
2698 << NoHostDevTy;
2699 }
2700 }
2701
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2702 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2703 const DeclarationNameInfo &DirName,
2704 Scope *CurScope, SourceLocation Loc) {
2705 DSAStack->push(DKind, DirName, CurScope, Loc);
2706 PushExpressionEvaluationContext(
2707 ExpressionEvaluationContext::PotentiallyEvaluated);
2708 }
2709
StartOpenMPClause(OpenMPClauseKind K)2710 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2711 DSAStack->setClauseParsingMode(K);
2712 }
2713
EndOpenMPClause()2714 void Sema::EndOpenMPClause() {
2715 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2716 CleanupVarDeclMarking();
2717 }
2718
2719 static std::pair<ValueDecl *, bool>
2720 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2721 SourceRange &ERange, bool AllowArraySection = false);
2722
2723 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2724 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2725 ArrayRef<OMPClause *> Clauses) {
2726 bool InscanFound = false;
2727 SourceLocation InscanLoc;
2728 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2729 // A reduction clause without the inscan reduction-modifier may not appear on
2730 // a construct on which a reduction clause with the inscan reduction-modifier
2731 // appears.
2732 for (OMPClause *C : Clauses) {
2733 if (C->getClauseKind() != OMPC_reduction)
2734 continue;
2735 auto *RC = cast<OMPReductionClause>(C);
2736 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2737 InscanFound = true;
2738 InscanLoc = RC->getModifierLoc();
2739 continue;
2740 }
2741 if (RC->getModifier() == OMPC_REDUCTION_task) {
2742 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2743 // A reduction clause with the task reduction-modifier may only appear on
2744 // a parallel construct, a worksharing construct or a combined or
2745 // composite construct for which any of the aforementioned constructs is a
2746 // constituent construct and simd or loop are not constituent constructs.
2747 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2748 if (!(isOpenMPParallelDirective(CurDir) ||
2749 isOpenMPWorksharingDirective(CurDir)) ||
2750 isOpenMPSimdDirective(CurDir))
2751 S.Diag(RC->getModifierLoc(),
2752 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2753 continue;
2754 }
2755 }
2756 if (InscanFound) {
2757 for (OMPClause *C : Clauses) {
2758 if (C->getClauseKind() != OMPC_reduction)
2759 continue;
2760 auto *RC = cast<OMPReductionClause>(C);
2761 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2762 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2763 ? RC->getBeginLoc()
2764 : RC->getModifierLoc(),
2765 diag::err_omp_inscan_reduction_expected);
2766 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2767 continue;
2768 }
2769 for (Expr *Ref : RC->varlists()) {
2770 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2771 SourceLocation ELoc;
2772 SourceRange ERange;
2773 Expr *SimpleRefExpr = Ref;
2774 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2775 /*AllowArraySection=*/true);
2776 ValueDecl *D = Res.first;
2777 if (!D)
2778 continue;
2779 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2780 S.Diag(Ref->getExprLoc(),
2781 diag::err_omp_reduction_not_inclusive_exclusive)
2782 << Ref->getSourceRange();
2783 }
2784 }
2785 }
2786 }
2787 }
2788
2789 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2790 ArrayRef<OMPClause *> Clauses);
2791 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2792 bool WithInit);
2793
2794 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2795 const ValueDecl *D,
2796 const DSAStackTy::DSAVarData &DVar,
2797 bool IsLoopIterVar = false);
2798
EndOpenMPDSABlock(Stmt * CurDirective)2799 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2800 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2801 // A variable of class type (or array thereof) that appears in a lastprivate
2802 // clause requires an accessible, unambiguous default constructor for the
2803 // class type, unless the list item is also specified in a firstprivate
2804 // clause.
2805 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2806 for (OMPClause *C : D->clauses()) {
2807 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2808 SmallVector<Expr *, 8> PrivateCopies;
2809 for (Expr *DE : Clause->varlists()) {
2810 if (DE->isValueDependent() || DE->isTypeDependent()) {
2811 PrivateCopies.push_back(nullptr);
2812 continue;
2813 }
2814 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2815 auto *VD = cast<VarDecl>(DRE->getDecl());
2816 QualType Type = VD->getType().getNonReferenceType();
2817 const DSAStackTy::DSAVarData DVar =
2818 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2819 if (DVar.CKind == OMPC_lastprivate) {
2820 // Generate helper private variable and initialize it with the
2821 // default value. The address of the original variable is replaced
2822 // by the address of the new private variable in CodeGen. This new
2823 // variable is not added to IdResolver, so the code in the OpenMP
2824 // region uses original variable for proper diagnostics.
2825 VarDecl *VDPrivate = buildVarDecl(
2826 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2827 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2828 ActOnUninitializedDecl(VDPrivate);
2829 if (VDPrivate->isInvalidDecl()) {
2830 PrivateCopies.push_back(nullptr);
2831 continue;
2832 }
2833 PrivateCopies.push_back(buildDeclRefExpr(
2834 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2835 } else {
2836 // The variable is also a firstprivate, so initialization sequence
2837 // for private copy is generated already.
2838 PrivateCopies.push_back(nullptr);
2839 }
2840 }
2841 Clause->setPrivateCopies(PrivateCopies);
2842 continue;
2843 }
2844 // Finalize nontemporal clause by handling private copies, if any.
2845 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2846 SmallVector<Expr *, 8> PrivateRefs;
2847 for (Expr *RefExpr : Clause->varlists()) {
2848 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2849 SourceLocation ELoc;
2850 SourceRange ERange;
2851 Expr *SimpleRefExpr = RefExpr;
2852 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2853 if (Res.second)
2854 // It will be analyzed later.
2855 PrivateRefs.push_back(RefExpr);
2856 ValueDecl *D = Res.first;
2857 if (!D)
2858 continue;
2859
2860 const DSAStackTy::DSAVarData DVar =
2861 DSAStack->getTopDSA(D, /*FromParent=*/false);
2862 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2863 : SimpleRefExpr);
2864 }
2865 Clause->setPrivateRefs(PrivateRefs);
2866 continue;
2867 }
2868 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2869 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2870 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2871 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2872 if (!DRE)
2873 continue;
2874 ValueDecl *VD = DRE->getDecl();
2875 if (!VD || !isa<VarDecl>(VD))
2876 continue;
2877 DSAStackTy::DSAVarData DVar =
2878 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2879 // OpenMP [2.12.5, target Construct]
2880 // Memory allocators that appear in a uses_allocators clause cannot
2881 // appear in other data-sharing attribute clauses or data-mapping
2882 // attribute clauses in the same construct.
2883 Expr *MapExpr = nullptr;
2884 if (DVar.RefExpr ||
2885 DSAStack->checkMappableExprComponentListsForDecl(
2886 VD, /*CurrentRegionOnly=*/true,
2887 [VD, &MapExpr](
2888 OMPClauseMappableExprCommon::MappableExprComponentListRef
2889 MapExprComponents,
2890 OpenMPClauseKind C) {
2891 auto MI = MapExprComponents.rbegin();
2892 auto ME = MapExprComponents.rend();
2893 if (MI != ME &&
2894 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2895 VD->getCanonicalDecl()) {
2896 MapExpr = MI->getAssociatedExpression();
2897 return true;
2898 }
2899 return false;
2900 })) {
2901 Diag(D.Allocator->getExprLoc(),
2902 diag::err_omp_allocator_used_in_clauses)
2903 << D.Allocator->getSourceRange();
2904 if (DVar.RefExpr)
2905 reportOriginalDsa(*this, DSAStack, VD, DVar);
2906 else
2907 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2908 << MapExpr->getSourceRange();
2909 }
2910 }
2911 continue;
2912 }
2913 }
2914 // Check allocate clauses.
2915 if (!CurContext->isDependentContext())
2916 checkAllocateClauses(*this, DSAStack, D->clauses());
2917 checkReductionClauses(*this, DSAStack, D->clauses());
2918 }
2919
2920 DSAStack->pop();
2921 DiscardCleanupsInEvaluationContext();
2922 PopExpressionEvaluationContext();
2923 }
2924
2925 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2926 Expr *NumIterations, Sema &SemaRef,
2927 Scope *S, DSAStackTy *Stack);
2928
2929 namespace {
2930
2931 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2932 private:
2933 Sema &SemaRef;
2934
2935 public:
VarDeclFilterCCC(Sema & S)2936 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2937 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2938 NamedDecl *ND = Candidate.getCorrectionDecl();
2939 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2940 return VD->hasGlobalStorage() &&
2941 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2942 SemaRef.getCurScope());
2943 }
2944 return false;
2945 }
2946
clone()2947 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2948 return std::make_unique<VarDeclFilterCCC>(*this);
2949 }
2950 };
2951
2952 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2953 private:
2954 Sema &SemaRef;
2955
2956 public:
VarOrFuncDeclFilterCCC(Sema & S)2957 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2958 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2959 NamedDecl *ND = Candidate.getCorrectionDecl();
2960 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2961 isa<FunctionDecl>(ND))) {
2962 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2963 SemaRef.getCurScope());
2964 }
2965 return false;
2966 }
2967
clone()2968 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2969 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2970 }
2971 };
2972
2973 } // namespace
2974
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2975 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2976 CXXScopeSpec &ScopeSpec,
2977 const DeclarationNameInfo &Id,
2978 OpenMPDirectiveKind Kind) {
2979 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2980 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2981
2982 if (Lookup.isAmbiguous())
2983 return ExprError();
2984
2985 VarDecl *VD;
2986 if (!Lookup.isSingleResult()) {
2987 VarDeclFilterCCC CCC(*this);
2988 if (TypoCorrection Corrected =
2989 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2990 CTK_ErrorRecovery)) {
2991 diagnoseTypo(Corrected,
2992 PDiag(Lookup.empty()
2993 ? diag::err_undeclared_var_use_suggest
2994 : diag::err_omp_expected_var_arg_suggest)
2995 << Id.getName());
2996 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2997 } else {
2998 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2999 : diag::err_omp_expected_var_arg)
3000 << Id.getName();
3001 return ExprError();
3002 }
3003 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3004 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3005 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3006 return ExprError();
3007 }
3008 Lookup.suppressDiagnostics();
3009
3010 // OpenMP [2.9.2, Syntax, C/C++]
3011 // Variables must be file-scope, namespace-scope, or static block-scope.
3012 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3013 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3014 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3015 bool IsDecl =
3016 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3017 Diag(VD->getLocation(),
3018 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3019 << VD;
3020 return ExprError();
3021 }
3022
3023 VarDecl *CanonicalVD = VD->getCanonicalDecl();
3024 NamedDecl *ND = CanonicalVD;
3025 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3026 // A threadprivate directive for file-scope variables must appear outside
3027 // any definition or declaration.
3028 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3029 !getCurLexicalContext()->isTranslationUnit()) {
3030 Diag(Id.getLoc(), diag::err_omp_var_scope)
3031 << getOpenMPDirectiveName(Kind) << VD;
3032 bool IsDecl =
3033 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3034 Diag(VD->getLocation(),
3035 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3036 << VD;
3037 return ExprError();
3038 }
3039 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3040 // A threadprivate directive for static class member variables must appear
3041 // in the class definition, in the same scope in which the member
3042 // variables are declared.
3043 if (CanonicalVD->isStaticDataMember() &&
3044 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3045 Diag(Id.getLoc(), diag::err_omp_var_scope)
3046 << getOpenMPDirectiveName(Kind) << VD;
3047 bool IsDecl =
3048 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3049 Diag(VD->getLocation(),
3050 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3051 << VD;
3052 return ExprError();
3053 }
3054 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3055 // A threadprivate directive for namespace-scope variables must appear
3056 // outside any definition or declaration other than the namespace
3057 // definition itself.
3058 if (CanonicalVD->getDeclContext()->isNamespace() &&
3059 (!getCurLexicalContext()->isFileContext() ||
3060 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3061 Diag(Id.getLoc(), diag::err_omp_var_scope)
3062 << getOpenMPDirectiveName(Kind) << VD;
3063 bool IsDecl =
3064 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3065 Diag(VD->getLocation(),
3066 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3067 << VD;
3068 return ExprError();
3069 }
3070 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3071 // A threadprivate directive for static block-scope variables must appear
3072 // in the scope of the variable and not in a nested scope.
3073 if (CanonicalVD->isLocalVarDecl() && CurScope &&
3074 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3075 Diag(Id.getLoc(), diag::err_omp_var_scope)
3076 << getOpenMPDirectiveName(Kind) << VD;
3077 bool IsDecl =
3078 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3079 Diag(VD->getLocation(),
3080 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3081 << VD;
3082 return ExprError();
3083 }
3084
3085 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3086 // A threadprivate directive must lexically precede all references to any
3087 // of the variables in its list.
3088 if (Kind == OMPD_threadprivate && VD->isUsed() &&
3089 !DSAStack->isThreadPrivate(VD)) {
3090 Diag(Id.getLoc(), diag::err_omp_var_used)
3091 << getOpenMPDirectiveName(Kind) << VD;
3092 return ExprError();
3093 }
3094
3095 QualType ExprType = VD->getType().getNonReferenceType();
3096 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3097 SourceLocation(), VD,
3098 /*RefersToEnclosingVariableOrCapture=*/false,
3099 Id.getLoc(), ExprType, VK_LValue);
3100 }
3101
3102 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)3103 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3104 ArrayRef<Expr *> VarList) {
3105 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3106 CurContext->addDecl(D);
3107 return DeclGroupPtrTy::make(DeclGroupRef(D));
3108 }
3109 return nullptr;
3110 }
3111
3112 namespace {
3113 class LocalVarRefChecker final
3114 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3115 Sema &SemaRef;
3116
3117 public:
VisitDeclRefExpr(const DeclRefExpr * E)3118 bool VisitDeclRefExpr(const DeclRefExpr *E) {
3119 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3120 if (VD->hasLocalStorage()) {
3121 SemaRef.Diag(E->getBeginLoc(),
3122 diag::err_omp_local_var_in_threadprivate_init)
3123 << E->getSourceRange();
3124 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3125 << VD << VD->getSourceRange();
3126 return true;
3127 }
3128 }
3129 return false;
3130 }
VisitStmt(const Stmt * S)3131 bool VisitStmt(const Stmt *S) {
3132 for (const Stmt *Child : S->children()) {
3133 if (Child && Visit(Child))
3134 return true;
3135 }
3136 return false;
3137 }
LocalVarRefChecker(Sema & SemaRef)3138 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3139 };
3140 } // namespace
3141
3142 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)3143 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3144 SmallVector<Expr *, 8> Vars;
3145 for (Expr *RefExpr : VarList) {
3146 auto *DE = cast<DeclRefExpr>(RefExpr);
3147 auto *VD = cast<VarDecl>(DE->getDecl());
3148 SourceLocation ILoc = DE->getExprLoc();
3149
3150 // Mark variable as used.
3151 VD->setReferenced();
3152 VD->markUsed(Context);
3153
3154 QualType QType = VD->getType();
3155 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3156 // It will be analyzed later.
3157 Vars.push_back(DE);
3158 continue;
3159 }
3160
3161 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3162 // A threadprivate variable must not have an incomplete type.
3163 if (RequireCompleteType(ILoc, VD->getType(),
3164 diag::err_omp_threadprivate_incomplete_type)) {
3165 continue;
3166 }
3167
3168 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3169 // A threadprivate variable must not have a reference type.
3170 if (VD->getType()->isReferenceType()) {
3171 Diag(ILoc, diag::err_omp_ref_type_arg)
3172 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3173 bool IsDecl =
3174 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3175 Diag(VD->getLocation(),
3176 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3177 << VD;
3178 continue;
3179 }
3180
3181 // Check if this is a TLS variable. If TLS is not being supported, produce
3182 // the corresponding diagnostic.
3183 if ((VD->getTLSKind() != VarDecl::TLS_None &&
3184 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3185 getLangOpts().OpenMPUseTLS &&
3186 getASTContext().getTargetInfo().isTLSSupported())) ||
3187 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3188 !VD->isLocalVarDecl())) {
3189 Diag(ILoc, diag::err_omp_var_thread_local)
3190 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3191 bool IsDecl =
3192 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3193 Diag(VD->getLocation(),
3194 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3195 << VD;
3196 continue;
3197 }
3198
3199 // Check if initial value of threadprivate variable reference variable with
3200 // local storage (it is not supported by runtime).
3201 if (const Expr *Init = VD->getAnyInitializer()) {
3202 LocalVarRefChecker Checker(*this);
3203 if (Checker.Visit(Init))
3204 continue;
3205 }
3206
3207 Vars.push_back(RefExpr);
3208 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3209 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3210 Context, SourceRange(Loc, Loc)));
3211 if (ASTMutationListener *ML = Context.getASTMutationListener())
3212 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3213 }
3214 OMPThreadPrivateDecl *D = nullptr;
3215 if (!Vars.empty()) {
3216 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3217 Vars);
3218 D->setAccess(AS_public);
3219 }
3220 return D;
3221 }
3222
3223 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3224 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3225 if (!Allocator)
3226 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3227 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3228 Allocator->isInstantiationDependent() ||
3229 Allocator->containsUnexpandedParameterPack())
3230 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3231 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3232 const Expr *AE = Allocator->IgnoreParenImpCasts();
3233 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3234 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3235 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3236 llvm::FoldingSetNodeID AEId, DAEId;
3237 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3238 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3239 if (AEId == DAEId) {
3240 AllocatorKindRes = AllocatorKind;
3241 break;
3242 }
3243 }
3244 return AllocatorKindRes;
3245 }
3246
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3247 static bool checkPreviousOMPAllocateAttribute(
3248 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3249 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3250 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3251 return false;
3252 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3253 Expr *PrevAllocator = A->getAllocator();
3254 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3255 getAllocatorKind(S, Stack, PrevAllocator);
3256 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3257 if (AllocatorsMatch &&
3258 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3259 Allocator && PrevAllocator) {
3260 const Expr *AE = Allocator->IgnoreParenImpCasts();
3261 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3262 llvm::FoldingSetNodeID AEId, PAEId;
3263 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3264 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3265 AllocatorsMatch = AEId == PAEId;
3266 }
3267 if (!AllocatorsMatch) {
3268 SmallString<256> AllocatorBuffer;
3269 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3270 if (Allocator)
3271 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3272 SmallString<256> PrevAllocatorBuffer;
3273 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3274 if (PrevAllocator)
3275 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3276 S.getPrintingPolicy());
3277
3278 SourceLocation AllocatorLoc =
3279 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3280 SourceRange AllocatorRange =
3281 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3282 SourceLocation PrevAllocatorLoc =
3283 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3284 SourceRange PrevAllocatorRange =
3285 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3286 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3287 << (Allocator ? 1 : 0) << AllocatorStream.str()
3288 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3289 << AllocatorRange;
3290 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3291 << PrevAllocatorRange;
3292 return true;
3293 }
3294 return false;
3295 }
3296
3297 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,Expr * Alignment,SourceRange SR)3298 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3299 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3300 Expr *Allocator, Expr *Alignment, SourceRange SR) {
3301 if (VD->hasAttr<OMPAllocateDeclAttr>())
3302 return;
3303 if (Alignment &&
3304 (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3305 Alignment->isInstantiationDependent() ||
3306 Alignment->containsUnexpandedParameterPack()))
3307 // Apply later when we have a usable value.
3308 return;
3309 if (Allocator &&
3310 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3311 Allocator->isInstantiationDependent() ||
3312 Allocator->containsUnexpandedParameterPack()))
3313 return;
3314 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3315 Allocator, Alignment, SR);
3316 VD->addAttr(A);
3317 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3318 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3319 }
3320
3321 Sema::DeclGroupPtrTy
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3322 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3323 ArrayRef<OMPClause *> Clauses,
3324 DeclContext *Owner) {
3325 assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3326 Expr *Alignment = nullptr;
3327 Expr *Allocator = nullptr;
3328 if (Clauses.empty()) {
3329 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3330 // allocate directives that appear in a target region must specify an
3331 // allocator clause unless a requires directive with the dynamic_allocators
3332 // clause is present in the same compilation unit.
3333 if (LangOpts.OpenMPIsDevice &&
3334 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3335 targetDiag(Loc, diag::err_expected_allocator_clause);
3336 } else {
3337 for (const OMPClause *C : Clauses)
3338 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3339 Allocator = AC->getAllocator();
3340 else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3341 Alignment = AC->getAlignment();
3342 else
3343 llvm_unreachable("Unexpected clause on allocate directive");
3344 }
3345 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3346 getAllocatorKind(*this, DSAStack, Allocator);
3347 SmallVector<Expr *, 8> Vars;
3348 for (Expr *RefExpr : VarList) {
3349 auto *DE = cast<DeclRefExpr>(RefExpr);
3350 auto *VD = cast<VarDecl>(DE->getDecl());
3351
3352 // Check if this is a TLS variable or global register.
3353 if (VD->getTLSKind() != VarDecl::TLS_None ||
3354 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3355 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3356 !VD->isLocalVarDecl()))
3357 continue;
3358
3359 // If the used several times in the allocate directive, the same allocator
3360 // must be used.
3361 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3362 AllocatorKind, Allocator))
3363 continue;
3364
3365 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3366 // If a list item has a static storage type, the allocator expression in the
3367 // allocator clause must be a constant expression that evaluates to one of
3368 // the predefined memory allocator values.
3369 if (Allocator && VD->hasGlobalStorage()) {
3370 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3371 Diag(Allocator->getExprLoc(),
3372 diag::err_omp_expected_predefined_allocator)
3373 << Allocator->getSourceRange();
3374 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3375 VarDecl::DeclarationOnly;
3376 Diag(VD->getLocation(),
3377 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3378 << VD;
3379 continue;
3380 }
3381 }
3382
3383 Vars.push_back(RefExpr);
3384 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3385 DE->getSourceRange());
3386 }
3387 if (Vars.empty())
3388 return nullptr;
3389 if (!Owner)
3390 Owner = getCurLexicalContext();
3391 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3392 D->setAccess(AS_public);
3393 Owner->addDecl(D);
3394 return DeclGroupPtrTy::make(DeclGroupRef(D));
3395 }
3396
3397 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3398 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3399 ArrayRef<OMPClause *> ClauseList) {
3400 OMPRequiresDecl *D = nullptr;
3401 if (!CurContext->isFileContext()) {
3402 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3403 } else {
3404 D = CheckOMPRequiresDecl(Loc, ClauseList);
3405 if (D) {
3406 CurContext->addDecl(D);
3407 DSAStack->addRequiresDecl(D);
3408 }
3409 }
3410 return DeclGroupPtrTy::make(DeclGroupRef(D));
3411 }
3412
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<std::string> Assumptions,bool SkippedClauses)3413 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3414 OpenMPDirectiveKind DKind,
3415 ArrayRef<std::string> Assumptions,
3416 bool SkippedClauses) {
3417 if (!SkippedClauses && Assumptions.empty())
3418 Diag(Loc, diag::err_omp_no_clause_for_directive)
3419 << llvm::omp::getAllAssumeClauseOptions()
3420 << llvm::omp::getOpenMPDirectiveName(DKind);
3421
3422 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3423 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3424 OMPAssumeScoped.push_back(AA);
3425 return;
3426 }
3427
3428 // Global assumes without assumption clauses are ignored.
3429 if (Assumptions.empty())
3430 return;
3431
3432 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3433 "Unexpected omp assumption directive!");
3434 OMPAssumeGlobal.push_back(AA);
3435
3436 // The OMPAssumeGlobal scope above will take care of new declarations but
3437 // we also want to apply the assumption to existing ones, e.g., to
3438 // declarations in included headers. To this end, we traverse all existing
3439 // declaration contexts and annotate function declarations here.
3440 SmallVector<DeclContext *, 8> DeclContexts;
3441 auto *Ctx = CurContext;
3442 while (Ctx->getLexicalParent())
3443 Ctx = Ctx->getLexicalParent();
3444 DeclContexts.push_back(Ctx);
3445 while (!DeclContexts.empty()) {
3446 DeclContext *DC = DeclContexts.pop_back_val();
3447 for (auto *SubDC : DC->decls()) {
3448 if (SubDC->isInvalidDecl())
3449 continue;
3450 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3451 DeclContexts.push_back(CTD->getTemplatedDecl());
3452 llvm::append_range(DeclContexts, CTD->specializations());
3453 continue;
3454 }
3455 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3456 DeclContexts.push_back(DC);
3457 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3458 F->addAttr(AA);
3459 continue;
3460 }
3461 }
3462 }
3463 }
3464
ActOnOpenMPEndAssumesDirective()3465 void Sema::ActOnOpenMPEndAssumesDirective() {
3466 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3467 OMPAssumeScoped.pop_back();
3468 }
3469
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3470 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3471 ArrayRef<OMPClause *> ClauseList) {
3472 /// For target specific clauses, the requires directive cannot be
3473 /// specified after the handling of any of the target regions in the
3474 /// current compilation unit.
3475 ArrayRef<SourceLocation> TargetLocations =
3476 DSAStack->getEncounteredTargetLocs();
3477 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3478 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3479 for (const OMPClause *CNew : ClauseList) {
3480 // Check if any of the requires clauses affect target regions.
3481 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3482 isa<OMPUnifiedAddressClause>(CNew) ||
3483 isa<OMPReverseOffloadClause>(CNew) ||
3484 isa<OMPDynamicAllocatorsClause>(CNew)) {
3485 Diag(Loc, diag::err_omp_directive_before_requires)
3486 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3487 for (SourceLocation TargetLoc : TargetLocations) {
3488 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3489 << "target";
3490 }
3491 } else if (!AtomicLoc.isInvalid() &&
3492 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3493 Diag(Loc, diag::err_omp_directive_before_requires)
3494 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3495 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3496 << "atomic";
3497 }
3498 }
3499 }
3500
3501 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3502 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3503 ClauseList);
3504 return nullptr;
3505 }
3506
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3507 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3508 const ValueDecl *D,
3509 const DSAStackTy::DSAVarData &DVar,
3510 bool IsLoopIterVar) {
3511 if (DVar.RefExpr) {
3512 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3513 << getOpenMPClauseName(DVar.CKind);
3514 return;
3515 }
3516 enum {
3517 PDSA_StaticMemberShared,
3518 PDSA_StaticLocalVarShared,
3519 PDSA_LoopIterVarPrivate,
3520 PDSA_LoopIterVarLinear,
3521 PDSA_LoopIterVarLastprivate,
3522 PDSA_ConstVarShared,
3523 PDSA_GlobalVarShared,
3524 PDSA_TaskVarFirstprivate,
3525 PDSA_LocalVarPrivate,
3526 PDSA_Implicit
3527 } Reason = PDSA_Implicit;
3528 bool ReportHint = false;
3529 auto ReportLoc = D->getLocation();
3530 auto *VD = dyn_cast<VarDecl>(D);
3531 if (IsLoopIterVar) {
3532 if (DVar.CKind == OMPC_private)
3533 Reason = PDSA_LoopIterVarPrivate;
3534 else if (DVar.CKind == OMPC_lastprivate)
3535 Reason = PDSA_LoopIterVarLastprivate;
3536 else
3537 Reason = PDSA_LoopIterVarLinear;
3538 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3539 DVar.CKind == OMPC_firstprivate) {
3540 Reason = PDSA_TaskVarFirstprivate;
3541 ReportLoc = DVar.ImplicitDSALoc;
3542 } else if (VD && VD->isStaticLocal())
3543 Reason = PDSA_StaticLocalVarShared;
3544 else if (VD && VD->isStaticDataMember())
3545 Reason = PDSA_StaticMemberShared;
3546 else if (VD && VD->isFileVarDecl())
3547 Reason = PDSA_GlobalVarShared;
3548 else if (D->getType().isConstant(SemaRef.getASTContext()))
3549 Reason = PDSA_ConstVarShared;
3550 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3551 ReportHint = true;
3552 Reason = PDSA_LocalVarPrivate;
3553 }
3554 if (Reason != PDSA_Implicit) {
3555 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3556 << Reason << ReportHint
3557 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3558 } else if (DVar.ImplicitDSALoc.isValid()) {
3559 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3560 << getOpenMPClauseName(DVar.CKind);
3561 }
3562 }
3563
3564 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3565 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3566 bool IsAggregateOrDeclareTarget) {
3567 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3568 switch (M) {
3569 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3570 Kind = OMPC_MAP_alloc;
3571 break;
3572 case OMPC_DEFAULTMAP_MODIFIER_to:
3573 Kind = OMPC_MAP_to;
3574 break;
3575 case OMPC_DEFAULTMAP_MODIFIER_from:
3576 Kind = OMPC_MAP_from;
3577 break;
3578 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3579 Kind = OMPC_MAP_tofrom;
3580 break;
3581 case OMPC_DEFAULTMAP_MODIFIER_present:
3582 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3583 // If implicit-behavior is present, each variable referenced in the
3584 // construct in the category specified by variable-category is treated as if
3585 // it had been listed in a map clause with the map-type of alloc and
3586 // map-type-modifier of present.
3587 Kind = OMPC_MAP_alloc;
3588 break;
3589 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3590 case OMPC_DEFAULTMAP_MODIFIER_last:
3591 llvm_unreachable("Unexpected defaultmap implicit behavior");
3592 case OMPC_DEFAULTMAP_MODIFIER_none:
3593 case OMPC_DEFAULTMAP_MODIFIER_default:
3594 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3595 // IsAggregateOrDeclareTarget could be true if:
3596 // 1. the implicit behavior for aggregate is tofrom
3597 // 2. it's a declare target link
3598 if (IsAggregateOrDeclareTarget) {
3599 Kind = OMPC_MAP_tofrom;
3600 break;
3601 }
3602 llvm_unreachable("Unexpected defaultmap implicit behavior");
3603 }
3604 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3605 return Kind;
3606 }
3607
3608 namespace {
3609 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3610 DSAStackTy *Stack;
3611 Sema &SemaRef;
3612 bool ErrorFound = false;
3613 bool TryCaptureCXXThisMembers = false;
3614 CapturedStmt *CS = nullptr;
3615 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3616 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3617 llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3618 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3619 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3620 ImplicitMapModifier[DefaultmapKindNum];
3621 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3622 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3623
VisitSubCaptures(OMPExecutableDirective * S)3624 void VisitSubCaptures(OMPExecutableDirective *S) {
3625 // Check implicitly captured variables.
3626 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3627 return;
3628 if (S->getDirectiveKind() == OMPD_atomic ||
3629 S->getDirectiveKind() == OMPD_critical ||
3630 S->getDirectiveKind() == OMPD_section ||
3631 S->getDirectiveKind() == OMPD_master ||
3632 S->getDirectiveKind() == OMPD_masked ||
3633 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3634 Visit(S->getAssociatedStmt());
3635 return;
3636 }
3637 visitSubCaptures(S->getInnermostCapturedStmt());
3638 // Try to capture inner this->member references to generate correct mappings
3639 // and diagnostics.
3640 if (TryCaptureCXXThisMembers ||
3641 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3642 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3643 [](const CapturedStmt::Capture &C) {
3644 return C.capturesThis();
3645 }))) {
3646 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3647 TryCaptureCXXThisMembers = true;
3648 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3649 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3650 }
3651 // In tasks firstprivates are not captured anymore, need to analyze them
3652 // explicitly.
3653 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3654 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3655 for (OMPClause *C : S->clauses())
3656 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3657 for (Expr *Ref : FC->varlists())
3658 Visit(Ref);
3659 }
3660 }
3661 }
3662
3663 public:
VisitDeclRefExpr(DeclRefExpr * E)3664 void VisitDeclRefExpr(DeclRefExpr *E) {
3665 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3666 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3667 E->isInstantiationDependent())
3668 return;
3669 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3670 // Check the datasharing rules for the expressions in the clauses.
3671 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3672 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3673 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3674 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3675 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3676 Visit(CED->getInit());
3677 return;
3678 }
3679 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3680 // Do not analyze internal variables and do not enclose them into
3681 // implicit clauses.
3682 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3683 return;
3684 VD = VD->getCanonicalDecl();
3685 // Skip internally declared variables.
3686 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3687 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3688 !Stack->isImplicitTaskFirstprivate(VD))
3689 return;
3690 // Skip allocators in uses_allocators clauses.
3691 if (Stack->isUsesAllocatorsDecl(VD))
3692 return;
3693
3694 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3695 // Check if the variable has explicit DSA set and stop analysis if it so.
3696 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3697 return;
3698
3699 // Skip internally declared static variables.
3700 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3701 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3702 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3703 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3704 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3705 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3706 !Stack->isImplicitTaskFirstprivate(VD))
3707 return;
3708
3709 SourceLocation ELoc = E->getExprLoc();
3710 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3711 // The default(none) clause requires that each variable that is referenced
3712 // in the construct, and does not have a predetermined data-sharing
3713 // attribute, must have its data-sharing attribute explicitly determined
3714 // by being listed in a data-sharing attribute clause.
3715 if (DVar.CKind == OMPC_unknown &&
3716 (Stack->getDefaultDSA() == DSA_none ||
3717 Stack->getDefaultDSA() == DSA_private ||
3718 Stack->getDefaultDSA() == DSA_firstprivate) &&
3719 isImplicitOrExplicitTaskingRegion(DKind) &&
3720 VarsWithInheritedDSA.count(VD) == 0) {
3721 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3722 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3723 Stack->getDefaultDSA() == DSA_private)) {
3724 DSAStackTy::DSAVarData DVar =
3725 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3726 InheritedDSA = DVar.CKind == OMPC_unknown;
3727 }
3728 if (InheritedDSA)
3729 VarsWithInheritedDSA[VD] = E;
3730 if (Stack->getDefaultDSA() == DSA_none)
3731 return;
3732 }
3733
3734 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3735 // If implicit-behavior is none, each variable referenced in the
3736 // construct that does not have a predetermined data-sharing attribute
3737 // and does not appear in a to or link clause on a declare target
3738 // directive must be listed in a data-mapping attribute clause, a
3739 // data-sharing attribute clause (including a data-sharing attribute
3740 // clause on a combined construct where target. is one of the
3741 // constituent constructs), or an is_device_ptr clause.
3742 OpenMPDefaultmapClauseKind ClauseKind =
3743 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3744 if (SemaRef.getLangOpts().OpenMP >= 50) {
3745 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3746 OMPC_DEFAULTMAP_MODIFIER_none;
3747 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3748 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3749 // Only check for data-mapping attribute and is_device_ptr here
3750 // since we have already make sure that the declaration does not
3751 // have a data-sharing attribute above
3752 if (!Stack->checkMappableExprComponentListsForDecl(
3753 VD, /*CurrentRegionOnly=*/true,
3754 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3755 MapExprComponents,
3756 OpenMPClauseKind) {
3757 auto MI = MapExprComponents.rbegin();
3758 auto ME = MapExprComponents.rend();
3759 return MI != ME && MI->getAssociatedDeclaration() == VD;
3760 })) {
3761 VarsWithInheritedDSA[VD] = E;
3762 return;
3763 }
3764 }
3765 }
3766 if (SemaRef.getLangOpts().OpenMP > 50) {
3767 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3768 OMPC_DEFAULTMAP_MODIFIER_present;
3769 if (IsModifierPresent) {
3770 if (llvm::find(ImplicitMapModifier[ClauseKind],
3771 OMPC_MAP_MODIFIER_present) ==
3772 std::end(ImplicitMapModifier[ClauseKind])) {
3773 ImplicitMapModifier[ClauseKind].push_back(
3774 OMPC_MAP_MODIFIER_present);
3775 }
3776 }
3777 }
3778
3779 if (isOpenMPTargetExecutionDirective(DKind) &&
3780 !Stack->isLoopControlVariable(VD).first) {
3781 if (!Stack->checkMappableExprComponentListsForDecl(
3782 VD, /*CurrentRegionOnly=*/true,
3783 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3784 StackComponents,
3785 OpenMPClauseKind) {
3786 if (SemaRef.LangOpts.OpenMP >= 50)
3787 return !StackComponents.empty();
3788 // Variable is used if it has been marked as an array, array
3789 // section, array shaping or the variable iself.
3790 return StackComponents.size() == 1 ||
3791 std::all_of(
3792 std::next(StackComponents.rbegin()),
3793 StackComponents.rend(),
3794 [](const OMPClauseMappableExprCommon::
3795 MappableComponent &MC) {
3796 return MC.getAssociatedDeclaration() ==
3797 nullptr &&
3798 (isa<OMPArraySectionExpr>(
3799 MC.getAssociatedExpression()) ||
3800 isa<OMPArrayShapingExpr>(
3801 MC.getAssociatedExpression()) ||
3802 isa<ArraySubscriptExpr>(
3803 MC.getAssociatedExpression()));
3804 });
3805 })) {
3806 bool IsFirstprivate = false;
3807 // By default lambdas are captured as firstprivates.
3808 if (const auto *RD =
3809 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3810 IsFirstprivate = RD->isLambda();
3811 IsFirstprivate =
3812 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3813 if (IsFirstprivate) {
3814 ImplicitFirstprivate.emplace_back(E);
3815 } else {
3816 OpenMPDefaultmapClauseModifier M =
3817 Stack->getDefaultmapModifier(ClauseKind);
3818 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3819 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3820 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3821 }
3822 return;
3823 }
3824 }
3825
3826 // OpenMP [2.9.3.6, Restrictions, p.2]
3827 // A list item that appears in a reduction clause of the innermost
3828 // enclosing worksharing or parallel construct may not be accessed in an
3829 // explicit task.
3830 DVar = Stack->hasInnermostDSA(
3831 VD,
3832 [](OpenMPClauseKind C, bool AppliedToPointee) {
3833 return C == OMPC_reduction && !AppliedToPointee;
3834 },
3835 [](OpenMPDirectiveKind K) {
3836 return isOpenMPParallelDirective(K) ||
3837 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3838 },
3839 /*FromParent=*/true);
3840 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3841 ErrorFound = true;
3842 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3843 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3844 return;
3845 }
3846
3847 // Define implicit data-sharing attributes for task.
3848 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3849 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3850 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3851 DVar.CKind == OMPC_firstprivate) ||
3852 (Stack->getDefaultDSA() == DSA_private &&
3853 DVar.CKind == OMPC_private)) &&
3854 !DVar.RefExpr)) &&
3855 !Stack->isLoopControlVariable(VD).first) {
3856 if (Stack->getDefaultDSA() == DSA_private)
3857 ImplicitPrivate.push_back(E);
3858 else
3859 ImplicitFirstprivate.push_back(E);
3860 return;
3861 }
3862
3863 // Store implicitly used globals with declare target link for parent
3864 // target.
3865 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3866 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3867 Stack->addToParentTargetRegionLinkGlobals(E);
3868 return;
3869 }
3870 }
3871 }
VisitMemberExpr(MemberExpr * E)3872 void VisitMemberExpr(MemberExpr *E) {
3873 if (E->isTypeDependent() || E->isValueDependent() ||
3874 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3875 return;
3876 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3877 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3878 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3879 if (!FD)
3880 return;
3881 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3882 // Check if the variable has explicit DSA set and stop analysis if it
3883 // so.
3884 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3885 return;
3886
3887 if (isOpenMPTargetExecutionDirective(DKind) &&
3888 !Stack->isLoopControlVariable(FD).first &&
3889 !Stack->checkMappableExprComponentListsForDecl(
3890 FD, /*CurrentRegionOnly=*/true,
3891 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3892 StackComponents,
3893 OpenMPClauseKind) {
3894 return isa<CXXThisExpr>(
3895 cast<MemberExpr>(
3896 StackComponents.back().getAssociatedExpression())
3897 ->getBase()
3898 ->IgnoreParens());
3899 })) {
3900 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3901 // A bit-field cannot appear in a map clause.
3902 //
3903 if (FD->isBitField())
3904 return;
3905
3906 // Check to see if the member expression is referencing a class that
3907 // has already been explicitly mapped
3908 if (Stack->isClassPreviouslyMapped(TE->getType()))
3909 return;
3910
3911 OpenMPDefaultmapClauseModifier Modifier =
3912 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3913 OpenMPDefaultmapClauseKind ClauseKind =
3914 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3915 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3916 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3917 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3918 return;
3919 }
3920
3921 SourceLocation ELoc = E->getExprLoc();
3922 // OpenMP [2.9.3.6, Restrictions, p.2]
3923 // A list item that appears in a reduction clause of the innermost
3924 // enclosing worksharing or parallel construct may not be accessed in
3925 // an explicit task.
3926 DVar = Stack->hasInnermostDSA(
3927 FD,
3928 [](OpenMPClauseKind C, bool AppliedToPointee) {
3929 return C == OMPC_reduction && !AppliedToPointee;
3930 },
3931 [](OpenMPDirectiveKind K) {
3932 return isOpenMPParallelDirective(K) ||
3933 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3934 },
3935 /*FromParent=*/true);
3936 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3937 ErrorFound = true;
3938 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3939 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3940 return;
3941 }
3942
3943 // Define implicit data-sharing attributes for task.
3944 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3945 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3946 !Stack->isLoopControlVariable(FD).first) {
3947 // Check if there is a captured expression for the current field in the
3948 // region. Do not mark it as firstprivate unless there is no captured
3949 // expression.
3950 // TODO: try to make it firstprivate.
3951 if (DVar.CKind != OMPC_unknown)
3952 ImplicitFirstprivate.push_back(E);
3953 }
3954 return;
3955 }
3956 if (isOpenMPTargetExecutionDirective(DKind)) {
3957 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3958 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3959 Stack->getCurrentDirective(),
3960 /*NoDiagnose=*/true))
3961 return;
3962 const auto *VD = cast<ValueDecl>(
3963 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3964 if (!Stack->checkMappableExprComponentListsForDecl(
3965 VD, /*CurrentRegionOnly=*/true,
3966 [&CurComponents](
3967 OMPClauseMappableExprCommon::MappableExprComponentListRef
3968 StackComponents,
3969 OpenMPClauseKind) {
3970 auto CCI = CurComponents.rbegin();
3971 auto CCE = CurComponents.rend();
3972 for (const auto &SC : llvm::reverse(StackComponents)) {
3973 // Do both expressions have the same kind?
3974 if (CCI->getAssociatedExpression()->getStmtClass() !=
3975 SC.getAssociatedExpression()->getStmtClass())
3976 if (!((isa<OMPArraySectionExpr>(
3977 SC.getAssociatedExpression()) ||
3978 isa<OMPArrayShapingExpr>(
3979 SC.getAssociatedExpression())) &&
3980 isa<ArraySubscriptExpr>(
3981 CCI->getAssociatedExpression())))
3982 return false;
3983
3984 const Decl *CCD = CCI->getAssociatedDeclaration();
3985 const Decl *SCD = SC.getAssociatedDeclaration();
3986 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3987 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3988 if (SCD != CCD)
3989 return false;
3990 std::advance(CCI, 1);
3991 if (CCI == CCE)
3992 break;
3993 }
3994 return true;
3995 })) {
3996 Visit(E->getBase());
3997 }
3998 } else if (!TryCaptureCXXThisMembers) {
3999 Visit(E->getBase());
4000 }
4001 }
VisitOMPExecutableDirective(OMPExecutableDirective * S)4002 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4003 for (OMPClause *C : S->clauses()) {
4004 // Skip analysis of arguments of private clauses for task|target
4005 // directives.
4006 if (isa_and_nonnull<OMPPrivateClause>(C))
4007 continue;
4008 // Skip analysis of arguments of implicitly defined firstprivate clause
4009 // for task|target directives.
4010 // Skip analysis of arguments of implicitly defined map clause for target
4011 // directives.
4012 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4013 C->isImplicit() &&
4014 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4015 for (Stmt *CC : C->children()) {
4016 if (CC)
4017 Visit(CC);
4018 }
4019 }
4020 }
4021 // Check implicitly captured variables.
4022 VisitSubCaptures(S);
4023 }
4024
VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective * S)4025 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4026 // Loop transformation directives do not introduce data sharing
4027 VisitStmt(S);
4028 }
4029
VisitCallExpr(CallExpr * S)4030 void VisitCallExpr(CallExpr *S) {
4031 for (Stmt *C : S->arguments()) {
4032 if (C) {
4033 // Check implicitly captured variables in the task-based directives to
4034 // check if they must be firstprivatized.
4035 Visit(C);
4036 }
4037 }
4038 if (Expr *Callee = S->getCallee())
4039 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
4040 Visit(CE->getBase());
4041 }
VisitStmt(Stmt * S)4042 void VisitStmt(Stmt *S) {
4043 for (Stmt *C : S->children()) {
4044 if (C) {
4045 // Check implicitly captured variables in the task-based directives to
4046 // check if they must be firstprivatized.
4047 Visit(C);
4048 }
4049 }
4050 }
4051
visitSubCaptures(CapturedStmt * S)4052 void visitSubCaptures(CapturedStmt *S) {
4053 for (const CapturedStmt::Capture &Cap : S->captures()) {
4054 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4055 continue;
4056 VarDecl *VD = Cap.getCapturedVar();
4057 // Do not try to map the variable if it or its sub-component was mapped
4058 // already.
4059 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4060 Stack->checkMappableExprComponentListsForDecl(
4061 VD, /*CurrentRegionOnly=*/true,
4062 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4063 OpenMPClauseKind) { return true; }))
4064 continue;
4065 DeclRefExpr *DRE = buildDeclRefExpr(
4066 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4067 Cap.getLocation(), /*RefersToCapture=*/true);
4068 Visit(DRE);
4069 }
4070 }
isErrorFound() const4071 bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const4072 ArrayRef<Expr *> getImplicitFirstprivate() const {
4073 return ImplicitFirstprivate;
4074 }
getImplicitPrivate() const4075 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const4076 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4077 OpenMPMapClauseKind MK) const {
4078 return ImplicitMap[DK][MK];
4079 }
4080 ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const4081 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4082 return ImplicitMapModifier[Kind];
4083 }
getVarsWithInheritedDSA() const4084 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4085 return VarsWithInheritedDSA;
4086 }
4087
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)4088 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4089 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4090 // Process declare target link variables for the target directives.
4091 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4092 for (DeclRefExpr *E : Stack->getLinkGlobals())
4093 Visit(E);
4094 }
4095 }
4096 };
4097 } // namespace
4098
handleDeclareVariantConstructTrait(DSAStackTy * Stack,OpenMPDirectiveKind DKind,bool ScopeEntry)4099 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4100 OpenMPDirectiveKind DKind,
4101 bool ScopeEntry) {
4102 SmallVector<llvm::omp::TraitProperty, 8> Traits;
4103 if (isOpenMPTargetExecutionDirective(DKind))
4104 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4105 if (isOpenMPTeamsDirective(DKind))
4106 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4107 if (isOpenMPParallelDirective(DKind))
4108 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4109 if (isOpenMPWorksharingDirective(DKind))
4110 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4111 if (isOpenMPSimdDirective(DKind))
4112 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4113 Stack->handleConstructTrait(Traits, ScopeEntry);
4114 }
4115
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)4116 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4117 switch (DKind) {
4118 case OMPD_parallel:
4119 case OMPD_parallel_for:
4120 case OMPD_parallel_for_simd:
4121 case OMPD_parallel_sections:
4122 case OMPD_parallel_master:
4123 case OMPD_parallel_masked:
4124 case OMPD_parallel_loop:
4125 case OMPD_teams:
4126 case OMPD_teams_distribute:
4127 case OMPD_teams_distribute_simd: {
4128 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4129 QualType KmpInt32PtrTy =
4130 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4131 Sema::CapturedParamNameType Params[] = {
4132 std::make_pair(".global_tid.", KmpInt32PtrTy),
4133 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4134 std::make_pair(StringRef(), QualType()) // __context with shared vars
4135 };
4136 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4137 Params);
4138 break;
4139 }
4140 case OMPD_target_teams:
4141 case OMPD_target_parallel:
4142 case OMPD_target_parallel_for:
4143 case OMPD_target_parallel_for_simd:
4144 case OMPD_target_teams_loop:
4145 case OMPD_target_parallel_loop:
4146 case OMPD_target_teams_distribute:
4147 case OMPD_target_teams_distribute_simd: {
4148 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4149 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4150 QualType KmpInt32PtrTy =
4151 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4152 QualType Args[] = {VoidPtrTy};
4153 FunctionProtoType::ExtProtoInfo EPI;
4154 EPI.Variadic = true;
4155 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4156 Sema::CapturedParamNameType Params[] = {
4157 std::make_pair(".global_tid.", KmpInt32Ty),
4158 std::make_pair(".part_id.", KmpInt32PtrTy),
4159 std::make_pair(".privates.", VoidPtrTy),
4160 std::make_pair(
4161 ".copy_fn.",
4162 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4163 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4164 std::make_pair(StringRef(), QualType()) // __context with shared vars
4165 };
4166 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4167 Params, /*OpenMPCaptureLevel=*/0);
4168 // Mark this captured region as inlined, because we don't use outlined
4169 // function directly.
4170 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4171 AlwaysInlineAttr::CreateImplicit(
4172 Context, {}, AttributeCommonInfo::AS_Keyword,
4173 AlwaysInlineAttr::Keyword_forceinline));
4174 Sema::CapturedParamNameType ParamsTarget[] = {
4175 std::make_pair(StringRef(), QualType()) // __context with shared vars
4176 };
4177 // Start a captured region for 'target' with no implicit parameters.
4178 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4179 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4180 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4181 std::make_pair(".global_tid.", KmpInt32PtrTy),
4182 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4183 std::make_pair(StringRef(), QualType()) // __context with shared vars
4184 };
4185 // Start a captured region for 'teams' or 'parallel'. Both regions have
4186 // the same implicit parameters.
4187 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4188 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4189 break;
4190 }
4191 case OMPD_target:
4192 case OMPD_target_simd: {
4193 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4194 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4195 QualType KmpInt32PtrTy =
4196 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4197 QualType Args[] = {VoidPtrTy};
4198 FunctionProtoType::ExtProtoInfo EPI;
4199 EPI.Variadic = true;
4200 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4201 Sema::CapturedParamNameType Params[] = {
4202 std::make_pair(".global_tid.", KmpInt32Ty),
4203 std::make_pair(".part_id.", KmpInt32PtrTy),
4204 std::make_pair(".privates.", VoidPtrTy),
4205 std::make_pair(
4206 ".copy_fn.",
4207 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4208 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4209 std::make_pair(StringRef(), QualType()) // __context with shared vars
4210 };
4211 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4212 Params, /*OpenMPCaptureLevel=*/0);
4213 // Mark this captured region as inlined, because we don't use outlined
4214 // function directly.
4215 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4216 AlwaysInlineAttr::CreateImplicit(
4217 Context, {}, AttributeCommonInfo::AS_Keyword,
4218 AlwaysInlineAttr::Keyword_forceinline));
4219 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4220 std::make_pair(StringRef(), QualType()),
4221 /*OpenMPCaptureLevel=*/1);
4222 break;
4223 }
4224 case OMPD_atomic:
4225 case OMPD_critical:
4226 case OMPD_section:
4227 case OMPD_master:
4228 case OMPD_masked:
4229 case OMPD_tile:
4230 case OMPD_unroll:
4231 break;
4232 case OMPD_loop:
4233 // TODO: 'loop' may require additional parameters depending on the binding.
4234 // Treat similar to OMPD_simd/OMPD_for for now.
4235 case OMPD_simd:
4236 case OMPD_for:
4237 case OMPD_for_simd:
4238 case OMPD_sections:
4239 case OMPD_single:
4240 case OMPD_taskgroup:
4241 case OMPD_distribute:
4242 case OMPD_distribute_simd:
4243 case OMPD_ordered:
4244 case OMPD_target_data:
4245 case OMPD_dispatch: {
4246 Sema::CapturedParamNameType Params[] = {
4247 std::make_pair(StringRef(), QualType()) // __context with shared vars
4248 };
4249 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4250 Params);
4251 break;
4252 }
4253 case OMPD_task: {
4254 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4255 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4256 QualType KmpInt32PtrTy =
4257 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4258 QualType Args[] = {VoidPtrTy};
4259 FunctionProtoType::ExtProtoInfo EPI;
4260 EPI.Variadic = true;
4261 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4262 Sema::CapturedParamNameType Params[] = {
4263 std::make_pair(".global_tid.", KmpInt32Ty),
4264 std::make_pair(".part_id.", KmpInt32PtrTy),
4265 std::make_pair(".privates.", VoidPtrTy),
4266 std::make_pair(
4267 ".copy_fn.",
4268 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4269 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4270 std::make_pair(StringRef(), QualType()) // __context with shared vars
4271 };
4272 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4273 Params);
4274 // Mark this captured region as inlined, because we don't use outlined
4275 // function directly.
4276 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4277 AlwaysInlineAttr::CreateImplicit(
4278 Context, {}, AttributeCommonInfo::AS_Keyword,
4279 AlwaysInlineAttr::Keyword_forceinline));
4280 break;
4281 }
4282 case OMPD_taskloop:
4283 case OMPD_taskloop_simd:
4284 case OMPD_master_taskloop:
4285 case OMPD_masked_taskloop:
4286 case OMPD_masked_taskloop_simd:
4287 case OMPD_master_taskloop_simd: {
4288 QualType KmpInt32Ty =
4289 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4290 .withConst();
4291 QualType KmpUInt64Ty =
4292 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4293 .withConst();
4294 QualType KmpInt64Ty =
4295 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4296 .withConst();
4297 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4298 QualType KmpInt32PtrTy =
4299 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4300 QualType Args[] = {VoidPtrTy};
4301 FunctionProtoType::ExtProtoInfo EPI;
4302 EPI.Variadic = true;
4303 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4304 Sema::CapturedParamNameType Params[] = {
4305 std::make_pair(".global_tid.", KmpInt32Ty),
4306 std::make_pair(".part_id.", KmpInt32PtrTy),
4307 std::make_pair(".privates.", VoidPtrTy),
4308 std::make_pair(
4309 ".copy_fn.",
4310 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4311 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4312 std::make_pair(".lb.", KmpUInt64Ty),
4313 std::make_pair(".ub.", KmpUInt64Ty),
4314 std::make_pair(".st.", KmpInt64Ty),
4315 std::make_pair(".liter.", KmpInt32Ty),
4316 std::make_pair(".reductions.", VoidPtrTy),
4317 std::make_pair(StringRef(), QualType()) // __context with shared vars
4318 };
4319 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4320 Params);
4321 // Mark this captured region as inlined, because we don't use outlined
4322 // function directly.
4323 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4324 AlwaysInlineAttr::CreateImplicit(
4325 Context, {}, AttributeCommonInfo::AS_Keyword,
4326 AlwaysInlineAttr::Keyword_forceinline));
4327 break;
4328 }
4329 case OMPD_parallel_masked_taskloop:
4330 case OMPD_parallel_masked_taskloop_simd:
4331 case OMPD_parallel_master_taskloop:
4332 case OMPD_parallel_master_taskloop_simd: {
4333 QualType KmpInt32Ty =
4334 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4335 .withConst();
4336 QualType KmpUInt64Ty =
4337 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4338 .withConst();
4339 QualType KmpInt64Ty =
4340 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4341 .withConst();
4342 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4343 QualType KmpInt32PtrTy =
4344 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4345 Sema::CapturedParamNameType ParamsParallel[] = {
4346 std::make_pair(".global_tid.", KmpInt32PtrTy),
4347 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4348 std::make_pair(StringRef(), QualType()) // __context with shared vars
4349 };
4350 // Start a captured region for 'parallel'.
4351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4352 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4353 QualType Args[] = {VoidPtrTy};
4354 FunctionProtoType::ExtProtoInfo EPI;
4355 EPI.Variadic = true;
4356 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4357 Sema::CapturedParamNameType Params[] = {
4358 std::make_pair(".global_tid.", KmpInt32Ty),
4359 std::make_pair(".part_id.", KmpInt32PtrTy),
4360 std::make_pair(".privates.", VoidPtrTy),
4361 std::make_pair(
4362 ".copy_fn.",
4363 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4364 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4365 std::make_pair(".lb.", KmpUInt64Ty),
4366 std::make_pair(".ub.", KmpUInt64Ty),
4367 std::make_pair(".st.", KmpInt64Ty),
4368 std::make_pair(".liter.", KmpInt32Ty),
4369 std::make_pair(".reductions.", VoidPtrTy),
4370 std::make_pair(StringRef(), QualType()) // __context with shared vars
4371 };
4372 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4373 Params, /*OpenMPCaptureLevel=*/1);
4374 // Mark this captured region as inlined, because we don't use outlined
4375 // function directly.
4376 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4377 AlwaysInlineAttr::CreateImplicit(
4378 Context, {}, AttributeCommonInfo::AS_Keyword,
4379 AlwaysInlineAttr::Keyword_forceinline));
4380 break;
4381 }
4382 case OMPD_distribute_parallel_for_simd:
4383 case OMPD_distribute_parallel_for: {
4384 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4385 QualType KmpInt32PtrTy =
4386 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4387 Sema::CapturedParamNameType Params[] = {
4388 std::make_pair(".global_tid.", KmpInt32PtrTy),
4389 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4390 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4391 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4392 std::make_pair(StringRef(), QualType()) // __context with shared vars
4393 };
4394 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4395 Params);
4396 break;
4397 }
4398 case OMPD_target_teams_distribute_parallel_for:
4399 case OMPD_target_teams_distribute_parallel_for_simd: {
4400 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4401 QualType KmpInt32PtrTy =
4402 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4403 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4404
4405 QualType Args[] = {VoidPtrTy};
4406 FunctionProtoType::ExtProtoInfo EPI;
4407 EPI.Variadic = true;
4408 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4409 Sema::CapturedParamNameType Params[] = {
4410 std::make_pair(".global_tid.", KmpInt32Ty),
4411 std::make_pair(".part_id.", KmpInt32PtrTy),
4412 std::make_pair(".privates.", VoidPtrTy),
4413 std::make_pair(
4414 ".copy_fn.",
4415 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4416 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4417 std::make_pair(StringRef(), QualType()) // __context with shared vars
4418 };
4419 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4420 Params, /*OpenMPCaptureLevel=*/0);
4421 // Mark this captured region as inlined, because we don't use outlined
4422 // function directly.
4423 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4424 AlwaysInlineAttr::CreateImplicit(
4425 Context, {}, AttributeCommonInfo::AS_Keyword,
4426 AlwaysInlineAttr::Keyword_forceinline));
4427 Sema::CapturedParamNameType ParamsTarget[] = {
4428 std::make_pair(StringRef(), QualType()) // __context with shared vars
4429 };
4430 // Start a captured region for 'target' with no implicit parameters.
4431 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4432 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4433
4434 Sema::CapturedParamNameType ParamsTeams[] = {
4435 std::make_pair(".global_tid.", KmpInt32PtrTy),
4436 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4437 std::make_pair(StringRef(), QualType()) // __context with shared vars
4438 };
4439 // Start a captured region for 'target' with no implicit parameters.
4440 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4441 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4442
4443 Sema::CapturedParamNameType ParamsParallel[] = {
4444 std::make_pair(".global_tid.", KmpInt32PtrTy),
4445 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4446 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4447 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4448 std::make_pair(StringRef(), QualType()) // __context with shared vars
4449 };
4450 // Start a captured region for 'teams' or 'parallel'. Both regions have
4451 // the same implicit parameters.
4452 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4453 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4454 break;
4455 }
4456
4457 case OMPD_teams_loop: {
4458 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4459 QualType KmpInt32PtrTy =
4460 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4461
4462 Sema::CapturedParamNameType ParamsTeams[] = {
4463 std::make_pair(".global_tid.", KmpInt32PtrTy),
4464 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4465 std::make_pair(StringRef(), QualType()) // __context with shared vars
4466 };
4467 // Start a captured region for 'teams'.
4468 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4469 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4470 break;
4471 }
4472
4473 case OMPD_teams_distribute_parallel_for:
4474 case OMPD_teams_distribute_parallel_for_simd: {
4475 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4476 QualType KmpInt32PtrTy =
4477 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4478
4479 Sema::CapturedParamNameType ParamsTeams[] = {
4480 std::make_pair(".global_tid.", KmpInt32PtrTy),
4481 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4482 std::make_pair(StringRef(), QualType()) // __context with shared vars
4483 };
4484 // Start a captured region for 'target' with no implicit parameters.
4485 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4486 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4487
4488 Sema::CapturedParamNameType ParamsParallel[] = {
4489 std::make_pair(".global_tid.", KmpInt32PtrTy),
4490 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4491 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4492 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4493 std::make_pair(StringRef(), QualType()) // __context with shared vars
4494 };
4495 // Start a captured region for 'teams' or 'parallel'. Both regions have
4496 // the same implicit parameters.
4497 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4498 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4499 break;
4500 }
4501 case OMPD_target_update:
4502 case OMPD_target_enter_data:
4503 case OMPD_target_exit_data: {
4504 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4505 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4506 QualType KmpInt32PtrTy =
4507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4508 QualType Args[] = {VoidPtrTy};
4509 FunctionProtoType::ExtProtoInfo EPI;
4510 EPI.Variadic = true;
4511 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4512 Sema::CapturedParamNameType Params[] = {
4513 std::make_pair(".global_tid.", KmpInt32Ty),
4514 std::make_pair(".part_id.", KmpInt32PtrTy),
4515 std::make_pair(".privates.", VoidPtrTy),
4516 std::make_pair(
4517 ".copy_fn.",
4518 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4519 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4520 std::make_pair(StringRef(), QualType()) // __context with shared vars
4521 };
4522 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4523 Params);
4524 // Mark this captured region as inlined, because we don't use outlined
4525 // function directly.
4526 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4527 AlwaysInlineAttr::CreateImplicit(
4528 Context, {}, AttributeCommonInfo::AS_Keyword,
4529 AlwaysInlineAttr::Keyword_forceinline));
4530 break;
4531 }
4532 case OMPD_threadprivate:
4533 case OMPD_allocate:
4534 case OMPD_taskyield:
4535 case OMPD_barrier:
4536 case OMPD_taskwait:
4537 case OMPD_cancellation_point:
4538 case OMPD_cancel:
4539 case OMPD_flush:
4540 case OMPD_depobj:
4541 case OMPD_scan:
4542 case OMPD_declare_reduction:
4543 case OMPD_declare_mapper:
4544 case OMPD_declare_simd:
4545 case OMPD_declare_target:
4546 case OMPD_end_declare_target:
4547 case OMPD_requires:
4548 case OMPD_declare_variant:
4549 case OMPD_begin_declare_variant:
4550 case OMPD_end_declare_variant:
4551 case OMPD_metadirective:
4552 llvm_unreachable("OpenMP Directive is not allowed");
4553 case OMPD_unknown:
4554 default:
4555 llvm_unreachable("Unknown OpenMP directive");
4556 }
4557 DSAStack->setContext(CurContext);
4558 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4559 }
4560
getNumberOfConstructScopes(unsigned Level) const4561 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4562 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4563 }
4564
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4565 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4566 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4567 getOpenMPCaptureRegions(CaptureRegions, DKind);
4568 return CaptureRegions.size();
4569 }
4570
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,DeclContext * CurContext,bool AsExpression)4571 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4572 Expr *CaptureExpr, bool WithInit,
4573 DeclContext *CurContext,
4574 bool AsExpression) {
4575 assert(CaptureExpr);
4576 ASTContext &C = S.getASTContext();
4577 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4578 QualType Ty = Init->getType();
4579 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4580 if (S.getLangOpts().CPlusPlus) {
4581 Ty = C.getLValueReferenceType(Ty);
4582 } else {
4583 Ty = C.getPointerType(Ty);
4584 ExprResult Res =
4585 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4586 if (!Res.isUsable())
4587 return nullptr;
4588 Init = Res.get();
4589 }
4590 WithInit = true;
4591 }
4592 auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4593 CaptureExpr->getBeginLoc());
4594 if (!WithInit)
4595 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4596 CurContext->addHiddenDecl(CED);
4597 Sema::TentativeAnalysisScope Trap(S);
4598 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4599 return CED;
4600 }
4601
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4602 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4603 bool WithInit) {
4604 OMPCapturedExprDecl *CD;
4605 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4606 CD = cast<OMPCapturedExprDecl>(VD);
4607 else
4608 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4609 S.CurContext,
4610 /*AsExpression=*/false);
4611 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4612 CaptureExpr->getExprLoc());
4613 }
4614
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4615 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4616 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4617 if (!Ref) {
4618 OMPCapturedExprDecl *CD = buildCaptureDecl(
4619 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4620 /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4621 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4622 CaptureExpr->getExprLoc());
4623 }
4624 ExprResult Res = Ref;
4625 if (!S.getLangOpts().CPlusPlus &&
4626 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4627 Ref->getType()->isPointerType()) {
4628 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4629 if (!Res.isUsable())
4630 return ExprError();
4631 }
4632 return S.DefaultLvalueConversion(Res.get());
4633 }
4634
4635 namespace {
4636 // OpenMP directives parsed in this section are represented as a
4637 // CapturedStatement with an associated statement. If a syntax error
4638 // is detected during the parsing of the associated statement, the
4639 // compiler must abort processing and close the CapturedStatement.
4640 //
4641 // Combined directives such as 'target parallel' have more than one
4642 // nested CapturedStatements. This RAII ensures that we unwind out
4643 // of all the nested CapturedStatements when an error is found.
4644 class CaptureRegionUnwinderRAII {
4645 private:
4646 Sema &S;
4647 bool &ErrorFound;
4648 OpenMPDirectiveKind DKind = OMPD_unknown;
4649
4650 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4651 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4652 OpenMPDirectiveKind DKind)
4653 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4654 ~CaptureRegionUnwinderRAII() {
4655 if (ErrorFound) {
4656 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4657 while (--ThisCaptureLevel >= 0)
4658 S.ActOnCapturedRegionError();
4659 }
4660 }
4661 };
4662 } // namespace
4663
tryCaptureOpenMPLambdas(ValueDecl * V)4664 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4665 // Capture variables captured by reference in lambdas for target-based
4666 // directives.
4667 if (!CurContext->isDependentContext() &&
4668 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4669 isOpenMPTargetDataManagementDirective(
4670 DSAStack->getCurrentDirective()))) {
4671 QualType Type = V->getType();
4672 if (const auto *RD = Type.getCanonicalType()
4673 .getNonReferenceType()
4674 ->getAsCXXRecordDecl()) {
4675 bool SavedForceCaptureByReferenceInTargetExecutable =
4676 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4677 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4678 /*V=*/true);
4679 if (RD->isLambda()) {
4680 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4681 FieldDecl *ThisCapture;
4682 RD->getCaptureFields(Captures, ThisCapture);
4683 for (const LambdaCapture &LC : RD->captures()) {
4684 if (LC.getCaptureKind() == LCK_ByRef) {
4685 VarDecl *VD = LC.getCapturedVar();
4686 DeclContext *VDC = VD->getDeclContext();
4687 if (!VDC->Encloses(CurContext))
4688 continue;
4689 MarkVariableReferenced(LC.getLocation(), VD);
4690 } else if (LC.getCaptureKind() == LCK_This) {
4691 QualType ThisTy = getCurrentThisType();
4692 if (!ThisTy.isNull() &&
4693 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4694 CheckCXXThisCapture(LC.getLocation());
4695 }
4696 }
4697 }
4698 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4699 SavedForceCaptureByReferenceInTargetExecutable);
4700 }
4701 }
4702 }
4703
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4704 static bool checkOrderedOrderSpecified(Sema &S,
4705 const ArrayRef<OMPClause *> Clauses) {
4706 const OMPOrderedClause *Ordered = nullptr;
4707 const OMPOrderClause *Order = nullptr;
4708
4709 for (const OMPClause *Clause : Clauses) {
4710 if (Clause->getClauseKind() == OMPC_ordered)
4711 Ordered = cast<OMPOrderedClause>(Clause);
4712 else if (Clause->getClauseKind() == OMPC_order) {
4713 Order = cast<OMPOrderClause>(Clause);
4714 if (Order->getKind() != OMPC_ORDER_concurrent)
4715 Order = nullptr;
4716 }
4717 if (Ordered && Order)
4718 break;
4719 }
4720
4721 if (Ordered && Order) {
4722 S.Diag(Order->getKindKwLoc(),
4723 diag::err_omp_simple_clause_incompatible_with_ordered)
4724 << getOpenMPClauseName(OMPC_order)
4725 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4726 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4727 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4728 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4729 return true;
4730 }
4731 return false;
4732 }
4733
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4734 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4735 ArrayRef<OMPClause *> Clauses) {
4736 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4737 /* ScopeEntry */ false);
4738 if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4739 DSAStack->getCurrentDirective() == OMPD_critical ||
4740 DSAStack->getCurrentDirective() == OMPD_section ||
4741 DSAStack->getCurrentDirective() == OMPD_master ||
4742 DSAStack->getCurrentDirective() == OMPD_masked)
4743 return S;
4744
4745 bool ErrorFound = false;
4746 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4747 *this, ErrorFound, DSAStack->getCurrentDirective());
4748 if (!S.isUsable()) {
4749 ErrorFound = true;
4750 return StmtError();
4751 }
4752
4753 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4754 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4755 OMPOrderedClause *OC = nullptr;
4756 OMPScheduleClause *SC = nullptr;
4757 SmallVector<const OMPLinearClause *, 4> LCs;
4758 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4759 // This is required for proper codegen.
4760 for (OMPClause *Clause : Clauses) {
4761 if (!LangOpts.OpenMPSimd &&
4762 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4763 DSAStack->getCurrentDirective() == OMPD_target) &&
4764 Clause->getClauseKind() == OMPC_in_reduction) {
4765 // Capture taskgroup task_reduction descriptors inside the tasking regions
4766 // with the corresponding in_reduction items.
4767 auto *IRC = cast<OMPInReductionClause>(Clause);
4768 for (Expr *E : IRC->taskgroup_descriptors())
4769 if (E)
4770 MarkDeclarationsReferencedInExpr(E);
4771 }
4772 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4773 Clause->getClauseKind() == OMPC_copyprivate ||
4774 (getLangOpts().OpenMPUseTLS &&
4775 getASTContext().getTargetInfo().isTLSSupported() &&
4776 Clause->getClauseKind() == OMPC_copyin)) {
4777 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4778 // Mark all variables in private list clauses as used in inner region.
4779 for (Stmt *VarRef : Clause->children()) {
4780 if (auto *E = cast_or_null<Expr>(VarRef)) {
4781 MarkDeclarationsReferencedInExpr(E);
4782 }
4783 }
4784 DSAStack->setForceVarCapturing(/*V=*/false);
4785 } else if (isOpenMPLoopTransformationDirective(
4786 DSAStack->getCurrentDirective())) {
4787 assert(CaptureRegions.empty() &&
4788 "No captured regions in loop transformation directives.");
4789 } else if (CaptureRegions.size() > 1 ||
4790 CaptureRegions.back() != OMPD_unknown) {
4791 if (auto *C = OMPClauseWithPreInit::get(Clause))
4792 PICs.push_back(C);
4793 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4794 if (Expr *E = C->getPostUpdateExpr())
4795 MarkDeclarationsReferencedInExpr(E);
4796 }
4797 }
4798 if (Clause->getClauseKind() == OMPC_schedule)
4799 SC = cast<OMPScheduleClause>(Clause);
4800 else if (Clause->getClauseKind() == OMPC_ordered)
4801 OC = cast<OMPOrderedClause>(Clause);
4802 else if (Clause->getClauseKind() == OMPC_linear)
4803 LCs.push_back(cast<OMPLinearClause>(Clause));
4804 }
4805 // Capture allocator expressions if used.
4806 for (Expr *E : DSAStack->getInnerAllocators())
4807 MarkDeclarationsReferencedInExpr(E);
4808 // OpenMP, 2.7.1 Loop Construct, Restrictions
4809 // The nonmonotonic modifier cannot be specified if an ordered clause is
4810 // specified.
4811 if (SC &&
4812 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4813 SC->getSecondScheduleModifier() ==
4814 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4815 OC) {
4816 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4817 ? SC->getFirstScheduleModifierLoc()
4818 : SC->getSecondScheduleModifierLoc(),
4819 diag::err_omp_simple_clause_incompatible_with_ordered)
4820 << getOpenMPClauseName(OMPC_schedule)
4821 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4822 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4823 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4824 ErrorFound = true;
4825 }
4826 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4827 // If an order(concurrent) clause is present, an ordered clause may not appear
4828 // on the same directive.
4829 if (checkOrderedOrderSpecified(*this, Clauses))
4830 ErrorFound = true;
4831 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4832 for (const OMPLinearClause *C : LCs) {
4833 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4834 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4835 }
4836 ErrorFound = true;
4837 }
4838 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4839 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4840 OC->getNumForLoops()) {
4841 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4842 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4843 ErrorFound = true;
4844 }
4845 if (ErrorFound) {
4846 return StmtError();
4847 }
4848 StmtResult SR = S;
4849 unsigned CompletedRegions = 0;
4850 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4851 // Mark all variables in private list clauses as used in inner region.
4852 // Required for proper codegen of combined directives.
4853 // TODO: add processing for other clauses.
4854 if (ThisCaptureRegion != OMPD_unknown) {
4855 for (const clang::OMPClauseWithPreInit *C : PICs) {
4856 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4857 // Find the particular capture region for the clause if the
4858 // directive is a combined one with multiple capture regions.
4859 // If the directive is not a combined one, the capture region
4860 // associated with the clause is OMPD_unknown and is generated
4861 // only once.
4862 if (CaptureRegion == ThisCaptureRegion ||
4863 CaptureRegion == OMPD_unknown) {
4864 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4865 for (Decl *D : DS->decls())
4866 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4867 }
4868 }
4869 }
4870 }
4871 if (ThisCaptureRegion == OMPD_target) {
4872 // Capture allocator traits in the target region. They are used implicitly
4873 // and, thus, are not captured by default.
4874 for (OMPClause *C : Clauses) {
4875 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4876 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4877 ++I) {
4878 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4879 if (Expr *E = D.AllocatorTraits)
4880 MarkDeclarationsReferencedInExpr(E);
4881 }
4882 continue;
4883 }
4884 }
4885 }
4886 if (ThisCaptureRegion == OMPD_parallel) {
4887 // Capture temp arrays for inscan reductions and locals in aligned
4888 // clauses.
4889 for (OMPClause *C : Clauses) {
4890 if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4891 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4892 continue;
4893 for (Expr *E : RC->copy_array_temps())
4894 MarkDeclarationsReferencedInExpr(E);
4895 }
4896 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4897 for (Expr *E : AC->varlists())
4898 MarkDeclarationsReferencedInExpr(E);
4899 }
4900 }
4901 }
4902 if (++CompletedRegions == CaptureRegions.size())
4903 DSAStack->setBodyComplete();
4904 SR = ActOnCapturedRegionEnd(SR.get());
4905 }
4906 return SR;
4907 }
4908
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4909 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4910 OpenMPDirectiveKind CancelRegion,
4911 SourceLocation StartLoc) {
4912 // CancelRegion is only needed for cancel and cancellation_point.
4913 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4914 return false;
4915
4916 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4917 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4918 return false;
4919
4920 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4921 << getOpenMPDirectiveName(CancelRegion);
4922 return true;
4923 }
4924
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,OpenMPBindClauseKind BindKind,SourceLocation StartLoc)4925 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4926 OpenMPDirectiveKind CurrentRegion,
4927 const DeclarationNameInfo &CurrentName,
4928 OpenMPDirectiveKind CancelRegion,
4929 OpenMPBindClauseKind BindKind,
4930 SourceLocation StartLoc) {
4931 if (Stack->getCurScope()) {
4932 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4933 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4934 bool NestingProhibited = false;
4935 bool CloseNesting = true;
4936 bool OrphanSeen = false;
4937 enum {
4938 NoRecommend,
4939 ShouldBeInParallelRegion,
4940 ShouldBeInOrderedRegion,
4941 ShouldBeInTargetRegion,
4942 ShouldBeInTeamsRegion,
4943 ShouldBeInLoopSimdRegion,
4944 } Recommend = NoRecommend;
4945 if (isOpenMPSimdDirective(ParentRegion) &&
4946 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4947 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4948 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4949 CurrentRegion != OMPD_scan))) {
4950 // OpenMP [2.16, Nesting of Regions]
4951 // OpenMP constructs may not be nested inside a simd region.
4952 // OpenMP [2.8.1,simd Construct, Restrictions]
4953 // An ordered construct with the simd clause is the only OpenMP
4954 // construct that can appear in the simd region.
4955 // Allowing a SIMD construct nested in another SIMD construct is an
4956 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4957 // message.
4958 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4959 // The only OpenMP constructs that can be encountered during execution of
4960 // a simd region are the atomic construct, the loop construct, the simd
4961 // construct and the ordered construct with the simd clause.
4962 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4963 ? diag::err_omp_prohibited_region_simd
4964 : diag::warn_omp_nesting_simd)
4965 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4966 return CurrentRegion != OMPD_simd;
4967 }
4968 if (ParentRegion == OMPD_atomic) {
4969 // OpenMP [2.16, Nesting of Regions]
4970 // OpenMP constructs may not be nested inside an atomic region.
4971 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4972 return true;
4973 }
4974 if (CurrentRegion == OMPD_section) {
4975 // OpenMP [2.7.2, sections Construct, Restrictions]
4976 // Orphaned section directives are prohibited. That is, the section
4977 // directives must appear within the sections construct and must not be
4978 // encountered elsewhere in the sections region.
4979 if (ParentRegion != OMPD_sections &&
4980 ParentRegion != OMPD_parallel_sections) {
4981 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4982 << (ParentRegion != OMPD_unknown)
4983 << getOpenMPDirectiveName(ParentRegion);
4984 return true;
4985 }
4986 return false;
4987 }
4988 // Allow some constructs (except teams and cancellation constructs) to be
4989 // orphaned (they could be used in functions, called from OpenMP regions
4990 // with the required preconditions).
4991 if (ParentRegion == OMPD_unknown &&
4992 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4993 CurrentRegion != OMPD_cancellation_point &&
4994 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4995 return false;
4996 if (CurrentRegion == OMPD_cancellation_point ||
4997 CurrentRegion == OMPD_cancel) {
4998 // OpenMP [2.16, Nesting of Regions]
4999 // A cancellation point construct for which construct-type-clause is
5000 // taskgroup must be nested inside a task construct. A cancellation
5001 // point construct for which construct-type-clause is not taskgroup must
5002 // be closely nested inside an OpenMP construct that matches the type
5003 // specified in construct-type-clause.
5004 // A cancel construct for which construct-type-clause is taskgroup must be
5005 // nested inside a task construct. A cancel construct for which
5006 // construct-type-clause is not taskgroup must be closely nested inside an
5007 // OpenMP construct that matches the type specified in
5008 // construct-type-clause.
5009 NestingProhibited =
5010 !((CancelRegion == OMPD_parallel &&
5011 (ParentRegion == OMPD_parallel ||
5012 ParentRegion == OMPD_target_parallel)) ||
5013 (CancelRegion == OMPD_for &&
5014 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5015 ParentRegion == OMPD_target_parallel_for ||
5016 ParentRegion == OMPD_distribute_parallel_for ||
5017 ParentRegion == OMPD_teams_distribute_parallel_for ||
5018 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5019 (CancelRegion == OMPD_taskgroup &&
5020 (ParentRegion == OMPD_task ||
5021 (SemaRef.getLangOpts().OpenMP >= 50 &&
5022 (ParentRegion == OMPD_taskloop ||
5023 ParentRegion == OMPD_master_taskloop ||
5024 ParentRegion == OMPD_masked_taskloop ||
5025 ParentRegion == OMPD_parallel_masked_taskloop ||
5026 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5027 (CancelRegion == OMPD_sections &&
5028 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5029 ParentRegion == OMPD_parallel_sections)));
5030 OrphanSeen = ParentRegion == OMPD_unknown;
5031 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5032 // OpenMP 5.1 [2.22, Nesting of Regions]
5033 // A masked region may not be closely nested inside a worksharing, loop,
5034 // atomic, task, or taskloop region.
5035 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5036 isOpenMPGenericLoopDirective(ParentRegion) ||
5037 isOpenMPTaskingDirective(ParentRegion);
5038 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5039 // OpenMP [2.16, Nesting of Regions]
5040 // A critical region may not be nested (closely or otherwise) inside a
5041 // critical region with the same name. Note that this restriction is not
5042 // sufficient to prevent deadlock.
5043 SourceLocation PreviousCriticalLoc;
5044 bool DeadLock = Stack->hasDirective(
5045 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5046 const DeclarationNameInfo &DNI,
5047 SourceLocation Loc) {
5048 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5049 PreviousCriticalLoc = Loc;
5050 return true;
5051 }
5052 return false;
5053 },
5054 false /* skip top directive */);
5055 if (DeadLock) {
5056 SemaRef.Diag(StartLoc,
5057 diag::err_omp_prohibited_region_critical_same_name)
5058 << CurrentName.getName();
5059 if (PreviousCriticalLoc.isValid())
5060 SemaRef.Diag(PreviousCriticalLoc,
5061 diag::note_omp_previous_critical_region);
5062 return true;
5063 }
5064 } else if (CurrentRegion == OMPD_barrier) {
5065 // OpenMP 5.1 [2.22, Nesting of Regions]
5066 // A barrier region may not be closely nested inside a worksharing, loop,
5067 // task, taskloop, critical, ordered, atomic, or masked region.
5068 NestingProhibited =
5069 isOpenMPWorksharingDirective(ParentRegion) ||
5070 isOpenMPGenericLoopDirective(ParentRegion) ||
5071 isOpenMPTaskingDirective(ParentRegion) ||
5072 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5073 ParentRegion == OMPD_parallel_master ||
5074 ParentRegion == OMPD_parallel_masked ||
5075 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5076 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5077 !isOpenMPParallelDirective(CurrentRegion) &&
5078 !isOpenMPTeamsDirective(CurrentRegion)) {
5079 // OpenMP 5.1 [2.22, Nesting of Regions]
5080 // A loop region that binds to a parallel region or a worksharing region
5081 // may not be closely nested inside a worksharing, loop, task, taskloop,
5082 // critical, ordered, atomic, or masked region.
5083 NestingProhibited =
5084 isOpenMPWorksharingDirective(ParentRegion) ||
5085 isOpenMPGenericLoopDirective(ParentRegion) ||
5086 isOpenMPTaskingDirective(ParentRegion) ||
5087 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5088 ParentRegion == OMPD_parallel_master ||
5089 ParentRegion == OMPD_parallel_masked ||
5090 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5091 Recommend = ShouldBeInParallelRegion;
5092 } else if (CurrentRegion == OMPD_ordered) {
5093 // OpenMP [2.16, Nesting of Regions]
5094 // An ordered region may not be closely nested inside a critical,
5095 // atomic, or explicit task region.
5096 // An ordered region must be closely nested inside a loop region (or
5097 // parallel loop region) with an ordered clause.
5098 // OpenMP [2.8.1,simd Construct, Restrictions]
5099 // An ordered construct with the simd clause is the only OpenMP construct
5100 // that can appear in the simd region.
5101 NestingProhibited = ParentRegion == OMPD_critical ||
5102 isOpenMPTaskingDirective(ParentRegion) ||
5103 !(isOpenMPSimdDirective(ParentRegion) ||
5104 Stack->isParentOrderedRegion());
5105 Recommend = ShouldBeInOrderedRegion;
5106 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5107 // OpenMP [2.16, Nesting of Regions]
5108 // If specified, a teams construct must be contained within a target
5109 // construct.
5110 NestingProhibited =
5111 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5112 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5113 ParentRegion != OMPD_target);
5114 OrphanSeen = ParentRegion == OMPD_unknown;
5115 Recommend = ShouldBeInTargetRegion;
5116 } else if (CurrentRegion == OMPD_scan) {
5117 // OpenMP [2.16, Nesting of Regions]
5118 // If specified, a teams construct must be contained within a target
5119 // construct.
5120 NestingProhibited =
5121 SemaRef.LangOpts.OpenMP < 50 ||
5122 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5123 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5124 ParentRegion != OMPD_parallel_for_simd);
5125 OrphanSeen = ParentRegion == OMPD_unknown;
5126 Recommend = ShouldBeInLoopSimdRegion;
5127 }
5128 if (!NestingProhibited &&
5129 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5130 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5131 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5132 // OpenMP [5.1, 2.22, Nesting of Regions]
5133 // distribute, distribute simd, distribute parallel worksharing-loop,
5134 // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5135 // including any parallel regions arising from combined constructs,
5136 // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5137 // only OpenMP regions that may be strictly nested inside the teams
5138 // region.
5139 //
5140 // As an extension, we permit atomic within teams as well.
5141 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5142 !isOpenMPDistributeDirective(CurrentRegion) &&
5143 CurrentRegion != OMPD_loop &&
5144 !(SemaRef.getLangOpts().OpenMPExtensions &&
5145 CurrentRegion == OMPD_atomic);
5146 Recommend = ShouldBeInParallelRegion;
5147 }
5148 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5149 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5150 // If the bind clause is present on the loop construct and binding is
5151 // teams then the corresponding loop region must be strictly nested inside
5152 // a teams region.
5153 NestingProhibited = BindKind == OMPC_BIND_teams &&
5154 ParentRegion != OMPD_teams &&
5155 ParentRegion != OMPD_target_teams;
5156 Recommend = ShouldBeInTeamsRegion;
5157 }
5158 if (!NestingProhibited &&
5159 isOpenMPNestingDistributeDirective(CurrentRegion)) {
5160 // OpenMP 4.5 [2.17 Nesting of Regions]
5161 // The region associated with the distribute construct must be strictly
5162 // nested inside a teams region
5163 NestingProhibited =
5164 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5165 Recommend = ShouldBeInTeamsRegion;
5166 }
5167 if (!NestingProhibited &&
5168 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5169 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5170 // OpenMP 4.5 [2.17 Nesting of Regions]
5171 // If a target, target update, target data, target enter data, or
5172 // target exit data construct is encountered during execution of a
5173 // target region, the behavior is unspecified.
5174 NestingProhibited = Stack->hasDirective(
5175 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5176 SourceLocation) {
5177 if (isOpenMPTargetExecutionDirective(K)) {
5178 OffendingRegion = K;
5179 return true;
5180 }
5181 return false;
5182 },
5183 false /* don't skip top directive */);
5184 CloseNesting = false;
5185 }
5186 if (NestingProhibited) {
5187 if (OrphanSeen) {
5188 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5189 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5190 } else {
5191 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5192 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5193 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5194 }
5195 return true;
5196 }
5197 }
5198 return false;
5199 }
5200
5201 struct Kind2Unsigned {
5202 using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned5203 unsigned operator()(argument_type DK) { return unsigned(DK); }
5204 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)5205 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5206 ArrayRef<OMPClause *> Clauses,
5207 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5208 bool ErrorFound = false;
5209 unsigned NamedModifiersNumber = 0;
5210 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5211 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5212 SmallVector<SourceLocation, 4> NameModifierLoc;
5213 for (const OMPClause *C : Clauses) {
5214 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5215 // At most one if clause without a directive-name-modifier can appear on
5216 // the directive.
5217 OpenMPDirectiveKind CurNM = IC->getNameModifier();
5218 if (FoundNameModifiers[CurNM]) {
5219 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5220 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5221 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5222 ErrorFound = true;
5223 } else if (CurNM != OMPD_unknown) {
5224 NameModifierLoc.push_back(IC->getNameModifierLoc());
5225 ++NamedModifiersNumber;
5226 }
5227 FoundNameModifiers[CurNM] = IC;
5228 if (CurNM == OMPD_unknown)
5229 continue;
5230 // Check if the specified name modifier is allowed for the current
5231 // directive.
5232 // At most one if clause with the particular directive-name-modifier can
5233 // appear on the directive.
5234 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5235 S.Diag(IC->getNameModifierLoc(),
5236 diag::err_omp_wrong_if_directive_name_modifier)
5237 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5238 ErrorFound = true;
5239 }
5240 }
5241 }
5242 // If any if clause on the directive includes a directive-name-modifier then
5243 // all if clauses on the directive must include a directive-name-modifier.
5244 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5245 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5246 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5247 diag::err_omp_no_more_if_clause);
5248 } else {
5249 std::string Values;
5250 std::string Sep(", ");
5251 unsigned AllowedCnt = 0;
5252 unsigned TotalAllowedNum =
5253 AllowedNameModifiers.size() - NamedModifiersNumber;
5254 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5255 ++Cnt) {
5256 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5257 if (!FoundNameModifiers[NM]) {
5258 Values += "'";
5259 Values += getOpenMPDirectiveName(NM);
5260 Values += "'";
5261 if (AllowedCnt + 2 == TotalAllowedNum)
5262 Values += " or ";
5263 else if (AllowedCnt + 1 != TotalAllowedNum)
5264 Values += Sep;
5265 ++AllowedCnt;
5266 }
5267 }
5268 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5269 diag::err_omp_unnamed_if_clause)
5270 << (TotalAllowedNum > 1) << Values;
5271 }
5272 for (SourceLocation Loc : NameModifierLoc) {
5273 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5274 }
5275 ErrorFound = true;
5276 }
5277 return ErrorFound;
5278 }
5279
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)5280 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5281 SourceLocation &ELoc,
5282 SourceRange &ERange,
5283 bool AllowArraySection) {
5284 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5285 RefExpr->containsUnexpandedParameterPack())
5286 return std::make_pair(nullptr, true);
5287
5288 // OpenMP [3.1, C/C++]
5289 // A list item is a variable name.
5290 // OpenMP [2.9.3.3, Restrictions, p.1]
5291 // A variable that is part of another variable (as an array or
5292 // structure element) cannot appear in a private clause.
5293 RefExpr = RefExpr->IgnoreParens();
5294 enum {
5295 NoArrayExpr = -1,
5296 ArraySubscript = 0,
5297 OMPArraySection = 1
5298 } IsArrayExpr = NoArrayExpr;
5299 if (AllowArraySection) {
5300 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5301 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5302 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5303 Base = TempASE->getBase()->IgnoreParenImpCasts();
5304 RefExpr = Base;
5305 IsArrayExpr = ArraySubscript;
5306 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5307 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5308 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5309 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5310 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5311 Base = TempASE->getBase()->IgnoreParenImpCasts();
5312 RefExpr = Base;
5313 IsArrayExpr = OMPArraySection;
5314 }
5315 }
5316 ELoc = RefExpr->getExprLoc();
5317 ERange = RefExpr->getSourceRange();
5318 RefExpr = RefExpr->IgnoreParenImpCasts();
5319 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5320 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5321 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5322 (S.getCurrentThisType().isNull() || !ME ||
5323 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5324 !isa<FieldDecl>(ME->getMemberDecl()))) {
5325 if (IsArrayExpr != NoArrayExpr) {
5326 S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5327 << IsArrayExpr << ERange;
5328 } else {
5329 S.Diag(ELoc,
5330 AllowArraySection
5331 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5332 : diag::err_omp_expected_var_name_member_expr)
5333 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5334 }
5335 return std::make_pair(nullptr, false);
5336 }
5337 return std::make_pair(
5338 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5339 }
5340
5341 namespace {
5342 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5343 /// target regions.
5344 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5345 DSAStackTy *S = nullptr;
5346
5347 public:
VisitDeclRefExpr(const DeclRefExpr * E)5348 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5349 return S->isUsesAllocatorsDecl(E->getDecl())
5350 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5351 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5352 }
VisitStmt(const Stmt * S)5353 bool VisitStmt(const Stmt *S) {
5354 for (const Stmt *Child : S->children()) {
5355 if (Child && Visit(Child))
5356 return true;
5357 }
5358 return false;
5359 }
AllocatorChecker(DSAStackTy * S)5360 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5361 };
5362 } // namespace
5363
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5364 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5365 ArrayRef<OMPClause *> Clauses) {
5366 assert(!S.CurContext->isDependentContext() &&
5367 "Expected non-dependent context.");
5368 auto AllocateRange =
5369 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5370 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5371 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5372 return isOpenMPPrivate(C->getClauseKind());
5373 });
5374 for (OMPClause *Cl : PrivateRange) {
5375 MutableArrayRef<Expr *>::iterator I, It, Et;
5376 if (Cl->getClauseKind() == OMPC_private) {
5377 auto *PC = cast<OMPPrivateClause>(Cl);
5378 I = PC->private_copies().begin();
5379 It = PC->varlist_begin();
5380 Et = PC->varlist_end();
5381 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5382 auto *PC = cast<OMPFirstprivateClause>(Cl);
5383 I = PC->private_copies().begin();
5384 It = PC->varlist_begin();
5385 Et = PC->varlist_end();
5386 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5387 auto *PC = cast<OMPLastprivateClause>(Cl);
5388 I = PC->private_copies().begin();
5389 It = PC->varlist_begin();
5390 Et = PC->varlist_end();
5391 } else if (Cl->getClauseKind() == OMPC_linear) {
5392 auto *PC = cast<OMPLinearClause>(Cl);
5393 I = PC->privates().begin();
5394 It = PC->varlist_begin();
5395 Et = PC->varlist_end();
5396 } else if (Cl->getClauseKind() == OMPC_reduction) {
5397 auto *PC = cast<OMPReductionClause>(Cl);
5398 I = PC->privates().begin();
5399 It = PC->varlist_begin();
5400 Et = PC->varlist_end();
5401 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5402 auto *PC = cast<OMPTaskReductionClause>(Cl);
5403 I = PC->privates().begin();
5404 It = PC->varlist_begin();
5405 Et = PC->varlist_end();
5406 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5407 auto *PC = cast<OMPInReductionClause>(Cl);
5408 I = PC->privates().begin();
5409 It = PC->varlist_begin();
5410 Et = PC->varlist_end();
5411 } else {
5412 llvm_unreachable("Expected private clause.");
5413 }
5414 for (Expr *E : llvm::make_range(It, Et)) {
5415 if (!*I) {
5416 ++I;
5417 continue;
5418 }
5419 SourceLocation ELoc;
5420 SourceRange ERange;
5421 Expr *SimpleRefExpr = E;
5422 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5423 /*AllowArraySection=*/true);
5424 DeclToCopy.try_emplace(Res.first,
5425 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5426 ++I;
5427 }
5428 }
5429 for (OMPClause *C : AllocateRange) {
5430 auto *AC = cast<OMPAllocateClause>(C);
5431 if (S.getLangOpts().OpenMP >= 50 &&
5432 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5433 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5434 AC->getAllocator()) {
5435 Expr *Allocator = AC->getAllocator();
5436 // OpenMP, 2.12.5 target Construct
5437 // Memory allocators that do not appear in a uses_allocators clause cannot
5438 // appear as an allocator in an allocate clause or be used in the target
5439 // region unless a requires directive with the dynamic_allocators clause
5440 // is present in the same compilation unit.
5441 AllocatorChecker Checker(Stack);
5442 if (Checker.Visit(Allocator))
5443 S.Diag(Allocator->getExprLoc(),
5444 diag::err_omp_allocator_not_in_uses_allocators)
5445 << Allocator->getSourceRange();
5446 }
5447 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5448 getAllocatorKind(S, Stack, AC->getAllocator());
5449 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5450 // For task, taskloop or target directives, allocation requests to memory
5451 // allocators with the trait access set to thread result in unspecified
5452 // behavior.
5453 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5454 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5455 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5456 S.Diag(AC->getAllocator()->getExprLoc(),
5457 diag::warn_omp_allocate_thread_on_task_target_directive)
5458 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5459 }
5460 for (Expr *E : AC->varlists()) {
5461 SourceLocation ELoc;
5462 SourceRange ERange;
5463 Expr *SimpleRefExpr = E;
5464 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5465 ValueDecl *VD = Res.first;
5466 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5467 if (!isOpenMPPrivate(Data.CKind)) {
5468 S.Diag(E->getExprLoc(),
5469 diag::err_omp_expected_private_copy_for_allocate);
5470 continue;
5471 }
5472 VarDecl *PrivateVD = DeclToCopy[VD];
5473 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5474 AllocatorKind, AC->getAllocator()))
5475 continue;
5476 // Placeholder until allocate clause supports align modifier.
5477 Expr *Alignment = nullptr;
5478 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5479 Alignment, E->getSourceRange());
5480 }
5481 }
5482 }
5483
5484 namespace {
5485 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5486 ///
5487 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5488 /// context. DeclRefExpr used inside the new context are changed to refer to the
5489 /// captured variable instead.
5490 class CaptureVars : public TreeTransform<CaptureVars> {
5491 using BaseTransform = TreeTransform<CaptureVars>;
5492
5493 public:
CaptureVars(Sema & Actions)5494 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5495
AlwaysRebuild()5496 bool AlwaysRebuild() { return true; }
5497 };
5498 } // namespace
5499
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5500 static VarDecl *precomputeExpr(Sema &Actions,
5501 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5502 StringRef Name) {
5503 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5504 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5505 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5506 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5507 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5508 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5509 BodyStmts.push_back(NewDeclStmt);
5510 return NewVar;
5511 }
5512
5513 /// Create a closure that computes the number of iterations of a loop.
5514 ///
5515 /// \param Actions The Sema object.
5516 /// \param LogicalTy Type for the logical iteration number.
5517 /// \param Rel Comparison operator of the loop condition.
5518 /// \param StartExpr Value of the loop counter at the first iteration.
5519 /// \param StopExpr Expression the loop counter is compared against in the loop
5520 /// condition. \param StepExpr Amount of increment after each iteration.
5521 ///
5522 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5523 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5524 BinaryOperator::Opcode Rel,
5525 Expr *StartExpr, Expr *StopExpr,
5526 Expr *StepExpr) {
5527 ASTContext &Ctx = Actions.getASTContext();
5528 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5529
5530 // Captured regions currently don't support return values, we use an
5531 // out-parameter instead. All inputs are implicit captures.
5532 // TODO: Instead of capturing each DeclRefExpr occurring in
5533 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5534 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5535 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5536 {StringRef(), QualType()}};
5537 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5538
5539 Stmt *Body;
5540 {
5541 Sema::CompoundScopeRAII CompoundScope(Actions);
5542 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5543
5544 // Get the LValue expression for the result.
5545 ImplicitParamDecl *DistParam = CS->getParam(0);
5546 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5547 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5548
5549 SmallVector<Stmt *, 4> BodyStmts;
5550
5551 // Capture all referenced variable references.
5552 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5553 // CapturedStmt, we could compute them before and capture the result, to be
5554 // used jointly with the LoopVar function.
5555 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5556 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5557 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5558 auto BuildVarRef = [&](VarDecl *VD) {
5559 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5560 };
5561
5562 IntegerLiteral *Zero = IntegerLiteral::Create(
5563 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5564 IntegerLiteral *One = IntegerLiteral::Create(
5565 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5566 Expr *Dist;
5567 if (Rel == BO_NE) {
5568 // When using a != comparison, the increment can be +1 or -1. This can be
5569 // dynamic at runtime, so we need to check for the direction.
5570 Expr *IsNegStep = AssertSuccess(
5571 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5572
5573 // Positive increment.
5574 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5575 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5576 ForwardRange = AssertSuccess(
5577 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5578 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5579 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5580
5581 // Negative increment.
5582 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5583 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5584 BackwardRange = AssertSuccess(
5585 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5586 Expr *NegIncAmount = AssertSuccess(
5587 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5588 Expr *BackwardDist = AssertSuccess(
5589 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5590
5591 // Use the appropriate case.
5592 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5593 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5594 } else {
5595 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5596 "Expected one of these relational operators");
5597
5598 // We can derive the direction from any other comparison operator. It is
5599 // non well-formed OpenMP if Step increments/decrements in the other
5600 // directions. Whether at least the first iteration passes the loop
5601 // condition.
5602 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5603 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5604
5605 // Compute the range between first and last counter value.
5606 Expr *Range;
5607 if (Rel == BO_GE || Rel == BO_GT)
5608 Range = AssertSuccess(Actions.BuildBinOp(
5609 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5610 else
5611 Range = AssertSuccess(Actions.BuildBinOp(
5612 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5613
5614 // Ensure unsigned range space.
5615 Range =
5616 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5617
5618 if (Rel == BO_LE || Rel == BO_GE) {
5619 // Add one to the range if the relational operator is inclusive.
5620 Range =
5621 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5622 }
5623
5624 // Divide by the absolute step amount. If the range is not a multiple of
5625 // the step size, rounding-up the effective upper bound ensures that the
5626 // last iteration is included.
5627 // Note that the rounding-up may cause an overflow in a temporry that
5628 // could be avoided, but would have occurred in a C-style for-loop as well.
5629 Expr *Divisor = BuildVarRef(NewStep);
5630 if (Rel == BO_GE || Rel == BO_GT)
5631 Divisor =
5632 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5633 Expr *DivisorMinusOne =
5634 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5635 Expr *RangeRoundUp = AssertSuccess(
5636 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5637 Dist = AssertSuccess(
5638 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5639
5640 // If there is not at least one iteration, the range contains garbage. Fix
5641 // to zero in this case.
5642 Dist = AssertSuccess(
5643 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5644 }
5645
5646 // Assign the result to the out-parameter.
5647 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5648 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5649 BodyStmts.push_back(ResultAssign);
5650
5651 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5652 }
5653
5654 return cast<CapturedStmt>(
5655 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5656 }
5657
5658 /// Create a closure that computes the loop variable from the logical iteration
5659 /// number.
5660 ///
5661 /// \param Actions The Sema object.
5662 /// \param LoopVarTy Type for the loop variable used for result value.
5663 /// \param LogicalTy Type for the logical iteration number.
5664 /// \param StartExpr Value of the loop counter at the first iteration.
5665 /// \param Step Amount of increment after each iteration.
5666 /// \param Deref Whether the loop variable is a dereference of the loop
5667 /// counter variable.
5668 ///
5669 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5670 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5671 QualType LogicalTy,
5672 DeclRefExpr *StartExpr, Expr *Step,
5673 bool Deref) {
5674 ASTContext &Ctx = Actions.getASTContext();
5675
5676 // Pass the result as an out-parameter. Passing as return value would require
5677 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5678 // invoke a copy constructor.
5679 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5680 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5681 {"Logical", LogicalTy},
5682 {StringRef(), QualType()}};
5683 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5684
5685 // Capture the initial iterator which represents the LoopVar value at the
5686 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5687 // it in every iteration, capture it by value before it is modified.
5688 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5689 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5690 Sema::TryCapture_ExplicitByVal, {});
5691 (void)Invalid;
5692 assert(!Invalid && "Expecting capture-by-value to work.");
5693
5694 Expr *Body;
5695 {
5696 Sema::CompoundScopeRAII CompoundScope(Actions);
5697 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5698
5699 ImplicitParamDecl *TargetParam = CS->getParam(0);
5700 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5701 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5702 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5703 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5704 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5705
5706 // Capture the Start expression.
5707 CaptureVars Recap(Actions);
5708 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5709 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5710
5711 Expr *Skip = AssertSuccess(
5712 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5713 // TODO: Explicitly cast to the iterator's difference_type instead of
5714 // relying on implicit conversion.
5715 Expr *Advanced =
5716 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5717
5718 if (Deref) {
5719 // For range-based for-loops convert the loop counter value to a concrete
5720 // loop variable value by dereferencing the iterator.
5721 Advanced =
5722 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5723 }
5724
5725 // Assign the result to the output parameter.
5726 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5727 BO_Assign, TargetRef, Advanced));
5728 }
5729 return cast<CapturedStmt>(
5730 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5731 }
5732
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5733 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5734 ASTContext &Ctx = getASTContext();
5735
5736 // Extract the common elements of ForStmt and CXXForRangeStmt:
5737 // Loop variable, repeat condition, increment
5738 Expr *Cond, *Inc;
5739 VarDecl *LIVDecl, *LUVDecl;
5740 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5741 Stmt *Init = For->getInit();
5742 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5743 // For statement declares loop variable.
5744 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5745 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5746 // For statement reuses variable.
5747 assert(LCAssign->getOpcode() == BO_Assign &&
5748 "init part must be a loop variable assignment");
5749 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5750 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5751 } else
5752 llvm_unreachable("Cannot determine loop variable");
5753 LUVDecl = LIVDecl;
5754
5755 Cond = For->getCond();
5756 Inc = For->getInc();
5757 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5758 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5759 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5760 LUVDecl = RangeFor->getLoopVariable();
5761
5762 Cond = RangeFor->getCond();
5763 Inc = RangeFor->getInc();
5764 } else
5765 llvm_unreachable("unhandled kind of loop");
5766
5767 QualType CounterTy = LIVDecl->getType();
5768 QualType LVTy = LUVDecl->getType();
5769
5770 // Analyze the loop condition.
5771 Expr *LHS, *RHS;
5772 BinaryOperator::Opcode CondRel;
5773 Cond = Cond->IgnoreImplicit();
5774 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5775 LHS = CondBinExpr->getLHS();
5776 RHS = CondBinExpr->getRHS();
5777 CondRel = CondBinExpr->getOpcode();
5778 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5779 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5780 LHS = CondCXXOp->getArg(0);
5781 RHS = CondCXXOp->getArg(1);
5782 switch (CondCXXOp->getOperator()) {
5783 case OO_ExclaimEqual:
5784 CondRel = BO_NE;
5785 break;
5786 case OO_Less:
5787 CondRel = BO_LT;
5788 break;
5789 case OO_LessEqual:
5790 CondRel = BO_LE;
5791 break;
5792 case OO_Greater:
5793 CondRel = BO_GT;
5794 break;
5795 case OO_GreaterEqual:
5796 CondRel = BO_GE;
5797 break;
5798 default:
5799 llvm_unreachable("unexpected iterator operator");
5800 }
5801 } else
5802 llvm_unreachable("unexpected loop condition");
5803
5804 // Normalize such that the loop counter is on the LHS.
5805 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5806 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5807 std::swap(LHS, RHS);
5808 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5809 }
5810 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5811
5812 // Decide the bit width for the logical iteration counter. By default use the
5813 // unsigned ptrdiff_t integer size (for iterators and pointers).
5814 // TODO: For iterators, use iterator::difference_type,
5815 // std::iterator_traits<>::difference_type or decltype(it - end).
5816 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5817 if (CounterTy->isIntegerType()) {
5818 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5819 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5820 }
5821
5822 // Analyze the loop increment.
5823 Expr *Step;
5824 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5825 int Direction;
5826 switch (IncUn->getOpcode()) {
5827 case UO_PreInc:
5828 case UO_PostInc:
5829 Direction = 1;
5830 break;
5831 case UO_PreDec:
5832 case UO_PostDec:
5833 Direction = -1;
5834 break;
5835 default:
5836 llvm_unreachable("unhandled unary increment operator");
5837 }
5838 Step = IntegerLiteral::Create(
5839 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5840 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5841 if (IncBin->getOpcode() == BO_AddAssign) {
5842 Step = IncBin->getRHS();
5843 } else if (IncBin->getOpcode() == BO_SubAssign) {
5844 Step =
5845 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5846 } else
5847 llvm_unreachable("unhandled binary increment operator");
5848 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5849 switch (CondCXXOp->getOperator()) {
5850 case OO_PlusPlus:
5851 Step = IntegerLiteral::Create(
5852 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5853 break;
5854 case OO_MinusMinus:
5855 Step = IntegerLiteral::Create(
5856 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5857 break;
5858 case OO_PlusEqual:
5859 Step = CondCXXOp->getArg(1);
5860 break;
5861 case OO_MinusEqual:
5862 Step = AssertSuccess(
5863 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5864 break;
5865 default:
5866 llvm_unreachable("unhandled overloaded increment operator");
5867 }
5868 } else
5869 llvm_unreachable("unknown increment expression");
5870
5871 CapturedStmt *DistanceFunc =
5872 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5873 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5874 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5875 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5876 {}, nullptr, nullptr, {}, nullptr);
5877 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5878 LoopVarFunc, LVRef);
5879 }
5880
ActOnOpenMPLoopnest(Stmt * AStmt)5881 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5882 // Handle a literal loop.
5883 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5884 return ActOnOpenMPCanonicalLoop(AStmt);
5885
5886 // If not a literal loop, it must be the result of a loop transformation.
5887 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5888 assert(
5889 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5890 "Loop transformation directive expected");
5891 return LoopTransform;
5892 }
5893
5894 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5895 CXXScopeSpec &MapperIdScopeSpec,
5896 const DeclarationNameInfo &MapperId,
5897 QualType Type,
5898 Expr *UnresolvedMapper);
5899
5900 /// Perform DFS through the structure/class data members trying to find
5901 /// member(s) with user-defined 'default' mapper and generate implicit map
5902 /// clauses for such members with the found 'default' mapper.
5903 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)5904 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5905 SmallVectorImpl<OMPClause *> &Clauses) {
5906 // Check for the deault mapper for data members.
5907 if (S.getLangOpts().OpenMP < 50)
5908 return;
5909 SmallVector<OMPClause *, 4> ImplicitMaps;
5910 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5911 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5912 if (!C)
5913 continue;
5914 SmallVector<Expr *, 4> SubExprs;
5915 auto *MI = C->mapperlist_begin();
5916 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5917 ++I, ++MI) {
5918 // Expression is mapped using mapper - skip it.
5919 if (*MI)
5920 continue;
5921 Expr *E = *I;
5922 // Expression is dependent - skip it, build the mapper when it gets
5923 // instantiated.
5924 if (E->isTypeDependent() || E->isValueDependent() ||
5925 E->containsUnexpandedParameterPack())
5926 continue;
5927 // Array section - need to check for the mapping of the array section
5928 // element.
5929 QualType CanonType = E->getType().getCanonicalType();
5930 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5931 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5932 QualType BaseType =
5933 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5934 QualType ElemType;
5935 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5936 ElemType = ATy->getElementType();
5937 else
5938 ElemType = BaseType->getPointeeType();
5939 CanonType = ElemType;
5940 }
5941
5942 // DFS over data members in structures/classes.
5943 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5944 1, {CanonType, nullptr});
5945 llvm::DenseMap<const Type *, Expr *> Visited;
5946 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5947 1, {nullptr, 1});
5948 while (!Types.empty()) {
5949 QualType BaseType;
5950 FieldDecl *CurFD;
5951 std::tie(BaseType, CurFD) = Types.pop_back_val();
5952 while (ParentChain.back().second == 0)
5953 ParentChain.pop_back();
5954 --ParentChain.back().second;
5955 if (BaseType.isNull())
5956 continue;
5957 // Only structs/classes are allowed to have mappers.
5958 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5959 if (!RD)
5960 continue;
5961 auto It = Visited.find(BaseType.getTypePtr());
5962 if (It == Visited.end()) {
5963 // Try to find the associated user-defined mapper.
5964 CXXScopeSpec MapperIdScopeSpec;
5965 DeclarationNameInfo DefaultMapperId;
5966 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5967 &S.Context.Idents.get("default")));
5968 DefaultMapperId.setLoc(E->getExprLoc());
5969 ExprResult ER = buildUserDefinedMapperRef(
5970 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5971 BaseType, /*UnresolvedMapper=*/nullptr);
5972 if (ER.isInvalid())
5973 continue;
5974 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5975 }
5976 // Found default mapper.
5977 if (It->second) {
5978 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5979 VK_LValue, OK_Ordinary, E);
5980 OE->setIsUnique(/*V=*/true);
5981 Expr *BaseExpr = OE;
5982 for (const auto &P : ParentChain) {
5983 if (P.first) {
5984 BaseExpr = S.BuildMemberExpr(
5985 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5986 NestedNameSpecifierLoc(), SourceLocation(), P.first,
5987 DeclAccessPair::make(P.first, P.first->getAccess()),
5988 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5989 P.first->getType(), VK_LValue, OK_Ordinary);
5990 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5991 }
5992 }
5993 if (CurFD)
5994 BaseExpr = S.BuildMemberExpr(
5995 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5996 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5997 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5998 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5999 CurFD->getType(), VK_LValue, OK_Ordinary);
6000 SubExprs.push_back(BaseExpr);
6001 continue;
6002 }
6003 // Check for the "default" mapper for data members.
6004 bool FirstIter = true;
6005 for (FieldDecl *FD : RD->fields()) {
6006 if (!FD)
6007 continue;
6008 QualType FieldTy = FD->getType();
6009 if (FieldTy.isNull() ||
6010 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6011 continue;
6012 if (FirstIter) {
6013 FirstIter = false;
6014 ParentChain.emplace_back(CurFD, 1);
6015 } else {
6016 ++ParentChain.back().second;
6017 }
6018 Types.emplace_back(FieldTy, FD);
6019 }
6020 }
6021 }
6022 if (SubExprs.empty())
6023 continue;
6024 CXXScopeSpec MapperIdScopeSpec;
6025 DeclarationNameInfo MapperId;
6026 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6027 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6028 MapperIdScopeSpec, MapperId, C->getMapType(),
6029 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6030 SubExprs, OMPVarListLocTy()))
6031 Clauses.push_back(NewClause);
6032 }
6033 }
6034
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6035 StmtResult Sema::ActOnOpenMPExecutableDirective(
6036 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6037 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6038 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
6039 StmtResult Res = StmtError();
6040 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6041 if (const OMPBindClause *BC =
6042 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6043 BindKind = BC->getBindKind();
6044 // First check CancelRegion which is then used in checkNestingOfRegions.
6045 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6046 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6047 BindKind, StartLoc))
6048 return StmtError();
6049
6050 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6051 VarsWithInheritedDSAType VarsWithInheritedDSA;
6052 bool ErrorFound = false;
6053 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6054 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6055 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6056 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6057 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6058
6059 // Check default data sharing attributes for referenced variables.
6060 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6061 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6062 Stmt *S = AStmt;
6063 while (--ThisCaptureLevel >= 0)
6064 S = cast<CapturedStmt>(S)->getCapturedStmt();
6065 DSAChecker.Visit(S);
6066 if (!isOpenMPTargetDataManagementDirective(Kind) &&
6067 !isOpenMPTaskingDirective(Kind)) {
6068 // Visit subcaptures to generate implicit clauses for captured vars.
6069 auto *CS = cast<CapturedStmt>(AStmt);
6070 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6071 getOpenMPCaptureRegions(CaptureRegions, Kind);
6072 // Ignore outer tasking regions for target directives.
6073 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6074 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6075 DSAChecker.visitSubCaptures(CS);
6076 }
6077 if (DSAChecker.isErrorFound())
6078 return StmtError();
6079 // Generate list of implicitly defined firstprivate variables.
6080 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6081
6082 SmallVector<Expr *, 4> ImplicitFirstprivates(
6083 DSAChecker.getImplicitFirstprivate().begin(),
6084 DSAChecker.getImplicitFirstprivate().end());
6085 SmallVector<Expr *, 4> ImplicitPrivates(
6086 DSAChecker.getImplicitPrivate().begin(),
6087 DSAChecker.getImplicitPrivate().end());
6088 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6089 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6090 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6091 ImplicitMapModifiers[DefaultmapKindNum];
6092 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6093 ImplicitMapModifiersLoc[DefaultmapKindNum];
6094 // Get the original location of present modifier from Defaultmap clause.
6095 SourceLocation PresentModifierLocs[DefaultmapKindNum];
6096 for (OMPClause *C : Clauses) {
6097 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6098 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6099 PresentModifierLocs[DMC->getDefaultmapKind()] =
6100 DMC->getDefaultmapModifierLoc();
6101 }
6102 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6103 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6104 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6105 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6106 Kind, static_cast<OpenMPMapClauseKind>(I));
6107 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6108 }
6109 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6110 DSAChecker.getImplicitMapModifier(Kind);
6111 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6112 ImplicitModifier.end());
6113 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6114 ImplicitModifier.size(), PresentModifierLocs[VC]);
6115 }
6116 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6117 for (OMPClause *C : Clauses) {
6118 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6119 for (Expr *E : IRC->taskgroup_descriptors())
6120 if (E)
6121 ImplicitFirstprivates.emplace_back(E);
6122 }
6123 // OpenMP 5.0, 2.10.1 task Construct
6124 // [detach clause]... The event-handle will be considered as if it was
6125 // specified on a firstprivate clause.
6126 if (auto *DC = dyn_cast<OMPDetachClause>(C))
6127 ImplicitFirstprivates.push_back(DC->getEventHandler());
6128 }
6129 if (!ImplicitFirstprivates.empty()) {
6130 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6131 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6132 SourceLocation())) {
6133 ClausesWithImplicit.push_back(Implicit);
6134 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6135 ImplicitFirstprivates.size();
6136 } else {
6137 ErrorFound = true;
6138 }
6139 }
6140 if (!ImplicitPrivates.empty()) {
6141 if (OMPClause *Implicit =
6142 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6143 SourceLocation(), SourceLocation())) {
6144 ClausesWithImplicit.push_back(Implicit);
6145 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6146 ImplicitPrivates.size();
6147 } else {
6148 ErrorFound = true;
6149 }
6150 }
6151 // OpenMP 5.0 [2.19.7]
6152 // If a list item appears in a reduction, lastprivate or linear
6153 // clause on a combined target construct then it is treated as
6154 // if it also appears in a map clause with a map-type of tofrom
6155 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6156 isOpenMPTargetExecutionDirective(Kind)) {
6157 SmallVector<Expr *, 4> ImplicitExprs;
6158 for (OMPClause *C : Clauses) {
6159 if (auto *RC = dyn_cast<OMPReductionClause>(C))
6160 for (Expr *E : RC->varlists())
6161 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6162 ImplicitExprs.emplace_back(E);
6163 }
6164 if (!ImplicitExprs.empty()) {
6165 ArrayRef<Expr *> Exprs = ImplicitExprs;
6166 CXXScopeSpec MapperIdScopeSpec;
6167 DeclarationNameInfo MapperId;
6168 if (OMPClause *Implicit = ActOnOpenMPMapClause(
6169 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
6170 MapperId, OMPC_MAP_tofrom,
6171 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6172 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6173 ClausesWithImplicit.emplace_back(Implicit);
6174 }
6175 }
6176 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6177 int ClauseKindCnt = -1;
6178 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6179 ++ClauseKindCnt;
6180 if (ImplicitMap.empty())
6181 continue;
6182 CXXScopeSpec MapperIdScopeSpec;
6183 DeclarationNameInfo MapperId;
6184 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6185 if (OMPClause *Implicit = ActOnOpenMPMapClause(
6186 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6187 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6188 SourceLocation(), SourceLocation(), ImplicitMap,
6189 OMPVarListLocTy())) {
6190 ClausesWithImplicit.emplace_back(Implicit);
6191 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6192 ImplicitMap.size();
6193 } else {
6194 ErrorFound = true;
6195 }
6196 }
6197 }
6198 // Build expressions for implicit maps of data members with 'default'
6199 // mappers.
6200 if (LangOpts.OpenMP >= 50)
6201 processImplicitMapsWithDefaultMappers(*this, DSAStack,
6202 ClausesWithImplicit);
6203 }
6204
6205 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6206 switch (Kind) {
6207 case OMPD_parallel:
6208 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6209 EndLoc);
6210 AllowedNameModifiers.push_back(OMPD_parallel);
6211 break;
6212 case OMPD_simd:
6213 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6214 VarsWithInheritedDSA);
6215 if (LangOpts.OpenMP >= 50)
6216 AllowedNameModifiers.push_back(OMPD_simd);
6217 break;
6218 case OMPD_tile:
6219 Res =
6220 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6221 break;
6222 case OMPD_unroll:
6223 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6224 EndLoc);
6225 break;
6226 case OMPD_for:
6227 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6228 VarsWithInheritedDSA);
6229 break;
6230 case OMPD_for_simd:
6231 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6232 EndLoc, VarsWithInheritedDSA);
6233 if (LangOpts.OpenMP >= 50)
6234 AllowedNameModifiers.push_back(OMPD_simd);
6235 break;
6236 case OMPD_sections:
6237 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6238 EndLoc);
6239 break;
6240 case OMPD_section:
6241 assert(ClausesWithImplicit.empty() &&
6242 "No clauses are allowed for 'omp section' directive");
6243 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6244 break;
6245 case OMPD_single:
6246 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6247 EndLoc);
6248 break;
6249 case OMPD_master:
6250 assert(ClausesWithImplicit.empty() &&
6251 "No clauses are allowed for 'omp master' directive");
6252 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6253 break;
6254 case OMPD_masked:
6255 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6256 EndLoc);
6257 break;
6258 case OMPD_critical:
6259 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6260 StartLoc, EndLoc);
6261 break;
6262 case OMPD_parallel_for:
6263 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6264 EndLoc, VarsWithInheritedDSA);
6265 AllowedNameModifiers.push_back(OMPD_parallel);
6266 break;
6267 case OMPD_parallel_for_simd:
6268 Res = ActOnOpenMPParallelForSimdDirective(
6269 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6270 AllowedNameModifiers.push_back(OMPD_parallel);
6271 if (LangOpts.OpenMP >= 50)
6272 AllowedNameModifiers.push_back(OMPD_simd);
6273 break;
6274 case OMPD_parallel_master:
6275 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6276 StartLoc, EndLoc);
6277 AllowedNameModifiers.push_back(OMPD_parallel);
6278 break;
6279 case OMPD_parallel_masked:
6280 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6281 StartLoc, EndLoc);
6282 AllowedNameModifiers.push_back(OMPD_parallel);
6283 break;
6284 case OMPD_parallel_sections:
6285 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6286 StartLoc, EndLoc);
6287 AllowedNameModifiers.push_back(OMPD_parallel);
6288 break;
6289 case OMPD_task:
6290 Res =
6291 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6292 AllowedNameModifiers.push_back(OMPD_task);
6293 break;
6294 case OMPD_taskyield:
6295 assert(ClausesWithImplicit.empty() &&
6296 "No clauses are allowed for 'omp taskyield' directive");
6297 assert(AStmt == nullptr &&
6298 "No associated statement allowed for 'omp taskyield' directive");
6299 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6300 break;
6301 case OMPD_barrier:
6302 assert(ClausesWithImplicit.empty() &&
6303 "No clauses are allowed for 'omp barrier' directive");
6304 assert(AStmt == nullptr &&
6305 "No associated statement allowed for 'omp barrier' directive");
6306 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6307 break;
6308 case OMPD_taskwait:
6309 assert(AStmt == nullptr &&
6310 "No associated statement allowed for 'omp taskwait' directive");
6311 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6312 break;
6313 case OMPD_taskgroup:
6314 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6315 EndLoc);
6316 break;
6317 case OMPD_flush:
6318 assert(AStmt == nullptr &&
6319 "No associated statement allowed for 'omp flush' directive");
6320 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6321 break;
6322 case OMPD_depobj:
6323 assert(AStmt == nullptr &&
6324 "No associated statement allowed for 'omp depobj' directive");
6325 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6326 break;
6327 case OMPD_scan:
6328 assert(AStmt == nullptr &&
6329 "No associated statement allowed for 'omp scan' directive");
6330 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6331 break;
6332 case OMPD_ordered:
6333 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6334 EndLoc);
6335 break;
6336 case OMPD_atomic:
6337 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6338 EndLoc);
6339 break;
6340 case OMPD_teams:
6341 Res =
6342 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6343 break;
6344 case OMPD_target:
6345 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6346 EndLoc);
6347 AllowedNameModifiers.push_back(OMPD_target);
6348 break;
6349 case OMPD_target_parallel:
6350 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6351 StartLoc, EndLoc);
6352 AllowedNameModifiers.push_back(OMPD_target);
6353 AllowedNameModifiers.push_back(OMPD_parallel);
6354 break;
6355 case OMPD_target_parallel_for:
6356 Res = ActOnOpenMPTargetParallelForDirective(
6357 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6358 AllowedNameModifiers.push_back(OMPD_target);
6359 AllowedNameModifiers.push_back(OMPD_parallel);
6360 break;
6361 case OMPD_cancellation_point:
6362 assert(ClausesWithImplicit.empty() &&
6363 "No clauses are allowed for 'omp cancellation point' directive");
6364 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6365 "cancellation point' directive");
6366 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6367 break;
6368 case OMPD_cancel:
6369 assert(AStmt == nullptr &&
6370 "No associated statement allowed for 'omp cancel' directive");
6371 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6372 CancelRegion);
6373 AllowedNameModifiers.push_back(OMPD_cancel);
6374 break;
6375 case OMPD_target_data:
6376 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6377 EndLoc);
6378 AllowedNameModifiers.push_back(OMPD_target_data);
6379 break;
6380 case OMPD_target_enter_data:
6381 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6382 EndLoc, AStmt);
6383 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6384 break;
6385 case OMPD_target_exit_data:
6386 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6387 EndLoc, AStmt);
6388 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6389 break;
6390 case OMPD_taskloop:
6391 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6392 EndLoc, VarsWithInheritedDSA);
6393 AllowedNameModifiers.push_back(OMPD_taskloop);
6394 break;
6395 case OMPD_taskloop_simd:
6396 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6397 EndLoc, VarsWithInheritedDSA);
6398 AllowedNameModifiers.push_back(OMPD_taskloop);
6399 if (LangOpts.OpenMP >= 50)
6400 AllowedNameModifiers.push_back(OMPD_simd);
6401 break;
6402 case OMPD_master_taskloop:
6403 Res = ActOnOpenMPMasterTaskLoopDirective(
6404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6405 AllowedNameModifiers.push_back(OMPD_taskloop);
6406 break;
6407 case OMPD_masked_taskloop:
6408 Res = ActOnOpenMPMaskedTaskLoopDirective(
6409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6410 AllowedNameModifiers.push_back(OMPD_taskloop);
6411 break;
6412 case OMPD_master_taskloop_simd:
6413 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6414 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6415 AllowedNameModifiers.push_back(OMPD_taskloop);
6416 if (LangOpts.OpenMP >= 50)
6417 AllowedNameModifiers.push_back(OMPD_simd);
6418 break;
6419 case OMPD_masked_taskloop_simd:
6420 Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6421 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6422 if (LangOpts.OpenMP >= 51) {
6423 AllowedNameModifiers.push_back(OMPD_taskloop);
6424 AllowedNameModifiers.push_back(OMPD_simd);
6425 }
6426 break;
6427 case OMPD_parallel_master_taskloop:
6428 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6429 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6430 AllowedNameModifiers.push_back(OMPD_taskloop);
6431 AllowedNameModifiers.push_back(OMPD_parallel);
6432 break;
6433 case OMPD_parallel_masked_taskloop:
6434 Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6435 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6436 if (LangOpts.OpenMP >= 51) {
6437 AllowedNameModifiers.push_back(OMPD_taskloop);
6438 AllowedNameModifiers.push_back(OMPD_parallel);
6439 }
6440 break;
6441 case OMPD_parallel_master_taskloop_simd:
6442 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6443 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6444 AllowedNameModifiers.push_back(OMPD_taskloop);
6445 AllowedNameModifiers.push_back(OMPD_parallel);
6446 if (LangOpts.OpenMP >= 50)
6447 AllowedNameModifiers.push_back(OMPD_simd);
6448 break;
6449 case OMPD_parallel_masked_taskloop_simd:
6450 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6451 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6452 if (LangOpts.OpenMP >= 51) {
6453 AllowedNameModifiers.push_back(OMPD_taskloop);
6454 AllowedNameModifiers.push_back(OMPD_parallel);
6455 AllowedNameModifiers.push_back(OMPD_simd);
6456 }
6457 break;
6458 case OMPD_distribute:
6459 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6460 EndLoc, VarsWithInheritedDSA);
6461 break;
6462 case OMPD_target_update:
6463 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6464 EndLoc, AStmt);
6465 AllowedNameModifiers.push_back(OMPD_target_update);
6466 break;
6467 case OMPD_distribute_parallel_for:
6468 Res = ActOnOpenMPDistributeParallelForDirective(
6469 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6470 AllowedNameModifiers.push_back(OMPD_parallel);
6471 break;
6472 case OMPD_distribute_parallel_for_simd:
6473 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6474 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6475 AllowedNameModifiers.push_back(OMPD_parallel);
6476 if (LangOpts.OpenMP >= 50)
6477 AllowedNameModifiers.push_back(OMPD_simd);
6478 break;
6479 case OMPD_distribute_simd:
6480 Res = ActOnOpenMPDistributeSimdDirective(
6481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6482 if (LangOpts.OpenMP >= 50)
6483 AllowedNameModifiers.push_back(OMPD_simd);
6484 break;
6485 case OMPD_target_parallel_for_simd:
6486 Res = ActOnOpenMPTargetParallelForSimdDirective(
6487 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6488 AllowedNameModifiers.push_back(OMPD_target);
6489 AllowedNameModifiers.push_back(OMPD_parallel);
6490 if (LangOpts.OpenMP >= 50)
6491 AllowedNameModifiers.push_back(OMPD_simd);
6492 break;
6493 case OMPD_target_simd:
6494 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6495 EndLoc, VarsWithInheritedDSA);
6496 AllowedNameModifiers.push_back(OMPD_target);
6497 if (LangOpts.OpenMP >= 50)
6498 AllowedNameModifiers.push_back(OMPD_simd);
6499 break;
6500 case OMPD_teams_distribute:
6501 Res = ActOnOpenMPTeamsDistributeDirective(
6502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6503 break;
6504 case OMPD_teams_distribute_simd:
6505 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6506 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6507 if (LangOpts.OpenMP >= 50)
6508 AllowedNameModifiers.push_back(OMPD_simd);
6509 break;
6510 case OMPD_teams_distribute_parallel_for_simd:
6511 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6512 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6513 AllowedNameModifiers.push_back(OMPD_parallel);
6514 if (LangOpts.OpenMP >= 50)
6515 AllowedNameModifiers.push_back(OMPD_simd);
6516 break;
6517 case OMPD_teams_distribute_parallel_for:
6518 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6519 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6520 AllowedNameModifiers.push_back(OMPD_parallel);
6521 break;
6522 case OMPD_target_teams:
6523 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6524 EndLoc);
6525 AllowedNameModifiers.push_back(OMPD_target);
6526 break;
6527 case OMPD_target_teams_distribute:
6528 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6529 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6530 AllowedNameModifiers.push_back(OMPD_target);
6531 break;
6532 case OMPD_target_teams_distribute_parallel_for:
6533 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6535 AllowedNameModifiers.push_back(OMPD_target);
6536 AllowedNameModifiers.push_back(OMPD_parallel);
6537 break;
6538 case OMPD_target_teams_distribute_parallel_for_simd:
6539 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6540 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6541 AllowedNameModifiers.push_back(OMPD_target);
6542 AllowedNameModifiers.push_back(OMPD_parallel);
6543 if (LangOpts.OpenMP >= 50)
6544 AllowedNameModifiers.push_back(OMPD_simd);
6545 break;
6546 case OMPD_target_teams_distribute_simd:
6547 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6548 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6549 AllowedNameModifiers.push_back(OMPD_target);
6550 if (LangOpts.OpenMP >= 50)
6551 AllowedNameModifiers.push_back(OMPD_simd);
6552 break;
6553 case OMPD_interop:
6554 assert(AStmt == nullptr &&
6555 "No associated statement allowed for 'omp interop' directive");
6556 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6557 break;
6558 case OMPD_dispatch:
6559 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6560 EndLoc);
6561 break;
6562 case OMPD_loop:
6563 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6564 EndLoc, VarsWithInheritedDSA);
6565 break;
6566 case OMPD_teams_loop:
6567 Res = ActOnOpenMPTeamsGenericLoopDirective(
6568 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6569 break;
6570 case OMPD_target_teams_loop:
6571 Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6572 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6573 break;
6574 case OMPD_parallel_loop:
6575 Res = ActOnOpenMPParallelGenericLoopDirective(
6576 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6577 break;
6578 case OMPD_target_parallel_loop:
6579 Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6580 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6581 break;
6582 case OMPD_declare_target:
6583 case OMPD_end_declare_target:
6584 case OMPD_threadprivate:
6585 case OMPD_allocate:
6586 case OMPD_declare_reduction:
6587 case OMPD_declare_mapper:
6588 case OMPD_declare_simd:
6589 case OMPD_requires:
6590 case OMPD_declare_variant:
6591 case OMPD_begin_declare_variant:
6592 case OMPD_end_declare_variant:
6593 llvm_unreachable("OpenMP Directive is not allowed");
6594 case OMPD_unknown:
6595 default:
6596 llvm_unreachable("Unknown OpenMP directive");
6597 }
6598
6599 ErrorFound = Res.isInvalid() || ErrorFound;
6600
6601 // Check variables in the clauses if default(none) or
6602 // default(firstprivate) was specified.
6603 if (DSAStack->getDefaultDSA() == DSA_none ||
6604 DSAStack->getDefaultDSA() == DSA_private ||
6605 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6606 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6607 for (OMPClause *C : Clauses) {
6608 switch (C->getClauseKind()) {
6609 case OMPC_num_threads:
6610 case OMPC_dist_schedule:
6611 // Do not analyse if no parent teams directive.
6612 if (isOpenMPTeamsDirective(Kind))
6613 break;
6614 continue;
6615 case OMPC_if:
6616 if (isOpenMPTeamsDirective(Kind) &&
6617 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6618 break;
6619 if (isOpenMPParallelDirective(Kind) &&
6620 isOpenMPTaskLoopDirective(Kind) &&
6621 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6622 break;
6623 continue;
6624 case OMPC_schedule:
6625 case OMPC_detach:
6626 break;
6627 case OMPC_grainsize:
6628 case OMPC_num_tasks:
6629 case OMPC_final:
6630 case OMPC_priority:
6631 case OMPC_novariants:
6632 case OMPC_nocontext:
6633 // Do not analyze if no parent parallel directive.
6634 if (isOpenMPParallelDirective(Kind))
6635 break;
6636 continue;
6637 case OMPC_ordered:
6638 case OMPC_device:
6639 case OMPC_num_teams:
6640 case OMPC_thread_limit:
6641 case OMPC_hint:
6642 case OMPC_collapse:
6643 case OMPC_safelen:
6644 case OMPC_simdlen:
6645 case OMPC_sizes:
6646 case OMPC_default:
6647 case OMPC_proc_bind:
6648 case OMPC_private:
6649 case OMPC_firstprivate:
6650 case OMPC_lastprivate:
6651 case OMPC_shared:
6652 case OMPC_reduction:
6653 case OMPC_task_reduction:
6654 case OMPC_in_reduction:
6655 case OMPC_linear:
6656 case OMPC_aligned:
6657 case OMPC_copyin:
6658 case OMPC_copyprivate:
6659 case OMPC_nowait:
6660 case OMPC_untied:
6661 case OMPC_mergeable:
6662 case OMPC_allocate:
6663 case OMPC_read:
6664 case OMPC_write:
6665 case OMPC_update:
6666 case OMPC_capture:
6667 case OMPC_compare:
6668 case OMPC_seq_cst:
6669 case OMPC_acq_rel:
6670 case OMPC_acquire:
6671 case OMPC_release:
6672 case OMPC_relaxed:
6673 case OMPC_depend:
6674 case OMPC_threads:
6675 case OMPC_simd:
6676 case OMPC_map:
6677 case OMPC_nogroup:
6678 case OMPC_defaultmap:
6679 case OMPC_to:
6680 case OMPC_from:
6681 case OMPC_use_device_ptr:
6682 case OMPC_use_device_addr:
6683 case OMPC_is_device_ptr:
6684 case OMPC_has_device_addr:
6685 case OMPC_nontemporal:
6686 case OMPC_order:
6687 case OMPC_destroy:
6688 case OMPC_inclusive:
6689 case OMPC_exclusive:
6690 case OMPC_uses_allocators:
6691 case OMPC_affinity:
6692 case OMPC_bind:
6693 case OMPC_filter:
6694 continue;
6695 case OMPC_allocator:
6696 case OMPC_flush:
6697 case OMPC_depobj:
6698 case OMPC_threadprivate:
6699 case OMPC_uniform:
6700 case OMPC_unknown:
6701 case OMPC_unified_address:
6702 case OMPC_unified_shared_memory:
6703 case OMPC_reverse_offload:
6704 case OMPC_dynamic_allocators:
6705 case OMPC_atomic_default_mem_order:
6706 case OMPC_device_type:
6707 case OMPC_match:
6708 case OMPC_when:
6709 default:
6710 llvm_unreachable("Unexpected clause");
6711 }
6712 for (Stmt *CC : C->children()) {
6713 if (CC)
6714 DSAChecker.Visit(CC);
6715 }
6716 }
6717 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6718 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6719 }
6720 for (const auto &P : VarsWithInheritedDSA) {
6721 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6722 continue;
6723 ErrorFound = true;
6724 if (DSAStack->getDefaultDSA() == DSA_none ||
6725 DSAStack->getDefaultDSA() == DSA_private ||
6726 DSAStack->getDefaultDSA() == DSA_firstprivate) {
6727 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6728 << P.first << P.second->getSourceRange();
6729 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6730 } else if (getLangOpts().OpenMP >= 50) {
6731 Diag(P.second->getExprLoc(),
6732 diag::err_omp_defaultmap_no_attr_for_variable)
6733 << P.first << P.second->getSourceRange();
6734 Diag(DSAStack->getDefaultDSALocation(),
6735 diag::note_omp_defaultmap_attr_none);
6736 }
6737 }
6738
6739 if (!AllowedNameModifiers.empty())
6740 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6741 ErrorFound;
6742
6743 if (ErrorFound)
6744 return StmtError();
6745
6746 if (!CurContext->isDependentContext() &&
6747 isOpenMPTargetExecutionDirective(Kind) &&
6748 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6749 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6750 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6751 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6752 // Register target to DSA Stack.
6753 DSAStack->addTargetDirLocation(StartLoc);
6754 }
6755
6756 return Res;
6757 }
6758
ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,OMPDeclareSimdDeclAttr::BranchStateTy BS,Expr * Simdlen,ArrayRef<Expr * > Uniforms,ArrayRef<Expr * > Aligneds,ArrayRef<Expr * > Alignments,ArrayRef<Expr * > Linears,ArrayRef<unsigned> LinModifiers,ArrayRef<Expr * > Steps,SourceRange SR)6759 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6760 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6761 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6762 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6763 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6764 assert(Aligneds.size() == Alignments.size());
6765 assert(Linears.size() == LinModifiers.size());
6766 assert(Linears.size() == Steps.size());
6767 if (!DG || DG.get().isNull())
6768 return DeclGroupPtrTy();
6769
6770 const int SimdId = 0;
6771 if (!DG.get().isSingleDecl()) {
6772 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6773 << SimdId;
6774 return DG;
6775 }
6776 Decl *ADecl = DG.get().getSingleDecl();
6777 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6778 ADecl = FTD->getTemplatedDecl();
6779
6780 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6781 if (!FD) {
6782 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6783 return DeclGroupPtrTy();
6784 }
6785
6786 // OpenMP [2.8.2, declare simd construct, Description]
6787 // The parameter of the simdlen clause must be a constant positive integer
6788 // expression.
6789 ExprResult SL;
6790 if (Simdlen)
6791 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6792 // OpenMP [2.8.2, declare simd construct, Description]
6793 // The special this pointer can be used as if was one of the arguments to the
6794 // function in any of the linear, aligned, or uniform clauses.
6795 // The uniform clause declares one or more arguments to have an invariant
6796 // value for all concurrent invocations of the function in the execution of a
6797 // single SIMD loop.
6798 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6799 const Expr *UniformedLinearThis = nullptr;
6800 for (const Expr *E : Uniforms) {
6801 E = E->IgnoreParenImpCasts();
6802 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6803 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6804 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6805 FD->getParamDecl(PVD->getFunctionScopeIndex())
6806 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6807 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6808 continue;
6809 }
6810 if (isa<CXXThisExpr>(E)) {
6811 UniformedLinearThis = E;
6812 continue;
6813 }
6814 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6815 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6816 }
6817 // OpenMP [2.8.2, declare simd construct, Description]
6818 // The aligned clause declares that the object to which each list item points
6819 // is aligned to the number of bytes expressed in the optional parameter of
6820 // the aligned clause.
6821 // The special this pointer can be used as if was one of the arguments to the
6822 // function in any of the linear, aligned, or uniform clauses.
6823 // The type of list items appearing in the aligned clause must be array,
6824 // pointer, reference to array, or reference to pointer.
6825 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6826 const Expr *AlignedThis = nullptr;
6827 for (const Expr *E : Aligneds) {
6828 E = E->IgnoreParenImpCasts();
6829 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6830 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6831 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6832 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6833 FD->getParamDecl(PVD->getFunctionScopeIndex())
6834 ->getCanonicalDecl() == CanonPVD) {
6835 // OpenMP [2.8.1, simd construct, Restrictions]
6836 // A list-item cannot appear in more than one aligned clause.
6837 if (AlignedArgs.count(CanonPVD) > 0) {
6838 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6839 << 1 << getOpenMPClauseName(OMPC_aligned)
6840 << E->getSourceRange();
6841 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6842 diag::note_omp_explicit_dsa)
6843 << getOpenMPClauseName(OMPC_aligned);
6844 continue;
6845 }
6846 AlignedArgs[CanonPVD] = E;
6847 QualType QTy = PVD->getType()
6848 .getNonReferenceType()
6849 .getUnqualifiedType()
6850 .getCanonicalType();
6851 const Type *Ty = QTy.getTypePtrOrNull();
6852 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6853 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6854 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6855 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6856 }
6857 continue;
6858 }
6859 }
6860 if (isa<CXXThisExpr>(E)) {
6861 if (AlignedThis) {
6862 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6863 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6864 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6865 << getOpenMPClauseName(OMPC_aligned);
6866 }
6867 AlignedThis = E;
6868 continue;
6869 }
6870 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6871 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6872 }
6873 // The optional parameter of the aligned clause, alignment, must be a constant
6874 // positive integer expression. If no optional parameter is specified,
6875 // implementation-defined default alignments for SIMD instructions on the
6876 // target platforms are assumed.
6877 SmallVector<const Expr *, 4> NewAligns;
6878 for (Expr *E : Alignments) {
6879 ExprResult Align;
6880 if (E)
6881 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6882 NewAligns.push_back(Align.get());
6883 }
6884 // OpenMP [2.8.2, declare simd construct, Description]
6885 // The linear clause declares one or more list items to be private to a SIMD
6886 // lane and to have a linear relationship with respect to the iteration space
6887 // of a loop.
6888 // The special this pointer can be used as if was one of the arguments to the
6889 // function in any of the linear, aligned, or uniform clauses.
6890 // When a linear-step expression is specified in a linear clause it must be
6891 // either a constant integer expression or an integer-typed parameter that is
6892 // specified in a uniform clause on the directive.
6893 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6894 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6895 auto MI = LinModifiers.begin();
6896 for (const Expr *E : Linears) {
6897 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6898 ++MI;
6899 E = E->IgnoreParenImpCasts();
6900 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6901 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6902 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6903 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6904 FD->getParamDecl(PVD->getFunctionScopeIndex())
6905 ->getCanonicalDecl() == CanonPVD) {
6906 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6907 // A list-item cannot appear in more than one linear clause.
6908 if (LinearArgs.count(CanonPVD) > 0) {
6909 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6910 << getOpenMPClauseName(OMPC_linear)
6911 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6912 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6913 diag::note_omp_explicit_dsa)
6914 << getOpenMPClauseName(OMPC_linear);
6915 continue;
6916 }
6917 // Each argument can appear in at most one uniform or linear clause.
6918 if (UniformedArgs.count(CanonPVD) > 0) {
6919 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6920 << getOpenMPClauseName(OMPC_linear)
6921 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6922 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6923 diag::note_omp_explicit_dsa)
6924 << getOpenMPClauseName(OMPC_uniform);
6925 continue;
6926 }
6927 LinearArgs[CanonPVD] = E;
6928 if (E->isValueDependent() || E->isTypeDependent() ||
6929 E->isInstantiationDependent() ||
6930 E->containsUnexpandedParameterPack())
6931 continue;
6932 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6933 PVD->getOriginalType(),
6934 /*IsDeclareSimd=*/true);
6935 continue;
6936 }
6937 }
6938 if (isa<CXXThisExpr>(E)) {
6939 if (UniformedLinearThis) {
6940 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6941 << getOpenMPClauseName(OMPC_linear)
6942 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6943 << E->getSourceRange();
6944 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6945 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6946 : OMPC_linear);
6947 continue;
6948 }
6949 UniformedLinearThis = E;
6950 if (E->isValueDependent() || E->isTypeDependent() ||
6951 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6952 continue;
6953 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6954 E->getType(), /*IsDeclareSimd=*/true);
6955 continue;
6956 }
6957 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6958 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6959 }
6960 Expr *Step = nullptr;
6961 Expr *NewStep = nullptr;
6962 SmallVector<Expr *, 4> NewSteps;
6963 for (Expr *E : Steps) {
6964 // Skip the same step expression, it was checked already.
6965 if (Step == E || !E) {
6966 NewSteps.push_back(E ? NewStep : nullptr);
6967 continue;
6968 }
6969 Step = E;
6970 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6971 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6972 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6973 if (UniformedArgs.count(CanonPVD) == 0) {
6974 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6975 << Step->getSourceRange();
6976 } else if (E->isValueDependent() || E->isTypeDependent() ||
6977 E->isInstantiationDependent() ||
6978 E->containsUnexpandedParameterPack() ||
6979 CanonPVD->getType()->hasIntegerRepresentation()) {
6980 NewSteps.push_back(Step);
6981 } else {
6982 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6983 << Step->getSourceRange();
6984 }
6985 continue;
6986 }
6987 NewStep = Step;
6988 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6989 !Step->isInstantiationDependent() &&
6990 !Step->containsUnexpandedParameterPack()) {
6991 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6992 .get();
6993 if (NewStep)
6994 NewStep =
6995 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6996 }
6997 NewSteps.push_back(NewStep);
6998 }
6999 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7000 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7001 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7002 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7003 const_cast<Expr **>(Linears.data()), Linears.size(),
7004 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7005 NewSteps.data(), NewSteps.size(), SR);
7006 ADecl->addAttr(NewAttr);
7007 return DG;
7008 }
7009
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)7010 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7011 QualType NewType) {
7012 assert(NewType->isFunctionProtoType() &&
7013 "Expected function type with prototype.");
7014 assert(FD->getType()->isFunctionNoProtoType() &&
7015 "Expected function with type with no prototype.");
7016 assert(FDWithProto->getType()->isFunctionProtoType() &&
7017 "Expected function with prototype.");
7018 // Synthesize parameters with the same types.
7019 FD->setType(NewType);
7020 SmallVector<ParmVarDecl *, 16> Params;
7021 for (const ParmVarDecl *P : FDWithProto->parameters()) {
7022 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7023 SourceLocation(), nullptr, P->getType(),
7024 /*TInfo=*/nullptr, SC_None, nullptr);
7025 Param->setScopeInfo(0, Params.size());
7026 Param->setImplicit();
7027 Params.push_back(Param);
7028 }
7029
7030 FD->setParams(Params);
7031 }
7032
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)7033 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7034 if (D->isInvalidDecl())
7035 return;
7036 FunctionDecl *FD = nullptr;
7037 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7038 FD = UTemplDecl->getTemplatedDecl();
7039 else
7040 FD = cast<FunctionDecl>(D);
7041 assert(FD && "Expected a function declaration!");
7042
7043 // If we are instantiating templates we do *not* apply scoped assumptions but
7044 // only global ones. We apply scoped assumption to the template definition
7045 // though.
7046 if (!inTemplateInstantiation()) {
7047 for (AssumptionAttr *AA : OMPAssumeScoped)
7048 FD->addAttr(AA);
7049 }
7050 for (AssumptionAttr *AA : OMPAssumeGlobal)
7051 FD->addAttr(AA);
7052 }
7053
OMPDeclareVariantScope(OMPTraitInfo & TI)7054 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7055 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7056
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)7057 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7058 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7059 SmallVectorImpl<FunctionDecl *> &Bases) {
7060 if (!D.getIdentifier())
7061 return;
7062
7063 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7064
7065 // Template specialization is an extension, check if we do it.
7066 bool IsTemplated = !TemplateParamLists.empty();
7067 if (IsTemplated &
7068 !DVScope.TI->isExtensionActive(
7069 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7070 return;
7071
7072 IdentifierInfo *BaseII = D.getIdentifier();
7073 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7074 LookupOrdinaryName);
7075 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7076
7077 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7078 QualType FType = TInfo->getType();
7079
7080 bool IsConstexpr =
7081 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7082 bool IsConsteval =
7083 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7084
7085 for (auto *Candidate : Lookup) {
7086 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7087 FunctionDecl *UDecl = nullptr;
7088 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7089 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7090 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7091 UDecl = FTD->getTemplatedDecl();
7092 } else if (!IsTemplated)
7093 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7094 if (!UDecl)
7095 continue;
7096
7097 // Don't specialize constexpr/consteval functions with
7098 // non-constexpr/consteval functions.
7099 if (UDecl->isConstexpr() && !IsConstexpr)
7100 continue;
7101 if (UDecl->isConsteval() && !IsConsteval)
7102 continue;
7103
7104 QualType UDeclTy = UDecl->getType();
7105 if (!UDeclTy->isDependentType()) {
7106 QualType NewType = Context.mergeFunctionTypes(
7107 FType, UDeclTy, /* OfBlockPointer */ false,
7108 /* Unqualified */ false, /* AllowCXX */ true);
7109 if (NewType.isNull())
7110 continue;
7111 }
7112
7113 // Found a base!
7114 Bases.push_back(UDecl);
7115 }
7116
7117 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7118 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7119 // If no base was found we create a declaration that we use as base.
7120 if (Bases.empty() && UseImplicitBase) {
7121 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7122 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7123 BaseD->setImplicit(true);
7124 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7125 Bases.push_back(BaseTemplD->getTemplatedDecl());
7126 else
7127 Bases.push_back(cast<FunctionDecl>(BaseD));
7128 }
7129
7130 std::string MangledName;
7131 MangledName += D.getIdentifier()->getName();
7132 MangledName += getOpenMPVariantManglingSeparatorStr();
7133 MangledName += DVScope.NameSuffix;
7134 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7135
7136 VariantII.setMangledOpenMPVariantName(true);
7137 D.SetIdentifier(&VariantII, D.getBeginLoc());
7138 }
7139
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)7140 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7141 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7142 // Do not mark function as is used to prevent its emission if this is the
7143 // only place where it is used.
7144 EnterExpressionEvaluationContext Unevaluated(
7145 *this, Sema::ExpressionEvaluationContext::Unevaluated);
7146
7147 FunctionDecl *FD = nullptr;
7148 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7149 FD = UTemplDecl->getTemplatedDecl();
7150 else
7151 FD = cast<FunctionDecl>(D);
7152 auto *VariantFuncRef = DeclRefExpr::Create(
7153 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7154 /* RefersToEnclosingVariableOrCapture */ false,
7155 /* NameLoc */ FD->getLocation(), FD->getType(),
7156 ExprValueKind::VK_PRValue);
7157
7158 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7159 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7160 Context, VariantFuncRef, DVScope.TI,
7161 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7162 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7163 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7164 for (FunctionDecl *BaseFD : Bases)
7165 BaseFD->addAttr(OMPDeclareVariantA);
7166 }
7167
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)7168 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7169 SourceLocation LParenLoc,
7170 MultiExprArg ArgExprs,
7171 SourceLocation RParenLoc, Expr *ExecConfig) {
7172 // The common case is a regular call we do not want to specialize at all. Try
7173 // to make that case fast by bailing early.
7174 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7175 if (!CE)
7176 return Call;
7177
7178 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7179 if (!CalleeFnDecl)
7180 return Call;
7181
7182 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7183 return Call;
7184
7185 ASTContext &Context = getASTContext();
7186 std::function<void(StringRef)> DiagUnknownTrait = [this,
7187 CE](StringRef ISATrait) {
7188 // TODO Track the selector locations in a way that is accessible here to
7189 // improve the diagnostic location.
7190 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7191 << ISATrait;
7192 };
7193 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7194 getCurFunctionDecl(), DSAStack->getConstructTraits());
7195
7196 QualType CalleeFnType = CalleeFnDecl->getType();
7197
7198 SmallVector<Expr *, 4> Exprs;
7199 SmallVector<VariantMatchInfo, 4> VMIs;
7200 while (CalleeFnDecl) {
7201 for (OMPDeclareVariantAttr *A :
7202 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7203 Expr *VariantRef = A->getVariantFuncRef();
7204
7205 VariantMatchInfo VMI;
7206 OMPTraitInfo &TI = A->getTraitInfo();
7207 TI.getAsVariantMatchInfo(Context, VMI);
7208 if (!isVariantApplicableInContext(VMI, OMPCtx,
7209 /* DeviceSetOnly */ false))
7210 continue;
7211
7212 VMIs.push_back(VMI);
7213 Exprs.push_back(VariantRef);
7214 }
7215
7216 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7217 }
7218
7219 ExprResult NewCall;
7220 do {
7221 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7222 if (BestIdx < 0)
7223 return Call;
7224 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7225 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7226
7227 {
7228 // Try to build a (member) call expression for the current best applicable
7229 // variant expression. We allow this to fail in which case we continue
7230 // with the next best variant expression. The fail case is part of the
7231 // implementation defined behavior in the OpenMP standard when it talks
7232 // about what differences in the function prototypes: "Any differences
7233 // that the specific OpenMP context requires in the prototype of the
7234 // variant from the base function prototype are implementation defined."
7235 // This wording is there to allow the specialized variant to have a
7236 // different type than the base function. This is intended and OK but if
7237 // we cannot create a call the difference is not in the "implementation
7238 // defined range" we allow.
7239 Sema::TentativeAnalysisScope Trap(*this);
7240
7241 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7242 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7243 BestExpr = MemberExpr::CreateImplicit(
7244 Context, MemberCall->getImplicitObjectArgument(),
7245 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7246 MemberCall->getValueKind(), MemberCall->getObjectKind());
7247 }
7248 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7249 ExecConfig);
7250 if (NewCall.isUsable()) {
7251 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7252 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7253 QualType NewType = Context.mergeFunctionTypes(
7254 CalleeFnType, NewCalleeFnDecl->getType(),
7255 /* OfBlockPointer */ false,
7256 /* Unqualified */ false, /* AllowCXX */ true);
7257 if (!NewType.isNull())
7258 break;
7259 // Don't use the call if the function type was not compatible.
7260 NewCall = nullptr;
7261 }
7262 }
7263 }
7264
7265 VMIs.erase(VMIs.begin() + BestIdx);
7266 Exprs.erase(Exprs.begin() + BestIdx);
7267 } while (!VMIs.empty());
7268
7269 if (!NewCall.isUsable())
7270 return Call;
7271 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7272 }
7273
7274 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,unsigned NumAppendArgs,SourceRange SR)7275 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7276 Expr *VariantRef, OMPTraitInfo &TI,
7277 unsigned NumAppendArgs,
7278 SourceRange SR) {
7279 if (!DG || DG.get().isNull())
7280 return None;
7281
7282 const int VariantId = 1;
7283 // Must be applied only to single decl.
7284 if (!DG.get().isSingleDecl()) {
7285 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7286 << VariantId << SR;
7287 return None;
7288 }
7289 Decl *ADecl = DG.get().getSingleDecl();
7290 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7291 ADecl = FTD->getTemplatedDecl();
7292
7293 // Decl must be a function.
7294 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7295 if (!FD) {
7296 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7297 << VariantId << SR;
7298 return None;
7299 }
7300
7301 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7302 // The 'target' attribute needs to be separately checked because it does
7303 // not always signify a multiversion function declaration.
7304 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7305 };
7306 // OpenMP is not compatible with multiversion function attributes.
7307 if (HasMultiVersionAttributes(FD)) {
7308 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7309 << SR;
7310 return None;
7311 }
7312
7313 // Allow #pragma omp declare variant only if the function is not used.
7314 if (FD->isUsed(false))
7315 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7316 << FD->getLocation();
7317
7318 // Check if the function was emitted already.
7319 const FunctionDecl *Definition;
7320 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7321 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7322 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7323 << FD->getLocation();
7324
7325 // The VariantRef must point to function.
7326 if (!VariantRef) {
7327 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7328 return None;
7329 }
7330
7331 auto ShouldDelayChecks = [](Expr *&E, bool) {
7332 return E && (E->isTypeDependent() || E->isValueDependent() ||
7333 E->containsUnexpandedParameterPack() ||
7334 E->isInstantiationDependent());
7335 };
7336 // Do not check templates, wait until instantiation.
7337 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7338 TI.anyScoreOrCondition(ShouldDelayChecks))
7339 return std::make_pair(FD, VariantRef);
7340
7341 // Deal with non-constant score and user condition expressions.
7342 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7343 bool IsScore) -> bool {
7344 if (!E || E->isIntegerConstantExpr(Context))
7345 return false;
7346
7347 if (IsScore) {
7348 // We warn on non-constant scores and pretend they were not present.
7349 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7350 << E;
7351 E = nullptr;
7352 } else {
7353 // We could replace a non-constant user condition with "false" but we
7354 // will soon need to handle these anyway for the dynamic version of
7355 // OpenMP context selectors.
7356 Diag(E->getExprLoc(),
7357 diag::err_omp_declare_variant_user_condition_not_constant)
7358 << E;
7359 }
7360 return true;
7361 };
7362 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7363 return None;
7364
7365 QualType AdjustedFnType = FD->getType();
7366 if (NumAppendArgs) {
7367 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7368 if (!PTy) {
7369 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7370 << SR;
7371 return None;
7372 }
7373 // Adjust the function type to account for an extra omp_interop_t for each
7374 // specified in the append_args clause.
7375 const TypeDecl *TD = nullptr;
7376 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7377 SR.getBegin(), Sema::LookupOrdinaryName);
7378 if (LookupName(Result, getCurScope())) {
7379 NamedDecl *ND = Result.getFoundDecl();
7380 TD = dyn_cast_or_null<TypeDecl>(ND);
7381 }
7382 if (!TD) {
7383 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7384 return None;
7385 }
7386 QualType InteropType = Context.getTypeDeclType(TD);
7387 if (PTy->isVariadic()) {
7388 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7389 return None;
7390 }
7391 llvm::SmallVector<QualType, 8> Params;
7392 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7393 Params.insert(Params.end(), NumAppendArgs, InteropType);
7394 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7395 PTy->getExtProtoInfo());
7396 }
7397
7398 // Convert VariantRef expression to the type of the original function to
7399 // resolve possible conflicts.
7400 ExprResult VariantRefCast = VariantRef;
7401 if (LangOpts.CPlusPlus) {
7402 QualType FnPtrType;
7403 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7404 if (Method && !Method->isStatic()) {
7405 const Type *ClassType =
7406 Context.getTypeDeclType(Method->getParent()).getTypePtr();
7407 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7408 ExprResult ER;
7409 {
7410 // Build adrr_of unary op to correctly handle type checks for member
7411 // functions.
7412 Sema::TentativeAnalysisScope Trap(*this);
7413 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7414 VariantRef);
7415 }
7416 if (!ER.isUsable()) {
7417 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7418 << VariantId << VariantRef->getSourceRange();
7419 return None;
7420 }
7421 VariantRef = ER.get();
7422 } else {
7423 FnPtrType = Context.getPointerType(AdjustedFnType);
7424 }
7425 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7426 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7427 ImplicitConversionSequence ICS = TryImplicitConversion(
7428 VariantRef, FnPtrType.getUnqualifiedType(),
7429 /*SuppressUserConversions=*/false, AllowedExplicit::None,
7430 /*InOverloadResolution=*/false,
7431 /*CStyle=*/false,
7432 /*AllowObjCWritebackConversion=*/false);
7433 if (ICS.isFailure()) {
7434 Diag(VariantRef->getExprLoc(),
7435 diag::err_omp_declare_variant_incompat_types)
7436 << VariantRef->getType()
7437 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7438 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7439 return None;
7440 }
7441 VariantRefCast = PerformImplicitConversion(
7442 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7443 if (!VariantRefCast.isUsable())
7444 return None;
7445 }
7446 // Drop previously built artificial addr_of unary op for member functions.
7447 if (Method && !Method->isStatic()) {
7448 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7449 if (auto *UO = dyn_cast<UnaryOperator>(
7450 PossibleAddrOfVariantRef->IgnoreImplicit()))
7451 VariantRefCast = UO->getSubExpr();
7452 }
7453 }
7454
7455 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7456 if (!ER.isUsable() ||
7457 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7458 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7459 << VariantId << VariantRef->getSourceRange();
7460 return None;
7461 }
7462
7463 // The VariantRef must point to function.
7464 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7465 if (!DRE) {
7466 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7467 << VariantId << VariantRef->getSourceRange();
7468 return None;
7469 }
7470 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7471 if (!NewFD) {
7472 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7473 << VariantId << VariantRef->getSourceRange();
7474 return None;
7475 }
7476
7477 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7478 Diag(VariantRef->getExprLoc(),
7479 diag::err_omp_declare_variant_same_base_function)
7480 << VariantRef->getSourceRange();
7481 return None;
7482 }
7483
7484 // Check if function types are compatible in C.
7485 if (!LangOpts.CPlusPlus) {
7486 QualType NewType =
7487 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7488 if (NewType.isNull()) {
7489 Diag(VariantRef->getExprLoc(),
7490 diag::err_omp_declare_variant_incompat_types)
7491 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7492 << VariantRef->getSourceRange();
7493 return None;
7494 }
7495 if (NewType->isFunctionProtoType()) {
7496 if (FD->getType()->isFunctionNoProtoType())
7497 setPrototype(*this, FD, NewFD, NewType);
7498 else if (NewFD->getType()->isFunctionNoProtoType())
7499 setPrototype(*this, NewFD, FD, NewType);
7500 }
7501 }
7502
7503 // Check if variant function is not marked with declare variant directive.
7504 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7505 Diag(VariantRef->getExprLoc(),
7506 diag::warn_omp_declare_variant_marked_as_declare_variant)
7507 << VariantRef->getSourceRange();
7508 SourceRange SR =
7509 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7510 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7511 return None;
7512 }
7513
7514 enum DoesntSupport {
7515 VirtFuncs = 1,
7516 Constructors = 3,
7517 Destructors = 4,
7518 DeletedFuncs = 5,
7519 DefaultedFuncs = 6,
7520 ConstexprFuncs = 7,
7521 ConstevalFuncs = 8,
7522 };
7523 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7524 if (CXXFD->isVirtual()) {
7525 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7526 << VirtFuncs;
7527 return None;
7528 }
7529
7530 if (isa<CXXConstructorDecl>(FD)) {
7531 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7532 << Constructors;
7533 return None;
7534 }
7535
7536 if (isa<CXXDestructorDecl>(FD)) {
7537 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7538 << Destructors;
7539 return None;
7540 }
7541 }
7542
7543 if (FD->isDeleted()) {
7544 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7545 << DeletedFuncs;
7546 return None;
7547 }
7548
7549 if (FD->isDefaulted()) {
7550 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7551 << DefaultedFuncs;
7552 return None;
7553 }
7554
7555 if (FD->isConstexpr()) {
7556 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7557 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7558 return None;
7559 }
7560
7561 // Check general compatibility.
7562 if (areMultiversionVariantFunctionsCompatible(
7563 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7564 PartialDiagnosticAt(SourceLocation(),
7565 PartialDiagnostic::NullDiagnostic()),
7566 PartialDiagnosticAt(
7567 VariantRef->getExprLoc(),
7568 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7569 PartialDiagnosticAt(VariantRef->getExprLoc(),
7570 PDiag(diag::err_omp_declare_variant_diff)
7571 << FD->getLocation()),
7572 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7573 /*CLinkageMayDiffer=*/true))
7574 return None;
7575 return std::make_pair(FD, cast<Expr>(DRE));
7576 }
7577
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,ArrayRef<Expr * > AdjustArgsNothing,ArrayRef<Expr * > AdjustArgsNeedDevicePtr,ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,SourceLocation AdjustArgsLoc,SourceLocation AppendArgsLoc,SourceRange SR)7578 void Sema::ActOnOpenMPDeclareVariantDirective(
7579 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7580 ArrayRef<Expr *> AdjustArgsNothing,
7581 ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7582 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,
7583 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
7584 SourceRange SR) {
7585
7586 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7587 // An adjust_args clause or append_args clause can only be specified if the
7588 // dispatch selector of the construct selector set appears in the match
7589 // clause.
7590
7591 SmallVector<Expr *, 8> AllAdjustArgs;
7592 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7593 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7594
7595 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7596 VariantMatchInfo VMI;
7597 TI.getAsVariantMatchInfo(Context, VMI);
7598 if (!llvm::is_contained(
7599 VMI.ConstructTraits,
7600 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7601 if (!AllAdjustArgs.empty())
7602 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7603 << getOpenMPClauseName(OMPC_adjust_args);
7604 if (!AppendArgs.empty())
7605 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7606 << getOpenMPClauseName(OMPC_append_args);
7607 return;
7608 }
7609 }
7610
7611 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7612 // Each argument can only appear in a single adjust_args clause for each
7613 // declare variant directive.
7614 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7615
7616 for (Expr *E : AllAdjustArgs) {
7617 E = E->IgnoreParenImpCasts();
7618 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7619 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7620 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7621 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7622 FD->getParamDecl(PVD->getFunctionScopeIndex())
7623 ->getCanonicalDecl() == CanonPVD) {
7624 // It's a parameter of the function, check duplicates.
7625 if (!AdjustVars.insert(CanonPVD).second) {
7626 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7627 << PVD;
7628 return;
7629 }
7630 continue;
7631 }
7632 }
7633 }
7634 // Anything that is not a function parameter is an error.
7635 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7636 return;
7637 }
7638
7639 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7640 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7641 AdjustArgsNothing.size(),
7642 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7643 AdjustArgsNeedDevicePtr.size(),
7644 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()),
7645 AppendArgs.size(), SR);
7646 FD->addAttr(NewAttr);
7647 }
7648
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7649 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7650 Stmt *AStmt,
7651 SourceLocation StartLoc,
7652 SourceLocation EndLoc) {
7653 if (!AStmt)
7654 return StmtError();
7655
7656 auto *CS = cast<CapturedStmt>(AStmt);
7657 // 1.2.2 OpenMP Language Terminology
7658 // Structured block - An executable statement with a single entry at the
7659 // top and a single exit at the bottom.
7660 // The point of exit cannot be a branch out of the structured block.
7661 // longjmp() and throw() must not violate the entry/exit criteria.
7662 CS->getCapturedDecl()->setNothrow();
7663
7664 setFunctionHasBranchProtectedScope();
7665
7666 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7667 DSAStack->getTaskgroupReductionRef(),
7668 DSAStack->isCancelRegion());
7669 }
7670
7671 namespace {
7672 /// Iteration space of a single for loop.
7673 struct LoopIterationSpace final {
7674 /// True if the condition operator is the strict compare operator (<, > or
7675 /// !=).
7676 bool IsStrictCompare = false;
7677 /// Condition of the loop.
7678 Expr *PreCond = nullptr;
7679 /// This expression calculates the number of iterations in the loop.
7680 /// It is always possible to calculate it before starting the loop.
7681 Expr *NumIterations = nullptr;
7682 /// The loop counter variable.
7683 Expr *CounterVar = nullptr;
7684 /// Private loop counter variable.
7685 Expr *PrivateCounterVar = nullptr;
7686 /// This is initializer for the initial value of #CounterVar.
7687 Expr *CounterInit = nullptr;
7688 /// This is step for the #CounterVar used to generate its update:
7689 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7690 Expr *CounterStep = nullptr;
7691 /// Should step be subtracted?
7692 bool Subtract = false;
7693 /// Source range of the loop init.
7694 SourceRange InitSrcRange;
7695 /// Source range of the loop condition.
7696 SourceRange CondSrcRange;
7697 /// Source range of the loop increment.
7698 SourceRange IncSrcRange;
7699 /// Minimum value that can have the loop control variable. Used to support
7700 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7701 /// since only such variables can be used in non-loop invariant expressions.
7702 Expr *MinValue = nullptr;
7703 /// Maximum value that can have the loop control variable. Used to support
7704 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7705 /// since only such variables can be used in non-loop invariant expressions.
7706 Expr *MaxValue = nullptr;
7707 /// true, if the lower bound depends on the outer loop control var.
7708 bool IsNonRectangularLB = false;
7709 /// true, if the upper bound depends on the outer loop control var.
7710 bool IsNonRectangularUB = false;
7711 /// Index of the loop this loop depends on and forms non-rectangular loop
7712 /// nest.
7713 unsigned LoopDependentIdx = 0;
7714 /// Final condition for the non-rectangular loop nest support. It is used to
7715 /// check that the number of iterations for this particular counter must be
7716 /// finished.
7717 Expr *FinalCondition = nullptr;
7718 };
7719
7720 /// Helper class for checking canonical form of the OpenMP loops and
7721 /// extracting iteration space of each loop in the loop nest, that will be used
7722 /// for IR generation.
7723 class OpenMPIterationSpaceChecker {
7724 /// Reference to Sema.
7725 Sema &SemaRef;
7726 /// Does the loop associated directive support non-rectangular loops?
7727 bool SupportsNonRectangular;
7728 /// Data-sharing stack.
7729 DSAStackTy &Stack;
7730 /// A location for diagnostics (when there is no some better location).
7731 SourceLocation DefaultLoc;
7732 /// A location for diagnostics (when increment is not compatible).
7733 SourceLocation ConditionLoc;
7734 /// A source location for referring to loop init later.
7735 SourceRange InitSrcRange;
7736 /// A source location for referring to condition later.
7737 SourceRange ConditionSrcRange;
7738 /// A source location for referring to increment later.
7739 SourceRange IncrementSrcRange;
7740 /// Loop variable.
7741 ValueDecl *LCDecl = nullptr;
7742 /// Reference to loop variable.
7743 Expr *LCRef = nullptr;
7744 /// Lower bound (initializer for the var).
7745 Expr *LB = nullptr;
7746 /// Upper bound.
7747 Expr *UB = nullptr;
7748 /// Loop step (increment).
7749 Expr *Step = nullptr;
7750 /// This flag is true when condition is one of:
7751 /// Var < UB
7752 /// Var <= UB
7753 /// UB > Var
7754 /// UB >= Var
7755 /// This will have no value when the condition is !=
7756 llvm::Optional<bool> TestIsLessOp;
7757 /// This flag is true when condition is strict ( < or > ).
7758 bool TestIsStrictOp = false;
7759 /// This flag is true when step is subtracted on each iteration.
7760 bool SubtractStep = false;
7761 /// The outer loop counter this loop depends on (if any).
7762 const ValueDecl *DepDecl = nullptr;
7763 /// Contains number of loop (starts from 1) on which loop counter init
7764 /// expression of this loop depends on.
7765 Optional<unsigned> InitDependOnLC;
7766 /// Contains number of loop (starts from 1) on which loop counter condition
7767 /// expression of this loop depends on.
7768 Optional<unsigned> CondDependOnLC;
7769 /// Checks if the provide statement depends on the loop counter.
7770 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7771 /// Original condition required for checking of the exit condition for
7772 /// non-rectangular loop.
7773 Expr *Condition = nullptr;
7774
7775 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)7776 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7777 DSAStackTy &Stack, SourceLocation DefaultLoc)
7778 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7779 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7780 /// Check init-expr for canonical loop form and save loop counter
7781 /// variable - #Var and its initialization value - #LB.
7782 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7783 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7784 /// for less/greater and for strict/non-strict comparison.
7785 bool checkAndSetCond(Expr *S);
7786 /// Check incr-expr for canonical loop form and return true if it
7787 /// does not conform, otherwise save loop step (#Step).
7788 bool checkAndSetInc(Expr *S);
7789 /// Return the loop counter variable.
getLoopDecl() const7790 ValueDecl *getLoopDecl() const { return LCDecl; }
7791 /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const7792 Expr *getLoopDeclRefExpr() const { return LCRef; }
7793 /// Source range of the loop init.
getInitSrcRange() const7794 SourceRange getInitSrcRange() const { return InitSrcRange; }
7795 /// Source range of the loop condition.
getConditionSrcRange() const7796 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7797 /// Source range of the loop increment.
getIncrementSrcRange() const7798 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7799 /// True if the step should be subtracted.
shouldSubtractStep() const7800 bool shouldSubtractStep() const { return SubtractStep; }
7801 /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const7802 bool isStrictTestOp() const { return TestIsStrictOp; }
7803 /// Build the expression to calculate the number of iterations.
7804 Expr *buildNumIterations(
7805 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7806 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7807 /// Build the precondition expression for the loops.
7808 Expr *
7809 buildPreCond(Scope *S, Expr *Cond,
7810 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7811 /// Build reference expression to the counter be used for codegen.
7812 DeclRefExpr *
7813 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7814 DSAStackTy &DSA) const;
7815 /// Build reference expression to the private counter be used for
7816 /// codegen.
7817 Expr *buildPrivateCounterVar() const;
7818 /// Build initialization of the counter be used for codegen.
7819 Expr *buildCounterInit() const;
7820 /// Build step of the counter be used for codegen.
7821 Expr *buildCounterStep() const;
7822 /// Build loop data with counter value for depend clauses in ordered
7823 /// directives.
7824 Expr *
7825 buildOrderedLoopData(Scope *S, Expr *Counter,
7826 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7827 SourceLocation Loc, Expr *Inc = nullptr,
7828 OverloadedOperatorKind OOK = OO_Amp);
7829 /// Builds the minimum value for the loop counter.
7830 std::pair<Expr *, Expr *> buildMinMaxValues(
7831 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7832 /// Builds final condition for the non-rectangular loops.
7833 Expr *buildFinalCondition(Scope *S) const;
7834 /// Return true if any expression is dependent.
7835 bool dependent() const;
7836 /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const7837 bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
7838 /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const7839 bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
7840 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const7841 unsigned getLoopDependentIdx() const {
7842 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7843 }
7844
7845 private:
7846 /// Check the right-hand side of an assignment in the increment
7847 /// expression.
7848 bool checkAndSetIncRHS(Expr *RHS);
7849 /// Helper to set loop counter variable and its initializer.
7850 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7851 bool EmitDiags);
7852 /// Helper to set upper bound.
7853 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7854 SourceRange SR, SourceLocation SL);
7855 /// Helper to set loop increment.
7856 bool setStep(Expr *NewStep, bool Subtract);
7857 };
7858
dependent() const7859 bool OpenMPIterationSpaceChecker::dependent() const {
7860 if (!LCDecl) {
7861 assert(!LB && !UB && !Step);
7862 return false;
7863 }
7864 return LCDecl->getType()->isDependentType() ||
7865 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7866 (Step && Step->isValueDependent());
7867 }
7868
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)7869 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7870 Expr *NewLCRefExpr,
7871 Expr *NewLB, bool EmitDiags) {
7872 // State consistency checking to ensure correct usage.
7873 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7874 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7875 if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7876 return true;
7877 LCDecl = getCanonicalDecl(NewLCDecl);
7878 LCRef = NewLCRefExpr;
7879 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7880 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7881 if ((Ctor->isCopyOrMoveConstructor() ||
7882 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7883 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7884 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7885 LB = NewLB;
7886 if (EmitDiags)
7887 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7888 return false;
7889 }
7890
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)7891 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7892 llvm::Optional<bool> LessOp,
7893 bool StrictOp, SourceRange SR,
7894 SourceLocation SL) {
7895 // State consistency checking to ensure correct usage.
7896 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7897 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7898 if (!NewUB || NewUB->containsErrors())
7899 return true;
7900 UB = NewUB;
7901 if (LessOp)
7902 TestIsLessOp = LessOp;
7903 TestIsStrictOp = StrictOp;
7904 ConditionSrcRange = SR;
7905 ConditionLoc = SL;
7906 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7907 return false;
7908 }
7909
setStep(Expr * NewStep,bool Subtract)7910 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7911 // State consistency checking to ensure correct usage.
7912 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7913 if (!NewStep || NewStep->containsErrors())
7914 return true;
7915 if (!NewStep->isValueDependent()) {
7916 // Check that the step is integer expression.
7917 SourceLocation StepLoc = NewStep->getBeginLoc();
7918 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7919 StepLoc, getExprAsWritten(NewStep));
7920 if (Val.isInvalid())
7921 return true;
7922 NewStep = Val.get();
7923
7924 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7925 // If test-expr is of form var relational-op b and relational-op is < or
7926 // <= then incr-expr must cause var to increase on each iteration of the
7927 // loop. If test-expr is of form var relational-op b and relational-op is
7928 // > or >= then incr-expr must cause var to decrease on each iteration of
7929 // the loop.
7930 // If test-expr is of form b relational-op var and relational-op is < or
7931 // <= then incr-expr must cause var to decrease on each iteration of the
7932 // loop. If test-expr is of form b relational-op var and relational-op is
7933 // > or >= then incr-expr must cause var to increase on each iteration of
7934 // the loop.
7935 Optional<llvm::APSInt> Result =
7936 NewStep->getIntegerConstantExpr(SemaRef.Context);
7937 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7938 bool IsConstNeg =
7939 Result && Result->isSigned() && (Subtract != Result->isNegative());
7940 bool IsConstPos =
7941 Result && Result->isSigned() && (Subtract == Result->isNegative());
7942 bool IsConstZero = Result && !Result->getBoolValue();
7943
7944 // != with increment is treated as <; != with decrement is treated as >
7945 if (!TestIsLessOp)
7946 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7947 if (UB &&
7948 (IsConstZero ||
7949 (TestIsLessOp.value() ? (IsConstNeg || (IsUnsigned && Subtract))
7950 : (IsConstPos || (IsUnsigned && !Subtract))))) {
7951 SemaRef.Diag(NewStep->getExprLoc(),
7952 diag::err_omp_loop_incr_not_compatible)
7953 << LCDecl << TestIsLessOp.value() << NewStep->getSourceRange();
7954 SemaRef.Diag(ConditionLoc,
7955 diag::note_omp_loop_cond_requres_compatible_incr)
7956 << TestIsLessOp.value() << ConditionSrcRange;
7957 return true;
7958 }
7959 if (TestIsLessOp.value() == Subtract) {
7960 NewStep =
7961 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7962 .get();
7963 Subtract = !Subtract;
7964 }
7965 }
7966
7967 Step = NewStep;
7968 SubtractStep = Subtract;
7969 return false;
7970 }
7971
7972 namespace {
7973 /// Checker for the non-rectangular loops. Checks if the initializer or
7974 /// condition expression references loop counter variable.
7975 class LoopCounterRefChecker final
7976 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7977 Sema &SemaRef;
7978 DSAStackTy &Stack;
7979 const ValueDecl *CurLCDecl = nullptr;
7980 const ValueDecl *DepDecl = nullptr;
7981 const ValueDecl *PrevDepDecl = nullptr;
7982 bool IsInitializer = true;
7983 bool SupportsNonRectangular;
7984 unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)7985 bool checkDecl(const Expr *E, const ValueDecl *VD) {
7986 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7987 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7988 << (IsInitializer ? 0 : 1);
7989 return false;
7990 }
7991 const auto &&Data = Stack.isLoopControlVariable(VD);
7992 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7993 // The type of the loop iterator on which we depend may not have a random
7994 // access iterator type.
7995 if (Data.first && VD->getType()->isRecordType()) {
7996 SmallString<128> Name;
7997 llvm::raw_svector_ostream OS(Name);
7998 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7999 /*Qualified=*/true);
8000 SemaRef.Diag(E->getExprLoc(),
8001 diag::err_omp_wrong_dependency_iterator_type)
8002 << OS.str();
8003 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8004 return false;
8005 }
8006 if (Data.first && !SupportsNonRectangular) {
8007 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8008 return false;
8009 }
8010 if (Data.first &&
8011 (DepDecl || (PrevDepDecl &&
8012 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8013 if (!DepDecl && PrevDepDecl)
8014 DepDecl = PrevDepDecl;
8015 SmallString<128> Name;
8016 llvm::raw_svector_ostream OS(Name);
8017 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8018 /*Qualified=*/true);
8019 SemaRef.Diag(E->getExprLoc(),
8020 diag::err_omp_invariant_or_linear_dependency)
8021 << OS.str();
8022 return false;
8023 }
8024 if (Data.first) {
8025 DepDecl = VD;
8026 BaseLoopId = Data.first;
8027 }
8028 return Data.first;
8029 }
8030
8031 public:
VisitDeclRefExpr(const DeclRefExpr * E)8032 bool VisitDeclRefExpr(const DeclRefExpr *E) {
8033 const ValueDecl *VD = E->getDecl();
8034 if (isa<VarDecl>(VD))
8035 return checkDecl(E, VD);
8036 return false;
8037 }
VisitMemberExpr(const MemberExpr * E)8038 bool VisitMemberExpr(const MemberExpr *E) {
8039 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8040 const ValueDecl *VD = E->getMemberDecl();
8041 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8042 return checkDecl(E, VD);
8043 }
8044 return false;
8045 }
VisitStmt(const Stmt * S)8046 bool VisitStmt(const Stmt *S) {
8047 bool Res = false;
8048 for (const Stmt *Child : S->children())
8049 Res = (Child && Visit(Child)) || Res;
8050 return Res;
8051 }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)8052 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8053 const ValueDecl *CurLCDecl, bool IsInitializer,
8054 const ValueDecl *PrevDepDecl = nullptr,
8055 bool SupportsNonRectangular = true)
8056 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8057 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8058 SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const8059 unsigned getBaseLoopId() const {
8060 assert(CurLCDecl && "Expected loop dependency.");
8061 return BaseLoopId;
8062 }
getDepDecl() const8063 const ValueDecl *getDepDecl() const {
8064 assert(CurLCDecl && "Expected loop dependency.");
8065 return DepDecl;
8066 }
8067 };
8068 } // namespace
8069
8070 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)8071 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8072 bool IsInitializer) {
8073 // Check for the non-rectangular loops.
8074 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8075 DepDecl, SupportsNonRectangular);
8076 if (LoopStmtChecker.Visit(S)) {
8077 DepDecl = LoopStmtChecker.getDepDecl();
8078 return LoopStmtChecker.getBaseLoopId();
8079 }
8080 return llvm::None;
8081 }
8082
checkAndSetInit(Stmt * S,bool EmitDiags)8083 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8084 // Check init-expr for canonical loop form and save loop counter
8085 // variable - #Var and its initialization value - #LB.
8086 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8087 // var = lb
8088 // integer-type var = lb
8089 // random-access-iterator-type var = lb
8090 // pointer-type var = lb
8091 //
8092 if (!S) {
8093 if (EmitDiags) {
8094 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8095 }
8096 return true;
8097 }
8098 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8099 if (!ExprTemp->cleanupsHaveSideEffects())
8100 S = ExprTemp->getSubExpr();
8101
8102 InitSrcRange = S->getSourceRange();
8103 if (Expr *E = dyn_cast<Expr>(S))
8104 S = E->IgnoreParens();
8105 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8106 if (BO->getOpcode() == BO_Assign) {
8107 Expr *LHS = BO->getLHS()->IgnoreParens();
8108 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8109 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8110 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8111 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8112 EmitDiags);
8113 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8114 }
8115 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8116 if (ME->isArrow() &&
8117 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8118 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8119 EmitDiags);
8120 }
8121 }
8122 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8123 if (DS->isSingleDecl()) {
8124 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8125 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8126 // Accept non-canonical init form here but emit ext. warning.
8127 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8128 SemaRef.Diag(S->getBeginLoc(),
8129 diag::ext_omp_loop_not_canonical_init)
8130 << S->getSourceRange();
8131 return setLCDeclAndLB(
8132 Var,
8133 buildDeclRefExpr(SemaRef, Var,
8134 Var->getType().getNonReferenceType(),
8135 DS->getBeginLoc()),
8136 Var->getInit(), EmitDiags);
8137 }
8138 }
8139 }
8140 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8141 if (CE->getOperator() == OO_Equal) {
8142 Expr *LHS = CE->getArg(0);
8143 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8144 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8145 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8146 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8147 EmitDiags);
8148 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8149 }
8150 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8151 if (ME->isArrow() &&
8152 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8153 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8154 EmitDiags);
8155 }
8156 }
8157 }
8158
8159 if (dependent() || SemaRef.CurContext->isDependentContext())
8160 return false;
8161 if (EmitDiags) {
8162 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8163 << S->getSourceRange();
8164 }
8165 return true;
8166 }
8167
8168 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8169 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)8170 static const ValueDecl *getInitLCDecl(const Expr *E) {
8171 if (!E)
8172 return nullptr;
8173 E = getExprAsWritten(E);
8174 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8175 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8176 if ((Ctor->isCopyOrMoveConstructor() ||
8177 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8178 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8179 E = CE->getArg(0)->IgnoreParenImpCasts();
8180 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8181 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8182 return getCanonicalDecl(VD);
8183 }
8184 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8185 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8186 return getCanonicalDecl(ME->getMemberDecl());
8187 return nullptr;
8188 }
8189
checkAndSetCond(Expr * S)8190 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8191 // Check test-expr for canonical form, save upper-bound UB, flags for
8192 // less/greater and for strict/non-strict comparison.
8193 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8194 // var relational-op b
8195 // b relational-op var
8196 //
8197 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8198 if (!S) {
8199 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8200 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8201 return true;
8202 }
8203 Condition = S;
8204 S = getExprAsWritten(S);
8205 SourceLocation CondLoc = S->getBeginLoc();
8206 auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
8207 BinaryOperatorKind Opcode, const Expr *LHS,
8208 const Expr *RHS, SourceRange SR,
8209 SourceLocation OpLoc) -> llvm::Optional<bool> {
8210 if (BinaryOperator::isRelationalOp(Opcode)) {
8211 if (getInitLCDecl(LHS) == LCDecl)
8212 return setUB(const_cast<Expr *>(RHS),
8213 (Opcode == BO_LT || Opcode == BO_LE),
8214 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8215 if (getInitLCDecl(RHS) == LCDecl)
8216 return setUB(const_cast<Expr *>(LHS),
8217 (Opcode == BO_GT || Opcode == BO_GE),
8218 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8219 } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8220 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8221 /*LessOp=*/llvm::None,
8222 /*StrictOp=*/true, SR, OpLoc);
8223 }
8224 return llvm::None;
8225 };
8226 llvm::Optional<bool> Res;
8227 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8228 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8229 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8230 RBO->getOperatorLoc());
8231 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8232 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8233 BO->getSourceRange(), BO->getOperatorLoc());
8234 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8235 if (CE->getNumArgs() == 2) {
8236 Res = CheckAndSetCond(
8237 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8238 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8239 }
8240 }
8241 if (Res)
8242 return *Res;
8243 if (dependent() || SemaRef.CurContext->isDependentContext())
8244 return false;
8245 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8246 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8247 return true;
8248 }
8249
checkAndSetIncRHS(Expr * RHS)8250 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8251 // RHS of canonical loop form increment can be:
8252 // var + incr
8253 // incr + var
8254 // var - incr
8255 //
8256 RHS = RHS->IgnoreParenImpCasts();
8257 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8258 if (BO->isAdditiveOp()) {
8259 bool IsAdd = BO->getOpcode() == BO_Add;
8260 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8261 return setStep(BO->getRHS(), !IsAdd);
8262 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8263 return setStep(BO->getLHS(), /*Subtract=*/false);
8264 }
8265 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8266 bool IsAdd = CE->getOperator() == OO_Plus;
8267 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8268 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8269 return setStep(CE->getArg(1), !IsAdd);
8270 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8271 return setStep(CE->getArg(0), /*Subtract=*/false);
8272 }
8273 }
8274 if (dependent() || SemaRef.CurContext->isDependentContext())
8275 return false;
8276 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8277 << RHS->getSourceRange() << LCDecl;
8278 return true;
8279 }
8280
checkAndSetInc(Expr * S)8281 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8282 // Check incr-expr for canonical loop form and return true if it
8283 // does not conform.
8284 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8285 // ++var
8286 // var++
8287 // --var
8288 // var--
8289 // var += incr
8290 // var -= incr
8291 // var = var + incr
8292 // var = incr + var
8293 // var = var - incr
8294 //
8295 if (!S) {
8296 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8297 return true;
8298 }
8299 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8300 if (!ExprTemp->cleanupsHaveSideEffects())
8301 S = ExprTemp->getSubExpr();
8302
8303 IncrementSrcRange = S->getSourceRange();
8304 S = S->IgnoreParens();
8305 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8306 if (UO->isIncrementDecrementOp() &&
8307 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8308 return setStep(SemaRef
8309 .ActOnIntegerConstant(UO->getBeginLoc(),
8310 (UO->isDecrementOp() ? -1 : 1))
8311 .get(),
8312 /*Subtract=*/false);
8313 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8314 switch (BO->getOpcode()) {
8315 case BO_AddAssign:
8316 case BO_SubAssign:
8317 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8318 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8319 break;
8320 case BO_Assign:
8321 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8322 return checkAndSetIncRHS(BO->getRHS());
8323 break;
8324 default:
8325 break;
8326 }
8327 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8328 switch (CE->getOperator()) {
8329 case OO_PlusPlus:
8330 case OO_MinusMinus:
8331 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8332 return setStep(SemaRef
8333 .ActOnIntegerConstant(
8334 CE->getBeginLoc(),
8335 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8336 .get(),
8337 /*Subtract=*/false);
8338 break;
8339 case OO_PlusEqual:
8340 case OO_MinusEqual:
8341 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8342 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8343 break;
8344 case OO_Equal:
8345 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8346 return checkAndSetIncRHS(CE->getArg(1));
8347 break;
8348 default:
8349 break;
8350 }
8351 }
8352 if (dependent() || SemaRef.CurContext->isDependentContext())
8353 return false;
8354 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8355 << S->getSourceRange() << LCDecl;
8356 return true;
8357 }
8358
8359 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8360 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8361 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8362 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8363 return Capture;
8364 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8365 return SemaRef.PerformImplicitConversion(
8366 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8367 /*AllowExplicit=*/true);
8368 auto I = Captures.find(Capture);
8369 if (I != Captures.end())
8370 return buildCapture(SemaRef, Capture, I->second);
8371 DeclRefExpr *Ref = nullptr;
8372 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
8373 Captures[Capture] = Ref;
8374 return Res;
8375 }
8376
8377 /// Calculate number of iterations, transforming to unsigned, if number of
8378 /// iterations may be larger than the original type.
8379 static Expr *
calculateNumIters(Sema & SemaRef,Scope * S,SourceLocation DefaultLoc,Expr * Lower,Expr * Upper,Expr * Step,QualType LCTy,bool TestIsStrictOp,bool RoundToStep,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8380 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8381 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8382 bool TestIsStrictOp, bool RoundToStep,
8383 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8384 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8385 if (!NewStep.isUsable())
8386 return nullptr;
8387 llvm::APSInt LRes, SRes;
8388 bool IsLowerConst = false, IsStepConst = false;
8389 if (Optional<llvm::APSInt> Res =
8390 Lower->getIntegerConstantExpr(SemaRef.Context)) {
8391 LRes = *Res;
8392 IsLowerConst = true;
8393 }
8394 if (Optional<llvm::APSInt> Res =
8395 Step->getIntegerConstantExpr(SemaRef.Context)) {
8396 SRes = *Res;
8397 IsStepConst = true;
8398 }
8399 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8400 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8401 (TestIsStrictOp && LRes.isStrictlyPositive()));
8402 bool NeedToReorganize = false;
8403 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8404 if (!NoNeedToConvert && IsLowerConst &&
8405 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8406 NoNeedToConvert = true;
8407 if (RoundToStep) {
8408 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8409 ? LRes.getBitWidth()
8410 : SRes.getBitWidth();
8411 LRes = LRes.extend(BW + 1);
8412 LRes.setIsSigned(true);
8413 SRes = SRes.extend(BW + 1);
8414 SRes.setIsSigned(true);
8415 LRes -= SRes;
8416 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8417 LRes = LRes.trunc(BW);
8418 }
8419 if (TestIsStrictOp) {
8420 unsigned BW = LRes.getBitWidth();
8421 LRes = LRes.extend(BW + 1);
8422 LRes.setIsSigned(true);
8423 ++LRes;
8424 NoNeedToConvert =
8425 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8426 // truncate to the original bitwidth.
8427 LRes = LRes.trunc(BW);
8428 }
8429 NeedToReorganize = NoNeedToConvert;
8430 }
8431 llvm::APSInt URes;
8432 bool IsUpperConst = false;
8433 if (Optional<llvm::APSInt> Res =
8434 Upper->getIntegerConstantExpr(SemaRef.Context)) {
8435 URes = *Res;
8436 IsUpperConst = true;
8437 }
8438 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8439 (!RoundToStep || IsStepConst)) {
8440 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8441 : URes.getBitWidth();
8442 LRes = LRes.extend(BW + 1);
8443 LRes.setIsSigned(true);
8444 URes = URes.extend(BW + 1);
8445 URes.setIsSigned(true);
8446 URes -= LRes;
8447 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8448 NeedToReorganize = NoNeedToConvert;
8449 }
8450 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8451 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8452 // unsigned.
8453 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8454 !LCTy->isDependentType() && LCTy->isIntegerType()) {
8455 QualType LowerTy = Lower->getType();
8456 QualType UpperTy = Upper->getType();
8457 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8458 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8459 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8460 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8461 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8462 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8463 Upper =
8464 SemaRef
8465 .PerformImplicitConversion(
8466 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8467 CastType, Sema::AA_Converting)
8468 .get();
8469 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8470 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8471 }
8472 }
8473 if (!Lower || !Upper || NewStep.isInvalid())
8474 return nullptr;
8475
8476 ExprResult Diff;
8477 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8478 // 1]).
8479 if (NeedToReorganize) {
8480 Diff = Lower;
8481
8482 if (RoundToStep) {
8483 // Lower - Step
8484 Diff =
8485 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8486 if (!Diff.isUsable())
8487 return nullptr;
8488 }
8489
8490 // Lower - Step [+ 1]
8491 if (TestIsStrictOp)
8492 Diff = SemaRef.BuildBinOp(
8493 S, DefaultLoc, BO_Add, Diff.get(),
8494 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8495 if (!Diff.isUsable())
8496 return nullptr;
8497
8498 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8499 if (!Diff.isUsable())
8500 return nullptr;
8501
8502 // Upper - (Lower - Step [+ 1]).
8503 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8504 if (!Diff.isUsable())
8505 return nullptr;
8506 } else {
8507 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8508
8509 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8510 // BuildBinOp already emitted error, this one is to point user to upper
8511 // and lower bound, and to tell what is passed to 'operator-'.
8512 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8513 << Upper->getSourceRange() << Lower->getSourceRange();
8514 return nullptr;
8515 }
8516
8517 if (!Diff.isUsable())
8518 return nullptr;
8519
8520 // Upper - Lower [- 1]
8521 if (TestIsStrictOp)
8522 Diff = SemaRef.BuildBinOp(
8523 S, DefaultLoc, BO_Sub, Diff.get(),
8524 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8525 if (!Diff.isUsable())
8526 return nullptr;
8527
8528 if (RoundToStep) {
8529 // Upper - Lower [- 1] + Step
8530 Diff =
8531 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8532 if (!Diff.isUsable())
8533 return nullptr;
8534 }
8535 }
8536
8537 // Parentheses (for dumping/debugging purposes only).
8538 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8539 if (!Diff.isUsable())
8540 return nullptr;
8541
8542 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8543 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8544 if (!Diff.isUsable())
8545 return nullptr;
8546
8547 return Diff.get();
8548 }
8549
8550 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8551 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8552 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8553 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8554 QualType VarType = LCDecl->getType().getNonReferenceType();
8555 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8556 !SemaRef.getLangOpts().CPlusPlus)
8557 return nullptr;
8558 Expr *LBVal = LB;
8559 Expr *UBVal = UB;
8560 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8561 // max(LB(MinVal), LB(MaxVal))
8562 if (InitDependOnLC) {
8563 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8564 if (!IS.MinValue || !IS.MaxValue)
8565 return nullptr;
8566 // OuterVar = Min
8567 ExprResult MinValue =
8568 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8569 if (!MinValue.isUsable())
8570 return nullptr;
8571
8572 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8573 IS.CounterVar, MinValue.get());
8574 if (!LBMinVal.isUsable())
8575 return nullptr;
8576 // OuterVar = Min, LBVal
8577 LBMinVal =
8578 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8579 if (!LBMinVal.isUsable())
8580 return nullptr;
8581 // (OuterVar = Min, LBVal)
8582 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8583 if (!LBMinVal.isUsable())
8584 return nullptr;
8585
8586 // OuterVar = Max
8587 ExprResult MaxValue =
8588 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8589 if (!MaxValue.isUsable())
8590 return nullptr;
8591
8592 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8593 IS.CounterVar, MaxValue.get());
8594 if (!LBMaxVal.isUsable())
8595 return nullptr;
8596 // OuterVar = Max, LBVal
8597 LBMaxVal =
8598 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8599 if (!LBMaxVal.isUsable())
8600 return nullptr;
8601 // (OuterVar = Max, LBVal)
8602 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8603 if (!LBMaxVal.isUsable())
8604 return nullptr;
8605
8606 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8607 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8608 if (!LBMin || !LBMax)
8609 return nullptr;
8610 // LB(MinVal) < LB(MaxVal)
8611 ExprResult MinLessMaxRes =
8612 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8613 if (!MinLessMaxRes.isUsable())
8614 return nullptr;
8615 Expr *MinLessMax =
8616 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8617 if (!MinLessMax)
8618 return nullptr;
8619 if (*TestIsLessOp) {
8620 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8621 // LB(MaxVal))
8622 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8623 MinLessMax, LBMin, LBMax);
8624 if (!MinLB.isUsable())
8625 return nullptr;
8626 LBVal = MinLB.get();
8627 } else {
8628 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8629 // LB(MaxVal))
8630 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8631 MinLessMax, LBMax, LBMin);
8632 if (!MaxLB.isUsable())
8633 return nullptr;
8634 LBVal = MaxLB.get();
8635 }
8636 }
8637 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8638 // min(UB(MinVal), UB(MaxVal))
8639 if (CondDependOnLC) {
8640 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8641 if (!IS.MinValue || !IS.MaxValue)
8642 return nullptr;
8643 // OuterVar = Min
8644 ExprResult MinValue =
8645 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8646 if (!MinValue.isUsable())
8647 return nullptr;
8648
8649 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8650 IS.CounterVar, MinValue.get());
8651 if (!UBMinVal.isUsable())
8652 return nullptr;
8653 // OuterVar = Min, UBVal
8654 UBMinVal =
8655 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8656 if (!UBMinVal.isUsable())
8657 return nullptr;
8658 // (OuterVar = Min, UBVal)
8659 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8660 if (!UBMinVal.isUsable())
8661 return nullptr;
8662
8663 // OuterVar = Max
8664 ExprResult MaxValue =
8665 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8666 if (!MaxValue.isUsable())
8667 return nullptr;
8668
8669 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8670 IS.CounterVar, MaxValue.get());
8671 if (!UBMaxVal.isUsable())
8672 return nullptr;
8673 // OuterVar = Max, UBVal
8674 UBMaxVal =
8675 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8676 if (!UBMaxVal.isUsable())
8677 return nullptr;
8678 // (OuterVar = Max, UBVal)
8679 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8680 if (!UBMaxVal.isUsable())
8681 return nullptr;
8682
8683 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8684 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8685 if (!UBMin || !UBMax)
8686 return nullptr;
8687 // UB(MinVal) > UB(MaxVal)
8688 ExprResult MinGreaterMaxRes =
8689 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8690 if (!MinGreaterMaxRes.isUsable())
8691 return nullptr;
8692 Expr *MinGreaterMax =
8693 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8694 if (!MinGreaterMax)
8695 return nullptr;
8696 if (*TestIsLessOp) {
8697 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8698 // UB(MaxVal))
8699 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8700 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8701 if (!MaxUB.isUsable())
8702 return nullptr;
8703 UBVal = MaxUB.get();
8704 } else {
8705 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8706 // UB(MaxVal))
8707 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8708 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8709 if (!MinUB.isUsable())
8710 return nullptr;
8711 UBVal = MinUB.get();
8712 }
8713 }
8714 Expr *UBExpr = TestIsLessOp.value() ? UBVal : LBVal;
8715 Expr *LBExpr = TestIsLessOp.value() ? LBVal : UBVal;
8716 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8717 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8718 if (!Upper || !Lower)
8719 return nullptr;
8720
8721 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8722 Step, VarType, TestIsStrictOp,
8723 /*RoundToStep=*/true, Captures);
8724 if (!Diff.isUsable())
8725 return nullptr;
8726
8727 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8728 QualType Type = Diff.get()->getType();
8729 ASTContext &C = SemaRef.Context;
8730 bool UseVarType = VarType->hasIntegerRepresentation() &&
8731 C.getTypeSize(Type) > C.getTypeSize(VarType);
8732 if (!Type->isIntegerType() || UseVarType) {
8733 unsigned NewSize =
8734 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8735 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8736 : Type->hasSignedIntegerRepresentation();
8737 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8738 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8739 Diff = SemaRef.PerformImplicitConversion(
8740 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8741 if (!Diff.isUsable())
8742 return nullptr;
8743 }
8744 }
8745 if (LimitedType) {
8746 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8747 if (NewSize != C.getTypeSize(Type)) {
8748 if (NewSize < C.getTypeSize(Type)) {
8749 assert(NewSize == 64 && "incorrect loop var size");
8750 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8751 << InitSrcRange << ConditionSrcRange;
8752 }
8753 QualType NewType = C.getIntTypeForBitwidth(
8754 NewSize, Type->hasSignedIntegerRepresentation() ||
8755 C.getTypeSize(Type) < NewSize);
8756 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8757 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8758 Sema::AA_Converting, true);
8759 if (!Diff.isUsable())
8760 return nullptr;
8761 }
8762 }
8763 }
8764
8765 return Diff.get();
8766 }
8767
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8768 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8769 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8770 // Do not build for iterators, they cannot be used in non-rectangular loop
8771 // nests.
8772 if (LCDecl->getType()->isRecordType())
8773 return std::make_pair(nullptr, nullptr);
8774 // If we subtract, the min is in the condition, otherwise the min is in the
8775 // init value.
8776 Expr *MinExpr = nullptr;
8777 Expr *MaxExpr = nullptr;
8778 Expr *LBExpr = TestIsLessOp.value() ? LB : UB;
8779 Expr *UBExpr = TestIsLessOp.value() ? UB : LB;
8780 bool LBNonRect = TestIsLessOp.value() ? InitDependOnLC.has_value()
8781 : CondDependOnLC.has_value();
8782 bool UBNonRect = TestIsLessOp.value() ? CondDependOnLC.has_value()
8783 : InitDependOnLC.has_value();
8784 Expr *Lower =
8785 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8786 Expr *Upper =
8787 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8788 if (!Upper || !Lower)
8789 return std::make_pair(nullptr, nullptr);
8790
8791 if (*TestIsLessOp)
8792 MinExpr = Lower;
8793 else
8794 MaxExpr = Upper;
8795
8796 // Build minimum/maximum value based on number of iterations.
8797 QualType VarType = LCDecl->getType().getNonReferenceType();
8798
8799 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8800 Step, VarType, TestIsStrictOp,
8801 /*RoundToStep=*/false, Captures);
8802 if (!Diff.isUsable())
8803 return std::make_pair(nullptr, nullptr);
8804
8805 // ((Upper - Lower [- 1]) / Step) * Step
8806 // Parentheses (for dumping/debugging purposes only).
8807 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8808 if (!Diff.isUsable())
8809 return std::make_pair(nullptr, nullptr);
8810
8811 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8812 if (!NewStep.isUsable())
8813 return std::make_pair(nullptr, nullptr);
8814 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8815 if (!Diff.isUsable())
8816 return std::make_pair(nullptr, nullptr);
8817
8818 // Parentheses (for dumping/debugging purposes only).
8819 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8820 if (!Diff.isUsable())
8821 return std::make_pair(nullptr, nullptr);
8822
8823 // Convert to the ptrdiff_t, if original type is pointer.
8824 if (VarType->isAnyPointerType() &&
8825 !SemaRef.Context.hasSameType(
8826 Diff.get()->getType(),
8827 SemaRef.Context.getUnsignedPointerDiffType())) {
8828 Diff = SemaRef.PerformImplicitConversion(
8829 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8830 Sema::AA_Converting, /*AllowExplicit=*/true);
8831 }
8832 if (!Diff.isUsable())
8833 return std::make_pair(nullptr, nullptr);
8834
8835 if (*TestIsLessOp) {
8836 // MinExpr = Lower;
8837 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8838 Diff = SemaRef.BuildBinOp(
8839 S, DefaultLoc, BO_Add,
8840 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8841 Diff.get());
8842 if (!Diff.isUsable())
8843 return std::make_pair(nullptr, nullptr);
8844 } else {
8845 // MaxExpr = Upper;
8846 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8847 Diff = SemaRef.BuildBinOp(
8848 S, DefaultLoc, BO_Sub,
8849 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8850 Diff.get());
8851 if (!Diff.isUsable())
8852 return std::make_pair(nullptr, nullptr);
8853 }
8854
8855 // Convert to the original type.
8856 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8857 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8858 Sema::AA_Converting,
8859 /*AllowExplicit=*/true);
8860 if (!Diff.isUsable())
8861 return std::make_pair(nullptr, nullptr);
8862
8863 Sema::TentativeAnalysisScope Trap(SemaRef);
8864 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8865 if (!Diff.isUsable())
8866 return std::make_pair(nullptr, nullptr);
8867
8868 if (*TestIsLessOp)
8869 MaxExpr = Diff.get();
8870 else
8871 MinExpr = Diff.get();
8872
8873 return std::make_pair(MinExpr, MaxExpr);
8874 }
8875
buildFinalCondition(Scope * S) const8876 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8877 if (InitDependOnLC || CondDependOnLC)
8878 return Condition;
8879 return nullptr;
8880 }
8881
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8882 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8883 Scope *S, Expr *Cond,
8884 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8885 // Do not build a precondition when the condition/initialization is dependent
8886 // to prevent pessimistic early loop exit.
8887 // TODO: this can be improved by calculating min/max values but not sure that
8888 // it will be very effective.
8889 if (CondDependOnLC || InitDependOnLC)
8890 return SemaRef
8891 .PerformImplicitConversion(
8892 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8893 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8894 /*AllowExplicit=*/true)
8895 .get();
8896
8897 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8898 Sema::TentativeAnalysisScope Trap(SemaRef);
8899
8900 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8901 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8902 if (!NewLB.isUsable() || !NewUB.isUsable())
8903 return nullptr;
8904
8905 ExprResult CondExpr = SemaRef.BuildBinOp(
8906 S, DefaultLoc,
8907 TestIsLessOp.value() ? (TestIsStrictOp ? BO_LT : BO_LE)
8908 : (TestIsStrictOp ? BO_GT : BO_GE),
8909 NewLB.get(), NewUB.get());
8910 if (CondExpr.isUsable()) {
8911 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8912 SemaRef.Context.BoolTy))
8913 CondExpr = SemaRef.PerformImplicitConversion(
8914 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8915 /*AllowExplicit=*/true);
8916 }
8917
8918 // Otherwise use original loop condition and evaluate it in runtime.
8919 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8920 }
8921
8922 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const8923 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8924 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8925 DSAStackTy &DSA) const {
8926 auto *VD = dyn_cast<VarDecl>(LCDecl);
8927 if (!VD) {
8928 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8929 DeclRefExpr *Ref = buildDeclRefExpr(
8930 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8931 const DSAStackTy::DSAVarData Data =
8932 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8933 // If the loop control decl is explicitly marked as private, do not mark it
8934 // as captured again.
8935 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8936 Captures.insert(std::make_pair(LCRef, Ref));
8937 return Ref;
8938 }
8939 return cast<DeclRefExpr>(LCRef);
8940 }
8941
buildPrivateCounterVar() const8942 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8943 if (LCDecl && !LCDecl->isInvalidDecl()) {
8944 QualType Type = LCDecl->getType().getNonReferenceType();
8945 VarDecl *PrivateVar = buildVarDecl(
8946 SemaRef, DefaultLoc, Type, LCDecl->getName(),
8947 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8948 isa<VarDecl>(LCDecl)
8949 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8950 : nullptr);
8951 if (PrivateVar->isInvalidDecl())
8952 return nullptr;
8953 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8954 }
8955 return nullptr;
8956 }
8957
8958 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const8959 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8960
8961 /// Build step of the counter be used for codegen.
buildCounterStep() const8962 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8963
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)8964 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8965 Scope *S, Expr *Counter,
8966 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8967 Expr *Inc, OverloadedOperatorKind OOK) {
8968 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8969 if (!Cnt)
8970 return nullptr;
8971 if (Inc) {
8972 assert((OOK == OO_Plus || OOK == OO_Minus) &&
8973 "Expected only + or - operations for depend clauses.");
8974 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8975 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8976 if (!Cnt)
8977 return nullptr;
8978 }
8979 QualType VarType = LCDecl->getType().getNonReferenceType();
8980 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8981 !SemaRef.getLangOpts().CPlusPlus)
8982 return nullptr;
8983 // Upper - Lower
8984 Expr *Upper =
8985 TestIsLessOp.value() ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
8986 Expr *Lower =
8987 TestIsLessOp.value() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
8988 if (!Upper || !Lower)
8989 return nullptr;
8990
8991 ExprResult Diff = calculateNumIters(
8992 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8993 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8994 if (!Diff.isUsable())
8995 return nullptr;
8996
8997 return Diff.get();
8998 }
8999 } // namespace
9000
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)9001 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9002 assert(getLangOpts().OpenMP && "OpenMP is not active.");
9003 assert(Init && "Expected loop in canonical form.");
9004 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9005 if (AssociatedLoops > 0 &&
9006 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9007 DSAStack->loopStart();
9008 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9009 *DSAStack, ForLoc);
9010 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9011 if (ValueDecl *D = ISC.getLoopDecl()) {
9012 auto *VD = dyn_cast<VarDecl>(D);
9013 DeclRefExpr *PrivateRef = nullptr;
9014 if (!VD) {
9015 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9016 VD = Private;
9017 } else {
9018 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9019 /*WithInit=*/false);
9020 VD = cast<VarDecl>(PrivateRef->getDecl());
9021 }
9022 }
9023 DSAStack->addLoopControlVariable(D, VD);
9024 const Decl *LD = DSAStack->getPossiblyLoopCunter();
9025 if (LD != D->getCanonicalDecl()) {
9026 DSAStack->resetPossibleLoopCounter();
9027 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9028 MarkDeclarationsReferencedInExpr(
9029 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9030 Var->getType().getNonLValueExprType(Context),
9031 ForLoc, /*RefersToCapture=*/true));
9032 }
9033 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9034 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9035 // Referenced in a Construct, C/C++]. The loop iteration variable in the
9036 // associated for-loop of a simd construct with just one associated
9037 // for-loop may be listed in a linear clause with a constant-linear-step
9038 // that is the increment of the associated for-loop. The loop iteration
9039 // variable(s) in the associated for-loop(s) of a for or parallel for
9040 // construct may be listed in a private or lastprivate clause.
9041 DSAStackTy::DSAVarData DVar =
9042 DSAStack->getTopDSA(D, /*FromParent=*/false);
9043 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9044 // is declared in the loop and it is predetermined as a private.
9045 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9046 OpenMPClauseKind PredeterminedCKind =
9047 isOpenMPSimdDirective(DKind)
9048 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9049 : OMPC_private;
9050 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9051 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9052 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9053 DVar.CKind != OMPC_private))) ||
9054 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9055 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9056 DKind == OMPD_parallel_master_taskloop ||
9057 DKind == OMPD_parallel_masked_taskloop ||
9058 isOpenMPDistributeDirective(DKind)) &&
9059 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9060 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9061 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9062 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9063 << getOpenMPClauseName(DVar.CKind)
9064 << getOpenMPDirectiveName(DKind)
9065 << getOpenMPClauseName(PredeterminedCKind);
9066 if (DVar.RefExpr == nullptr)
9067 DVar.CKind = PredeterminedCKind;
9068 reportOriginalDsa(*this, DSAStack, D, DVar,
9069 /*IsLoopIterVar=*/true);
9070 } else if (LoopDeclRefExpr) {
9071 // Make the loop iteration variable private (for worksharing
9072 // constructs), linear (for simd directives with the only one
9073 // associated loop) or lastprivate (for simd directives with several
9074 // collapsed or ordered loops).
9075 if (DVar.CKind == OMPC_unknown)
9076 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9077 PrivateRef);
9078 }
9079 }
9080 }
9081 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9082 }
9083 }
9084
9085 /// Called on a for stmt to check and extract its iteration space
9086 /// for further processing (such as collapsing).
checkOpenMPIterationSpace(OpenMPDirectiveKind DKind,Stmt * S,Sema & SemaRef,DSAStackTy & DSA,unsigned CurrentNestedLoopCount,unsigned NestedLoopCount,unsigned TotalNestedLoopCount,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)9087 static bool checkOpenMPIterationSpace(
9088 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9089 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9090 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9091 Expr *OrderedLoopCountExpr,
9092 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9093 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9094 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9095 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9096 // OpenMP [2.9.1, Canonical Loop Form]
9097 // for (init-expr; test-expr; incr-expr) structured-block
9098 // for (range-decl: range-expr) structured-block
9099 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9100 S = CanonLoop->getLoopStmt();
9101 auto *For = dyn_cast_or_null<ForStmt>(S);
9102 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9103 // Ranged for is supported only in OpenMP 5.0.
9104 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9105 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9106 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9107 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9108 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9109 if (TotalNestedLoopCount > 1) {
9110 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9111 SemaRef.Diag(DSA.getConstructLoc(),
9112 diag::note_omp_collapse_ordered_expr)
9113 << 2 << CollapseLoopCountExpr->getSourceRange()
9114 << OrderedLoopCountExpr->getSourceRange();
9115 else if (CollapseLoopCountExpr)
9116 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9117 diag::note_omp_collapse_ordered_expr)
9118 << 0 << CollapseLoopCountExpr->getSourceRange();
9119 else
9120 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9121 diag::note_omp_collapse_ordered_expr)
9122 << 1 << OrderedLoopCountExpr->getSourceRange();
9123 }
9124 return true;
9125 }
9126 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9127 "No loop body.");
9128 // Postpone analysis in dependent contexts for ranged for loops.
9129 if (CXXFor && SemaRef.CurContext->isDependentContext())
9130 return false;
9131
9132 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9133 For ? For->getForLoc() : CXXFor->getForLoc());
9134
9135 // Check init.
9136 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9137 if (ISC.checkAndSetInit(Init))
9138 return true;
9139
9140 bool HasErrors = false;
9141
9142 // Check loop variable's type.
9143 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9144 // OpenMP [2.6, Canonical Loop Form]
9145 // Var is one of the following:
9146 // A variable of signed or unsigned integer type.
9147 // For C++, a variable of a random access iterator type.
9148 // For C, a variable of a pointer type.
9149 QualType VarType = LCDecl->getType().getNonReferenceType();
9150 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9151 !VarType->isPointerType() &&
9152 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9153 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9154 << SemaRef.getLangOpts().CPlusPlus;
9155 HasErrors = true;
9156 }
9157
9158 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9159 // a Construct
9160 // The loop iteration variable(s) in the associated for-loop(s) of a for or
9161 // parallel for construct is (are) private.
9162 // The loop iteration variable in the associated for-loop of a simd
9163 // construct with just one associated for-loop is linear with a
9164 // constant-linear-step that is the increment of the associated for-loop.
9165 // Exclude loop var from the list of variables with implicitly defined data
9166 // sharing attributes.
9167 VarsWithImplicitDSA.erase(LCDecl);
9168
9169 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9170
9171 // Check test-expr.
9172 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9173
9174 // Check incr-expr.
9175 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9176 }
9177
9178 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9179 return HasErrors;
9180
9181 // Build the loop's iteration space representation.
9182 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9183 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9184 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9185 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9186 (isOpenMPWorksharingDirective(DKind) ||
9187 isOpenMPGenericLoopDirective(DKind) ||
9188 isOpenMPTaskLoopDirective(DKind) ||
9189 isOpenMPDistributeDirective(DKind) ||
9190 isOpenMPLoopTransformationDirective(DKind)),
9191 Captures);
9192 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9193 ISC.buildCounterVar(Captures, DSA);
9194 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9195 ISC.buildPrivateCounterVar();
9196 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9197 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9198 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9199 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9200 ISC.getConditionSrcRange();
9201 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9202 ISC.getIncrementSrcRange();
9203 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9204 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9205 ISC.isStrictTestOp();
9206 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9207 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9208 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9209 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9210 ISC.buildFinalCondition(DSA.getCurScope());
9211 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9212 ISC.doesInitDependOnLC();
9213 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9214 ISC.doesCondDependOnLC();
9215 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9216 ISC.getLoopDependentIdx();
9217
9218 HasErrors |=
9219 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9220 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9221 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9222 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9223 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9224 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9225 if (!HasErrors && DSA.isOrderedRegion()) {
9226 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9227 if (CurrentNestedLoopCount <
9228 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9229 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9230 CurrentNestedLoopCount,
9231 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9232 DSA.getOrderedRegionParam().second->setLoopCounter(
9233 CurrentNestedLoopCount,
9234 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9235 }
9236 }
9237 for (auto &Pair : DSA.getDoacrossDependClauses()) {
9238 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
9239 // Erroneous case - clause has some problems.
9240 continue;
9241 }
9242 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
9243 Pair.second.size() <= CurrentNestedLoopCount) {
9244 // Erroneous case - clause has some problems.
9245 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
9246 continue;
9247 }
9248 Expr *CntValue;
9249 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
9250 CntValue = ISC.buildOrderedLoopData(
9251 DSA.getCurScope(),
9252 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9253 Pair.first->getDependencyLoc());
9254 else
9255 CntValue = ISC.buildOrderedLoopData(
9256 DSA.getCurScope(),
9257 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9258 Pair.first->getDependencyLoc(),
9259 Pair.second[CurrentNestedLoopCount].first,
9260 Pair.second[CurrentNestedLoopCount].second);
9261 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9262 }
9263 }
9264
9265 return HasErrors;
9266 }
9267
9268 /// Build 'VarRef = Start.
9269 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)9270 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9271 ExprResult Start, bool IsNonRectangularLB,
9272 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9273 // Build 'VarRef = Start.
9274 ExprResult NewStart = IsNonRectangularLB
9275 ? Start.get()
9276 : tryBuildCapture(SemaRef, Start.get(), Captures);
9277 if (!NewStart.isUsable())
9278 return ExprError();
9279 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9280 VarRef.get()->getType())) {
9281 NewStart = SemaRef.PerformImplicitConversion(
9282 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9283 /*AllowExplicit=*/true);
9284 if (!NewStart.isUsable())
9285 return ExprError();
9286 }
9287
9288 ExprResult Init =
9289 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9290 return Init;
9291 }
9292
9293 /// Build 'VarRef = Start + Iter * Step'.
buildCounterUpdate(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,ExprResult Iter,ExprResult Step,bool Subtract,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > * Captures=nullptr)9294 static ExprResult buildCounterUpdate(
9295 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9296 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9297 bool IsNonRectangularLB,
9298 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9299 // Add parentheses (for debugging purposes only).
9300 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9301 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9302 !Step.isUsable())
9303 return ExprError();
9304
9305 ExprResult NewStep = Step;
9306 if (Captures)
9307 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9308 if (NewStep.isInvalid())
9309 return ExprError();
9310 ExprResult Update =
9311 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9312 if (!Update.isUsable())
9313 return ExprError();
9314
9315 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9316 // 'VarRef = Start (+|-) Iter * Step'.
9317 if (!Start.isUsable())
9318 return ExprError();
9319 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9320 if (!NewStart.isUsable())
9321 return ExprError();
9322 if (Captures && !IsNonRectangularLB)
9323 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9324 if (NewStart.isInvalid())
9325 return ExprError();
9326
9327 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9328 ExprResult SavedUpdate = Update;
9329 ExprResult UpdateVal;
9330 if (VarRef.get()->getType()->isOverloadableType() ||
9331 NewStart.get()->getType()->isOverloadableType() ||
9332 Update.get()->getType()->isOverloadableType()) {
9333 Sema::TentativeAnalysisScope Trap(SemaRef);
9334
9335 Update =
9336 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9337 if (Update.isUsable()) {
9338 UpdateVal =
9339 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9340 VarRef.get(), SavedUpdate.get());
9341 if (UpdateVal.isUsable()) {
9342 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9343 UpdateVal.get());
9344 }
9345 }
9346 }
9347
9348 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9349 if (!Update.isUsable() || !UpdateVal.isUsable()) {
9350 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9351 NewStart.get(), SavedUpdate.get());
9352 if (!Update.isUsable())
9353 return ExprError();
9354
9355 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9356 VarRef.get()->getType())) {
9357 Update = SemaRef.PerformImplicitConversion(
9358 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9359 if (!Update.isUsable())
9360 return ExprError();
9361 }
9362
9363 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9364 }
9365 return Update;
9366 }
9367
9368 /// Convert integer expression \a E to make it have at least \a Bits
9369 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)9370 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9371 if (E == nullptr)
9372 return ExprError();
9373 ASTContext &C = SemaRef.Context;
9374 QualType OldType = E->getType();
9375 unsigned HasBits = C.getTypeSize(OldType);
9376 if (HasBits >= Bits)
9377 return ExprResult(E);
9378 // OK to convert to signed, because new type has more bits than old.
9379 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9380 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9381 true);
9382 }
9383
9384 /// Check if the given expression \a E is a constant integer that fits
9385 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)9386 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9387 if (E == nullptr)
9388 return false;
9389 if (Optional<llvm::APSInt> Result =
9390 E->getIntegerConstantExpr(SemaRef.Context))
9391 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9392 return false;
9393 }
9394
9395 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)9396 static Stmt *buildPreInits(ASTContext &Context,
9397 MutableArrayRef<Decl *> PreInits) {
9398 if (!PreInits.empty()) {
9399 return new (Context) DeclStmt(
9400 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9401 SourceLocation(), SourceLocation());
9402 }
9403 return nullptr;
9404 }
9405
9406 /// Build preinits statement for the given declarations.
9407 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)9408 buildPreInits(ASTContext &Context,
9409 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9410 if (!Captures.empty()) {
9411 SmallVector<Decl *, 16> PreInits;
9412 for (const auto &Pair : Captures)
9413 PreInits.push_back(Pair.second->getDecl());
9414 return buildPreInits(Context, PreInits);
9415 }
9416 return nullptr;
9417 }
9418
9419 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)9420 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9421 Expr *PostUpdate = nullptr;
9422 if (!PostUpdates.empty()) {
9423 for (Expr *E : PostUpdates) {
9424 Expr *ConvE = S.BuildCStyleCastExpr(
9425 E->getExprLoc(),
9426 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9427 E->getExprLoc(), E)
9428 .get();
9429 PostUpdate = PostUpdate
9430 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9431 PostUpdate, ConvE)
9432 .get()
9433 : ConvE;
9434 }
9435 }
9436 return PostUpdate;
9437 }
9438
9439 /// Called on a for stmt to check itself and nested loops (if any).
9440 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9441 /// number of collapsed loops otherwise.
9442 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)9443 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9444 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9445 DSAStackTy &DSA,
9446 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9447 OMPLoopBasedDirective::HelperExprs &Built) {
9448 unsigned NestedLoopCount = 1;
9449 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9450 !isOpenMPLoopTransformationDirective(DKind);
9451
9452 if (CollapseLoopCountExpr) {
9453 // Found 'collapse' clause - calculate collapse number.
9454 Expr::EvalResult Result;
9455 if (!CollapseLoopCountExpr->isValueDependent() &&
9456 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9457 NestedLoopCount = Result.Val.getInt().getLimitedValue();
9458 } else {
9459 Built.clear(/*Size=*/1);
9460 return 1;
9461 }
9462 }
9463 unsigned OrderedLoopCount = 1;
9464 if (OrderedLoopCountExpr) {
9465 // Found 'ordered' clause - calculate collapse number.
9466 Expr::EvalResult EVResult;
9467 if (!OrderedLoopCountExpr->isValueDependent() &&
9468 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9469 SemaRef.getASTContext())) {
9470 llvm::APSInt Result = EVResult.Val.getInt();
9471 if (Result.getLimitedValue() < NestedLoopCount) {
9472 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9473 diag::err_omp_wrong_ordered_loop_count)
9474 << OrderedLoopCountExpr->getSourceRange();
9475 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9476 diag::note_collapse_loop_count)
9477 << CollapseLoopCountExpr->getSourceRange();
9478 }
9479 OrderedLoopCount = Result.getLimitedValue();
9480 } else {
9481 Built.clear(/*Size=*/1);
9482 return 1;
9483 }
9484 }
9485 // This is helper routine for loop directives (e.g., 'for', 'simd',
9486 // 'for simd', etc.).
9487 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9488 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9489 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9490 if (!OMPLoopBasedDirective::doForAllLoops(
9491 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9492 SupportsNonPerfectlyNested, NumLoops,
9493 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9494 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9495 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9496 if (checkOpenMPIterationSpace(
9497 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9498 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9499 VarsWithImplicitDSA, IterSpaces, Captures))
9500 return true;
9501 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9502 IterSpaces[Cnt].CounterVar) {
9503 // Handle initialization of captured loop iterator variables.
9504 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9505 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9506 Captures[DRE] = DRE;
9507 }
9508 }
9509 return false;
9510 },
9511 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9512 Stmt *DependentPreInits = Transform->getPreInits();
9513 if (!DependentPreInits)
9514 return;
9515 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9516 auto *D = cast<VarDecl>(C);
9517 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9518 Transform->getBeginLoc());
9519 Captures[Ref] = Ref;
9520 }
9521 }))
9522 return 0;
9523
9524 Built.clear(/* size */ NestedLoopCount);
9525
9526 if (SemaRef.CurContext->isDependentContext())
9527 return NestedLoopCount;
9528
9529 // An example of what is generated for the following code:
9530 //
9531 // #pragma omp simd collapse(2) ordered(2)
9532 // for (i = 0; i < NI; ++i)
9533 // for (k = 0; k < NK; ++k)
9534 // for (j = J0; j < NJ; j+=2) {
9535 // <loop body>
9536 // }
9537 //
9538 // We generate the code below.
9539 // Note: the loop body may be outlined in CodeGen.
9540 // Note: some counters may be C++ classes, operator- is used to find number of
9541 // iterations and operator+= to calculate counter value.
9542 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9543 // or i64 is currently supported).
9544 //
9545 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9546 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9547 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9548 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9549 // // similar updates for vars in clauses (e.g. 'linear')
9550 // <loop body (using local i and j)>
9551 // }
9552 // i = NI; // assign final values of counters
9553 // j = NJ;
9554 //
9555
9556 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9557 // the iteration counts of the collapsed for loops.
9558 // Precondition tests if there is at least one iteration (all conditions are
9559 // true).
9560 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9561 Expr *N0 = IterSpaces[0].NumIterations;
9562 ExprResult LastIteration32 =
9563 widenIterationCount(/*Bits=*/32,
9564 SemaRef
9565 .PerformImplicitConversion(
9566 N0->IgnoreImpCasts(), N0->getType(),
9567 Sema::AA_Converting, /*AllowExplicit=*/true)
9568 .get(),
9569 SemaRef);
9570 ExprResult LastIteration64 = widenIterationCount(
9571 /*Bits=*/64,
9572 SemaRef
9573 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9574 Sema::AA_Converting,
9575 /*AllowExplicit=*/true)
9576 .get(),
9577 SemaRef);
9578
9579 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9580 return NestedLoopCount;
9581
9582 ASTContext &C = SemaRef.Context;
9583 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9584
9585 Scope *CurScope = DSA.getCurScope();
9586 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9587 if (PreCond.isUsable()) {
9588 PreCond =
9589 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9590 PreCond.get(), IterSpaces[Cnt].PreCond);
9591 }
9592 Expr *N = IterSpaces[Cnt].NumIterations;
9593 SourceLocation Loc = N->getExprLoc();
9594 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9595 if (LastIteration32.isUsable())
9596 LastIteration32 = SemaRef.BuildBinOp(
9597 CurScope, Loc, BO_Mul, LastIteration32.get(),
9598 SemaRef
9599 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9600 Sema::AA_Converting,
9601 /*AllowExplicit=*/true)
9602 .get());
9603 if (LastIteration64.isUsable())
9604 LastIteration64 = SemaRef.BuildBinOp(
9605 CurScope, Loc, BO_Mul, LastIteration64.get(),
9606 SemaRef
9607 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9608 Sema::AA_Converting,
9609 /*AllowExplicit=*/true)
9610 .get());
9611 }
9612
9613 // Choose either the 32-bit or 64-bit version.
9614 ExprResult LastIteration = LastIteration64;
9615 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9616 (LastIteration32.isUsable() &&
9617 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9618 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9619 fitsInto(
9620 /*Bits=*/32,
9621 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9622 LastIteration64.get(), SemaRef))))
9623 LastIteration = LastIteration32;
9624 QualType VType = LastIteration.get()->getType();
9625 QualType RealVType = VType;
9626 QualType StrideVType = VType;
9627 if (isOpenMPTaskLoopDirective(DKind)) {
9628 VType =
9629 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9630 StrideVType =
9631 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9632 }
9633
9634 if (!LastIteration.isUsable())
9635 return 0;
9636
9637 // Save the number of iterations.
9638 ExprResult NumIterations = LastIteration;
9639 {
9640 LastIteration = SemaRef.BuildBinOp(
9641 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9642 LastIteration.get(),
9643 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9644 if (!LastIteration.isUsable())
9645 return 0;
9646 }
9647
9648 // Calculate the last iteration number beforehand instead of doing this on
9649 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9650 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9651 ExprResult CalcLastIteration;
9652 if (!IsConstant) {
9653 ExprResult SaveRef =
9654 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9655 LastIteration = SaveRef;
9656
9657 // Prepare SaveRef + 1.
9658 NumIterations = SemaRef.BuildBinOp(
9659 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9660 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9661 if (!NumIterations.isUsable())
9662 return 0;
9663 }
9664
9665 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9666
9667 // Build variables passed into runtime, necessary for worksharing directives.
9668 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9669 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9670 isOpenMPDistributeDirective(DKind) ||
9671 isOpenMPGenericLoopDirective(DKind) ||
9672 isOpenMPLoopTransformationDirective(DKind)) {
9673 // Lower bound variable, initialized with zero.
9674 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9675 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9676 SemaRef.AddInitializerToDecl(LBDecl,
9677 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9678 /*DirectInit*/ false);
9679
9680 // Upper bound variable, initialized with last iteration number.
9681 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9682 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9683 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9684 /*DirectInit*/ false);
9685
9686 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9687 // This will be used to implement clause 'lastprivate'.
9688 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9689 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9690 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9691 SemaRef.AddInitializerToDecl(ILDecl,
9692 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9693 /*DirectInit*/ false);
9694
9695 // Stride variable returned by runtime (we initialize it to 1 by default).
9696 VarDecl *STDecl =
9697 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9698 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9699 SemaRef.AddInitializerToDecl(STDecl,
9700 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9701 /*DirectInit*/ false);
9702
9703 // Build expression: UB = min(UB, LastIteration)
9704 // It is necessary for CodeGen of directives with static scheduling.
9705 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9706 UB.get(), LastIteration.get());
9707 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9708 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9709 LastIteration.get(), UB.get());
9710 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9711 CondOp.get());
9712 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9713
9714 // If we have a combined directive that combines 'distribute', 'for' or
9715 // 'simd' we need to be able to access the bounds of the schedule of the
9716 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9717 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9718 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9719 // Lower bound variable, initialized with zero.
9720 VarDecl *CombLBDecl =
9721 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9722 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9723 SemaRef.AddInitializerToDecl(
9724 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9725 /*DirectInit*/ false);
9726
9727 // Upper bound variable, initialized with last iteration number.
9728 VarDecl *CombUBDecl =
9729 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9730 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9731 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9732 /*DirectInit*/ false);
9733
9734 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9735 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9736 ExprResult CombCondOp =
9737 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9738 LastIteration.get(), CombUB.get());
9739 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9740 CombCondOp.get());
9741 CombEUB =
9742 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9743
9744 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9745 // We expect to have at least 2 more parameters than the 'parallel'
9746 // directive does - the lower and upper bounds of the previous schedule.
9747 assert(CD->getNumParams() >= 4 &&
9748 "Unexpected number of parameters in loop combined directive");
9749
9750 // Set the proper type for the bounds given what we learned from the
9751 // enclosed loops.
9752 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9753 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9754
9755 // Previous lower and upper bounds are obtained from the region
9756 // parameters.
9757 PrevLB =
9758 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9759 PrevUB =
9760 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9761 }
9762 }
9763
9764 // Build the iteration variable and its initialization before loop.
9765 ExprResult IV;
9766 ExprResult Init, CombInit;
9767 {
9768 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9769 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9770 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9771 isOpenMPGenericLoopDirective(DKind) ||
9772 isOpenMPTaskLoopDirective(DKind) ||
9773 isOpenMPDistributeDirective(DKind) ||
9774 isOpenMPLoopTransformationDirective(DKind))
9775 ? LB.get()
9776 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9777 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9778 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9779
9780 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9781 Expr *CombRHS =
9782 (isOpenMPWorksharingDirective(DKind) ||
9783 isOpenMPGenericLoopDirective(DKind) ||
9784 isOpenMPTaskLoopDirective(DKind) ||
9785 isOpenMPDistributeDirective(DKind))
9786 ? CombLB.get()
9787 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9788 CombInit =
9789 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9790 CombInit =
9791 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9792 }
9793 }
9794
9795 bool UseStrictCompare =
9796 RealVType->hasUnsignedIntegerRepresentation() &&
9797 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9798 return LIS.IsStrictCompare;
9799 });
9800 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9801 // unsigned IV)) for worksharing loops.
9802 SourceLocation CondLoc = AStmt->getBeginLoc();
9803 Expr *BoundUB = UB.get();
9804 if (UseStrictCompare) {
9805 BoundUB =
9806 SemaRef
9807 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9808 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9809 .get();
9810 BoundUB =
9811 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9812 }
9813 ExprResult Cond =
9814 (isOpenMPWorksharingDirective(DKind) ||
9815 isOpenMPGenericLoopDirective(DKind) ||
9816 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9817 isOpenMPLoopTransformationDirective(DKind))
9818 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9819 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9820 BoundUB)
9821 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9822 NumIterations.get());
9823 ExprResult CombDistCond;
9824 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9825 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9826 NumIterations.get());
9827 }
9828
9829 ExprResult CombCond;
9830 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9831 Expr *BoundCombUB = CombUB.get();
9832 if (UseStrictCompare) {
9833 BoundCombUB =
9834 SemaRef
9835 .BuildBinOp(
9836 CurScope, CondLoc, BO_Add, BoundCombUB,
9837 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9838 .get();
9839 BoundCombUB =
9840 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9841 .get();
9842 }
9843 CombCond =
9844 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9845 IV.get(), BoundCombUB);
9846 }
9847 // Loop increment (IV = IV + 1)
9848 SourceLocation IncLoc = AStmt->getBeginLoc();
9849 ExprResult Inc =
9850 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9851 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9852 if (!Inc.isUsable())
9853 return 0;
9854 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9855 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9856 if (!Inc.isUsable())
9857 return 0;
9858
9859 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9860 // Used for directives with static scheduling.
9861 // In combined construct, add combined version that use CombLB and CombUB
9862 // base variables for the update
9863 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9864 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9865 isOpenMPGenericLoopDirective(DKind) ||
9866 isOpenMPDistributeDirective(DKind) ||
9867 isOpenMPLoopTransformationDirective(DKind)) {
9868 // LB + ST
9869 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9870 if (!NextLB.isUsable())
9871 return 0;
9872 // LB = LB + ST
9873 NextLB =
9874 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9875 NextLB =
9876 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9877 if (!NextLB.isUsable())
9878 return 0;
9879 // UB + ST
9880 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9881 if (!NextUB.isUsable())
9882 return 0;
9883 // UB = UB + ST
9884 NextUB =
9885 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9886 NextUB =
9887 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9888 if (!NextUB.isUsable())
9889 return 0;
9890 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9891 CombNextLB =
9892 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9893 if (!NextLB.isUsable())
9894 return 0;
9895 // LB = LB + ST
9896 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9897 CombNextLB.get());
9898 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9899 /*DiscardedValue*/ false);
9900 if (!CombNextLB.isUsable())
9901 return 0;
9902 // UB + ST
9903 CombNextUB =
9904 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9905 if (!CombNextUB.isUsable())
9906 return 0;
9907 // UB = UB + ST
9908 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9909 CombNextUB.get());
9910 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9911 /*DiscardedValue*/ false);
9912 if (!CombNextUB.isUsable())
9913 return 0;
9914 }
9915 }
9916
9917 // Create increment expression for distribute loop when combined in a same
9918 // directive with for as IV = IV + ST; ensure upper bound expression based
9919 // on PrevUB instead of NumIterations - used to implement 'for' when found
9920 // in combination with 'distribute', like in 'distribute parallel for'
9921 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9922 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9923 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9924 DistCond = SemaRef.BuildBinOp(
9925 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9926 assert(DistCond.isUsable() && "distribute cond expr was not built");
9927
9928 DistInc =
9929 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9930 assert(DistInc.isUsable() && "distribute inc expr was not built");
9931 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9932 DistInc.get());
9933 DistInc =
9934 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9935 assert(DistInc.isUsable() && "distribute inc expr was not built");
9936
9937 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9938 // construct
9939 ExprResult NewPrevUB = PrevUB;
9940 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9941 if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9942 PrevUB.get()->getType())) {
9943 NewPrevUB = SemaRef.BuildCStyleCastExpr(
9944 DistEUBLoc,
9945 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9946 DistEUBLoc, NewPrevUB.get());
9947 if (!NewPrevUB.isUsable())
9948 return 0;
9949 }
9950 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9951 UB.get(), NewPrevUB.get());
9952 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9953 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9954 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9955 CondOp.get());
9956 PrevEUB =
9957 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9958
9959 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9960 // parallel for is in combination with a distribute directive with
9961 // schedule(static, 1)
9962 Expr *BoundPrevUB = PrevUB.get();
9963 if (UseStrictCompare) {
9964 BoundPrevUB =
9965 SemaRef
9966 .BuildBinOp(
9967 CurScope, CondLoc, BO_Add, BoundPrevUB,
9968 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9969 .get();
9970 BoundPrevUB =
9971 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9972 .get();
9973 }
9974 ParForInDistCond =
9975 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9976 IV.get(), BoundPrevUB);
9977 }
9978
9979 // Build updates and final values of the loop counters.
9980 bool HasErrors = false;
9981 Built.Counters.resize(NestedLoopCount);
9982 Built.Inits.resize(NestedLoopCount);
9983 Built.Updates.resize(NestedLoopCount);
9984 Built.Finals.resize(NestedLoopCount);
9985 Built.DependentCounters.resize(NestedLoopCount);
9986 Built.DependentInits.resize(NestedLoopCount);
9987 Built.FinalsConditions.resize(NestedLoopCount);
9988 {
9989 // We implement the following algorithm for obtaining the
9990 // original loop iteration variable values based on the
9991 // value of the collapsed loop iteration variable IV.
9992 //
9993 // Let n+1 be the number of collapsed loops in the nest.
9994 // Iteration variables (I0, I1, .... In)
9995 // Iteration counts (N0, N1, ... Nn)
9996 //
9997 // Acc = IV;
9998 //
9999 // To compute Ik for loop k, 0 <= k <= n, generate:
10000 // Prod = N(k+1) * N(k+2) * ... * Nn;
10001 // Ik = Acc / Prod;
10002 // Acc -= Ik * Prod;
10003 //
10004 ExprResult Acc = IV;
10005 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10006 LoopIterationSpace &IS = IterSpaces[Cnt];
10007 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10008 ExprResult Iter;
10009
10010 // Compute prod
10011 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10012 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10013 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10014 IterSpaces[K].NumIterations);
10015
10016 // Iter = Acc / Prod
10017 // If there is at least one more inner loop to avoid
10018 // multiplication by 1.
10019 if (Cnt + 1 < NestedLoopCount)
10020 Iter =
10021 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10022 else
10023 Iter = Acc;
10024 if (!Iter.isUsable()) {
10025 HasErrors = true;
10026 break;
10027 }
10028
10029 // Update Acc:
10030 // Acc -= Iter * Prod
10031 // Check if there is at least one more inner loop to avoid
10032 // multiplication by 1.
10033 if (Cnt + 1 < NestedLoopCount)
10034 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10035 Prod.get());
10036 else
10037 Prod = Iter;
10038 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10039
10040 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10041 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10042 DeclRefExpr *CounterVar = buildDeclRefExpr(
10043 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10044 /*RefersToCapture=*/true);
10045 ExprResult Init =
10046 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10047 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10048 if (!Init.isUsable()) {
10049 HasErrors = true;
10050 break;
10051 }
10052 ExprResult Update = buildCounterUpdate(
10053 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10054 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10055 if (!Update.isUsable()) {
10056 HasErrors = true;
10057 break;
10058 }
10059
10060 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10061 ExprResult Final =
10062 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10063 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10064 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10065 if (!Final.isUsable()) {
10066 HasErrors = true;
10067 break;
10068 }
10069
10070 if (!Update.isUsable() || !Final.isUsable()) {
10071 HasErrors = true;
10072 break;
10073 }
10074 // Save results
10075 Built.Counters[Cnt] = IS.CounterVar;
10076 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10077 Built.Inits[Cnt] = Init.get();
10078 Built.Updates[Cnt] = Update.get();
10079 Built.Finals[Cnt] = Final.get();
10080 Built.DependentCounters[Cnt] = nullptr;
10081 Built.DependentInits[Cnt] = nullptr;
10082 Built.FinalsConditions[Cnt] = nullptr;
10083 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10084 Built.DependentCounters[Cnt] =
10085 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
10086 Built.DependentInits[Cnt] =
10087 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
10088 Built.FinalsConditions[Cnt] = IS.FinalCondition;
10089 }
10090 }
10091 }
10092
10093 if (HasErrors)
10094 return 0;
10095
10096 // Save results
10097 Built.IterationVarRef = IV.get();
10098 Built.LastIteration = LastIteration.get();
10099 Built.NumIterations = NumIterations.get();
10100 Built.CalcLastIteration = SemaRef
10101 .ActOnFinishFullExpr(CalcLastIteration.get(),
10102 /*DiscardedValue=*/false)
10103 .get();
10104 Built.PreCond = PreCond.get();
10105 Built.PreInits = buildPreInits(C, Captures);
10106 Built.Cond = Cond.get();
10107 Built.Init = Init.get();
10108 Built.Inc = Inc.get();
10109 Built.LB = LB.get();
10110 Built.UB = UB.get();
10111 Built.IL = IL.get();
10112 Built.ST = ST.get();
10113 Built.EUB = EUB.get();
10114 Built.NLB = NextLB.get();
10115 Built.NUB = NextUB.get();
10116 Built.PrevLB = PrevLB.get();
10117 Built.PrevUB = PrevUB.get();
10118 Built.DistInc = DistInc.get();
10119 Built.PrevEUB = PrevEUB.get();
10120 Built.DistCombinedFields.LB = CombLB.get();
10121 Built.DistCombinedFields.UB = CombUB.get();
10122 Built.DistCombinedFields.EUB = CombEUB.get();
10123 Built.DistCombinedFields.Init = CombInit.get();
10124 Built.DistCombinedFields.Cond = CombCond.get();
10125 Built.DistCombinedFields.NLB = CombNextLB.get();
10126 Built.DistCombinedFields.NUB = CombNextUB.get();
10127 Built.DistCombinedFields.DistCond = CombDistCond.get();
10128 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10129
10130 return NestedLoopCount;
10131 }
10132
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)10133 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10134 auto CollapseClauses =
10135 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10136 if (CollapseClauses.begin() != CollapseClauses.end())
10137 return (*CollapseClauses.begin())->getNumForLoops();
10138 return nullptr;
10139 }
10140
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)10141 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10142 auto OrderedClauses =
10143 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10144 if (OrderedClauses.begin() != OrderedClauses.end())
10145 return (*OrderedClauses.begin())->getNumForLoops();
10146 return nullptr;
10147 }
10148
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)10149 static bool checkSimdlenSafelenSpecified(Sema &S,
10150 const ArrayRef<OMPClause *> Clauses) {
10151 const OMPSafelenClause *Safelen = nullptr;
10152 const OMPSimdlenClause *Simdlen = nullptr;
10153
10154 for (const OMPClause *Clause : Clauses) {
10155 if (Clause->getClauseKind() == OMPC_safelen)
10156 Safelen = cast<OMPSafelenClause>(Clause);
10157 else if (Clause->getClauseKind() == OMPC_simdlen)
10158 Simdlen = cast<OMPSimdlenClause>(Clause);
10159 if (Safelen && Simdlen)
10160 break;
10161 }
10162
10163 if (Simdlen && Safelen) {
10164 const Expr *SimdlenLength = Simdlen->getSimdlen();
10165 const Expr *SafelenLength = Safelen->getSafelen();
10166 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10167 SimdlenLength->isInstantiationDependent() ||
10168 SimdlenLength->containsUnexpandedParameterPack())
10169 return false;
10170 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10171 SafelenLength->isInstantiationDependent() ||
10172 SafelenLength->containsUnexpandedParameterPack())
10173 return false;
10174 Expr::EvalResult SimdlenResult, SafelenResult;
10175 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10176 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10177 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10178 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10179 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10180 // If both simdlen and safelen clauses are specified, the value of the
10181 // simdlen parameter must be less than or equal to the value of the safelen
10182 // parameter.
10183 if (SimdlenRes > SafelenRes) {
10184 S.Diag(SimdlenLength->getExprLoc(),
10185 diag::err_omp_wrong_simdlen_safelen_values)
10186 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10187 return true;
10188 }
10189 }
10190 return false;
10191 }
10192
10193 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10194 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10195 SourceLocation StartLoc, SourceLocation EndLoc,
10196 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10197 if (!AStmt)
10198 return StmtError();
10199
10200 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10201 OMPLoopBasedDirective::HelperExprs B;
10202 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10203 // define the nested loops number.
10204 unsigned NestedLoopCount = checkOpenMPLoop(
10205 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10206 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10207 if (NestedLoopCount == 0)
10208 return StmtError();
10209
10210 assert((CurContext->isDependentContext() || B.builtAll()) &&
10211 "omp simd loop exprs were not built");
10212
10213 if (!CurContext->isDependentContext()) {
10214 // Finalize the clauses that need pre-built expressions for CodeGen.
10215 for (OMPClause *C : Clauses) {
10216 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10217 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10218 B.NumIterations, *this, CurScope,
10219 DSAStack))
10220 return StmtError();
10221 }
10222 }
10223
10224 if (checkSimdlenSafelenSpecified(*this, Clauses))
10225 return StmtError();
10226
10227 setFunctionHasBranchProtectedScope();
10228 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10229 Clauses, AStmt, B);
10230 }
10231
10232 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10233 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10234 SourceLocation StartLoc, SourceLocation EndLoc,
10235 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10236 if (!AStmt)
10237 return StmtError();
10238
10239 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10240 OMPLoopBasedDirective::HelperExprs B;
10241 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10242 // define the nested loops number.
10243 unsigned NestedLoopCount = checkOpenMPLoop(
10244 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10245 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10246 if (NestedLoopCount == 0)
10247 return StmtError();
10248
10249 assert((CurContext->isDependentContext() || B.builtAll()) &&
10250 "omp for loop exprs were not built");
10251
10252 if (!CurContext->isDependentContext()) {
10253 // Finalize the clauses that need pre-built expressions for CodeGen.
10254 for (OMPClause *C : Clauses) {
10255 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10256 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10257 B.NumIterations, *this, CurScope,
10258 DSAStack))
10259 return StmtError();
10260 }
10261 }
10262
10263 setFunctionHasBranchProtectedScope();
10264 return OMPForDirective::Create(
10265 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10266 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10267 }
10268
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10269 StmtResult Sema::ActOnOpenMPForSimdDirective(
10270 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10271 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10272 if (!AStmt)
10273 return StmtError();
10274
10275 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10276 OMPLoopBasedDirective::HelperExprs B;
10277 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10278 // define the nested loops number.
10279 unsigned NestedLoopCount =
10280 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10281 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10282 VarsWithImplicitDSA, B);
10283 if (NestedLoopCount == 0)
10284 return StmtError();
10285
10286 assert((CurContext->isDependentContext() || B.builtAll()) &&
10287 "omp for simd loop exprs were not built");
10288
10289 if (!CurContext->isDependentContext()) {
10290 // Finalize the clauses that need pre-built expressions for CodeGen.
10291 for (OMPClause *C : Clauses) {
10292 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10293 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10294 B.NumIterations, *this, CurScope,
10295 DSAStack))
10296 return StmtError();
10297 }
10298 }
10299
10300 if (checkSimdlenSafelenSpecified(*this, Clauses))
10301 return StmtError();
10302
10303 setFunctionHasBranchProtectedScope();
10304 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10305 Clauses, AStmt, B);
10306 }
10307
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10308 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10309 Stmt *AStmt,
10310 SourceLocation StartLoc,
10311 SourceLocation EndLoc) {
10312 if (!AStmt)
10313 return StmtError();
10314
10315 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10316 auto BaseStmt = AStmt;
10317 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10318 BaseStmt = CS->getCapturedStmt();
10319 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10320 auto S = C->children();
10321 if (S.begin() == S.end())
10322 return StmtError();
10323 // All associated statements must be '#pragma omp section' except for
10324 // the first one.
10325 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10326 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10327 if (SectionStmt)
10328 Diag(SectionStmt->getBeginLoc(),
10329 diag::err_omp_sections_substmt_not_section);
10330 return StmtError();
10331 }
10332 cast<OMPSectionDirective>(SectionStmt)
10333 ->setHasCancel(DSAStack->isCancelRegion());
10334 }
10335 } else {
10336 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10337 return StmtError();
10338 }
10339
10340 setFunctionHasBranchProtectedScope();
10341
10342 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10343 DSAStack->getTaskgroupReductionRef(),
10344 DSAStack->isCancelRegion());
10345 }
10346
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10347 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10348 SourceLocation StartLoc,
10349 SourceLocation EndLoc) {
10350 if (!AStmt)
10351 return StmtError();
10352
10353 setFunctionHasBranchProtectedScope();
10354 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10355
10356 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10357 DSAStack->isCancelRegion());
10358 }
10359
getDirectCallExpr(Expr * E)10360 static Expr *getDirectCallExpr(Expr *E) {
10361 E = E->IgnoreParenCasts()->IgnoreImplicit();
10362 if (auto *CE = dyn_cast<CallExpr>(E))
10363 if (CE->getDirectCallee())
10364 return E;
10365 return nullptr;
10366 }
10367
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10368 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10369 Stmt *AStmt,
10370 SourceLocation StartLoc,
10371 SourceLocation EndLoc) {
10372 if (!AStmt)
10373 return StmtError();
10374
10375 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10376
10377 // 5.1 OpenMP
10378 // expression-stmt : an expression statement with one of the following forms:
10379 // expression = target-call ( [expression-list] );
10380 // target-call ( [expression-list] );
10381
10382 SourceLocation TargetCallLoc;
10383
10384 if (!CurContext->isDependentContext()) {
10385 Expr *TargetCall = nullptr;
10386
10387 auto *E = dyn_cast<Expr>(S);
10388 if (!E) {
10389 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10390 return StmtError();
10391 }
10392
10393 E = E->IgnoreParenCasts()->IgnoreImplicit();
10394
10395 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10396 if (BO->getOpcode() == BO_Assign)
10397 TargetCall = getDirectCallExpr(BO->getRHS());
10398 } else {
10399 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10400 if (COCE->getOperator() == OO_Equal)
10401 TargetCall = getDirectCallExpr(COCE->getArg(1));
10402 if (!TargetCall)
10403 TargetCall = getDirectCallExpr(E);
10404 }
10405 if (!TargetCall) {
10406 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10407 return StmtError();
10408 }
10409 TargetCallLoc = TargetCall->getExprLoc();
10410 }
10411
10412 setFunctionHasBranchProtectedScope();
10413
10414 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10415 TargetCallLoc);
10416 }
10417
checkGenericLoopLastprivate(Sema & S,ArrayRef<OMPClause * > Clauses,OpenMPDirectiveKind K,DSAStackTy * Stack)10418 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10419 OpenMPDirectiveKind K,
10420 DSAStackTy *Stack) {
10421 bool ErrorFound = false;
10422 for (OMPClause *C : Clauses) {
10423 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10424 for (Expr *RefExpr : LPC->varlists()) {
10425 SourceLocation ELoc;
10426 SourceRange ERange;
10427 Expr *SimpleRefExpr = RefExpr;
10428 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10429 if (ValueDecl *D = Res.first) {
10430 auto &&Info = Stack->isLoopControlVariable(D);
10431 if (!Info.first) {
10432 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10433 << getOpenMPDirectiveName(K);
10434 ErrorFound = true;
10435 }
10436 }
10437 }
10438 }
10439 }
10440 return ErrorFound;
10441 }
10442
ActOnOpenMPGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10443 StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10446 if (!AStmt)
10447 return StmtError();
10448
10449 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10450 // A list item may not appear in a lastprivate clause unless it is the
10451 // loop iteration variable of a loop that is associated with the construct.
10452 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10453 return StmtError();
10454
10455 auto *CS = cast<CapturedStmt>(AStmt);
10456 // 1.2.2 OpenMP Language Terminology
10457 // Structured block - An executable statement with a single entry at the
10458 // top and a single exit at the bottom.
10459 // The point of exit cannot be a branch out of the structured block.
10460 // longjmp() and throw() must not violate the entry/exit criteria.
10461 CS->getCapturedDecl()->setNothrow();
10462
10463 OMPLoopDirective::HelperExprs B;
10464 // In presence of clause 'collapse', it will define the nested loops number.
10465 unsigned NestedLoopCount = checkOpenMPLoop(
10466 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10467 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10468 if (NestedLoopCount == 0)
10469 return StmtError();
10470
10471 assert((CurContext->isDependentContext() || B.builtAll()) &&
10472 "omp loop exprs were not built");
10473
10474 setFunctionHasBranchProtectedScope();
10475 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10476 NestedLoopCount, Clauses, AStmt, B);
10477 }
10478
ActOnOpenMPTeamsGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10479 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10480 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10481 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10482 if (!AStmt)
10483 return StmtError();
10484
10485 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10486 // A list item may not appear in a lastprivate clause unless it is the
10487 // loop iteration variable of a loop that is associated with the construct.
10488 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10489 return StmtError();
10490
10491 auto *CS = cast<CapturedStmt>(AStmt);
10492 // 1.2.2 OpenMP Language Terminology
10493 // Structured block - An executable statement with a single entry at the
10494 // top and a single exit at the bottom.
10495 // The point of exit cannot be a branch out of the structured block.
10496 // longjmp() and throw() must not violate the entry/exit criteria.
10497 CS->getCapturedDecl()->setNothrow();
10498 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10499 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10500 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10501 // 1.2.2 OpenMP Language Terminology
10502 // Structured block - An executable statement with a single entry at the
10503 // top and a single exit at the bottom.
10504 // The point of exit cannot be a branch out of the structured block.
10505 // longjmp() and throw() must not violate the entry/exit criteria.
10506 CS->getCapturedDecl()->setNothrow();
10507 }
10508
10509 OMPLoopDirective::HelperExprs B;
10510 // In presence of clause 'collapse', it will define the nested loops number.
10511 unsigned NestedLoopCount =
10512 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10513 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10514 VarsWithImplicitDSA, B);
10515 if (NestedLoopCount == 0)
10516 return StmtError();
10517
10518 assert((CurContext->isDependentContext() || B.builtAll()) &&
10519 "omp loop exprs were not built");
10520
10521 setFunctionHasBranchProtectedScope();
10522 DSAStack->setParentTeamsRegionLoc(StartLoc);
10523
10524 return OMPTeamsGenericLoopDirective::Create(
10525 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10526 }
10527
ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10528 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10529 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10530 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10531 if (!AStmt)
10532 return StmtError();
10533
10534 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10535 // A list item may not appear in a lastprivate clause unless it is the
10536 // loop iteration variable of a loop that is associated with the construct.
10537 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10538 DSAStack))
10539 return StmtError();
10540
10541 auto *CS = cast<CapturedStmt>(AStmt);
10542 // 1.2.2 OpenMP Language Terminology
10543 // Structured block - An executable statement with a single entry at the
10544 // top and a single exit at the bottom.
10545 // The point of exit cannot be a branch out of the structured block.
10546 // longjmp() and throw() must not violate the entry/exit criteria.
10547 CS->getCapturedDecl()->setNothrow();
10548 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10549 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10550 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10551 // 1.2.2 OpenMP Language Terminology
10552 // Structured block - An executable statement with a single entry at the
10553 // top and a single exit at the bottom.
10554 // The point of exit cannot be a branch out of the structured block.
10555 // longjmp() and throw() must not violate the entry/exit criteria.
10556 CS->getCapturedDecl()->setNothrow();
10557 }
10558
10559 OMPLoopDirective::HelperExprs B;
10560 // In presence of clause 'collapse', it will define the nested loops number.
10561 unsigned NestedLoopCount =
10562 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10563 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10564 VarsWithImplicitDSA, B);
10565 if (NestedLoopCount == 0)
10566 return StmtError();
10567
10568 assert((CurContext->isDependentContext() || B.builtAll()) &&
10569 "omp loop exprs were not built");
10570
10571 setFunctionHasBranchProtectedScope();
10572
10573 return OMPTargetTeamsGenericLoopDirective::Create(
10574 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10575 }
10576
ActOnOpenMPParallelGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10577 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10578 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10579 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10580 if (!AStmt)
10581 return StmtError();
10582
10583 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10584 // A list item may not appear in a lastprivate clause unless it is the
10585 // loop iteration variable of a loop that is associated with the construct.
10586 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10587 return StmtError();
10588
10589 auto *CS = cast<CapturedStmt>(AStmt);
10590 // 1.2.2 OpenMP Language Terminology
10591 // Structured block - An executable statement with a single entry at the
10592 // top and a single exit at the bottom.
10593 // The point of exit cannot be a branch out of the structured block.
10594 // longjmp() and throw() must not violate the entry/exit criteria.
10595 CS->getCapturedDecl()->setNothrow();
10596 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10597 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10598 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10599 // 1.2.2 OpenMP Language Terminology
10600 // Structured block - An executable statement with a single entry at the
10601 // top and a single exit at the bottom.
10602 // The point of exit cannot be a branch out of the structured block.
10603 // longjmp() and throw() must not violate the entry/exit criteria.
10604 CS->getCapturedDecl()->setNothrow();
10605 }
10606
10607 OMPLoopDirective::HelperExprs B;
10608 // In presence of clause 'collapse', it will define the nested loops number.
10609 unsigned NestedLoopCount =
10610 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10611 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10612 VarsWithImplicitDSA, B);
10613 if (NestedLoopCount == 0)
10614 return StmtError();
10615
10616 assert((CurContext->isDependentContext() || B.builtAll()) &&
10617 "omp loop exprs were not built");
10618
10619 setFunctionHasBranchProtectedScope();
10620
10621 return OMPParallelGenericLoopDirective::Create(
10622 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10623 }
10624
ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10625 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10626 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10627 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10628 if (!AStmt)
10629 return StmtError();
10630
10631 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10632 // A list item may not appear in a lastprivate clause unless it is the
10633 // loop iteration variable of a loop that is associated with the construct.
10634 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10635 DSAStack))
10636 return StmtError();
10637
10638 auto *CS = cast<CapturedStmt>(AStmt);
10639 // 1.2.2 OpenMP Language Terminology
10640 // Structured block - An executable statement with a single entry at the
10641 // top and a single exit at the bottom.
10642 // The point of exit cannot be a branch out of the structured block.
10643 // longjmp() and throw() must not violate the entry/exit criteria.
10644 CS->getCapturedDecl()->setNothrow();
10645 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10646 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10647 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10648 // 1.2.2 OpenMP Language Terminology
10649 // Structured block - An executable statement with a single entry at the
10650 // top and a single exit at the bottom.
10651 // The point of exit cannot be a branch out of the structured block.
10652 // longjmp() and throw() must not violate the entry/exit criteria.
10653 CS->getCapturedDecl()->setNothrow();
10654 }
10655
10656 OMPLoopDirective::HelperExprs B;
10657 // In presence of clause 'collapse', it will define the nested loops number.
10658 unsigned NestedLoopCount =
10659 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10660 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10661 VarsWithImplicitDSA, B);
10662 if (NestedLoopCount == 0)
10663 return StmtError();
10664
10665 assert((CurContext->isDependentContext() || B.builtAll()) &&
10666 "omp loop exprs were not built");
10667
10668 setFunctionHasBranchProtectedScope();
10669
10670 return OMPTargetParallelGenericLoopDirective::Create(
10671 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10672 }
10673
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10674 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10675 Stmt *AStmt,
10676 SourceLocation StartLoc,
10677 SourceLocation EndLoc) {
10678 if (!AStmt)
10679 return StmtError();
10680
10681 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10682
10683 setFunctionHasBranchProtectedScope();
10684
10685 // OpenMP [2.7.3, single Construct, Restrictions]
10686 // The copyprivate clause must not be used with the nowait clause.
10687 const OMPClause *Nowait = nullptr;
10688 const OMPClause *Copyprivate = nullptr;
10689 for (const OMPClause *Clause : Clauses) {
10690 if (Clause->getClauseKind() == OMPC_nowait)
10691 Nowait = Clause;
10692 else if (Clause->getClauseKind() == OMPC_copyprivate)
10693 Copyprivate = Clause;
10694 if (Copyprivate && Nowait) {
10695 Diag(Copyprivate->getBeginLoc(),
10696 diag::err_omp_single_copyprivate_with_nowait);
10697 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10698 return StmtError();
10699 }
10700 }
10701
10702 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10703 }
10704
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10705 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
10706 SourceLocation StartLoc,
10707 SourceLocation EndLoc) {
10708 if (!AStmt)
10709 return StmtError();
10710
10711 setFunctionHasBranchProtectedScope();
10712
10713 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10714 }
10715
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10716 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10717 Stmt *AStmt,
10718 SourceLocation StartLoc,
10719 SourceLocation EndLoc) {
10720 if (!AStmt)
10721 return StmtError();
10722
10723 setFunctionHasBranchProtectedScope();
10724
10725 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10726 }
10727
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10728 StmtResult Sema::ActOnOpenMPCriticalDirective(
10729 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10730 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10731 if (!AStmt)
10732 return StmtError();
10733
10734 bool ErrorFound = false;
10735 llvm::APSInt Hint;
10736 SourceLocation HintLoc;
10737 bool DependentHint = false;
10738 for (const OMPClause *C : Clauses) {
10739 if (C->getClauseKind() == OMPC_hint) {
10740 if (!DirName.getName()) {
10741 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10742 ErrorFound = true;
10743 }
10744 Expr *E = cast<OMPHintClause>(C)->getHint();
10745 if (E->isTypeDependent() || E->isValueDependent() ||
10746 E->isInstantiationDependent()) {
10747 DependentHint = true;
10748 } else {
10749 Hint = E->EvaluateKnownConstInt(Context);
10750 HintLoc = C->getBeginLoc();
10751 }
10752 }
10753 }
10754 if (ErrorFound)
10755 return StmtError();
10756 const auto Pair = DSAStack->getCriticalWithHint(DirName);
10757 if (Pair.first && DirName.getName() && !DependentHint) {
10758 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10759 Diag(StartLoc, diag::err_omp_critical_with_hint);
10760 if (HintLoc.isValid())
10761 Diag(HintLoc, diag::note_omp_critical_hint_here)
10762 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10763 else
10764 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10765 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10766 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10767 << 1
10768 << toString(C->getHint()->EvaluateKnownConstInt(Context),
10769 /*Radix=*/10, /*Signed=*/false);
10770 } else {
10771 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10772 }
10773 }
10774 }
10775
10776 setFunctionHasBranchProtectedScope();
10777
10778 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10779 Clauses, AStmt);
10780 if (!Pair.first && DirName.getName() && !DependentHint)
10781 DSAStack->addCriticalWithHint(Dir, Hint);
10782 return Dir;
10783 }
10784
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10785 StmtResult Sema::ActOnOpenMPParallelForDirective(
10786 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10787 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10788 if (!AStmt)
10789 return StmtError();
10790
10791 auto *CS = cast<CapturedStmt>(AStmt);
10792 // 1.2.2 OpenMP Language Terminology
10793 // Structured block - An executable statement with a single entry at the
10794 // top and a single exit at the bottom.
10795 // The point of exit cannot be a branch out of the structured block.
10796 // longjmp() and throw() must not violate the entry/exit criteria.
10797 CS->getCapturedDecl()->setNothrow();
10798
10799 OMPLoopBasedDirective::HelperExprs B;
10800 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10801 // define the nested loops number.
10802 unsigned NestedLoopCount =
10803 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10804 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10805 VarsWithImplicitDSA, B);
10806 if (NestedLoopCount == 0)
10807 return StmtError();
10808
10809 assert((CurContext->isDependentContext() || B.builtAll()) &&
10810 "omp parallel for loop exprs were not built");
10811
10812 if (!CurContext->isDependentContext()) {
10813 // Finalize the clauses that need pre-built expressions for CodeGen.
10814 for (OMPClause *C : Clauses) {
10815 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10816 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10817 B.NumIterations, *this, CurScope,
10818 DSAStack))
10819 return StmtError();
10820 }
10821 }
10822
10823 setFunctionHasBranchProtectedScope();
10824 return OMPParallelForDirective::Create(
10825 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10826 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10827 }
10828
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10829 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10830 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10831 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10832 if (!AStmt)
10833 return StmtError();
10834
10835 auto *CS = cast<CapturedStmt>(AStmt);
10836 // 1.2.2 OpenMP Language Terminology
10837 // Structured block - An executable statement with a single entry at the
10838 // top and a single exit at the bottom.
10839 // The point of exit cannot be a branch out of the structured block.
10840 // longjmp() and throw() must not violate the entry/exit criteria.
10841 CS->getCapturedDecl()->setNothrow();
10842
10843 OMPLoopBasedDirective::HelperExprs B;
10844 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10845 // define the nested loops number.
10846 unsigned NestedLoopCount =
10847 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10848 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10849 VarsWithImplicitDSA, B);
10850 if (NestedLoopCount == 0)
10851 return StmtError();
10852
10853 if (!CurContext->isDependentContext()) {
10854 // Finalize the clauses that need pre-built expressions for CodeGen.
10855 for (OMPClause *C : Clauses) {
10856 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10857 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10858 B.NumIterations, *this, CurScope,
10859 DSAStack))
10860 return StmtError();
10861 }
10862 }
10863
10864 if (checkSimdlenSafelenSpecified(*this, Clauses))
10865 return StmtError();
10866
10867 setFunctionHasBranchProtectedScope();
10868 return OMPParallelForSimdDirective::Create(
10869 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10870 }
10871
10872 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10873 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10874 Stmt *AStmt, SourceLocation StartLoc,
10875 SourceLocation EndLoc) {
10876 if (!AStmt)
10877 return StmtError();
10878
10879 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10880 auto *CS = cast<CapturedStmt>(AStmt);
10881 // 1.2.2 OpenMP Language Terminology
10882 // Structured block - An executable statement with a single entry at the
10883 // top and a single exit at the bottom.
10884 // The point of exit cannot be a branch out of the structured block.
10885 // longjmp() and throw() must not violate the entry/exit criteria.
10886 CS->getCapturedDecl()->setNothrow();
10887
10888 setFunctionHasBranchProtectedScope();
10889
10890 return OMPParallelMasterDirective::Create(
10891 Context, StartLoc, EndLoc, Clauses, AStmt,
10892 DSAStack->getTaskgroupReductionRef());
10893 }
10894
10895 StmtResult
ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10896 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
10897 Stmt *AStmt, SourceLocation StartLoc,
10898 SourceLocation EndLoc) {
10899 if (!AStmt)
10900 return StmtError();
10901
10902 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10903 auto *CS = cast<CapturedStmt>(AStmt);
10904 // 1.2.2 OpenMP Language Terminology
10905 // Structured block - An executable statement with a single entry at the
10906 // top and a single exit at the bottom.
10907 // The point of exit cannot be a branch out of the structured block.
10908 // longjmp() and throw() must not violate the entry/exit criteria.
10909 CS->getCapturedDecl()->setNothrow();
10910
10911 setFunctionHasBranchProtectedScope();
10912
10913 return OMPParallelMaskedDirective::Create(
10914 Context, StartLoc, EndLoc, Clauses, AStmt,
10915 DSAStack->getTaskgroupReductionRef());
10916 }
10917
10918 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10919 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10920 Stmt *AStmt, SourceLocation StartLoc,
10921 SourceLocation EndLoc) {
10922 if (!AStmt)
10923 return StmtError();
10924
10925 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10926 auto BaseStmt = AStmt;
10927 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10928 BaseStmt = CS->getCapturedStmt();
10929 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10930 auto S = C->children();
10931 if (S.begin() == S.end())
10932 return StmtError();
10933 // All associated statements must be '#pragma omp section' except for
10934 // the first one.
10935 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10936 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10937 if (SectionStmt)
10938 Diag(SectionStmt->getBeginLoc(),
10939 diag::err_omp_parallel_sections_substmt_not_section);
10940 return StmtError();
10941 }
10942 cast<OMPSectionDirective>(SectionStmt)
10943 ->setHasCancel(DSAStack->isCancelRegion());
10944 }
10945 } else {
10946 Diag(AStmt->getBeginLoc(),
10947 diag::err_omp_parallel_sections_not_compound_stmt);
10948 return StmtError();
10949 }
10950
10951 setFunctionHasBranchProtectedScope();
10952
10953 return OMPParallelSectionsDirective::Create(
10954 Context, StartLoc, EndLoc, Clauses, AStmt,
10955 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10956 }
10957
10958 /// Find and diagnose mutually exclusive clause kinds.
checkMutuallyExclusiveClauses(Sema & S,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses)10959 static bool checkMutuallyExclusiveClauses(
10960 Sema &S, ArrayRef<OMPClause *> Clauses,
10961 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10962 const OMPClause *PrevClause = nullptr;
10963 bool ErrorFound = false;
10964 for (const OMPClause *C : Clauses) {
10965 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10966 if (!PrevClause) {
10967 PrevClause = C;
10968 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10969 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10970 << getOpenMPClauseName(C->getClauseKind())
10971 << getOpenMPClauseName(PrevClause->getClauseKind());
10972 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10973 << getOpenMPClauseName(PrevClause->getClauseKind());
10974 ErrorFound = true;
10975 }
10976 }
10977 }
10978 return ErrorFound;
10979 }
10980
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10981 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10982 Stmt *AStmt, SourceLocation StartLoc,
10983 SourceLocation EndLoc) {
10984 if (!AStmt)
10985 return StmtError();
10986
10987 // OpenMP 5.0, 2.10.1 task Construct
10988 // If a detach clause appears on the directive, then a mergeable clause cannot
10989 // appear on the same directive.
10990 if (checkMutuallyExclusiveClauses(*this, Clauses,
10991 {OMPC_detach, OMPC_mergeable}))
10992 return StmtError();
10993
10994 auto *CS = cast<CapturedStmt>(AStmt);
10995 // 1.2.2 OpenMP Language Terminology
10996 // Structured block - An executable statement with a single entry at the
10997 // top and a single exit at the bottom.
10998 // The point of exit cannot be a branch out of the structured block.
10999 // longjmp() and throw() must not violate the entry/exit criteria.
11000 CS->getCapturedDecl()->setNothrow();
11001
11002 setFunctionHasBranchProtectedScope();
11003
11004 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11005 DSAStack->isCancelRegion());
11006 }
11007
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)11008 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11009 SourceLocation EndLoc) {
11010 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11011 }
11012
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)11013 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11014 SourceLocation EndLoc) {
11015 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11016 }
11017
ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11018 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11019 SourceLocation StartLoc,
11020 SourceLocation EndLoc) {
11021 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11022 }
11023
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11024 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11025 Stmt *AStmt,
11026 SourceLocation StartLoc,
11027 SourceLocation EndLoc) {
11028 if (!AStmt)
11029 return StmtError();
11030
11031 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11032
11033 setFunctionHasBranchProtectedScope();
11034
11035 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11036 AStmt,
11037 DSAStack->getTaskgroupReductionRef());
11038 }
11039
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11040 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11041 SourceLocation StartLoc,
11042 SourceLocation EndLoc) {
11043 OMPFlushClause *FC = nullptr;
11044 OMPClause *OrderClause = nullptr;
11045 for (OMPClause *C : Clauses) {
11046 if (C->getClauseKind() == OMPC_flush)
11047 FC = cast<OMPFlushClause>(C);
11048 else
11049 OrderClause = C;
11050 }
11051 OpenMPClauseKind MemOrderKind = OMPC_unknown;
11052 SourceLocation MemOrderLoc;
11053 for (const OMPClause *C : Clauses) {
11054 if (C->getClauseKind() == OMPC_acq_rel ||
11055 C->getClauseKind() == OMPC_acquire ||
11056 C->getClauseKind() == OMPC_release) {
11057 if (MemOrderKind != OMPC_unknown) {
11058 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11059 << getOpenMPDirectiveName(OMPD_flush) << 1
11060 << SourceRange(C->getBeginLoc(), C->getEndLoc());
11061 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11062 << getOpenMPClauseName(MemOrderKind);
11063 } else {
11064 MemOrderKind = C->getClauseKind();
11065 MemOrderLoc = C->getBeginLoc();
11066 }
11067 }
11068 }
11069 if (FC && OrderClause) {
11070 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11071 << getOpenMPClauseName(OrderClause->getClauseKind());
11072 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11073 << getOpenMPClauseName(OrderClause->getClauseKind());
11074 return StmtError();
11075 }
11076 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11077 }
11078
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11079 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11080 SourceLocation StartLoc,
11081 SourceLocation EndLoc) {
11082 if (Clauses.empty()) {
11083 Diag(StartLoc, diag::err_omp_depobj_expected);
11084 return StmtError();
11085 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11086 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11087 return StmtError();
11088 }
11089 // Only depobj expression and another single clause is allowed.
11090 if (Clauses.size() > 2) {
11091 Diag(Clauses[2]->getBeginLoc(),
11092 diag::err_omp_depobj_single_clause_expected);
11093 return StmtError();
11094 } else if (Clauses.size() < 1) {
11095 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11096 return StmtError();
11097 }
11098 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11099 }
11100
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11101 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11102 SourceLocation StartLoc,
11103 SourceLocation EndLoc) {
11104 // Check that exactly one clause is specified.
11105 if (Clauses.size() != 1) {
11106 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11107 diag::err_omp_scan_single_clause_expected);
11108 return StmtError();
11109 }
11110 // Check that scan directive is used in the scopeof the OpenMP loop body.
11111 if (Scope *S = DSAStack->getCurScope()) {
11112 Scope *ParentS = S->getParent();
11113 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11114 !ParentS->getBreakParent()->isOpenMPLoopScope())
11115 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11116 << getOpenMPDirectiveName(OMPD_scan) << 5);
11117 }
11118 // Check that only one instance of scan directives is used in the same outer
11119 // region.
11120 if (DSAStack->doesParentHasScanDirective()) {
11121 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11122 Diag(DSAStack->getParentScanDirectiveLoc(),
11123 diag::note_omp_previous_directive)
11124 << "scan";
11125 return StmtError();
11126 }
11127 DSAStack->setParentHasScanDirective(StartLoc);
11128 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11129 }
11130
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11131 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11132 Stmt *AStmt,
11133 SourceLocation StartLoc,
11134 SourceLocation EndLoc) {
11135 const OMPClause *DependFound = nullptr;
11136 const OMPClause *DependSourceClause = nullptr;
11137 const OMPClause *DependSinkClause = nullptr;
11138 bool ErrorFound = false;
11139 const OMPThreadsClause *TC = nullptr;
11140 const OMPSIMDClause *SC = nullptr;
11141 for (const OMPClause *C : Clauses) {
11142 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
11143 DependFound = C;
11144 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
11145 if (DependSourceClause) {
11146 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11147 << getOpenMPDirectiveName(OMPD_ordered)
11148 << getOpenMPClauseName(OMPC_depend) << 2;
11149 ErrorFound = true;
11150 } else {
11151 DependSourceClause = C;
11152 }
11153 if (DependSinkClause) {
11154 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11155 << 0;
11156 ErrorFound = true;
11157 }
11158 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
11159 if (DependSourceClause) {
11160 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11161 << 1;
11162 ErrorFound = true;
11163 }
11164 DependSinkClause = C;
11165 }
11166 } else if (C->getClauseKind() == OMPC_threads) {
11167 TC = cast<OMPThreadsClause>(C);
11168 } else if (C->getClauseKind() == OMPC_simd) {
11169 SC = cast<OMPSIMDClause>(C);
11170 }
11171 }
11172 if (!ErrorFound && !SC &&
11173 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11174 // OpenMP [2.8.1,simd Construct, Restrictions]
11175 // An ordered construct with the simd clause is the only OpenMP construct
11176 // that can appear in the simd region.
11177 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11178 << (LangOpts.OpenMP >= 50 ? 1 : 0);
11179 ErrorFound = true;
11180 } else if (DependFound && (TC || SC)) {
11181 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
11182 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11183 ErrorFound = true;
11184 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
11185 Diag(DependFound->getBeginLoc(),
11186 diag::err_omp_ordered_directive_without_param);
11187 ErrorFound = true;
11188 } else if (TC || Clauses.empty()) {
11189 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11190 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11191 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11192 << (TC != nullptr);
11193 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11194 ErrorFound = true;
11195 }
11196 }
11197 if ((!AStmt && !DependFound) || ErrorFound)
11198 return StmtError();
11199
11200 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11201 // During execution of an iteration of a worksharing-loop or a loop nest
11202 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11203 // must not execute more than one ordered region corresponding to an ordered
11204 // construct without a depend clause.
11205 if (!DependFound) {
11206 if (DSAStack->doesParentHasOrderedDirective()) {
11207 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11208 Diag(DSAStack->getParentOrderedDirectiveLoc(),
11209 diag::note_omp_previous_directive)
11210 << "ordered";
11211 return StmtError();
11212 }
11213 DSAStack->setParentHasOrderedDirective(StartLoc);
11214 }
11215
11216 if (AStmt) {
11217 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11218
11219 setFunctionHasBranchProtectedScope();
11220 }
11221
11222 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11223 }
11224
11225 namespace {
11226 /// Helper class for checking expression in 'omp atomic [update]'
11227 /// construct.
11228 class OpenMPAtomicUpdateChecker {
11229 /// Error results for atomic update expressions.
11230 enum ExprAnalysisErrorCode {
11231 /// A statement is not an expression statement.
11232 NotAnExpression,
11233 /// Expression is not builtin binary or unary operation.
11234 NotABinaryOrUnaryExpression,
11235 /// Unary operation is not post-/pre- increment/decrement operation.
11236 NotAnUnaryIncDecExpression,
11237 /// An expression is not of scalar type.
11238 NotAScalarType,
11239 /// A binary operation is not an assignment operation.
11240 NotAnAssignmentOp,
11241 /// RHS part of the binary operation is not a binary expression.
11242 NotABinaryExpression,
11243 /// RHS part is not additive/multiplicative/shift/biwise binary
11244 /// expression.
11245 NotABinaryOperator,
11246 /// RHS binary operation does not have reference to the updated LHS
11247 /// part.
11248 NotAnUpdateExpression,
11249 /// No errors is found.
11250 NoError
11251 };
11252 /// Reference to Sema.
11253 Sema &SemaRef;
11254 /// A location for note diagnostics (when error is found).
11255 SourceLocation NoteLoc;
11256 /// 'x' lvalue part of the source atomic expression.
11257 Expr *X;
11258 /// 'expr' rvalue part of the source atomic expression.
11259 Expr *E;
11260 /// Helper expression of the form
11261 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11262 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11263 Expr *UpdateExpr;
11264 /// Is 'x' a LHS in a RHS part of full update expression. It is
11265 /// important for non-associative operations.
11266 bool IsXLHSInRHSPart;
11267 BinaryOperatorKind Op;
11268 SourceLocation OpLoc;
11269 /// true if the source expression is a postfix unary operation, false
11270 /// if it is a prefix unary operation.
11271 bool IsPostfixUpdate;
11272
11273 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)11274 OpenMPAtomicUpdateChecker(Sema &SemaRef)
11275 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11276 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11277 /// Check specified statement that it is suitable for 'atomic update'
11278 /// constructs and extract 'x', 'expr' and Operation from the original
11279 /// expression. If DiagId and NoteId == 0, then only check is performed
11280 /// without error notification.
11281 /// \param DiagId Diagnostic which should be emitted if error is found.
11282 /// \param NoteId Diagnostic note for the main error message.
11283 /// \return true if statement is not an update expression, false otherwise.
11284 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11285 /// Return the 'x' lvalue part of the source atomic expression.
getX() const11286 Expr *getX() const { return X; }
11287 /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const11288 Expr *getExpr() const { return E; }
11289 /// Return the update expression used in calculation of the updated
11290 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11291 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const11292 Expr *getUpdateExpr() const { return UpdateExpr; }
11293 /// Return true if 'x' is LHS in RHS part of full update expression,
11294 /// false otherwise.
isXLHSInRHSPart() const11295 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11296
11297 /// true if the source expression is a postfix unary operation, false
11298 /// if it is a prefix unary operation.
isPostfixUpdate() const11299 bool isPostfixUpdate() const { return IsPostfixUpdate; }
11300
11301 private:
11302 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11303 unsigned NoteId = 0);
11304 };
11305
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)11306 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11307 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11308 ExprAnalysisErrorCode ErrorFound = NoError;
11309 SourceLocation ErrorLoc, NoteLoc;
11310 SourceRange ErrorRange, NoteRange;
11311 // Allowed constructs are:
11312 // x = x binop expr;
11313 // x = expr binop x;
11314 if (AtomicBinOp->getOpcode() == BO_Assign) {
11315 X = AtomicBinOp->getLHS();
11316 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11317 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11318 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11319 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11320 AtomicInnerBinOp->isBitwiseOp()) {
11321 Op = AtomicInnerBinOp->getOpcode();
11322 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11323 Expr *LHS = AtomicInnerBinOp->getLHS();
11324 Expr *RHS = AtomicInnerBinOp->getRHS();
11325 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11326 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11327 /*Canonical=*/true);
11328 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11329 /*Canonical=*/true);
11330 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11331 /*Canonical=*/true);
11332 if (XId == LHSId) {
11333 E = RHS;
11334 IsXLHSInRHSPart = true;
11335 } else if (XId == RHSId) {
11336 E = LHS;
11337 IsXLHSInRHSPart = false;
11338 } else {
11339 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11340 ErrorRange = AtomicInnerBinOp->getSourceRange();
11341 NoteLoc = X->getExprLoc();
11342 NoteRange = X->getSourceRange();
11343 ErrorFound = NotAnUpdateExpression;
11344 }
11345 } else {
11346 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11347 ErrorRange = AtomicInnerBinOp->getSourceRange();
11348 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11349 NoteRange = SourceRange(NoteLoc, NoteLoc);
11350 ErrorFound = NotABinaryOperator;
11351 }
11352 } else {
11353 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11354 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11355 ErrorFound = NotABinaryExpression;
11356 }
11357 } else {
11358 ErrorLoc = AtomicBinOp->getExprLoc();
11359 ErrorRange = AtomicBinOp->getSourceRange();
11360 NoteLoc = AtomicBinOp->getOperatorLoc();
11361 NoteRange = SourceRange(NoteLoc, NoteLoc);
11362 ErrorFound = NotAnAssignmentOp;
11363 }
11364 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11365 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11366 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11367 return true;
11368 }
11369 if (SemaRef.CurContext->isDependentContext())
11370 E = X = UpdateExpr = nullptr;
11371 return ErrorFound != NoError;
11372 }
11373
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)11374 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11375 unsigned NoteId) {
11376 ExprAnalysisErrorCode ErrorFound = NoError;
11377 SourceLocation ErrorLoc, NoteLoc;
11378 SourceRange ErrorRange, NoteRange;
11379 // Allowed constructs are:
11380 // x++;
11381 // x--;
11382 // ++x;
11383 // --x;
11384 // x binop= expr;
11385 // x = x binop expr;
11386 // x = expr binop x;
11387 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11388 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11389 if (AtomicBody->getType()->isScalarType() ||
11390 AtomicBody->isInstantiationDependent()) {
11391 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11392 AtomicBody->IgnoreParenImpCasts())) {
11393 // Check for Compound Assignment Operation
11394 Op = BinaryOperator::getOpForCompoundAssignment(
11395 AtomicCompAssignOp->getOpcode());
11396 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11397 E = AtomicCompAssignOp->getRHS();
11398 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11399 IsXLHSInRHSPart = true;
11400 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11401 AtomicBody->IgnoreParenImpCasts())) {
11402 // Check for Binary Operation
11403 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11404 return true;
11405 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11406 AtomicBody->IgnoreParenImpCasts())) {
11407 // Check for Unary Operation
11408 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11409 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11410 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11411 OpLoc = AtomicUnaryOp->getOperatorLoc();
11412 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11413 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11414 IsXLHSInRHSPart = true;
11415 } else {
11416 ErrorFound = NotAnUnaryIncDecExpression;
11417 ErrorLoc = AtomicUnaryOp->getExprLoc();
11418 ErrorRange = AtomicUnaryOp->getSourceRange();
11419 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11420 NoteRange = SourceRange(NoteLoc, NoteLoc);
11421 }
11422 } else if (!AtomicBody->isInstantiationDependent()) {
11423 ErrorFound = NotABinaryOrUnaryExpression;
11424 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11425 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11426 }
11427 } else {
11428 ErrorFound = NotAScalarType;
11429 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11430 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11431 }
11432 } else {
11433 ErrorFound = NotAnExpression;
11434 NoteLoc = ErrorLoc = S->getBeginLoc();
11435 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11436 }
11437 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11438 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11439 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11440 return true;
11441 }
11442 if (SemaRef.CurContext->isDependentContext())
11443 E = X = UpdateExpr = nullptr;
11444 if (ErrorFound == NoError && E && X) {
11445 // Build an update expression of form 'OpaqueValueExpr(x) binop
11446 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11447 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11448 auto *OVEX = new (SemaRef.getASTContext())
11449 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11450 auto *OVEExpr = new (SemaRef.getASTContext())
11451 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11452 ExprResult Update =
11453 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11454 IsXLHSInRHSPart ? OVEExpr : OVEX);
11455 if (Update.isInvalid())
11456 return true;
11457 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11458 Sema::AA_Casting);
11459 if (Update.isInvalid())
11460 return true;
11461 UpdateExpr = Update.get();
11462 }
11463 return ErrorFound != NoError;
11464 }
11465
11466 /// Get the node id of the fixed point of an expression \a S.
getNodeId(ASTContext & Context,const Expr * S)11467 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11468 llvm::FoldingSetNodeID Id;
11469 S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11470 return Id;
11471 }
11472
11473 /// Check if two expressions are same.
checkIfTwoExprsAreSame(ASTContext & Context,const Expr * LHS,const Expr * RHS)11474 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11475 const Expr *RHS) {
11476 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11477 }
11478
11479 class OpenMPAtomicCompareChecker {
11480 public:
11481 /// All kinds of errors that can occur in `atomic compare`
11482 enum ErrorTy {
11483 /// Empty compound statement.
11484 NoStmt = 0,
11485 /// More than one statement in a compound statement.
11486 MoreThanOneStmt,
11487 /// Not an assignment binary operator.
11488 NotAnAssignment,
11489 /// Not a conditional operator.
11490 NotCondOp,
11491 /// Wrong false expr. According to the spec, 'x' should be at the false
11492 /// expression of a conditional expression.
11493 WrongFalseExpr,
11494 /// The condition of a conditional expression is not a binary operator.
11495 NotABinaryOp,
11496 /// Invalid binary operator (not <, >, or ==).
11497 InvalidBinaryOp,
11498 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11499 InvalidComparison,
11500 /// X is not a lvalue.
11501 XNotLValue,
11502 /// Not a scalar.
11503 NotScalar,
11504 /// Not an integer.
11505 NotInteger,
11506 /// 'else' statement is not expected.
11507 UnexpectedElse,
11508 /// Not an equality operator.
11509 NotEQ,
11510 /// Invalid assignment (not v == x).
11511 InvalidAssignment,
11512 /// Not if statement
11513 NotIfStmt,
11514 /// More than two statements in a compund statement.
11515 MoreThanTwoStmts,
11516 /// Not a compound statement.
11517 NotCompoundStmt,
11518 /// No else statement.
11519 NoElse,
11520 /// Not 'if (r)'.
11521 InvalidCondition,
11522 /// No error.
11523 NoError,
11524 };
11525
11526 struct ErrorInfoTy {
11527 ErrorTy Error;
11528 SourceLocation ErrorLoc;
11529 SourceRange ErrorRange;
11530 SourceLocation NoteLoc;
11531 SourceRange NoteRange;
11532 };
11533
OpenMPAtomicCompareChecker(Sema & S)11534 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11535
11536 /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11537 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11538
getX() const11539 Expr *getX() const { return X; }
getE() const11540 Expr *getE() const { return E; }
getD() const11541 Expr *getD() const { return D; }
getCond() const11542 Expr *getCond() const { return C; }
isXBinopExpr() const11543 bool isXBinopExpr() const { return IsXBinopExpr; }
11544
11545 protected:
11546 /// Reference to ASTContext
11547 ASTContext &ContextRef;
11548 /// 'x' lvalue part of the source atomic expression.
11549 Expr *X = nullptr;
11550 /// 'expr' or 'e' rvalue part of the source atomic expression.
11551 Expr *E = nullptr;
11552 /// 'd' rvalue part of the source atomic expression.
11553 Expr *D = nullptr;
11554 /// 'cond' part of the source atomic expression. It is in one of the following
11555 /// forms:
11556 /// expr ordop x
11557 /// x ordop expr
11558 /// x == e
11559 /// e == x
11560 Expr *C = nullptr;
11561 /// True if the cond expr is in the form of 'x ordop expr'.
11562 bool IsXBinopExpr = true;
11563
11564 /// Check if it is a valid conditional update statement (cond-update-stmt).
11565 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11566
11567 /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11568 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11569
11570 /// Check if all captured values have right type.
11571 bool checkType(ErrorInfoTy &ErrorInfo) const;
11572
CheckValue(const Expr * E,ErrorInfoTy & ErrorInfo,bool ShouldBeLValue,bool ShouldBeInteger=false)11573 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11574 bool ShouldBeLValue, bool ShouldBeInteger = false) {
11575 if (ShouldBeLValue && !E->isLValue()) {
11576 ErrorInfo.Error = ErrorTy::XNotLValue;
11577 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11578 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11579 return false;
11580 }
11581
11582 if (!E->isInstantiationDependent()) {
11583 QualType QTy = E->getType();
11584 if (!QTy->isScalarType()) {
11585 ErrorInfo.Error = ErrorTy::NotScalar;
11586 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11587 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11588 return false;
11589 }
11590 if (ShouldBeInteger && !QTy->isIntegerType()) {
11591 ErrorInfo.Error = ErrorTy::NotInteger;
11592 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11593 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11594 return false;
11595 }
11596 }
11597
11598 return true;
11599 }
11600 };
11601
checkCondUpdateStmt(IfStmt * S,ErrorInfoTy & ErrorInfo)11602 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11603 ErrorInfoTy &ErrorInfo) {
11604 auto *Then = S->getThen();
11605 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11606 if (CS->body_empty()) {
11607 ErrorInfo.Error = ErrorTy::NoStmt;
11608 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11609 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11610 return false;
11611 }
11612 if (CS->size() > 1) {
11613 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11614 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11615 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11616 return false;
11617 }
11618 Then = CS->body_front();
11619 }
11620
11621 auto *BO = dyn_cast<BinaryOperator>(Then);
11622 if (!BO) {
11623 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11624 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11625 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11626 return false;
11627 }
11628 if (BO->getOpcode() != BO_Assign) {
11629 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11630 ErrorInfo.ErrorLoc = BO->getExprLoc();
11631 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11632 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11633 return false;
11634 }
11635
11636 X = BO->getLHS();
11637
11638 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11639 if (!Cond) {
11640 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11641 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11642 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11643 return false;
11644 }
11645
11646 switch (Cond->getOpcode()) {
11647 case BO_EQ: {
11648 C = Cond;
11649 D = BO->getRHS();
11650 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11651 E = Cond->getRHS();
11652 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11653 E = Cond->getLHS();
11654 } else {
11655 ErrorInfo.Error = ErrorTy::InvalidComparison;
11656 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11657 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11658 return false;
11659 }
11660 break;
11661 }
11662 case BO_LT:
11663 case BO_GT: {
11664 E = BO->getRHS();
11665 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11666 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11667 C = Cond;
11668 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11669 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11670 C = Cond;
11671 IsXBinopExpr = false;
11672 } else {
11673 ErrorInfo.Error = ErrorTy::InvalidComparison;
11674 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11675 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11676 return false;
11677 }
11678 break;
11679 }
11680 default:
11681 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11682 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11683 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11684 return false;
11685 }
11686
11687 if (S->getElse()) {
11688 ErrorInfo.Error = ErrorTy::UnexpectedElse;
11689 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11690 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11691 return false;
11692 }
11693
11694 return true;
11695 }
11696
checkCondExprStmt(Stmt * S,ErrorInfoTy & ErrorInfo)11697 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11698 ErrorInfoTy &ErrorInfo) {
11699 auto *BO = dyn_cast<BinaryOperator>(S);
11700 if (!BO) {
11701 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11702 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11703 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11704 return false;
11705 }
11706 if (BO->getOpcode() != BO_Assign) {
11707 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11708 ErrorInfo.ErrorLoc = BO->getExprLoc();
11709 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11710 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11711 return false;
11712 }
11713
11714 X = BO->getLHS();
11715
11716 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11717 if (!CO) {
11718 ErrorInfo.Error = ErrorTy::NotCondOp;
11719 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11720 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11721 return false;
11722 }
11723
11724 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11725 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11726 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11727 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11728 CO->getFalseExpr()->getSourceRange();
11729 return false;
11730 }
11731
11732 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11733 if (!Cond) {
11734 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11735 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11736 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11737 CO->getCond()->getSourceRange();
11738 return false;
11739 }
11740
11741 switch (Cond->getOpcode()) {
11742 case BO_EQ: {
11743 C = Cond;
11744 D = CO->getTrueExpr();
11745 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11746 E = Cond->getRHS();
11747 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11748 E = Cond->getLHS();
11749 } else {
11750 ErrorInfo.Error = ErrorTy::InvalidComparison;
11751 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11752 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11753 return false;
11754 }
11755 break;
11756 }
11757 case BO_LT:
11758 case BO_GT: {
11759 E = CO->getTrueExpr();
11760 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11761 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11762 C = Cond;
11763 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11764 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11765 C = Cond;
11766 IsXBinopExpr = false;
11767 } else {
11768 ErrorInfo.Error = ErrorTy::InvalidComparison;
11769 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11770 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11771 return false;
11772 }
11773 break;
11774 }
11775 default:
11776 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11777 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11778 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11779 return false;
11780 }
11781
11782 return true;
11783 }
11784
checkType(ErrorInfoTy & ErrorInfo) const11785 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11786 // 'x' and 'e' cannot be nullptr
11787 assert(X && E && "X and E cannot be nullptr");
11788
11789 if (!CheckValue(X, ErrorInfo, true))
11790 return false;
11791
11792 if (!CheckValue(E, ErrorInfo, false))
11793 return false;
11794
11795 if (D && !CheckValue(D, ErrorInfo, false))
11796 return false;
11797
11798 return true;
11799 }
11800
checkStmt(Stmt * S,OpenMPAtomicCompareChecker::ErrorInfoTy & ErrorInfo)11801 bool OpenMPAtomicCompareChecker::checkStmt(
11802 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11803 auto *CS = dyn_cast<CompoundStmt>(S);
11804 if (CS) {
11805 if (CS->body_empty()) {
11806 ErrorInfo.Error = ErrorTy::NoStmt;
11807 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11808 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11809 return false;
11810 }
11811
11812 if (CS->size() != 1) {
11813 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11814 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11815 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11816 return false;
11817 }
11818 S = CS->body_front();
11819 }
11820
11821 auto Res = false;
11822
11823 if (auto *IS = dyn_cast<IfStmt>(S)) {
11824 // Check if the statement is in one of the following forms
11825 // (cond-update-stmt):
11826 // if (expr ordop x) { x = expr; }
11827 // if (x ordop expr) { x = expr; }
11828 // if (x == e) { x = d; }
11829 Res = checkCondUpdateStmt(IS, ErrorInfo);
11830 } else {
11831 // Check if the statement is in one of the following forms (cond-expr-stmt):
11832 // x = expr ordop x ? expr : x;
11833 // x = x ordop expr ? expr : x;
11834 // x = x == e ? d : x;
11835 Res = checkCondExprStmt(S, ErrorInfo);
11836 }
11837
11838 if (!Res)
11839 return false;
11840
11841 return checkType(ErrorInfo);
11842 }
11843
11844 class OpenMPAtomicCompareCaptureChecker final
11845 : public OpenMPAtomicCompareChecker {
11846 public:
OpenMPAtomicCompareCaptureChecker(Sema & S)11847 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11848
getV() const11849 Expr *getV() const { return V; }
getR() const11850 Expr *getR() const { return R; }
isFailOnly() const11851 bool isFailOnly() const { return IsFailOnly; }
isPostfixUpdate() const11852 bool isPostfixUpdate() const { return IsPostfixUpdate; }
11853
11854 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11855 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11856
11857 private:
11858 bool checkType(ErrorInfoTy &ErrorInfo);
11859
11860 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11861 // form of 'conditional-update-capture-atomic' structured block on the v5.2
11862 // spec p.p. 82:
11863 // (1) { v = x; cond-update-stmt }
11864 // (2) { cond-update-stmt v = x; }
11865 // (3) if(x == e) { x = d; } else { v = x; }
11866 // (4) { r = x == e; if(r) { x = d; } }
11867 // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11868
11869 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11870 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11871
11872 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11873 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11874 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11875
11876 /// 'v' lvalue part of the source atomic expression.
11877 Expr *V = nullptr;
11878 /// 'r' lvalue part of the source atomic expression.
11879 Expr *R = nullptr;
11880 /// If 'v' is only updated when the comparison fails.
11881 bool IsFailOnly = false;
11882 /// If original value of 'x' must be stored in 'v', not an updated one.
11883 bool IsPostfixUpdate = false;
11884 };
11885
checkType(ErrorInfoTy & ErrorInfo)11886 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11887 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11888 return false;
11889
11890 if (V && !CheckValue(V, ErrorInfo, true))
11891 return false;
11892
11893 if (R && !CheckValue(R, ErrorInfo, true, true))
11894 return false;
11895
11896 return true;
11897 }
11898
checkForm3(IfStmt * S,ErrorInfoTy & ErrorInfo)11899 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11900 ErrorInfoTy &ErrorInfo) {
11901 IsFailOnly = true;
11902
11903 auto *Then = S->getThen();
11904 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11905 if (CS->body_empty()) {
11906 ErrorInfo.Error = ErrorTy::NoStmt;
11907 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11908 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11909 return false;
11910 }
11911 if (CS->size() > 1) {
11912 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11913 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11914 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11915 return false;
11916 }
11917 Then = CS->body_front();
11918 }
11919
11920 auto *BO = dyn_cast<BinaryOperator>(Then);
11921 if (!BO) {
11922 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11923 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11924 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11925 return false;
11926 }
11927 if (BO->getOpcode() != BO_Assign) {
11928 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11929 ErrorInfo.ErrorLoc = BO->getExprLoc();
11930 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11931 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11932 return false;
11933 }
11934
11935 X = BO->getLHS();
11936 D = BO->getRHS();
11937
11938 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11939 if (!Cond) {
11940 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11941 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11942 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11943 return false;
11944 }
11945 if (Cond->getOpcode() != BO_EQ) {
11946 ErrorInfo.Error = ErrorTy::NotEQ;
11947 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11948 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11949 return false;
11950 }
11951
11952 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11953 E = Cond->getRHS();
11954 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11955 E = Cond->getLHS();
11956 } else {
11957 ErrorInfo.Error = ErrorTy::InvalidComparison;
11958 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11959 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11960 return false;
11961 }
11962
11963 C = Cond;
11964
11965 if (!S->getElse()) {
11966 ErrorInfo.Error = ErrorTy::NoElse;
11967 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11968 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11969 return false;
11970 }
11971
11972 auto *Else = S->getElse();
11973 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
11974 if (CS->body_empty()) {
11975 ErrorInfo.Error = ErrorTy::NoStmt;
11976 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11977 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11978 return false;
11979 }
11980 if (CS->size() > 1) {
11981 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11982 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11983 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11984 return false;
11985 }
11986 Else = CS->body_front();
11987 }
11988
11989 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11990 if (!ElseBO) {
11991 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11992 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11993 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11994 return false;
11995 }
11996 if (ElseBO->getOpcode() != BO_Assign) {
11997 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11998 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11999 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12000 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12001 return false;
12002 }
12003
12004 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12005 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12006 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12007 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12008 ElseBO->getRHS()->getSourceRange();
12009 return false;
12010 }
12011
12012 V = ElseBO->getLHS();
12013
12014 return checkType(ErrorInfo);
12015 }
12016
checkForm45(Stmt * S,ErrorInfoTy & ErrorInfo)12017 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12018 ErrorInfoTy &ErrorInfo) {
12019 // We don't check here as they should be already done before call this
12020 // function.
12021 auto *CS = cast<CompoundStmt>(S);
12022 assert(CS->size() == 2 && "CompoundStmt size is not expected");
12023 auto *S1 = cast<BinaryOperator>(CS->body_front());
12024 auto *S2 = cast<IfStmt>(CS->body_back());
12025 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12026
12027 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12028 ErrorInfo.Error = ErrorTy::InvalidCondition;
12029 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12030 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12031 return false;
12032 }
12033
12034 R = S1->getLHS();
12035
12036 auto *Then = S2->getThen();
12037 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12038 if (ThenCS->body_empty()) {
12039 ErrorInfo.Error = ErrorTy::NoStmt;
12040 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12041 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12042 return false;
12043 }
12044 if (ThenCS->size() > 1) {
12045 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12046 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12047 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12048 return false;
12049 }
12050 Then = ThenCS->body_front();
12051 }
12052
12053 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12054 if (!ThenBO) {
12055 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12056 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12057 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12058 return false;
12059 }
12060 if (ThenBO->getOpcode() != BO_Assign) {
12061 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12062 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12063 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12064 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12065 return false;
12066 }
12067
12068 X = ThenBO->getLHS();
12069 D = ThenBO->getRHS();
12070
12071 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12072 if (BO->getOpcode() != BO_EQ) {
12073 ErrorInfo.Error = ErrorTy::NotEQ;
12074 ErrorInfo.ErrorLoc = BO->getExprLoc();
12075 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12076 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12077 return false;
12078 }
12079
12080 C = BO;
12081
12082 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12083 E = BO->getRHS();
12084 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12085 E = BO->getLHS();
12086 } else {
12087 ErrorInfo.Error = ErrorTy::InvalidComparison;
12088 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12089 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12090 return false;
12091 }
12092
12093 if (S2->getElse()) {
12094 IsFailOnly = true;
12095
12096 auto *Else = S2->getElse();
12097 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12098 if (ElseCS->body_empty()) {
12099 ErrorInfo.Error = ErrorTy::NoStmt;
12100 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12101 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12102 return false;
12103 }
12104 if (ElseCS->size() > 1) {
12105 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12106 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12107 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12108 return false;
12109 }
12110 Else = ElseCS->body_front();
12111 }
12112
12113 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12114 if (!ElseBO) {
12115 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12116 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12117 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12118 return false;
12119 }
12120 if (ElseBO->getOpcode() != BO_Assign) {
12121 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12122 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12123 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12124 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12125 return false;
12126 }
12127 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12128 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12129 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12130 ErrorInfo.NoteLoc = X->getExprLoc();
12131 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12132 ErrorInfo.NoteRange = X->getSourceRange();
12133 return false;
12134 }
12135
12136 V = ElseBO->getLHS();
12137 }
12138
12139 return checkType(ErrorInfo);
12140 }
12141
checkStmt(Stmt * S,ErrorInfoTy & ErrorInfo)12142 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12143 ErrorInfoTy &ErrorInfo) {
12144 // if(x == e) { x = d; } else { v = x; }
12145 if (auto *IS = dyn_cast<IfStmt>(S))
12146 return checkForm3(IS, ErrorInfo);
12147
12148 auto *CS = dyn_cast<CompoundStmt>(S);
12149 if (!CS) {
12150 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12151 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12152 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12153 return false;
12154 }
12155 if (CS->body_empty()) {
12156 ErrorInfo.Error = ErrorTy::NoStmt;
12157 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12158 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12159 return false;
12160 }
12161
12162 // { if(x == e) { x = d; } else { v = x; } }
12163 if (CS->size() == 1) {
12164 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12165 if (!IS) {
12166 ErrorInfo.Error = ErrorTy::NotIfStmt;
12167 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12168 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12169 CS->body_front()->getSourceRange();
12170 return false;
12171 }
12172
12173 return checkForm3(IS, ErrorInfo);
12174 } else if (CS->size() == 2) {
12175 auto *S1 = CS->body_front();
12176 auto *S2 = CS->body_back();
12177
12178 Stmt *UpdateStmt = nullptr;
12179 Stmt *CondUpdateStmt = nullptr;
12180
12181 if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12182 // { v = x; cond-update-stmt } or form 45.
12183 UpdateStmt = S1;
12184 CondUpdateStmt = S2;
12185 // Check if form 45.
12186 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
12187 isa<IfStmt>(S2))
12188 return checkForm45(CS, ErrorInfo);
12189 // It cannot be set before we the check for form45.
12190 IsPostfixUpdate = true;
12191 } else {
12192 // { cond-update-stmt v = x; }
12193 UpdateStmt = S2;
12194 CondUpdateStmt = S1;
12195 }
12196
12197 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12198 auto *IS = dyn_cast<IfStmt>(CUS);
12199 if (!IS) {
12200 ErrorInfo.Error = ErrorTy::NotIfStmt;
12201 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12202 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12203 return false;
12204 }
12205
12206 if (!checkCondUpdateStmt(IS, ErrorInfo))
12207 return false;
12208
12209 return true;
12210 };
12211
12212 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12213 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12214 auto *BO = dyn_cast<BinaryOperator>(US);
12215 if (!BO) {
12216 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12217 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12218 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12219 return false;
12220 }
12221 if (BO->getOpcode() != BO_Assign) {
12222 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12223 ErrorInfo.ErrorLoc = BO->getExprLoc();
12224 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12225 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12226 return false;
12227 }
12228 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12229 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12230 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12231 ErrorInfo.NoteLoc = this->X->getExprLoc();
12232 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12233 ErrorInfo.NoteRange = this->X->getSourceRange();
12234 return false;
12235 }
12236
12237 this->V = BO->getLHS();
12238
12239 return true;
12240 };
12241
12242 if (!CheckCondUpdateStmt(CondUpdateStmt))
12243 return false;
12244 if (!CheckUpdateStmt(UpdateStmt))
12245 return false;
12246 } else {
12247 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12248 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12249 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12250 return false;
12251 }
12252
12253 return checkType(ErrorInfo);
12254 }
12255 } // namespace
12256
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12257 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12258 Stmt *AStmt,
12259 SourceLocation StartLoc,
12260 SourceLocation EndLoc) {
12261 // Register location of the first atomic directive.
12262 DSAStack->addAtomicDirectiveLoc(StartLoc);
12263 if (!AStmt)
12264 return StmtError();
12265
12266 // 1.2.2 OpenMP Language Terminology
12267 // Structured block - An executable statement with a single entry at the
12268 // top and a single exit at the bottom.
12269 // The point of exit cannot be a branch out of the structured block.
12270 // longjmp() and throw() must not violate the entry/exit criteria.
12271 OpenMPClauseKind AtomicKind = OMPC_unknown;
12272 SourceLocation AtomicKindLoc;
12273 OpenMPClauseKind MemOrderKind = OMPC_unknown;
12274 SourceLocation MemOrderLoc;
12275 bool MutexClauseEncountered = false;
12276 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12277 for (const OMPClause *C : Clauses) {
12278 switch (C->getClauseKind()) {
12279 case OMPC_read:
12280 case OMPC_write:
12281 case OMPC_update:
12282 MutexClauseEncountered = true;
12283 LLVM_FALLTHROUGH;
12284 case OMPC_capture:
12285 case OMPC_compare: {
12286 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12287 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12288 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12289 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12290 << getOpenMPClauseName(AtomicKind);
12291 } else {
12292 AtomicKind = C->getClauseKind();
12293 AtomicKindLoc = C->getBeginLoc();
12294 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12295 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12296 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12297 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12298 << getOpenMPClauseName(AtomicKind);
12299 }
12300 }
12301 break;
12302 }
12303 case OMPC_seq_cst:
12304 case OMPC_acq_rel:
12305 case OMPC_acquire:
12306 case OMPC_release:
12307 case OMPC_relaxed: {
12308 if (MemOrderKind != OMPC_unknown) {
12309 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12310 << getOpenMPDirectiveName(OMPD_atomic) << 0
12311 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12312 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12313 << getOpenMPClauseName(MemOrderKind);
12314 } else {
12315 MemOrderKind = C->getClauseKind();
12316 MemOrderLoc = C->getBeginLoc();
12317 }
12318 break;
12319 }
12320 // The following clauses are allowed, but we don't need to do anything here.
12321 case OMPC_hint:
12322 break;
12323 default:
12324 llvm_unreachable("unknown clause is encountered");
12325 }
12326 }
12327 bool IsCompareCapture = false;
12328 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12329 EncounteredAtomicKinds.contains(OMPC_capture)) {
12330 IsCompareCapture = true;
12331 AtomicKind = OMPC_compare;
12332 }
12333 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12334 // If atomic-clause is read then memory-order-clause must not be acq_rel or
12335 // release.
12336 // If atomic-clause is write then memory-order-clause must not be acq_rel or
12337 // acquire.
12338 // If atomic-clause is update or not present then memory-order-clause must not
12339 // be acq_rel or acquire.
12340 if ((AtomicKind == OMPC_read &&
12341 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12342 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12343 AtomicKind == OMPC_unknown) &&
12344 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12345 SourceLocation Loc = AtomicKindLoc;
12346 if (AtomicKind == OMPC_unknown)
12347 Loc = StartLoc;
12348 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12349 << getOpenMPClauseName(AtomicKind)
12350 << (AtomicKind == OMPC_unknown ? 1 : 0)
12351 << getOpenMPClauseName(MemOrderKind);
12352 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12353 << getOpenMPClauseName(MemOrderKind);
12354 }
12355
12356 Stmt *Body = AStmt;
12357 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12358 Body = EWC->getSubExpr();
12359
12360 Expr *X = nullptr;
12361 Expr *V = nullptr;
12362 Expr *E = nullptr;
12363 Expr *UE = nullptr;
12364 Expr *D = nullptr;
12365 Expr *CE = nullptr;
12366 Expr *R = nullptr;
12367 bool IsXLHSInRHSPart = false;
12368 bool IsPostfixUpdate = false;
12369 bool IsFailOnly = false;
12370 // OpenMP [2.12.6, atomic Construct]
12371 // In the next expressions:
12372 // * x and v (as applicable) are both l-value expressions with scalar type.
12373 // * During the execution of an atomic region, multiple syntactic
12374 // occurrences of x must designate the same storage location.
12375 // * Neither of v and expr (as applicable) may access the storage location
12376 // designated by x.
12377 // * Neither of x and expr (as applicable) may access the storage location
12378 // designated by v.
12379 // * expr is an expression with scalar type.
12380 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12381 // * binop, binop=, ++, and -- are not overloaded operators.
12382 // * The expression x binop expr must be numerically equivalent to x binop
12383 // (expr). This requirement is satisfied if the operators in expr have
12384 // precedence greater than binop, or by using parentheses around expr or
12385 // subexpressions of expr.
12386 // * The expression expr binop x must be numerically equivalent to (expr)
12387 // binop x. This requirement is satisfied if the operators in expr have
12388 // precedence equal to or greater than binop, or by using parentheses around
12389 // expr or subexpressions of expr.
12390 // * For forms that allow multiple occurrences of x, the number of times
12391 // that x is evaluated is unspecified.
12392 if (AtomicKind == OMPC_read) {
12393 enum {
12394 NotAnExpression,
12395 NotAnAssignmentOp,
12396 NotAScalarType,
12397 NotAnLValue,
12398 NoError
12399 } ErrorFound = NoError;
12400 SourceLocation ErrorLoc, NoteLoc;
12401 SourceRange ErrorRange, NoteRange;
12402 // If clause is read:
12403 // v = x;
12404 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12405 const auto *AtomicBinOp =
12406 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12407 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12408 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12409 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12410 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12411 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12412 if (!X->isLValue() || !V->isLValue()) {
12413 const Expr *NotLValueExpr = X->isLValue() ? V : X;
12414 ErrorFound = NotAnLValue;
12415 ErrorLoc = AtomicBinOp->getExprLoc();
12416 ErrorRange = AtomicBinOp->getSourceRange();
12417 NoteLoc = NotLValueExpr->getExprLoc();
12418 NoteRange = NotLValueExpr->getSourceRange();
12419 }
12420 } else if (!X->isInstantiationDependent() ||
12421 !V->isInstantiationDependent()) {
12422 const Expr *NotScalarExpr =
12423 (X->isInstantiationDependent() || X->getType()->isScalarType())
12424 ? V
12425 : X;
12426 ErrorFound = NotAScalarType;
12427 ErrorLoc = AtomicBinOp->getExprLoc();
12428 ErrorRange = AtomicBinOp->getSourceRange();
12429 NoteLoc = NotScalarExpr->getExprLoc();
12430 NoteRange = NotScalarExpr->getSourceRange();
12431 }
12432 } else if (!AtomicBody->isInstantiationDependent()) {
12433 ErrorFound = NotAnAssignmentOp;
12434 ErrorLoc = AtomicBody->getExprLoc();
12435 ErrorRange = AtomicBody->getSourceRange();
12436 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12437 : AtomicBody->getExprLoc();
12438 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12439 : AtomicBody->getSourceRange();
12440 }
12441 } else {
12442 ErrorFound = NotAnExpression;
12443 NoteLoc = ErrorLoc = Body->getBeginLoc();
12444 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12445 }
12446 if (ErrorFound != NoError) {
12447 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12448 << ErrorRange;
12449 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12450 << ErrorFound << NoteRange;
12451 return StmtError();
12452 }
12453 if (CurContext->isDependentContext())
12454 V = X = nullptr;
12455 } else if (AtomicKind == OMPC_write) {
12456 enum {
12457 NotAnExpression,
12458 NotAnAssignmentOp,
12459 NotAScalarType,
12460 NotAnLValue,
12461 NoError
12462 } ErrorFound = NoError;
12463 SourceLocation ErrorLoc, NoteLoc;
12464 SourceRange ErrorRange, NoteRange;
12465 // If clause is write:
12466 // x = expr;
12467 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12468 const auto *AtomicBinOp =
12469 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12470 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12471 X = AtomicBinOp->getLHS();
12472 E = AtomicBinOp->getRHS();
12473 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12474 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12475 if (!X->isLValue()) {
12476 ErrorFound = NotAnLValue;
12477 ErrorLoc = AtomicBinOp->getExprLoc();
12478 ErrorRange = AtomicBinOp->getSourceRange();
12479 NoteLoc = X->getExprLoc();
12480 NoteRange = X->getSourceRange();
12481 }
12482 } else if (!X->isInstantiationDependent() ||
12483 !E->isInstantiationDependent()) {
12484 const Expr *NotScalarExpr =
12485 (X->isInstantiationDependent() || X->getType()->isScalarType())
12486 ? E
12487 : X;
12488 ErrorFound = NotAScalarType;
12489 ErrorLoc = AtomicBinOp->getExprLoc();
12490 ErrorRange = AtomicBinOp->getSourceRange();
12491 NoteLoc = NotScalarExpr->getExprLoc();
12492 NoteRange = NotScalarExpr->getSourceRange();
12493 }
12494 } else if (!AtomicBody->isInstantiationDependent()) {
12495 ErrorFound = NotAnAssignmentOp;
12496 ErrorLoc = AtomicBody->getExprLoc();
12497 ErrorRange = AtomicBody->getSourceRange();
12498 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12499 : AtomicBody->getExprLoc();
12500 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12501 : AtomicBody->getSourceRange();
12502 }
12503 } else {
12504 ErrorFound = NotAnExpression;
12505 NoteLoc = ErrorLoc = Body->getBeginLoc();
12506 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12507 }
12508 if (ErrorFound != NoError) {
12509 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12510 << ErrorRange;
12511 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12512 << ErrorFound << NoteRange;
12513 return StmtError();
12514 }
12515 if (CurContext->isDependentContext())
12516 E = X = nullptr;
12517 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12518 // If clause is update:
12519 // x++;
12520 // x--;
12521 // ++x;
12522 // --x;
12523 // x binop= expr;
12524 // x = x binop expr;
12525 // x = expr binop x;
12526 OpenMPAtomicUpdateChecker Checker(*this);
12527 if (Checker.checkStatement(
12528 Body,
12529 (AtomicKind == OMPC_update)
12530 ? diag::err_omp_atomic_update_not_expression_statement
12531 : diag::err_omp_atomic_not_expression_statement,
12532 diag::note_omp_atomic_update))
12533 return StmtError();
12534 if (!CurContext->isDependentContext()) {
12535 E = Checker.getExpr();
12536 X = Checker.getX();
12537 UE = Checker.getUpdateExpr();
12538 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12539 }
12540 } else if (AtomicKind == OMPC_capture) {
12541 enum {
12542 NotAnAssignmentOp,
12543 NotACompoundStatement,
12544 NotTwoSubstatements,
12545 NotASpecificExpression,
12546 NoError
12547 } ErrorFound = NoError;
12548 SourceLocation ErrorLoc, NoteLoc;
12549 SourceRange ErrorRange, NoteRange;
12550 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12551 // If clause is a capture:
12552 // v = x++;
12553 // v = x--;
12554 // v = ++x;
12555 // v = --x;
12556 // v = x binop= expr;
12557 // v = x = x binop expr;
12558 // v = x = expr binop x;
12559 const auto *AtomicBinOp =
12560 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12561 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12562 V = AtomicBinOp->getLHS();
12563 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12564 OpenMPAtomicUpdateChecker Checker(*this);
12565 if (Checker.checkStatement(
12566 Body, diag::err_omp_atomic_capture_not_expression_statement,
12567 diag::note_omp_atomic_update))
12568 return StmtError();
12569 E = Checker.getExpr();
12570 X = Checker.getX();
12571 UE = Checker.getUpdateExpr();
12572 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12573 IsPostfixUpdate = Checker.isPostfixUpdate();
12574 } else if (!AtomicBody->isInstantiationDependent()) {
12575 ErrorLoc = AtomicBody->getExprLoc();
12576 ErrorRange = AtomicBody->getSourceRange();
12577 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12578 : AtomicBody->getExprLoc();
12579 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12580 : AtomicBody->getSourceRange();
12581 ErrorFound = NotAnAssignmentOp;
12582 }
12583 if (ErrorFound != NoError) {
12584 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12585 << ErrorRange;
12586 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12587 return StmtError();
12588 }
12589 if (CurContext->isDependentContext())
12590 UE = V = E = X = nullptr;
12591 } else {
12592 // If clause is a capture:
12593 // { v = x; x = expr; }
12594 // { v = x; x++; }
12595 // { v = x; x--; }
12596 // { v = x; ++x; }
12597 // { v = x; --x; }
12598 // { v = x; x binop= expr; }
12599 // { v = x; x = x binop expr; }
12600 // { v = x; x = expr binop x; }
12601 // { x++; v = x; }
12602 // { x--; v = x; }
12603 // { ++x; v = x; }
12604 // { --x; v = x; }
12605 // { x binop= expr; v = x; }
12606 // { x = x binop expr; v = x; }
12607 // { x = expr binop x; v = x; }
12608 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12609 // Check that this is { expr1; expr2; }
12610 if (CS->size() == 2) {
12611 Stmt *First = CS->body_front();
12612 Stmt *Second = CS->body_back();
12613 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12614 First = EWC->getSubExpr()->IgnoreParenImpCasts();
12615 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12616 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12617 // Need to find what subexpression is 'v' and what is 'x'.
12618 OpenMPAtomicUpdateChecker Checker(*this);
12619 bool IsUpdateExprFound = !Checker.checkStatement(Second);
12620 BinaryOperator *BinOp = nullptr;
12621 if (IsUpdateExprFound) {
12622 BinOp = dyn_cast<BinaryOperator>(First);
12623 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12624 }
12625 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12626 // { v = x; x++; }
12627 // { v = x; x--; }
12628 // { v = x; ++x; }
12629 // { v = x; --x; }
12630 // { v = x; x binop= expr; }
12631 // { v = x; x = x binop expr; }
12632 // { v = x; x = expr binop x; }
12633 // Check that the first expression has form v = x.
12634 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12635 llvm::FoldingSetNodeID XId, PossibleXId;
12636 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12637 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12638 IsUpdateExprFound = XId == PossibleXId;
12639 if (IsUpdateExprFound) {
12640 V = BinOp->getLHS();
12641 X = Checker.getX();
12642 E = Checker.getExpr();
12643 UE = Checker.getUpdateExpr();
12644 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12645 IsPostfixUpdate = true;
12646 }
12647 }
12648 if (!IsUpdateExprFound) {
12649 IsUpdateExprFound = !Checker.checkStatement(First);
12650 BinOp = nullptr;
12651 if (IsUpdateExprFound) {
12652 BinOp = dyn_cast<BinaryOperator>(Second);
12653 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12654 }
12655 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12656 // { x++; v = x; }
12657 // { x--; v = x; }
12658 // { ++x; v = x; }
12659 // { --x; v = x; }
12660 // { x binop= expr; v = x; }
12661 // { x = x binop expr; v = x; }
12662 // { x = expr binop x; v = x; }
12663 // Check that the second expression has form v = x.
12664 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12665 llvm::FoldingSetNodeID XId, PossibleXId;
12666 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12667 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12668 IsUpdateExprFound = XId == PossibleXId;
12669 if (IsUpdateExprFound) {
12670 V = BinOp->getLHS();
12671 X = Checker.getX();
12672 E = Checker.getExpr();
12673 UE = Checker.getUpdateExpr();
12674 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12675 IsPostfixUpdate = false;
12676 }
12677 }
12678 }
12679 if (!IsUpdateExprFound) {
12680 // { v = x; x = expr; }
12681 auto *FirstExpr = dyn_cast<Expr>(First);
12682 auto *SecondExpr = dyn_cast<Expr>(Second);
12683 if (!FirstExpr || !SecondExpr ||
12684 !(FirstExpr->isInstantiationDependent() ||
12685 SecondExpr->isInstantiationDependent())) {
12686 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12687 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12688 ErrorFound = NotAnAssignmentOp;
12689 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12690 : First->getBeginLoc();
12691 NoteRange = ErrorRange = FirstBinOp
12692 ? FirstBinOp->getSourceRange()
12693 : SourceRange(ErrorLoc, ErrorLoc);
12694 } else {
12695 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12696 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12697 ErrorFound = NotAnAssignmentOp;
12698 NoteLoc = ErrorLoc = SecondBinOp
12699 ? SecondBinOp->getOperatorLoc()
12700 : Second->getBeginLoc();
12701 NoteRange = ErrorRange =
12702 SecondBinOp ? SecondBinOp->getSourceRange()
12703 : SourceRange(ErrorLoc, ErrorLoc);
12704 } else {
12705 Expr *PossibleXRHSInFirst =
12706 FirstBinOp->getRHS()->IgnoreParenImpCasts();
12707 Expr *PossibleXLHSInSecond =
12708 SecondBinOp->getLHS()->IgnoreParenImpCasts();
12709 llvm::FoldingSetNodeID X1Id, X2Id;
12710 PossibleXRHSInFirst->Profile(X1Id, Context,
12711 /*Canonical=*/true);
12712 PossibleXLHSInSecond->Profile(X2Id, Context,
12713 /*Canonical=*/true);
12714 IsUpdateExprFound = X1Id == X2Id;
12715 if (IsUpdateExprFound) {
12716 V = FirstBinOp->getLHS();
12717 X = SecondBinOp->getLHS();
12718 E = SecondBinOp->getRHS();
12719 UE = nullptr;
12720 IsXLHSInRHSPart = false;
12721 IsPostfixUpdate = true;
12722 } else {
12723 ErrorFound = NotASpecificExpression;
12724 ErrorLoc = FirstBinOp->getExprLoc();
12725 ErrorRange = FirstBinOp->getSourceRange();
12726 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12727 NoteRange = SecondBinOp->getRHS()->getSourceRange();
12728 }
12729 }
12730 }
12731 }
12732 }
12733 } else {
12734 NoteLoc = ErrorLoc = Body->getBeginLoc();
12735 NoteRange = ErrorRange =
12736 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12737 ErrorFound = NotTwoSubstatements;
12738 }
12739 } else {
12740 NoteLoc = ErrorLoc = Body->getBeginLoc();
12741 NoteRange = ErrorRange =
12742 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12743 ErrorFound = NotACompoundStatement;
12744 }
12745 }
12746 if (ErrorFound != NoError) {
12747 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12748 << ErrorRange;
12749 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12750 return StmtError();
12751 }
12752 if (CurContext->isDependentContext())
12753 UE = V = E = X = nullptr;
12754 } else if (AtomicKind == OMPC_compare) {
12755 if (IsCompareCapture) {
12756 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12757 OpenMPAtomicCompareCaptureChecker Checker(*this);
12758 if (!Checker.checkStmt(Body, ErrorInfo)) {
12759 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12760 << ErrorInfo.ErrorRange;
12761 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12762 << ErrorInfo.Error << ErrorInfo.NoteRange;
12763 return StmtError();
12764 }
12765 X = Checker.getX();
12766 E = Checker.getE();
12767 D = Checker.getD();
12768 CE = Checker.getCond();
12769 V = Checker.getV();
12770 R = Checker.getR();
12771 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12772 IsXLHSInRHSPart = Checker.isXBinopExpr();
12773 IsFailOnly = Checker.isFailOnly();
12774 IsPostfixUpdate = Checker.isPostfixUpdate();
12775 } else {
12776 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12777 OpenMPAtomicCompareChecker Checker(*this);
12778 if (!Checker.checkStmt(Body, ErrorInfo)) {
12779 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12780 << ErrorInfo.ErrorRange;
12781 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12782 << ErrorInfo.Error << ErrorInfo.NoteRange;
12783 return StmtError();
12784 }
12785 X = Checker.getX();
12786 E = Checker.getE();
12787 D = Checker.getD();
12788 CE = Checker.getCond();
12789 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12790 IsXLHSInRHSPart = Checker.isXBinopExpr();
12791 }
12792 }
12793
12794 setFunctionHasBranchProtectedScope();
12795
12796 return OMPAtomicDirective::Create(
12797 Context, StartLoc, EndLoc, Clauses, AStmt,
12798 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
12799 }
12800
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12801 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
12802 Stmt *AStmt,
12803 SourceLocation StartLoc,
12804 SourceLocation EndLoc) {
12805 if (!AStmt)
12806 return StmtError();
12807
12808 auto *CS = cast<CapturedStmt>(AStmt);
12809 // 1.2.2 OpenMP Language Terminology
12810 // Structured block - An executable statement with a single entry at the
12811 // top and a single exit at the bottom.
12812 // The point of exit cannot be a branch out of the structured block.
12813 // longjmp() and throw() must not violate the entry/exit criteria.
12814 CS->getCapturedDecl()->setNothrow();
12815 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12816 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12817 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12818 // 1.2.2 OpenMP Language Terminology
12819 // Structured block - An executable statement with a single entry at the
12820 // top and a single exit at the bottom.
12821 // The point of exit cannot be a branch out of the structured block.
12822 // longjmp() and throw() must not violate the entry/exit criteria.
12823 CS->getCapturedDecl()->setNothrow();
12824 }
12825
12826 // OpenMP [2.16, Nesting of Regions]
12827 // If specified, a teams construct must be contained within a target
12828 // construct. That target construct must contain no statements or directives
12829 // outside of the teams construct.
12830 if (DSAStack->hasInnerTeamsRegion()) {
12831 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12832 bool OMPTeamsFound = true;
12833 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12834 auto I = CS->body_begin();
12835 while (I != CS->body_end()) {
12836 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12837 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12838 OMPTeamsFound) {
12839
12840 OMPTeamsFound = false;
12841 break;
12842 }
12843 ++I;
12844 }
12845 assert(I != CS->body_end() && "Not found statement");
12846 S = *I;
12847 } else {
12848 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12849 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12850 }
12851 if (!OMPTeamsFound) {
12852 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12853 Diag(DSAStack->getInnerTeamsRegionLoc(),
12854 diag::note_omp_nested_teams_construct_here);
12855 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12856 << isa<OMPExecutableDirective>(S);
12857 return StmtError();
12858 }
12859 }
12860
12861 setFunctionHasBranchProtectedScope();
12862
12863 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12864 }
12865
12866 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12867 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
12868 Stmt *AStmt, SourceLocation StartLoc,
12869 SourceLocation EndLoc) {
12870 if (!AStmt)
12871 return StmtError();
12872
12873 auto *CS = cast<CapturedStmt>(AStmt);
12874 // 1.2.2 OpenMP Language Terminology
12875 // Structured block - An executable statement with a single entry at the
12876 // top and a single exit at the bottom.
12877 // The point of exit cannot be a branch out of the structured block.
12878 // longjmp() and throw() must not violate the entry/exit criteria.
12879 CS->getCapturedDecl()->setNothrow();
12880 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
12881 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12882 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12883 // 1.2.2 OpenMP Language Terminology
12884 // Structured block - An executable statement with a single entry at the
12885 // top and a single exit at the bottom.
12886 // The point of exit cannot be a branch out of the structured block.
12887 // longjmp() and throw() must not violate the entry/exit criteria.
12888 CS->getCapturedDecl()->setNothrow();
12889 }
12890
12891 setFunctionHasBranchProtectedScope();
12892
12893 return OMPTargetParallelDirective::Create(
12894 Context, StartLoc, EndLoc, Clauses, AStmt,
12895 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12896 }
12897
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12898 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
12899 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12900 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12901 if (!AStmt)
12902 return StmtError();
12903
12904 auto *CS = cast<CapturedStmt>(AStmt);
12905 // 1.2.2 OpenMP Language Terminology
12906 // Structured block - An executable statement with a single entry at the
12907 // top and a single exit at the bottom.
12908 // The point of exit cannot be a branch out of the structured block.
12909 // longjmp() and throw() must not violate the entry/exit criteria.
12910 CS->getCapturedDecl()->setNothrow();
12911 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12912 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12913 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12914 // 1.2.2 OpenMP Language Terminology
12915 // Structured block - An executable statement with a single entry at the
12916 // top and a single exit at the bottom.
12917 // The point of exit cannot be a branch out of the structured block.
12918 // longjmp() and throw() must not violate the entry/exit criteria.
12919 CS->getCapturedDecl()->setNothrow();
12920 }
12921
12922 OMPLoopBasedDirective::HelperExprs B;
12923 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12924 // define the nested loops number.
12925 unsigned NestedLoopCount =
12926 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
12927 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12928 VarsWithImplicitDSA, B);
12929 if (NestedLoopCount == 0)
12930 return StmtError();
12931
12932 assert((CurContext->isDependentContext() || B.builtAll()) &&
12933 "omp target parallel for loop exprs were not built");
12934
12935 if (!CurContext->isDependentContext()) {
12936 // Finalize the clauses that need pre-built expressions for CodeGen.
12937 for (OMPClause *C : Clauses) {
12938 if (auto *LC = dyn_cast<OMPLinearClause>(C))
12939 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12940 B.NumIterations, *this, CurScope,
12941 DSAStack))
12942 return StmtError();
12943 }
12944 }
12945
12946 setFunctionHasBranchProtectedScope();
12947 return OMPTargetParallelForDirective::Create(
12948 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12949 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12950 }
12951
12952 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)12953 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
12954 const OpenMPClauseKind K) {
12955 return llvm::any_of(
12956 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
12957 }
12958
12959 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)12960 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
12961 const Params... ClauseTypes) {
12962 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
12963 }
12964
12965 /// Check if the variables in the mapping clause are externally visible.
isClauseMappable(ArrayRef<OMPClause * > Clauses)12966 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
12967 for (const OMPClause *C : Clauses) {
12968 if (auto *TC = dyn_cast<OMPToClause>(C))
12969 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
12970 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12971 (VD->isExternallyVisible() &&
12972 VD->getVisibility() != HiddenVisibility);
12973 });
12974 else if (auto *FC = dyn_cast<OMPFromClause>(C))
12975 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
12976 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
12977 (VD->isExternallyVisible() &&
12978 VD->getVisibility() != HiddenVisibility);
12979 });
12980 }
12981
12982 return true;
12983 }
12984
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12985 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
12986 Stmt *AStmt,
12987 SourceLocation StartLoc,
12988 SourceLocation EndLoc) {
12989 if (!AStmt)
12990 return StmtError();
12991
12992 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12993
12994 // OpenMP [2.12.2, target data Construct, Restrictions]
12995 // At least one map, use_device_addr or use_device_ptr clause must appear on
12996 // the directive.
12997 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
12998 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
12999 StringRef Expected;
13000 if (LangOpts.OpenMP < 50)
13001 Expected = "'map' or 'use_device_ptr'";
13002 else
13003 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13004 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13005 << Expected << getOpenMPDirectiveName(OMPD_target_data);
13006 return StmtError();
13007 }
13008
13009 setFunctionHasBranchProtectedScope();
13010
13011 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13012 AStmt);
13013 }
13014
13015 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13016 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13017 SourceLocation StartLoc,
13018 SourceLocation EndLoc, Stmt *AStmt) {
13019 if (!AStmt)
13020 return StmtError();
13021
13022 auto *CS = cast<CapturedStmt>(AStmt);
13023 // 1.2.2 OpenMP Language Terminology
13024 // Structured block - An executable statement with a single entry at the
13025 // top and a single exit at the bottom.
13026 // The point of exit cannot be a branch out of the structured block.
13027 // longjmp() and throw() must not violate the entry/exit criteria.
13028 CS->getCapturedDecl()->setNothrow();
13029 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13030 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13031 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13032 // 1.2.2 OpenMP Language Terminology
13033 // Structured block - An executable statement with a single entry at the
13034 // top and a single exit at the bottom.
13035 // The point of exit cannot be a branch out of the structured block.
13036 // longjmp() and throw() must not violate the entry/exit criteria.
13037 CS->getCapturedDecl()->setNothrow();
13038 }
13039
13040 // OpenMP [2.10.2, Restrictions, p. 99]
13041 // At least one map clause must appear on the directive.
13042 if (!hasClauses(Clauses, OMPC_map)) {
13043 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13044 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13045 return StmtError();
13046 }
13047
13048 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13049 AStmt);
13050 }
13051
13052 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13053 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13054 SourceLocation StartLoc,
13055 SourceLocation EndLoc, Stmt *AStmt) {
13056 if (!AStmt)
13057 return StmtError();
13058
13059 auto *CS = cast<CapturedStmt>(AStmt);
13060 // 1.2.2 OpenMP Language Terminology
13061 // Structured block - An executable statement with a single entry at the
13062 // top and a single exit at the bottom.
13063 // The point of exit cannot be a branch out of the structured block.
13064 // longjmp() and throw() must not violate the entry/exit criteria.
13065 CS->getCapturedDecl()->setNothrow();
13066 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13067 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13068 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13069 // 1.2.2 OpenMP Language Terminology
13070 // Structured block - An executable statement with a single entry at the
13071 // top and a single exit at the bottom.
13072 // The point of exit cannot be a branch out of the structured block.
13073 // longjmp() and throw() must not violate the entry/exit criteria.
13074 CS->getCapturedDecl()->setNothrow();
13075 }
13076
13077 // OpenMP [2.10.3, Restrictions, p. 102]
13078 // At least one map clause must appear on the directive.
13079 if (!hasClauses(Clauses, OMPC_map)) {
13080 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13081 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13082 return StmtError();
13083 }
13084
13085 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13086 AStmt);
13087 }
13088
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13089 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13090 SourceLocation StartLoc,
13091 SourceLocation EndLoc,
13092 Stmt *AStmt) {
13093 if (!AStmt)
13094 return StmtError();
13095
13096 auto *CS = cast<CapturedStmt>(AStmt);
13097 // 1.2.2 OpenMP Language Terminology
13098 // Structured block - An executable statement with a single entry at the
13099 // top and a single exit at the bottom.
13100 // The point of exit cannot be a branch out of the structured block.
13101 // longjmp() and throw() must not violate the entry/exit criteria.
13102 CS->getCapturedDecl()->setNothrow();
13103 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13104 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13105 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13106 // 1.2.2 OpenMP Language Terminology
13107 // Structured block - An executable statement with a single entry at the
13108 // top and a single exit at the bottom.
13109 // The point of exit cannot be a branch out of the structured block.
13110 // longjmp() and throw() must not violate the entry/exit criteria.
13111 CS->getCapturedDecl()->setNothrow();
13112 }
13113
13114 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13115 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13116 return StmtError();
13117 }
13118
13119 if (!isClauseMappable(Clauses)) {
13120 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13121 return StmtError();
13122 }
13123
13124 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13125 AStmt);
13126 }
13127
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)13128 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13129 Stmt *AStmt, SourceLocation StartLoc,
13130 SourceLocation EndLoc) {
13131 if (!AStmt)
13132 return StmtError();
13133
13134 auto *CS = cast<CapturedStmt>(AStmt);
13135 // 1.2.2 OpenMP Language Terminology
13136 // Structured block - An executable statement with a single entry at the
13137 // top and a single exit at the bottom.
13138 // The point of exit cannot be a branch out of the structured block.
13139 // longjmp() and throw() must not violate the entry/exit criteria.
13140 CS->getCapturedDecl()->setNothrow();
13141
13142 setFunctionHasBranchProtectedScope();
13143
13144 DSAStack->setParentTeamsRegionLoc(StartLoc);
13145
13146 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13147 }
13148
13149 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)13150 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13151 SourceLocation EndLoc,
13152 OpenMPDirectiveKind CancelRegion) {
13153 if (DSAStack->isParentNowaitRegion()) {
13154 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13155 return StmtError();
13156 }
13157 if (DSAStack->isParentOrderedRegion()) {
13158 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13159 return StmtError();
13160 }
13161 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13162 CancelRegion);
13163 }
13164
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)13165 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13166 SourceLocation StartLoc,
13167 SourceLocation EndLoc,
13168 OpenMPDirectiveKind CancelRegion) {
13169 if (DSAStack->isParentNowaitRegion()) {
13170 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13171 return StmtError();
13172 }
13173 if (DSAStack->isParentOrderedRegion()) {
13174 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13175 return StmtError();
13176 }
13177 DSAStack->setParentCancelRegion(/*Cancel=*/true);
13178 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13179 CancelRegion);
13180 }
13181
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)13182 static bool checkReductionClauseWithNogroup(Sema &S,
13183 ArrayRef<OMPClause *> Clauses) {
13184 const OMPClause *ReductionClause = nullptr;
13185 const OMPClause *NogroupClause = nullptr;
13186 for (const OMPClause *C : Clauses) {
13187 if (C->getClauseKind() == OMPC_reduction) {
13188 ReductionClause = C;
13189 if (NogroupClause)
13190 break;
13191 continue;
13192 }
13193 if (C->getClauseKind() == OMPC_nogroup) {
13194 NogroupClause = C;
13195 if (ReductionClause)
13196 break;
13197 continue;
13198 }
13199 }
13200 if (ReductionClause && NogroupClause) {
13201 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13202 << SourceRange(NogroupClause->getBeginLoc(),
13203 NogroupClause->getEndLoc());
13204 return true;
13205 }
13206 return false;
13207 }
13208
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13209 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13210 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13211 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13212 if (!AStmt)
13213 return StmtError();
13214
13215 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13216 OMPLoopBasedDirective::HelperExprs B;
13217 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13218 // define the nested loops number.
13219 unsigned NestedLoopCount =
13220 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13221 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13222 VarsWithImplicitDSA, B);
13223 if (NestedLoopCount == 0)
13224 return StmtError();
13225
13226 assert((CurContext->isDependentContext() || B.builtAll()) &&
13227 "omp for loop exprs were not built");
13228
13229 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13230 // The grainsize clause and num_tasks clause are mutually exclusive and may
13231 // not appear on the same taskloop directive.
13232 if (checkMutuallyExclusiveClauses(*this, Clauses,
13233 {OMPC_grainsize, OMPC_num_tasks}))
13234 return StmtError();
13235 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13236 // If a reduction clause is present on the taskloop directive, the nogroup
13237 // clause must not be specified.
13238 if (checkReductionClauseWithNogroup(*this, Clauses))
13239 return StmtError();
13240
13241 setFunctionHasBranchProtectedScope();
13242 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13243 NestedLoopCount, Clauses, AStmt, B,
13244 DSAStack->isCancelRegion());
13245 }
13246
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13247 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13248 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13249 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13250 if (!AStmt)
13251 return StmtError();
13252
13253 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13254 OMPLoopBasedDirective::HelperExprs B;
13255 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13256 // define the nested loops number.
13257 unsigned NestedLoopCount =
13258 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13259 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13260 VarsWithImplicitDSA, B);
13261 if (NestedLoopCount == 0)
13262 return StmtError();
13263
13264 assert((CurContext->isDependentContext() || B.builtAll()) &&
13265 "omp for loop exprs were not built");
13266
13267 if (!CurContext->isDependentContext()) {
13268 // Finalize the clauses that need pre-built expressions for CodeGen.
13269 for (OMPClause *C : Clauses) {
13270 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13271 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13272 B.NumIterations, *this, CurScope,
13273 DSAStack))
13274 return StmtError();
13275 }
13276 }
13277
13278 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13279 // The grainsize clause and num_tasks clause are mutually exclusive and may
13280 // not appear on the same taskloop directive.
13281 if (checkMutuallyExclusiveClauses(*this, Clauses,
13282 {OMPC_grainsize, OMPC_num_tasks}))
13283 return StmtError();
13284 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13285 // If a reduction clause is present on the taskloop directive, the nogroup
13286 // clause must not be specified.
13287 if (checkReductionClauseWithNogroup(*this, Clauses))
13288 return StmtError();
13289 if (checkSimdlenSafelenSpecified(*this, Clauses))
13290 return StmtError();
13291
13292 setFunctionHasBranchProtectedScope();
13293 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13294 NestedLoopCount, Clauses, AStmt, B);
13295 }
13296
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13297 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13298 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13299 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13300 if (!AStmt)
13301 return StmtError();
13302
13303 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13304 OMPLoopBasedDirective::HelperExprs B;
13305 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13306 // define the nested loops number.
13307 unsigned NestedLoopCount =
13308 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13309 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13310 VarsWithImplicitDSA, B);
13311 if (NestedLoopCount == 0)
13312 return StmtError();
13313
13314 assert((CurContext->isDependentContext() || B.builtAll()) &&
13315 "omp for loop exprs were not built");
13316
13317 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13318 // The grainsize clause and num_tasks clause are mutually exclusive and may
13319 // not appear on the same taskloop directive.
13320 if (checkMutuallyExclusiveClauses(*this, Clauses,
13321 {OMPC_grainsize, OMPC_num_tasks}))
13322 return StmtError();
13323 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13324 // If a reduction clause is present on the taskloop directive, the nogroup
13325 // clause must not be specified.
13326 if (checkReductionClauseWithNogroup(*this, Clauses))
13327 return StmtError();
13328
13329 setFunctionHasBranchProtectedScope();
13330 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13331 NestedLoopCount, Clauses, AStmt, B,
13332 DSAStack->isCancelRegion());
13333 }
13334
ActOnOpenMPMaskedTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13335 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13336 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13337 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13338 if (!AStmt)
13339 return StmtError();
13340
13341 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13342 OMPLoopBasedDirective::HelperExprs B;
13343 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13344 // define the nested loops number.
13345 unsigned NestedLoopCount =
13346 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13347 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13348 VarsWithImplicitDSA, B);
13349 if (NestedLoopCount == 0)
13350 return StmtError();
13351
13352 assert((CurContext->isDependentContext() || B.builtAll()) &&
13353 "omp for loop exprs were not built");
13354
13355 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13356 // The grainsize clause and num_tasks clause are mutually exclusive and may
13357 // not appear on the same taskloop directive.
13358 if (checkMutuallyExclusiveClauses(*this, Clauses,
13359 {OMPC_grainsize, OMPC_num_tasks}))
13360 return StmtError();
13361 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13362 // If a reduction clause is present on the taskloop directive, the nogroup
13363 // clause must not be specified.
13364 if (checkReductionClauseWithNogroup(*this, Clauses))
13365 return StmtError();
13366
13367 setFunctionHasBranchProtectedScope();
13368 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13369 NestedLoopCount, Clauses, AStmt, B,
13370 DSAStack->isCancelRegion());
13371 }
13372
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13373 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13374 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13375 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13376 if (!AStmt)
13377 return StmtError();
13378
13379 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13380 OMPLoopBasedDirective::HelperExprs B;
13381 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13382 // define the nested loops number.
13383 unsigned NestedLoopCount =
13384 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13385 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13386 VarsWithImplicitDSA, B);
13387 if (NestedLoopCount == 0)
13388 return StmtError();
13389
13390 assert((CurContext->isDependentContext() || B.builtAll()) &&
13391 "omp for loop exprs were not built");
13392
13393 if (!CurContext->isDependentContext()) {
13394 // Finalize the clauses that need pre-built expressions for CodeGen.
13395 for (OMPClause *C : Clauses) {
13396 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13397 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13398 B.NumIterations, *this, CurScope,
13399 DSAStack))
13400 return StmtError();
13401 }
13402 }
13403
13404 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13405 // The grainsize clause and num_tasks clause are mutually exclusive and may
13406 // not appear on the same taskloop directive.
13407 if (checkMutuallyExclusiveClauses(*this, Clauses,
13408 {OMPC_grainsize, OMPC_num_tasks}))
13409 return StmtError();
13410 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13411 // If a reduction clause is present on the taskloop directive, the nogroup
13412 // clause must not be specified.
13413 if (checkReductionClauseWithNogroup(*this, Clauses))
13414 return StmtError();
13415 if (checkSimdlenSafelenSpecified(*this, Clauses))
13416 return StmtError();
13417
13418 setFunctionHasBranchProtectedScope();
13419 return OMPMasterTaskLoopSimdDirective::Create(
13420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13421 }
13422
ActOnOpenMPMaskedTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13423 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13424 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13425 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13426 if (!AStmt)
13427 return StmtError();
13428
13429 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13430 OMPLoopBasedDirective::HelperExprs B;
13431 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13432 // define the nested loops number.
13433 unsigned NestedLoopCount =
13434 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13435 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13436 VarsWithImplicitDSA, B);
13437 if (NestedLoopCount == 0)
13438 return StmtError();
13439
13440 assert((CurContext->isDependentContext() || B.builtAll()) &&
13441 "omp for loop exprs were not built");
13442
13443 if (!CurContext->isDependentContext()) {
13444 // Finalize the clauses that need pre-built expressions for CodeGen.
13445 for (OMPClause *C : Clauses) {
13446 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13447 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13448 B.NumIterations, *this, CurScope,
13449 DSAStack))
13450 return StmtError();
13451 }
13452 }
13453
13454 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13455 // The grainsize clause and num_tasks clause are mutually exclusive and may
13456 // not appear on the same taskloop directive.
13457 if (checkMutuallyExclusiveClauses(*this, Clauses,
13458 {OMPC_grainsize, OMPC_num_tasks}))
13459 return StmtError();
13460 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13461 // If a reduction clause is present on the taskloop directive, the nogroup
13462 // clause must not be specified.
13463 if (checkReductionClauseWithNogroup(*this, Clauses))
13464 return StmtError();
13465 if (checkSimdlenSafelenSpecified(*this, Clauses))
13466 return StmtError();
13467
13468 setFunctionHasBranchProtectedScope();
13469 return OMPMaskedTaskLoopSimdDirective::Create(
13470 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13471 }
13472
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13473 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13474 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13475 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13476 if (!AStmt)
13477 return StmtError();
13478
13479 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13480 auto *CS = cast<CapturedStmt>(AStmt);
13481 // 1.2.2 OpenMP Language Terminology
13482 // Structured block - An executable statement with a single entry at the
13483 // top and a single exit at the bottom.
13484 // The point of exit cannot be a branch out of the structured block.
13485 // longjmp() and throw() must not violate the entry/exit criteria.
13486 CS->getCapturedDecl()->setNothrow();
13487 for (int ThisCaptureLevel =
13488 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13489 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13490 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13491 // 1.2.2 OpenMP Language Terminology
13492 // Structured block - An executable statement with a single entry at the
13493 // top and a single exit at the bottom.
13494 // The point of exit cannot be a branch out of the structured block.
13495 // longjmp() and throw() must not violate the entry/exit criteria.
13496 CS->getCapturedDecl()->setNothrow();
13497 }
13498
13499 OMPLoopBasedDirective::HelperExprs B;
13500 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13501 // define the nested loops number.
13502 unsigned NestedLoopCount = checkOpenMPLoop(
13503 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13504 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13505 VarsWithImplicitDSA, B);
13506 if (NestedLoopCount == 0)
13507 return StmtError();
13508
13509 assert((CurContext->isDependentContext() || B.builtAll()) &&
13510 "omp for loop exprs were not built");
13511
13512 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13513 // The grainsize clause and num_tasks clause are mutually exclusive and may
13514 // not appear on the same taskloop directive.
13515 if (checkMutuallyExclusiveClauses(*this, Clauses,
13516 {OMPC_grainsize, OMPC_num_tasks}))
13517 return StmtError();
13518 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13519 // If a reduction clause is present on the taskloop directive, the nogroup
13520 // clause must not be specified.
13521 if (checkReductionClauseWithNogroup(*this, Clauses))
13522 return StmtError();
13523
13524 setFunctionHasBranchProtectedScope();
13525 return OMPParallelMasterTaskLoopDirective::Create(
13526 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13527 DSAStack->isCancelRegion());
13528 }
13529
ActOnOpenMPParallelMaskedTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13530 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13531 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13532 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13533 if (!AStmt)
13534 return StmtError();
13535
13536 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13537 auto *CS = cast<CapturedStmt>(AStmt);
13538 // 1.2.2 OpenMP Language Terminology
13539 // Structured block - An executable statement with a single entry at the
13540 // top and a single exit at the bottom.
13541 // The point of exit cannot be a branch out of the structured block.
13542 // longjmp() and throw() must not violate the entry/exit criteria.
13543 CS->getCapturedDecl()->setNothrow();
13544 for (int ThisCaptureLevel =
13545 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13546 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13547 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13548 // 1.2.2 OpenMP Language Terminology
13549 // Structured block - An executable statement with a single entry at the
13550 // top and a single exit at the bottom.
13551 // The point of exit cannot be a branch out of the structured block.
13552 // longjmp() and throw() must not violate the entry/exit criteria.
13553 CS->getCapturedDecl()->setNothrow();
13554 }
13555
13556 OMPLoopBasedDirective::HelperExprs B;
13557 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13558 // define the nested loops number.
13559 unsigned NestedLoopCount = checkOpenMPLoop(
13560 OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13561 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13562 VarsWithImplicitDSA, B);
13563 if (NestedLoopCount == 0)
13564 return StmtError();
13565
13566 assert((CurContext->isDependentContext() || B.builtAll()) &&
13567 "omp for loop exprs were not built");
13568
13569 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13570 // The grainsize clause and num_tasks clause are mutually exclusive and may
13571 // not appear on the same taskloop directive.
13572 if (checkMutuallyExclusiveClauses(*this, Clauses,
13573 {OMPC_grainsize, OMPC_num_tasks}))
13574 return StmtError();
13575 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13576 // If a reduction clause is present on the taskloop directive, the nogroup
13577 // clause must not be specified.
13578 if (checkReductionClauseWithNogroup(*this, Clauses))
13579 return StmtError();
13580
13581 setFunctionHasBranchProtectedScope();
13582 return OMPParallelMaskedTaskLoopDirective::Create(
13583 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13584 DSAStack->isCancelRegion());
13585 }
13586
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13587 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13590 if (!AStmt)
13591 return StmtError();
13592
13593 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13594 auto *CS = cast<CapturedStmt>(AStmt);
13595 // 1.2.2 OpenMP Language Terminology
13596 // Structured block - An executable statement with a single entry at the
13597 // top and a single exit at the bottom.
13598 // The point of exit cannot be a branch out of the structured block.
13599 // longjmp() and throw() must not violate the entry/exit criteria.
13600 CS->getCapturedDecl()->setNothrow();
13601 for (int ThisCaptureLevel =
13602 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13603 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13604 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13605 // 1.2.2 OpenMP Language Terminology
13606 // Structured block - An executable statement with a single entry at the
13607 // top and a single exit at the bottom.
13608 // The point of exit cannot be a branch out of the structured block.
13609 // longjmp() and throw() must not violate the entry/exit criteria.
13610 CS->getCapturedDecl()->setNothrow();
13611 }
13612
13613 OMPLoopBasedDirective::HelperExprs B;
13614 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13615 // define the nested loops number.
13616 unsigned NestedLoopCount = checkOpenMPLoop(
13617 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13618 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13619 VarsWithImplicitDSA, B);
13620 if (NestedLoopCount == 0)
13621 return StmtError();
13622
13623 assert((CurContext->isDependentContext() || B.builtAll()) &&
13624 "omp for loop exprs were not built");
13625
13626 if (!CurContext->isDependentContext()) {
13627 // Finalize the clauses that need pre-built expressions for CodeGen.
13628 for (OMPClause *C : Clauses) {
13629 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13630 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13631 B.NumIterations, *this, CurScope,
13632 DSAStack))
13633 return StmtError();
13634 }
13635 }
13636
13637 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13638 // The grainsize clause and num_tasks clause are mutually exclusive and may
13639 // not appear on the same taskloop directive.
13640 if (checkMutuallyExclusiveClauses(*this, Clauses,
13641 {OMPC_grainsize, OMPC_num_tasks}))
13642 return StmtError();
13643 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13644 // If a reduction clause is present on the taskloop directive, the nogroup
13645 // clause must not be specified.
13646 if (checkReductionClauseWithNogroup(*this, Clauses))
13647 return StmtError();
13648 if (checkSimdlenSafelenSpecified(*this, Clauses))
13649 return StmtError();
13650
13651 setFunctionHasBranchProtectedScope();
13652 return OMPParallelMasterTaskLoopSimdDirective::Create(
13653 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13654 }
13655
ActOnOpenMPParallelMaskedTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13656 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
13657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13659 if (!AStmt)
13660 return StmtError();
13661
13662 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13663 auto *CS = cast<CapturedStmt>(AStmt);
13664 // 1.2.2 OpenMP Language Terminology
13665 // Structured block - An executable statement with a single entry at the
13666 // top and a single exit at the bottom.
13667 // The point of exit cannot be a branch out of the structured block.
13668 // longjmp() and throw() must not violate the entry/exit criteria.
13669 CS->getCapturedDecl()->setNothrow();
13670 for (int ThisCaptureLevel =
13671 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
13672 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13673 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13674 // 1.2.2 OpenMP Language Terminology
13675 // Structured block - An executable statement with a single entry at the
13676 // top and a single exit at the bottom.
13677 // The point of exit cannot be a branch out of the structured block.
13678 // longjmp() and throw() must not violate the entry/exit criteria.
13679 CS->getCapturedDecl()->setNothrow();
13680 }
13681
13682 OMPLoopBasedDirective::HelperExprs B;
13683 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13684 // define the nested loops number.
13685 unsigned NestedLoopCount = checkOpenMPLoop(
13686 OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13687 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13688 VarsWithImplicitDSA, B);
13689 if (NestedLoopCount == 0)
13690 return StmtError();
13691
13692 assert((CurContext->isDependentContext() || B.builtAll()) &&
13693 "omp for loop exprs were not built");
13694
13695 if (!CurContext->isDependentContext()) {
13696 // Finalize the clauses that need pre-built expressions for CodeGen.
13697 for (OMPClause *C : Clauses) {
13698 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13699 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13700 B.NumIterations, *this, CurScope,
13701 DSAStack))
13702 return StmtError();
13703 }
13704 }
13705
13706 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13707 // The grainsize clause and num_tasks clause are mutually exclusive and may
13708 // not appear on the same taskloop directive.
13709 if (checkMutuallyExclusiveClauses(*this, Clauses,
13710 {OMPC_grainsize, OMPC_num_tasks}))
13711 return StmtError();
13712 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13713 // If a reduction clause is present on the taskloop directive, the nogroup
13714 // clause must not be specified.
13715 if (checkReductionClauseWithNogroup(*this, Clauses))
13716 return StmtError();
13717 if (checkSimdlenSafelenSpecified(*this, Clauses))
13718 return StmtError();
13719
13720 setFunctionHasBranchProtectedScope();
13721 return OMPParallelMaskedTaskLoopSimdDirective::Create(
13722 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13723 }
13724
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13725 StmtResult Sema::ActOnOpenMPDistributeDirective(
13726 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13727 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13728 if (!AStmt)
13729 return StmtError();
13730
13731 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13732 OMPLoopBasedDirective::HelperExprs B;
13733 // In presence of clause 'collapse' with number of loops, it will
13734 // define the nested loops number.
13735 unsigned NestedLoopCount =
13736 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13737 nullptr /*ordered not a clause on distribute*/, AStmt,
13738 *this, *DSAStack, VarsWithImplicitDSA, B);
13739 if (NestedLoopCount == 0)
13740 return StmtError();
13741
13742 assert((CurContext->isDependentContext() || B.builtAll()) &&
13743 "omp for loop exprs were not built");
13744
13745 setFunctionHasBranchProtectedScope();
13746 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13747 NestedLoopCount, Clauses, AStmt, B);
13748 }
13749
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13750 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
13751 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13752 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13753 if (!AStmt)
13754 return StmtError();
13755
13756 auto *CS = cast<CapturedStmt>(AStmt);
13757 // 1.2.2 OpenMP Language Terminology
13758 // Structured block - An executable statement with a single entry at the
13759 // top and a single exit at the bottom.
13760 // The point of exit cannot be a branch out of the structured block.
13761 // longjmp() and throw() must not violate the entry/exit criteria.
13762 CS->getCapturedDecl()->setNothrow();
13763 for (int ThisCaptureLevel =
13764 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13765 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13766 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13767 // 1.2.2 OpenMP Language Terminology
13768 // Structured block - An executable statement with a single entry at the
13769 // top and a single exit at the bottom.
13770 // The point of exit cannot be a branch out of the structured block.
13771 // longjmp() and throw() must not violate the entry/exit criteria.
13772 CS->getCapturedDecl()->setNothrow();
13773 }
13774
13775 OMPLoopBasedDirective::HelperExprs B;
13776 // In presence of clause 'collapse' with number of loops, it will
13777 // define the nested loops number.
13778 unsigned NestedLoopCount = checkOpenMPLoop(
13779 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13780 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13781 VarsWithImplicitDSA, B);
13782 if (NestedLoopCount == 0)
13783 return StmtError();
13784
13785 assert((CurContext->isDependentContext() || B.builtAll()) &&
13786 "omp for loop exprs were not built");
13787
13788 setFunctionHasBranchProtectedScope();
13789 return OMPDistributeParallelForDirective::Create(
13790 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13791 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13792 }
13793
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13794 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
13795 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13796 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13797 if (!AStmt)
13798 return StmtError();
13799
13800 auto *CS = cast<CapturedStmt>(AStmt);
13801 // 1.2.2 OpenMP Language Terminology
13802 // Structured block - An executable statement with a single entry at the
13803 // top and a single exit at the bottom.
13804 // The point of exit cannot be a branch out of the structured block.
13805 // longjmp() and throw() must not violate the entry/exit criteria.
13806 CS->getCapturedDecl()->setNothrow();
13807 for (int ThisCaptureLevel =
13808 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13809 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13810 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13811 // 1.2.2 OpenMP Language Terminology
13812 // Structured block - An executable statement with a single entry at the
13813 // top and a single exit at the bottom.
13814 // The point of exit cannot be a branch out of the structured block.
13815 // longjmp() and throw() must not violate the entry/exit criteria.
13816 CS->getCapturedDecl()->setNothrow();
13817 }
13818
13819 OMPLoopBasedDirective::HelperExprs B;
13820 // In presence of clause 'collapse' with number of loops, it will
13821 // define the nested loops number.
13822 unsigned NestedLoopCount = checkOpenMPLoop(
13823 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13824 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13825 VarsWithImplicitDSA, B);
13826 if (NestedLoopCount == 0)
13827 return StmtError();
13828
13829 assert((CurContext->isDependentContext() || B.builtAll()) &&
13830 "omp for loop exprs were not built");
13831
13832 if (!CurContext->isDependentContext()) {
13833 // Finalize the clauses that need pre-built expressions for CodeGen.
13834 for (OMPClause *C : Clauses) {
13835 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13836 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13837 B.NumIterations, *this, CurScope,
13838 DSAStack))
13839 return StmtError();
13840 }
13841 }
13842
13843 if (checkSimdlenSafelenSpecified(*this, Clauses))
13844 return StmtError();
13845
13846 setFunctionHasBranchProtectedScope();
13847 return OMPDistributeParallelForSimdDirective::Create(
13848 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13849 }
13850
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13851 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
13852 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13853 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13854 if (!AStmt)
13855 return StmtError();
13856
13857 auto *CS = cast<CapturedStmt>(AStmt);
13858 // 1.2.2 OpenMP Language Terminology
13859 // Structured block - An executable statement with a single entry at the
13860 // top and a single exit at the bottom.
13861 // The point of exit cannot be a branch out of the structured block.
13862 // longjmp() and throw() must not violate the entry/exit criteria.
13863 CS->getCapturedDecl()->setNothrow();
13864 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
13865 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13866 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13867 // 1.2.2 OpenMP Language Terminology
13868 // Structured block - An executable statement with a single entry at the
13869 // top and a single exit at the bottom.
13870 // The point of exit cannot be a branch out of the structured block.
13871 // longjmp() and throw() must not violate the entry/exit criteria.
13872 CS->getCapturedDecl()->setNothrow();
13873 }
13874
13875 OMPLoopBasedDirective::HelperExprs B;
13876 // In presence of clause 'collapse' with number of loops, it will
13877 // define the nested loops number.
13878 unsigned NestedLoopCount =
13879 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13880 nullptr /*ordered not a clause on distribute*/, CS, *this,
13881 *DSAStack, VarsWithImplicitDSA, B);
13882 if (NestedLoopCount == 0)
13883 return StmtError();
13884
13885 assert((CurContext->isDependentContext() || B.builtAll()) &&
13886 "omp for loop exprs were not built");
13887
13888 if (!CurContext->isDependentContext()) {
13889 // Finalize the clauses that need pre-built expressions for CodeGen.
13890 for (OMPClause *C : Clauses) {
13891 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13892 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13893 B.NumIterations, *this, CurScope,
13894 DSAStack))
13895 return StmtError();
13896 }
13897 }
13898
13899 if (checkSimdlenSafelenSpecified(*this, Clauses))
13900 return StmtError();
13901
13902 setFunctionHasBranchProtectedScope();
13903 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
13904 NestedLoopCount, Clauses, AStmt, B);
13905 }
13906
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13907 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
13908 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13909 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13910 if (!AStmt)
13911 return StmtError();
13912
13913 auto *CS = cast<CapturedStmt>(AStmt);
13914 // 1.2.2 OpenMP Language Terminology
13915 // Structured block - An executable statement with a single entry at the
13916 // top and a single exit at the bottom.
13917 // The point of exit cannot be a branch out of the structured block.
13918 // longjmp() and throw() must not violate the entry/exit criteria.
13919 CS->getCapturedDecl()->setNothrow();
13920 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13921 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13922 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13923 // 1.2.2 OpenMP Language Terminology
13924 // Structured block - An executable statement with a single entry at the
13925 // top and a single exit at the bottom.
13926 // The point of exit cannot be a branch out of the structured block.
13927 // longjmp() and throw() must not violate the entry/exit criteria.
13928 CS->getCapturedDecl()->setNothrow();
13929 }
13930
13931 OMPLoopBasedDirective::HelperExprs B;
13932 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13933 // define the nested loops number.
13934 unsigned NestedLoopCount = checkOpenMPLoop(
13935 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
13936 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
13937 B);
13938 if (NestedLoopCount == 0)
13939 return StmtError();
13940
13941 assert((CurContext->isDependentContext() || B.builtAll()) &&
13942 "omp target parallel for simd loop exprs were not built");
13943
13944 if (!CurContext->isDependentContext()) {
13945 // Finalize the clauses that need pre-built expressions for CodeGen.
13946 for (OMPClause *C : Clauses) {
13947 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13948 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13949 B.NumIterations, *this, CurScope,
13950 DSAStack))
13951 return StmtError();
13952 }
13953 }
13954 if (checkSimdlenSafelenSpecified(*this, Clauses))
13955 return StmtError();
13956
13957 setFunctionHasBranchProtectedScope();
13958 return OMPTargetParallelForSimdDirective::Create(
13959 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13960 }
13961
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13962 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
13963 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13964 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13965 if (!AStmt)
13966 return StmtError();
13967
13968 auto *CS = cast<CapturedStmt>(AStmt);
13969 // 1.2.2 OpenMP Language Terminology
13970 // Structured block - An executable statement with a single entry at the
13971 // top and a single exit at the bottom.
13972 // The point of exit cannot be a branch out of the structured block.
13973 // longjmp() and throw() must not violate the entry/exit criteria.
13974 CS->getCapturedDecl()->setNothrow();
13975 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
13976 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13977 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13978 // 1.2.2 OpenMP Language Terminology
13979 // Structured block - An executable statement with a single entry at the
13980 // top and a single exit at the bottom.
13981 // The point of exit cannot be a branch out of the structured block.
13982 // longjmp() and throw() must not violate the entry/exit criteria.
13983 CS->getCapturedDecl()->setNothrow();
13984 }
13985
13986 OMPLoopBasedDirective::HelperExprs B;
13987 // In presence of clause 'collapse' with number of loops, it will define the
13988 // nested loops number.
13989 unsigned NestedLoopCount =
13990 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
13991 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13992 VarsWithImplicitDSA, B);
13993 if (NestedLoopCount == 0)
13994 return StmtError();
13995
13996 assert((CurContext->isDependentContext() || B.builtAll()) &&
13997 "omp target simd loop exprs were not built");
13998
13999 if (!CurContext->isDependentContext()) {
14000 // Finalize the clauses that need pre-built expressions for CodeGen.
14001 for (OMPClause *C : Clauses) {
14002 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14003 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14004 B.NumIterations, *this, CurScope,
14005 DSAStack))
14006 return StmtError();
14007 }
14008 }
14009
14010 if (checkSimdlenSafelenSpecified(*this, Clauses))
14011 return StmtError();
14012
14013 setFunctionHasBranchProtectedScope();
14014 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14015 NestedLoopCount, Clauses, AStmt, B);
14016 }
14017
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14018 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14019 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14020 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14021 if (!AStmt)
14022 return StmtError();
14023
14024 auto *CS = cast<CapturedStmt>(AStmt);
14025 // 1.2.2 OpenMP Language Terminology
14026 // Structured block - An executable statement with a single entry at the
14027 // top and a single exit at the bottom.
14028 // The point of exit cannot be a branch out of the structured block.
14029 // longjmp() and throw() must not violate the entry/exit criteria.
14030 CS->getCapturedDecl()->setNothrow();
14031 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14032 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14033 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14034 // 1.2.2 OpenMP Language Terminology
14035 // Structured block - An executable statement with a single entry at the
14036 // top and a single exit at the bottom.
14037 // The point of exit cannot be a branch out of the structured block.
14038 // longjmp() and throw() must not violate the entry/exit criteria.
14039 CS->getCapturedDecl()->setNothrow();
14040 }
14041
14042 OMPLoopBasedDirective::HelperExprs B;
14043 // In presence of clause 'collapse' with number of loops, it will
14044 // define the nested loops number.
14045 unsigned NestedLoopCount =
14046 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14047 nullptr /*ordered not a clause on distribute*/, CS, *this,
14048 *DSAStack, VarsWithImplicitDSA, B);
14049 if (NestedLoopCount == 0)
14050 return StmtError();
14051
14052 assert((CurContext->isDependentContext() || B.builtAll()) &&
14053 "omp teams distribute loop exprs were not built");
14054
14055 setFunctionHasBranchProtectedScope();
14056
14057 DSAStack->setParentTeamsRegionLoc(StartLoc);
14058
14059 return OMPTeamsDistributeDirective::Create(
14060 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14061 }
14062
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14063 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14064 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14065 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14066 if (!AStmt)
14067 return StmtError();
14068
14069 auto *CS = cast<CapturedStmt>(AStmt);
14070 // 1.2.2 OpenMP Language Terminology
14071 // Structured block - An executable statement with a single entry at the
14072 // top and a single exit at the bottom.
14073 // The point of exit cannot be a branch out of the structured block.
14074 // longjmp() and throw() must not violate the entry/exit criteria.
14075 CS->getCapturedDecl()->setNothrow();
14076 for (int ThisCaptureLevel =
14077 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14078 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14079 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14080 // 1.2.2 OpenMP Language Terminology
14081 // Structured block - An executable statement with a single entry at the
14082 // top and a single exit at the bottom.
14083 // The point of exit cannot be a branch out of the structured block.
14084 // longjmp() and throw() must not violate the entry/exit criteria.
14085 CS->getCapturedDecl()->setNothrow();
14086 }
14087
14088 OMPLoopBasedDirective::HelperExprs B;
14089 // In presence of clause 'collapse' with number of loops, it will
14090 // define the nested loops number.
14091 unsigned NestedLoopCount = checkOpenMPLoop(
14092 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14093 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14094 VarsWithImplicitDSA, B);
14095
14096 if (NestedLoopCount == 0)
14097 return StmtError();
14098
14099 assert((CurContext->isDependentContext() || B.builtAll()) &&
14100 "omp teams distribute simd loop exprs were not built");
14101
14102 if (!CurContext->isDependentContext()) {
14103 // Finalize the clauses that need pre-built expressions for CodeGen.
14104 for (OMPClause *C : Clauses) {
14105 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14107 B.NumIterations, *this, CurScope,
14108 DSAStack))
14109 return StmtError();
14110 }
14111 }
14112
14113 if (checkSimdlenSafelenSpecified(*this, Clauses))
14114 return StmtError();
14115
14116 setFunctionHasBranchProtectedScope();
14117
14118 DSAStack->setParentTeamsRegionLoc(StartLoc);
14119
14120 return OMPTeamsDistributeSimdDirective::Create(
14121 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14122 }
14123
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14124 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14125 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14126 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14127 if (!AStmt)
14128 return StmtError();
14129
14130 auto *CS = cast<CapturedStmt>(AStmt);
14131 // 1.2.2 OpenMP Language Terminology
14132 // Structured block - An executable statement with a single entry at the
14133 // top and a single exit at the bottom.
14134 // The point of exit cannot be a branch out of the structured block.
14135 // longjmp() and throw() must not violate the entry/exit criteria.
14136 CS->getCapturedDecl()->setNothrow();
14137
14138 for (int ThisCaptureLevel =
14139 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14140 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14141 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14142 // 1.2.2 OpenMP Language Terminology
14143 // Structured block - An executable statement with a single entry at the
14144 // top and a single exit at the bottom.
14145 // The point of exit cannot be a branch out of the structured block.
14146 // longjmp() and throw() must not violate the entry/exit criteria.
14147 CS->getCapturedDecl()->setNothrow();
14148 }
14149
14150 OMPLoopBasedDirective::HelperExprs B;
14151 // In presence of clause 'collapse' with number of loops, it will
14152 // define the nested loops number.
14153 unsigned NestedLoopCount = checkOpenMPLoop(
14154 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14155 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14156 VarsWithImplicitDSA, B);
14157
14158 if (NestedLoopCount == 0)
14159 return StmtError();
14160
14161 assert((CurContext->isDependentContext() || B.builtAll()) &&
14162 "omp for loop exprs were not built");
14163
14164 if (!CurContext->isDependentContext()) {
14165 // Finalize the clauses that need pre-built expressions for CodeGen.
14166 for (OMPClause *C : Clauses) {
14167 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14168 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14169 B.NumIterations, *this, CurScope,
14170 DSAStack))
14171 return StmtError();
14172 }
14173 }
14174
14175 if (checkSimdlenSafelenSpecified(*this, Clauses))
14176 return StmtError();
14177
14178 setFunctionHasBranchProtectedScope();
14179
14180 DSAStack->setParentTeamsRegionLoc(StartLoc);
14181
14182 return OMPTeamsDistributeParallelForSimdDirective::Create(
14183 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14184 }
14185
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14186 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14187 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14188 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14189 if (!AStmt)
14190 return StmtError();
14191
14192 auto *CS = cast<CapturedStmt>(AStmt);
14193 // 1.2.2 OpenMP Language Terminology
14194 // Structured block - An executable statement with a single entry at the
14195 // top and a single exit at the bottom.
14196 // The point of exit cannot be a branch out of the structured block.
14197 // longjmp() and throw() must not violate the entry/exit criteria.
14198 CS->getCapturedDecl()->setNothrow();
14199
14200 for (int ThisCaptureLevel =
14201 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14202 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14203 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14204 // 1.2.2 OpenMP Language Terminology
14205 // Structured block - An executable statement with a single entry at the
14206 // top and a single exit at the bottom.
14207 // The point of exit cannot be a branch out of the structured block.
14208 // longjmp() and throw() must not violate the entry/exit criteria.
14209 CS->getCapturedDecl()->setNothrow();
14210 }
14211
14212 OMPLoopBasedDirective::HelperExprs B;
14213 // In presence of clause 'collapse' with number of loops, it will
14214 // define the nested loops number.
14215 unsigned NestedLoopCount = checkOpenMPLoop(
14216 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14217 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14218 VarsWithImplicitDSA, B);
14219
14220 if (NestedLoopCount == 0)
14221 return StmtError();
14222
14223 assert((CurContext->isDependentContext() || B.builtAll()) &&
14224 "omp for loop exprs were not built");
14225
14226 setFunctionHasBranchProtectedScope();
14227
14228 DSAStack->setParentTeamsRegionLoc(StartLoc);
14229
14230 return OMPTeamsDistributeParallelForDirective::Create(
14231 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14232 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14233 }
14234
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)14235 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14236 Stmt *AStmt,
14237 SourceLocation StartLoc,
14238 SourceLocation EndLoc) {
14239 if (!AStmt)
14240 return StmtError();
14241
14242 auto *CS = cast<CapturedStmt>(AStmt);
14243 // 1.2.2 OpenMP Language Terminology
14244 // Structured block - An executable statement with a single entry at the
14245 // top and a single exit at the bottom.
14246 // The point of exit cannot be a branch out of the structured block.
14247 // longjmp() and throw() must not violate the entry/exit criteria.
14248 CS->getCapturedDecl()->setNothrow();
14249
14250 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14251 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14252 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14253 // 1.2.2 OpenMP Language Terminology
14254 // Structured block - An executable statement with a single entry at the
14255 // top and a single exit at the bottom.
14256 // The point of exit cannot be a branch out of the structured block.
14257 // longjmp() and throw() must not violate the entry/exit criteria.
14258 CS->getCapturedDecl()->setNothrow();
14259 }
14260 setFunctionHasBranchProtectedScope();
14261
14262 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14263 AStmt);
14264 }
14265
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14266 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14267 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14268 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14269 if (!AStmt)
14270 return StmtError();
14271
14272 auto *CS = cast<CapturedStmt>(AStmt);
14273 // 1.2.2 OpenMP Language Terminology
14274 // Structured block - An executable statement with a single entry at the
14275 // top and a single exit at the bottom.
14276 // The point of exit cannot be a branch out of the structured block.
14277 // longjmp() and throw() must not violate the entry/exit criteria.
14278 CS->getCapturedDecl()->setNothrow();
14279 for (int ThisCaptureLevel =
14280 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14281 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14282 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14283 // 1.2.2 OpenMP Language Terminology
14284 // Structured block - An executable statement with a single entry at the
14285 // top and a single exit at the bottom.
14286 // The point of exit cannot be a branch out of the structured block.
14287 // longjmp() and throw() must not violate the entry/exit criteria.
14288 CS->getCapturedDecl()->setNothrow();
14289 }
14290
14291 OMPLoopBasedDirective::HelperExprs B;
14292 // In presence of clause 'collapse' with number of loops, it will
14293 // define the nested loops number.
14294 unsigned NestedLoopCount = checkOpenMPLoop(
14295 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14296 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14297 VarsWithImplicitDSA, B);
14298 if (NestedLoopCount == 0)
14299 return StmtError();
14300
14301 assert((CurContext->isDependentContext() || B.builtAll()) &&
14302 "omp target teams distribute loop exprs were not built");
14303
14304 setFunctionHasBranchProtectedScope();
14305 return OMPTargetTeamsDistributeDirective::Create(
14306 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14307 }
14308
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14309 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14310 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14311 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14312 if (!AStmt)
14313 return StmtError();
14314
14315 auto *CS = cast<CapturedStmt>(AStmt);
14316 // 1.2.2 OpenMP Language Terminology
14317 // Structured block - An executable statement with a single entry at the
14318 // top and a single exit at the bottom.
14319 // The point of exit cannot be a branch out of the structured block.
14320 // longjmp() and throw() must not violate the entry/exit criteria.
14321 CS->getCapturedDecl()->setNothrow();
14322 for (int ThisCaptureLevel =
14323 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14324 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14325 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14326 // 1.2.2 OpenMP Language Terminology
14327 // Structured block - An executable statement with a single entry at the
14328 // top and a single exit at the bottom.
14329 // The point of exit cannot be a branch out of the structured block.
14330 // longjmp() and throw() must not violate the entry/exit criteria.
14331 CS->getCapturedDecl()->setNothrow();
14332 }
14333
14334 OMPLoopBasedDirective::HelperExprs B;
14335 // In presence of clause 'collapse' with number of loops, it will
14336 // define the nested loops number.
14337 unsigned NestedLoopCount = checkOpenMPLoop(
14338 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14339 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14340 VarsWithImplicitDSA, B);
14341 if (NestedLoopCount == 0)
14342 return StmtError();
14343
14344 assert((CurContext->isDependentContext() || B.builtAll()) &&
14345 "omp target teams distribute parallel for loop exprs were not built");
14346
14347 if (!CurContext->isDependentContext()) {
14348 // Finalize the clauses that need pre-built expressions for CodeGen.
14349 for (OMPClause *C : Clauses) {
14350 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14351 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14352 B.NumIterations, *this, CurScope,
14353 DSAStack))
14354 return StmtError();
14355 }
14356 }
14357
14358 setFunctionHasBranchProtectedScope();
14359 return OMPTargetTeamsDistributeParallelForDirective::Create(
14360 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14361 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14362 }
14363
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14364 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14366 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14367 if (!AStmt)
14368 return StmtError();
14369
14370 auto *CS = cast<CapturedStmt>(AStmt);
14371 // 1.2.2 OpenMP Language Terminology
14372 // Structured block - An executable statement with a single entry at the
14373 // top and a single exit at the bottom.
14374 // The point of exit cannot be a branch out of the structured block.
14375 // longjmp() and throw() must not violate the entry/exit criteria.
14376 CS->getCapturedDecl()->setNothrow();
14377 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14378 OMPD_target_teams_distribute_parallel_for_simd);
14379 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14380 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14381 // 1.2.2 OpenMP Language Terminology
14382 // Structured block - An executable statement with a single entry at the
14383 // top and a single exit at the bottom.
14384 // The point of exit cannot be a branch out of the structured block.
14385 // longjmp() and throw() must not violate the entry/exit criteria.
14386 CS->getCapturedDecl()->setNothrow();
14387 }
14388
14389 OMPLoopBasedDirective::HelperExprs B;
14390 // In presence of clause 'collapse' with number of loops, it will
14391 // define the nested loops number.
14392 unsigned NestedLoopCount =
14393 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14394 getCollapseNumberExpr(Clauses),
14395 nullptr /*ordered not a clause on distribute*/, CS, *this,
14396 *DSAStack, VarsWithImplicitDSA, B);
14397 if (NestedLoopCount == 0)
14398 return StmtError();
14399
14400 assert((CurContext->isDependentContext() || B.builtAll()) &&
14401 "omp target teams distribute parallel for simd loop exprs were not "
14402 "built");
14403
14404 if (!CurContext->isDependentContext()) {
14405 // Finalize the clauses that need pre-built expressions for CodeGen.
14406 for (OMPClause *C : Clauses) {
14407 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14408 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14409 B.NumIterations, *this, CurScope,
14410 DSAStack))
14411 return StmtError();
14412 }
14413 }
14414
14415 if (checkSimdlenSafelenSpecified(*this, Clauses))
14416 return StmtError();
14417
14418 setFunctionHasBranchProtectedScope();
14419 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14420 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14421 }
14422
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14423 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14424 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14425 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14426 if (!AStmt)
14427 return StmtError();
14428
14429 auto *CS = cast<CapturedStmt>(AStmt);
14430 // 1.2.2 OpenMP Language Terminology
14431 // Structured block - An executable statement with a single entry at the
14432 // top and a single exit at the bottom.
14433 // The point of exit cannot be a branch out of the structured block.
14434 // longjmp() and throw() must not violate the entry/exit criteria.
14435 CS->getCapturedDecl()->setNothrow();
14436 for (int ThisCaptureLevel =
14437 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14438 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14439 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14440 // 1.2.2 OpenMP Language Terminology
14441 // Structured block - An executable statement with a single entry at the
14442 // top and a single exit at the bottom.
14443 // The point of exit cannot be a branch out of the structured block.
14444 // longjmp() and throw() must not violate the entry/exit criteria.
14445 CS->getCapturedDecl()->setNothrow();
14446 }
14447
14448 OMPLoopBasedDirective::HelperExprs B;
14449 // In presence of clause 'collapse' with number of loops, it will
14450 // define the nested loops number.
14451 unsigned NestedLoopCount = checkOpenMPLoop(
14452 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14453 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14454 VarsWithImplicitDSA, B);
14455 if (NestedLoopCount == 0)
14456 return StmtError();
14457
14458 assert((CurContext->isDependentContext() || B.builtAll()) &&
14459 "omp target teams distribute simd loop exprs were not built");
14460
14461 if (!CurContext->isDependentContext()) {
14462 // Finalize the clauses that need pre-built expressions for CodeGen.
14463 for (OMPClause *C : Clauses) {
14464 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14465 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14466 B.NumIterations, *this, CurScope,
14467 DSAStack))
14468 return StmtError();
14469 }
14470 }
14471
14472 if (checkSimdlenSafelenSpecified(*this, Clauses))
14473 return StmtError();
14474
14475 setFunctionHasBranchProtectedScope();
14476 return OMPTargetTeamsDistributeSimdDirective::Create(
14477 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14478 }
14479
checkTransformableLoopNest(OpenMPDirectiveKind Kind,Stmt * AStmt,int NumLoops,SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> & LoopHelpers,Stmt * & Body,SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *,Decl * >,0>> & OriginalInits)14480 bool Sema::checkTransformableLoopNest(
14481 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14482 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14483 Stmt *&Body,
14484 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14485 &OriginalInits) {
14486 OriginalInits.emplace_back();
14487 bool Result = OMPLoopBasedDirective::doForAllLoops(
14488 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14489 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14490 Stmt *CurStmt) {
14491 VarsWithInheritedDSAType TmpDSA;
14492 unsigned SingleNumLoops =
14493 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14494 TmpDSA, LoopHelpers[Cnt]);
14495 if (SingleNumLoops == 0)
14496 return true;
14497 assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14498 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14499 OriginalInits.back().push_back(For->getInit());
14500 Body = For->getBody();
14501 } else {
14502 assert(isa<CXXForRangeStmt>(CurStmt) &&
14503 "Expected canonical for or range-based for loops.");
14504 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14505 OriginalInits.back().push_back(CXXFor->getBeginStmt());
14506 Body = CXXFor->getBody();
14507 }
14508 OriginalInits.emplace_back();
14509 return false;
14510 },
14511 [&OriginalInits](OMPLoopBasedDirective *Transform) {
14512 Stmt *DependentPreInits;
14513 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14514 DependentPreInits = Dir->getPreInits();
14515 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14516 DependentPreInits = Dir->getPreInits();
14517 else
14518 llvm_unreachable("Unhandled loop transformation");
14519 if (!DependentPreInits)
14520 return;
14521 llvm::append_range(OriginalInits.back(),
14522 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14523 });
14524 assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14525 OriginalInits.pop_back();
14526 return Result;
14527 }
14528
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)14529 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14530 Stmt *AStmt, SourceLocation StartLoc,
14531 SourceLocation EndLoc) {
14532 auto SizesClauses =
14533 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14534 if (SizesClauses.empty()) {
14535 // A missing 'sizes' clause is already reported by the parser.
14536 return StmtError();
14537 }
14538 const OMPSizesClause *SizesClause = *SizesClauses.begin();
14539 unsigned NumLoops = SizesClause->getNumSizes();
14540
14541 // Empty statement should only be possible if there already was an error.
14542 if (!AStmt)
14543 return StmtError();
14544
14545 // Verify and diagnose loop nest.
14546 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14547 Stmt *Body = nullptr;
14548 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14549 OriginalInits;
14550 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14551 OriginalInits))
14552 return StmtError();
14553
14554 // Delay tiling to when template is completely instantiated.
14555 if (CurContext->isDependentContext())
14556 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14557 NumLoops, AStmt, nullptr, nullptr);
14558
14559 SmallVector<Decl *, 4> PreInits;
14560
14561 // Create iteration variables for the generated loops.
14562 SmallVector<VarDecl *, 4> FloorIndVars;
14563 SmallVector<VarDecl *, 4> TileIndVars;
14564 FloorIndVars.resize(NumLoops);
14565 TileIndVars.resize(NumLoops);
14566 for (unsigned I = 0; I < NumLoops; ++I) {
14567 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14568
14569 assert(LoopHelper.Counters.size() == 1 &&
14570 "Expect single-dimensional loop iteration space");
14571 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14572 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14573 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14574 QualType CntTy = IterVarRef->getType();
14575
14576 // Iteration variable for the floor (i.e. outer) loop.
14577 {
14578 std::string FloorCntName =
14579 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14580 VarDecl *FloorCntDecl =
14581 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14582 FloorIndVars[I] = FloorCntDecl;
14583 }
14584
14585 // Iteration variable for the tile (i.e. inner) loop.
14586 {
14587 std::string TileCntName =
14588 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14589
14590 // Reuse the iteration variable created by checkOpenMPLoop. It is also
14591 // used by the expressions to derive the original iteration variable's
14592 // value from the logical iteration number.
14593 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14594 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14595 TileIndVars[I] = TileCntDecl;
14596 }
14597 for (auto &P : OriginalInits[I]) {
14598 if (auto *D = P.dyn_cast<Decl *>())
14599 PreInits.push_back(D);
14600 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14601 PreInits.append(PI->decl_begin(), PI->decl_end());
14602 }
14603 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14604 PreInits.append(PI->decl_begin(), PI->decl_end());
14605 // Gather declarations for the data members used as counters.
14606 for (Expr *CounterRef : LoopHelper.Counters) {
14607 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14608 if (isa<OMPCapturedExprDecl>(CounterDecl))
14609 PreInits.push_back(CounterDecl);
14610 }
14611 }
14612
14613 // Once the original iteration values are set, append the innermost body.
14614 Stmt *Inner = Body;
14615
14616 // Create tile loops from the inside to the outside.
14617 for (int I = NumLoops - 1; I >= 0; --I) {
14618 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14619 Expr *NumIterations = LoopHelper.NumIterations;
14620 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14621 QualType CntTy = OrigCntVar->getType();
14622 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14623 Scope *CurScope = getCurScope();
14624
14625 // Commonly used variables.
14626 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14627 OrigCntVar->getExprLoc());
14628 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14629 OrigCntVar->getExprLoc());
14630
14631 // For init-statement: auto .tile.iv = .floor.iv
14632 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14633 /*DirectInit=*/false);
14634 Decl *CounterDecl = TileIndVars[I];
14635 StmtResult InitStmt = new (Context)
14636 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14637 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14638 if (!InitStmt.isUsable())
14639 return StmtError();
14640
14641 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14642 // NumIterations)
14643 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14644 BO_Add, FloorIV, DimTileSize);
14645 if (!EndOfTile.isUsable())
14646 return StmtError();
14647 ExprResult IsPartialTile =
14648 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14649 NumIterations, EndOfTile.get());
14650 if (!IsPartialTile.isUsable())
14651 return StmtError();
14652 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14653 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14654 IsPartialTile.get(), NumIterations, EndOfTile.get());
14655 if (!MinTileAndIterSpace.isUsable())
14656 return StmtError();
14657 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14658 BO_LT, TileIV, MinTileAndIterSpace.get());
14659 if (!CondExpr.isUsable())
14660 return StmtError();
14661
14662 // For incr-statement: ++.tile.iv
14663 ExprResult IncrStmt =
14664 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14665 if (!IncrStmt.isUsable())
14666 return StmtError();
14667
14668 // Statements to set the original iteration variable's value from the
14669 // logical iteration number.
14670 // Generated for loop is:
14671 // Original_for_init;
14672 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14673 // NumIterations); ++.tile.iv) {
14674 // Original_Body;
14675 // Original_counter_update;
14676 // }
14677 // FIXME: If the innermost body is an loop itself, inserting these
14678 // statements stops it being recognized as a perfectly nested loop (e.g.
14679 // for applying tiling again). If this is the case, sink the expressions
14680 // further into the inner loop.
14681 SmallVector<Stmt *, 4> BodyParts;
14682 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14683 BodyParts.push_back(Inner);
14684 Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
14685 Inner->getBeginLoc(), Inner->getEndLoc());
14686 Inner = new (Context)
14687 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14688 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14689 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14690 }
14691
14692 // Create floor loops from the inside to the outside.
14693 for (int I = NumLoops - 1; I >= 0; --I) {
14694 auto &LoopHelper = LoopHelpers[I];
14695 Expr *NumIterations = LoopHelper.NumIterations;
14696 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14697 QualType CntTy = OrigCntVar->getType();
14698 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14699 Scope *CurScope = getCurScope();
14700
14701 // Commonly used variables.
14702 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14703 OrigCntVar->getExprLoc());
14704
14705 // For init-statement: auto .floor.iv = 0
14706 AddInitializerToDecl(
14707 FloorIndVars[I],
14708 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14709 /*DirectInit=*/false);
14710 Decl *CounterDecl = FloorIndVars[I];
14711 StmtResult InitStmt = new (Context)
14712 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14713 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14714 if (!InitStmt.isUsable())
14715 return StmtError();
14716
14717 // For cond-expression: .floor.iv < NumIterations
14718 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14719 BO_LT, FloorIV, NumIterations);
14720 if (!CondExpr.isUsable())
14721 return StmtError();
14722
14723 // For incr-statement: .floor.iv += DimTileSize
14724 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14725 BO_AddAssign, FloorIV, DimTileSize);
14726 if (!IncrStmt.isUsable())
14727 return StmtError();
14728
14729 Inner = new (Context)
14730 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14731 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14732 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14733 }
14734
14735 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14736 AStmt, Inner,
14737 buildPreInits(Context, PreInits));
14738 }
14739
ActOnOpenMPUnrollDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)14740 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
14741 Stmt *AStmt,
14742 SourceLocation StartLoc,
14743 SourceLocation EndLoc) {
14744 // Empty statement should only be possible if there already was an error.
14745 if (!AStmt)
14746 return StmtError();
14747
14748 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14749 return StmtError();
14750
14751 const OMPFullClause *FullClause =
14752 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14753 const OMPPartialClause *PartialClause =
14754 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14755 assert(!(FullClause && PartialClause) &&
14756 "mutual exclusivity must have been checked before");
14757
14758 constexpr unsigned NumLoops = 1;
14759 Stmt *Body = nullptr;
14760 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14761 NumLoops);
14762 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
14763 OriginalInits;
14764 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14765 Body, OriginalInits))
14766 return StmtError();
14767
14768 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14769
14770 // Delay unrolling to when template is completely instantiated.
14771 if (CurContext->isDependentContext())
14772 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14773 NumGeneratedLoops, nullptr, nullptr);
14774
14775 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14776
14777 if (FullClause) {
14778 if (!VerifyPositiveIntegerConstantInClause(
14779 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14780 /*SuppressExprDiags=*/true)
14781 .isUsable()) {
14782 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14783 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14784 << "#pragma omp unroll full";
14785 return StmtError();
14786 }
14787 }
14788
14789 // The generated loop may only be passed to other loop-associated directive
14790 // when a partial clause is specified. Without the requirement it is
14791 // sufficient to generate loop unroll metadata at code-generation.
14792 if (NumGeneratedLoops == 0)
14793 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14794 NumGeneratedLoops, nullptr, nullptr);
14795
14796 // Otherwise, we need to provide a de-sugared/transformed AST that can be
14797 // associated with another loop directive.
14798 //
14799 // The canonical loop analysis return by checkTransformableLoopNest assumes
14800 // the following structure to be the same loop without transformations or
14801 // directives applied: \code OriginalInits; LoopHelper.PreInits;
14802 // LoopHelper.Counters;
14803 // for (; IV < LoopHelper.NumIterations; ++IV) {
14804 // LoopHelper.Updates;
14805 // Body;
14806 // }
14807 // \endcode
14808 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14809 // and referenced by LoopHelper.IterationVarRef.
14810 //
14811 // The unrolling directive transforms this into the following loop:
14812 // \code
14813 // OriginalInits; \
14814 // LoopHelper.PreInits; > NewPreInits
14815 // LoopHelper.Counters; /
14816 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14817 // #pragma clang loop unroll_count(Factor)
14818 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14819 // {
14820 // LoopHelper.Updates;
14821 // Body;
14822 // }
14823 // }
14824 // \endcode
14825 // where UIV is a new logical iteration counter. IV must be the same VarDecl
14826 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14827 // references it. If the partially unrolled loop is associated with another
14828 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14829 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14830 // OpenMP canonical loop. The inner loop is not an associable canonical loop
14831 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14832 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14833 // property of the OMPLoopBasedDirective instead of statements in
14834 // CompoundStatement. This is to allow the loop to become a non-outermost loop
14835 // of a canonical loop nest where these PreInits are emitted before the
14836 // outermost directive.
14837
14838 // Determine the PreInit declarations.
14839 SmallVector<Decl *, 4> PreInits;
14840 assert(OriginalInits.size() == 1 &&
14841 "Expecting a single-dimensional loop iteration space");
14842 for (auto &P : OriginalInits[0]) {
14843 if (auto *D = P.dyn_cast<Decl *>())
14844 PreInits.push_back(D);
14845 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14846 PreInits.append(PI->decl_begin(), PI->decl_end());
14847 }
14848 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14849 PreInits.append(PI->decl_begin(), PI->decl_end());
14850 // Gather declarations for the data members used as counters.
14851 for (Expr *CounterRef : LoopHelper.Counters) {
14852 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14853 if (isa<OMPCapturedExprDecl>(CounterDecl))
14854 PreInits.push_back(CounterDecl);
14855 }
14856
14857 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14858 QualType IVTy = IterationVarRef->getType();
14859 assert(LoopHelper.Counters.size() == 1 &&
14860 "Expecting a single-dimensional loop iteration space");
14861 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14862
14863 // Determine the unroll factor.
14864 uint64_t Factor;
14865 SourceLocation FactorLoc;
14866 if (Expr *FactorVal = PartialClause->getFactor()) {
14867 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
14868 FactorLoc = FactorVal->getExprLoc();
14869 } else {
14870 // TODO: Use a better profitability model.
14871 Factor = 2;
14872 }
14873 assert(Factor > 0 && "Expected positive unroll factor");
14874 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14875 return IntegerLiteral::Create(
14876 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
14877 FactorLoc);
14878 };
14879
14880 // Iteration variable SourceLocations.
14881 SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14882 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14883 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14884
14885 // Internal variable names.
14886 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14887 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14888 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14889 std::string InnerTripCountName =
14890 (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14891
14892 // Create the iteration variable for the unrolled loop.
14893 VarDecl *OuterIVDecl =
14894 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
14895 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
14896 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
14897 };
14898
14899 // Iteration variable for the inner loop: Reuse the iteration variable created
14900 // by checkOpenMPLoop.
14901 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14902 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
14903 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
14904 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
14905 };
14906
14907 // Make a copy of the NumIterations expression for each use: By the AST
14908 // constraints, every expression object in a DeclContext must be unique.
14909 CaptureVars CopyTransformer(*this);
14910 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14911 return AssertSuccess(
14912 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14913 };
14914
14915 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14916 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
14917 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
14918 StmtResult InnerInit = new (Context)
14919 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14920 if (!InnerInit.isUsable())
14921 return StmtError();
14922
14923 // Inner For cond-expression:
14924 // \code
14925 // .unroll_inner.iv < .unrolled.iv + Factor &&
14926 // .unroll_inner.iv < NumIterations
14927 // \endcode
14928 // This conjunction of two conditions allows ScalarEvolution to derive the
14929 // maximum trip count of the inner loop.
14930 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14931 BO_Add, MakeOuterRef(), MakeFactorExpr());
14932 if (!EndOfTile.isUsable())
14933 return StmtError();
14934 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14935 BO_LT, MakeInnerRef(), EndOfTile.get());
14936 if (!InnerCond1.isUsable())
14937 return StmtError();
14938 ExprResult InnerCond2 =
14939 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
14940 MakeNumIterations());
14941 if (!InnerCond2.isUsable())
14942 return StmtError();
14943 ExprResult InnerCond =
14944 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14945 InnerCond1.get(), InnerCond2.get());
14946 if (!InnerCond.isUsable())
14947 return StmtError();
14948
14949 // Inner For incr-statement: ++.unroll_inner.iv
14950 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
14951 UO_PreInc, MakeInnerRef());
14952 if (!InnerIncr.isUsable())
14953 return StmtError();
14954
14955 // Inner For statement.
14956 SmallVector<Stmt *> InnerBodyStmts;
14957 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14958 InnerBodyStmts.push_back(Body);
14959 CompoundStmt *InnerBody =
14960 CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
14961 Body->getBeginLoc(), Body->getEndLoc());
14962 ForStmt *InnerFor = new (Context)
14963 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
14964 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
14965 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14966
14967 // Unroll metadata for the inner loop.
14968 // This needs to take into account the remainder portion of the unrolled loop,
14969 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14970 // supports multiple loop exits. Instead, unroll using a factor equivalent to
14971 // the maximum trip count, which will also generate a remainder loop. Just
14972 // `unroll(enable)` (which could have been useful if the user has not
14973 // specified a concrete factor; even though the outer loop cannot be
14974 // influenced anymore, would avoid more code bloat than necessary) will refuse
14975 // the loop because "Won't unroll; remainder loop could not be generated when
14976 // assuming runtime trip count". Even if it did work, it must not choose a
14977 // larger unroll factor than the maximum loop length, or it would always just
14978 // execute the remainder loop.
14979 LoopHintAttr *UnrollHintAttr =
14980 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
14981 LoopHintAttr::Numeric, MakeFactorExpr());
14982 AttributedStmt *InnerUnrolled =
14983 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
14984
14985 // Outer For init-statement: auto .unrolled.iv = 0
14986 AddInitializerToDecl(
14987 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14988 /*DirectInit=*/false);
14989 StmtResult OuterInit = new (Context)
14990 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14991 if (!OuterInit.isUsable())
14992 return StmtError();
14993
14994 // Outer For cond-expression: .unrolled.iv < NumIterations
14995 ExprResult OuterConde =
14996 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
14997 MakeNumIterations());
14998 if (!OuterConde.isUsable())
14999 return StmtError();
15000
15001 // Outer For incr-statement: .unrolled.iv += Factor
15002 ExprResult OuterIncr =
15003 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15004 MakeOuterRef(), MakeFactorExpr());
15005 if (!OuterIncr.isUsable())
15006 return StmtError();
15007
15008 // Outer For statement.
15009 ForStmt *OuterFor = new (Context)
15010 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15011 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15012 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15013
15014 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15015 NumGeneratedLoops, OuterFor,
15016 buildPreInits(Context, PreInits));
15017 }
15018
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15019 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15020 SourceLocation StartLoc,
15021 SourceLocation LParenLoc,
15022 SourceLocation EndLoc) {
15023 OMPClause *Res = nullptr;
15024 switch (Kind) {
15025 case OMPC_final:
15026 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15027 break;
15028 case OMPC_num_threads:
15029 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15030 break;
15031 case OMPC_safelen:
15032 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15033 break;
15034 case OMPC_simdlen:
15035 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15036 break;
15037 case OMPC_allocator:
15038 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15039 break;
15040 case OMPC_collapse:
15041 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15042 break;
15043 case OMPC_ordered:
15044 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15045 break;
15046 case OMPC_num_teams:
15047 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15048 break;
15049 case OMPC_thread_limit:
15050 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15051 break;
15052 case OMPC_priority:
15053 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15054 break;
15055 case OMPC_grainsize:
15056 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
15057 break;
15058 case OMPC_num_tasks:
15059 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
15060 break;
15061 case OMPC_hint:
15062 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15063 break;
15064 case OMPC_depobj:
15065 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15066 break;
15067 case OMPC_detach:
15068 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15069 break;
15070 case OMPC_novariants:
15071 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15072 break;
15073 case OMPC_nocontext:
15074 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15075 break;
15076 case OMPC_filter:
15077 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15078 break;
15079 case OMPC_partial:
15080 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15081 break;
15082 case OMPC_align:
15083 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15084 break;
15085 case OMPC_device:
15086 case OMPC_if:
15087 case OMPC_default:
15088 case OMPC_proc_bind:
15089 case OMPC_schedule:
15090 case OMPC_private:
15091 case OMPC_firstprivate:
15092 case OMPC_lastprivate:
15093 case OMPC_shared:
15094 case OMPC_reduction:
15095 case OMPC_task_reduction:
15096 case OMPC_in_reduction:
15097 case OMPC_linear:
15098 case OMPC_aligned:
15099 case OMPC_copyin:
15100 case OMPC_copyprivate:
15101 case OMPC_nowait:
15102 case OMPC_untied:
15103 case OMPC_mergeable:
15104 case OMPC_threadprivate:
15105 case OMPC_sizes:
15106 case OMPC_allocate:
15107 case OMPC_flush:
15108 case OMPC_read:
15109 case OMPC_write:
15110 case OMPC_update:
15111 case OMPC_capture:
15112 case OMPC_compare:
15113 case OMPC_seq_cst:
15114 case OMPC_acq_rel:
15115 case OMPC_acquire:
15116 case OMPC_release:
15117 case OMPC_relaxed:
15118 case OMPC_depend:
15119 case OMPC_threads:
15120 case OMPC_simd:
15121 case OMPC_map:
15122 case OMPC_nogroup:
15123 case OMPC_dist_schedule:
15124 case OMPC_defaultmap:
15125 case OMPC_unknown:
15126 case OMPC_uniform:
15127 case OMPC_to:
15128 case OMPC_from:
15129 case OMPC_use_device_ptr:
15130 case OMPC_use_device_addr:
15131 case OMPC_is_device_ptr:
15132 case OMPC_unified_address:
15133 case OMPC_unified_shared_memory:
15134 case OMPC_reverse_offload:
15135 case OMPC_dynamic_allocators:
15136 case OMPC_atomic_default_mem_order:
15137 case OMPC_device_type:
15138 case OMPC_match:
15139 case OMPC_nontemporal:
15140 case OMPC_order:
15141 case OMPC_destroy:
15142 case OMPC_inclusive:
15143 case OMPC_exclusive:
15144 case OMPC_uses_allocators:
15145 case OMPC_affinity:
15146 case OMPC_when:
15147 case OMPC_bind:
15148 default:
15149 llvm_unreachable("Clause is not allowed.");
15150 }
15151 return Res;
15152 }
15153
15154 // An OpenMP directive such as 'target parallel' has two captured regions:
15155 // for the 'target' and 'parallel' respectively. This function returns
15156 // the region in which to capture expressions associated with a clause.
15157 // A return value of OMPD_unknown signifies that the expression should not
15158 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)15159 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15160 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15161 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15162 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15163 switch (CKind) {
15164 case OMPC_if:
15165 switch (DKind) {
15166 case OMPD_target_parallel_for_simd:
15167 if (OpenMPVersion >= 50 &&
15168 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15169 CaptureRegion = OMPD_parallel;
15170 break;
15171 }
15172 LLVM_FALLTHROUGH;
15173 case OMPD_target_parallel:
15174 case OMPD_target_parallel_for:
15175 case OMPD_target_parallel_loop:
15176 // If this clause applies to the nested 'parallel' region, capture within
15177 // the 'target' region, otherwise do not capture.
15178 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15179 CaptureRegion = OMPD_target;
15180 break;
15181 case OMPD_target_teams_distribute_parallel_for_simd:
15182 if (OpenMPVersion >= 50 &&
15183 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15184 CaptureRegion = OMPD_parallel;
15185 break;
15186 }
15187 LLVM_FALLTHROUGH;
15188 case OMPD_target_teams_distribute_parallel_for:
15189 // If this clause applies to the nested 'parallel' region, capture within
15190 // the 'teams' region, otherwise do not capture.
15191 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15192 CaptureRegion = OMPD_teams;
15193 break;
15194 case OMPD_teams_distribute_parallel_for_simd:
15195 if (OpenMPVersion >= 50 &&
15196 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15197 CaptureRegion = OMPD_parallel;
15198 break;
15199 }
15200 LLVM_FALLTHROUGH;
15201 case OMPD_teams_distribute_parallel_for:
15202 CaptureRegion = OMPD_teams;
15203 break;
15204 case OMPD_target_update:
15205 case OMPD_target_enter_data:
15206 case OMPD_target_exit_data:
15207 CaptureRegion = OMPD_task;
15208 break;
15209 case OMPD_parallel_masked_taskloop:
15210 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15211 CaptureRegion = OMPD_parallel;
15212 break;
15213 case OMPD_parallel_master_taskloop:
15214 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15215 CaptureRegion = OMPD_parallel;
15216 break;
15217 case OMPD_parallel_masked_taskloop_simd:
15218 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15219 NameModifier == OMPD_taskloop) {
15220 CaptureRegion = OMPD_parallel;
15221 break;
15222 }
15223 if (OpenMPVersion <= 45)
15224 break;
15225 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15226 CaptureRegion = OMPD_taskloop;
15227 break;
15228 case OMPD_parallel_master_taskloop_simd:
15229 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15230 NameModifier == OMPD_taskloop) {
15231 CaptureRegion = OMPD_parallel;
15232 break;
15233 }
15234 if (OpenMPVersion <= 45)
15235 break;
15236 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15237 CaptureRegion = OMPD_taskloop;
15238 break;
15239 case OMPD_parallel_for_simd:
15240 if (OpenMPVersion <= 45)
15241 break;
15242 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15243 CaptureRegion = OMPD_parallel;
15244 break;
15245 case OMPD_taskloop_simd:
15246 case OMPD_master_taskloop_simd:
15247 case OMPD_masked_taskloop_simd:
15248 if (OpenMPVersion <= 45)
15249 break;
15250 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15251 CaptureRegion = OMPD_taskloop;
15252 break;
15253 case OMPD_distribute_parallel_for_simd:
15254 if (OpenMPVersion <= 45)
15255 break;
15256 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15257 CaptureRegion = OMPD_parallel;
15258 break;
15259 case OMPD_target_simd:
15260 if (OpenMPVersion >= 50 &&
15261 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15262 CaptureRegion = OMPD_target;
15263 break;
15264 case OMPD_teams_distribute_simd:
15265 case OMPD_target_teams_distribute_simd:
15266 if (OpenMPVersion >= 50 &&
15267 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15268 CaptureRegion = OMPD_teams;
15269 break;
15270 case OMPD_cancel:
15271 case OMPD_parallel:
15272 case OMPD_parallel_master:
15273 case OMPD_parallel_masked:
15274 case OMPD_parallel_sections:
15275 case OMPD_parallel_for:
15276 case OMPD_parallel_loop:
15277 case OMPD_target:
15278 case OMPD_target_teams:
15279 case OMPD_target_teams_distribute:
15280 case OMPD_target_teams_loop:
15281 case OMPD_distribute_parallel_for:
15282 case OMPD_task:
15283 case OMPD_taskloop:
15284 case OMPD_master_taskloop:
15285 case OMPD_masked_taskloop:
15286 case OMPD_target_data:
15287 case OMPD_simd:
15288 case OMPD_for_simd:
15289 case OMPD_distribute_simd:
15290 // Do not capture if-clause expressions.
15291 break;
15292 case OMPD_threadprivate:
15293 case OMPD_allocate:
15294 case OMPD_taskyield:
15295 case OMPD_barrier:
15296 case OMPD_taskwait:
15297 case OMPD_cancellation_point:
15298 case OMPD_flush:
15299 case OMPD_depobj:
15300 case OMPD_scan:
15301 case OMPD_declare_reduction:
15302 case OMPD_declare_mapper:
15303 case OMPD_declare_simd:
15304 case OMPD_declare_variant:
15305 case OMPD_begin_declare_variant:
15306 case OMPD_end_declare_variant:
15307 case OMPD_declare_target:
15308 case OMPD_end_declare_target:
15309 case OMPD_loop:
15310 case OMPD_teams_loop:
15311 case OMPD_teams:
15312 case OMPD_tile:
15313 case OMPD_unroll:
15314 case OMPD_for:
15315 case OMPD_sections:
15316 case OMPD_section:
15317 case OMPD_single:
15318 case OMPD_master:
15319 case OMPD_masked:
15320 case OMPD_critical:
15321 case OMPD_taskgroup:
15322 case OMPD_distribute:
15323 case OMPD_ordered:
15324 case OMPD_atomic:
15325 case OMPD_teams_distribute:
15326 case OMPD_requires:
15327 case OMPD_metadirective:
15328 llvm_unreachable("Unexpected OpenMP directive with if-clause");
15329 case OMPD_unknown:
15330 default:
15331 llvm_unreachable("Unknown OpenMP directive");
15332 }
15333 break;
15334 case OMPC_num_threads:
15335 switch (DKind) {
15336 case OMPD_target_parallel:
15337 case OMPD_target_parallel_for:
15338 case OMPD_target_parallel_for_simd:
15339 case OMPD_target_parallel_loop:
15340 CaptureRegion = OMPD_target;
15341 break;
15342 case OMPD_teams_distribute_parallel_for:
15343 case OMPD_teams_distribute_parallel_for_simd:
15344 case OMPD_target_teams_distribute_parallel_for:
15345 case OMPD_target_teams_distribute_parallel_for_simd:
15346 CaptureRegion = OMPD_teams;
15347 break;
15348 case OMPD_parallel:
15349 case OMPD_parallel_master:
15350 case OMPD_parallel_masked:
15351 case OMPD_parallel_sections:
15352 case OMPD_parallel_for:
15353 case OMPD_parallel_for_simd:
15354 case OMPD_parallel_loop:
15355 case OMPD_distribute_parallel_for:
15356 case OMPD_distribute_parallel_for_simd:
15357 case OMPD_parallel_master_taskloop:
15358 case OMPD_parallel_masked_taskloop:
15359 case OMPD_parallel_master_taskloop_simd:
15360 case OMPD_parallel_masked_taskloop_simd:
15361 // Do not capture num_threads-clause expressions.
15362 break;
15363 case OMPD_target_data:
15364 case OMPD_target_enter_data:
15365 case OMPD_target_exit_data:
15366 case OMPD_target_update:
15367 case OMPD_target:
15368 case OMPD_target_simd:
15369 case OMPD_target_teams:
15370 case OMPD_target_teams_distribute:
15371 case OMPD_target_teams_distribute_simd:
15372 case OMPD_cancel:
15373 case OMPD_task:
15374 case OMPD_taskloop:
15375 case OMPD_taskloop_simd:
15376 case OMPD_master_taskloop:
15377 case OMPD_masked_taskloop:
15378 case OMPD_master_taskloop_simd:
15379 case OMPD_masked_taskloop_simd:
15380 case OMPD_threadprivate:
15381 case OMPD_allocate:
15382 case OMPD_taskyield:
15383 case OMPD_barrier:
15384 case OMPD_taskwait:
15385 case OMPD_cancellation_point:
15386 case OMPD_flush:
15387 case OMPD_depobj:
15388 case OMPD_scan:
15389 case OMPD_declare_reduction:
15390 case OMPD_declare_mapper:
15391 case OMPD_declare_simd:
15392 case OMPD_declare_variant:
15393 case OMPD_begin_declare_variant:
15394 case OMPD_end_declare_variant:
15395 case OMPD_declare_target:
15396 case OMPD_end_declare_target:
15397 case OMPD_loop:
15398 case OMPD_teams_loop:
15399 case OMPD_target_teams_loop:
15400 case OMPD_teams:
15401 case OMPD_simd:
15402 case OMPD_tile:
15403 case OMPD_unroll:
15404 case OMPD_for:
15405 case OMPD_for_simd:
15406 case OMPD_sections:
15407 case OMPD_section:
15408 case OMPD_single:
15409 case OMPD_master:
15410 case OMPD_masked:
15411 case OMPD_critical:
15412 case OMPD_taskgroup:
15413 case OMPD_distribute:
15414 case OMPD_ordered:
15415 case OMPD_atomic:
15416 case OMPD_distribute_simd:
15417 case OMPD_teams_distribute:
15418 case OMPD_teams_distribute_simd:
15419 case OMPD_requires:
15420 case OMPD_metadirective:
15421 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15422 case OMPD_unknown:
15423 default:
15424 llvm_unreachable("Unknown OpenMP directive");
15425 }
15426 break;
15427 case OMPC_num_teams:
15428 switch (DKind) {
15429 case OMPD_target_teams:
15430 case OMPD_target_teams_distribute:
15431 case OMPD_target_teams_distribute_simd:
15432 case OMPD_target_teams_distribute_parallel_for:
15433 case OMPD_target_teams_distribute_parallel_for_simd:
15434 case OMPD_target_teams_loop:
15435 CaptureRegion = OMPD_target;
15436 break;
15437 case OMPD_teams_distribute_parallel_for:
15438 case OMPD_teams_distribute_parallel_for_simd:
15439 case OMPD_teams:
15440 case OMPD_teams_distribute:
15441 case OMPD_teams_distribute_simd:
15442 case OMPD_teams_loop:
15443 // Do not capture num_teams-clause expressions.
15444 break;
15445 case OMPD_distribute_parallel_for:
15446 case OMPD_distribute_parallel_for_simd:
15447 case OMPD_task:
15448 case OMPD_taskloop:
15449 case OMPD_taskloop_simd:
15450 case OMPD_master_taskloop:
15451 case OMPD_masked_taskloop:
15452 case OMPD_master_taskloop_simd:
15453 case OMPD_masked_taskloop_simd:
15454 case OMPD_parallel_master_taskloop:
15455 case OMPD_parallel_masked_taskloop:
15456 case OMPD_parallel_master_taskloop_simd:
15457 case OMPD_parallel_masked_taskloop_simd:
15458 case OMPD_target_data:
15459 case OMPD_target_enter_data:
15460 case OMPD_target_exit_data:
15461 case OMPD_target_update:
15462 case OMPD_cancel:
15463 case OMPD_parallel:
15464 case OMPD_parallel_master:
15465 case OMPD_parallel_masked:
15466 case OMPD_parallel_sections:
15467 case OMPD_parallel_for:
15468 case OMPD_parallel_for_simd:
15469 case OMPD_parallel_loop:
15470 case OMPD_target:
15471 case OMPD_target_simd:
15472 case OMPD_target_parallel:
15473 case OMPD_target_parallel_for:
15474 case OMPD_target_parallel_for_simd:
15475 case OMPD_target_parallel_loop:
15476 case OMPD_threadprivate:
15477 case OMPD_allocate:
15478 case OMPD_taskyield:
15479 case OMPD_barrier:
15480 case OMPD_taskwait:
15481 case OMPD_cancellation_point:
15482 case OMPD_flush:
15483 case OMPD_depobj:
15484 case OMPD_scan:
15485 case OMPD_declare_reduction:
15486 case OMPD_declare_mapper:
15487 case OMPD_declare_simd:
15488 case OMPD_declare_variant:
15489 case OMPD_begin_declare_variant:
15490 case OMPD_end_declare_variant:
15491 case OMPD_declare_target:
15492 case OMPD_end_declare_target:
15493 case OMPD_loop:
15494 case OMPD_simd:
15495 case OMPD_tile:
15496 case OMPD_unroll:
15497 case OMPD_for:
15498 case OMPD_for_simd:
15499 case OMPD_sections:
15500 case OMPD_section:
15501 case OMPD_single:
15502 case OMPD_master:
15503 case OMPD_masked:
15504 case OMPD_critical:
15505 case OMPD_taskgroup:
15506 case OMPD_distribute:
15507 case OMPD_ordered:
15508 case OMPD_atomic:
15509 case OMPD_distribute_simd:
15510 case OMPD_requires:
15511 case OMPD_metadirective:
15512 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15513 case OMPD_unknown:
15514 default:
15515 llvm_unreachable("Unknown OpenMP directive");
15516 }
15517 break;
15518 case OMPC_thread_limit:
15519 switch (DKind) {
15520 case OMPD_target_teams:
15521 case OMPD_target_teams_distribute:
15522 case OMPD_target_teams_distribute_simd:
15523 case OMPD_target_teams_distribute_parallel_for:
15524 case OMPD_target_teams_distribute_parallel_for_simd:
15525 case OMPD_target_teams_loop:
15526 CaptureRegion = OMPD_target;
15527 break;
15528 case OMPD_teams_distribute_parallel_for:
15529 case OMPD_teams_distribute_parallel_for_simd:
15530 case OMPD_teams:
15531 case OMPD_teams_distribute:
15532 case OMPD_teams_distribute_simd:
15533 case OMPD_teams_loop:
15534 // Do not capture thread_limit-clause expressions.
15535 break;
15536 case OMPD_distribute_parallel_for:
15537 case OMPD_distribute_parallel_for_simd:
15538 case OMPD_task:
15539 case OMPD_taskloop:
15540 case OMPD_taskloop_simd:
15541 case OMPD_master_taskloop:
15542 case OMPD_masked_taskloop:
15543 case OMPD_master_taskloop_simd:
15544 case OMPD_masked_taskloop_simd:
15545 case OMPD_parallel_master_taskloop:
15546 case OMPD_parallel_masked_taskloop:
15547 case OMPD_parallel_master_taskloop_simd:
15548 case OMPD_parallel_masked_taskloop_simd:
15549 case OMPD_target_data:
15550 case OMPD_target_enter_data:
15551 case OMPD_target_exit_data:
15552 case OMPD_target_update:
15553 case OMPD_cancel:
15554 case OMPD_parallel:
15555 case OMPD_parallel_master:
15556 case OMPD_parallel_masked:
15557 case OMPD_parallel_sections:
15558 case OMPD_parallel_for:
15559 case OMPD_parallel_for_simd:
15560 case OMPD_parallel_loop:
15561 case OMPD_target:
15562 case OMPD_target_simd:
15563 case OMPD_target_parallel:
15564 case OMPD_target_parallel_for:
15565 case OMPD_target_parallel_for_simd:
15566 case OMPD_target_parallel_loop:
15567 case OMPD_threadprivate:
15568 case OMPD_allocate:
15569 case OMPD_taskyield:
15570 case OMPD_barrier:
15571 case OMPD_taskwait:
15572 case OMPD_cancellation_point:
15573 case OMPD_flush:
15574 case OMPD_depobj:
15575 case OMPD_scan:
15576 case OMPD_declare_reduction:
15577 case OMPD_declare_mapper:
15578 case OMPD_declare_simd:
15579 case OMPD_declare_variant:
15580 case OMPD_begin_declare_variant:
15581 case OMPD_end_declare_variant:
15582 case OMPD_declare_target:
15583 case OMPD_end_declare_target:
15584 case OMPD_loop:
15585 case OMPD_simd:
15586 case OMPD_tile:
15587 case OMPD_unroll:
15588 case OMPD_for:
15589 case OMPD_for_simd:
15590 case OMPD_sections:
15591 case OMPD_section:
15592 case OMPD_single:
15593 case OMPD_master:
15594 case OMPD_masked:
15595 case OMPD_critical:
15596 case OMPD_taskgroup:
15597 case OMPD_distribute:
15598 case OMPD_ordered:
15599 case OMPD_atomic:
15600 case OMPD_distribute_simd:
15601 case OMPD_requires:
15602 case OMPD_metadirective:
15603 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
15604 case OMPD_unknown:
15605 default:
15606 llvm_unreachable("Unknown OpenMP directive");
15607 }
15608 break;
15609 case OMPC_schedule:
15610 switch (DKind) {
15611 case OMPD_parallel_for:
15612 case OMPD_parallel_for_simd:
15613 case OMPD_distribute_parallel_for:
15614 case OMPD_distribute_parallel_for_simd:
15615 case OMPD_teams_distribute_parallel_for:
15616 case OMPD_teams_distribute_parallel_for_simd:
15617 case OMPD_target_parallel_for:
15618 case OMPD_target_parallel_for_simd:
15619 case OMPD_target_teams_distribute_parallel_for:
15620 case OMPD_target_teams_distribute_parallel_for_simd:
15621 CaptureRegion = OMPD_parallel;
15622 break;
15623 case OMPD_for:
15624 case OMPD_for_simd:
15625 // Do not capture schedule-clause expressions.
15626 break;
15627 case OMPD_task:
15628 case OMPD_taskloop:
15629 case OMPD_taskloop_simd:
15630 case OMPD_master_taskloop:
15631 case OMPD_masked_taskloop:
15632 case OMPD_master_taskloop_simd:
15633 case OMPD_masked_taskloop_simd:
15634 case OMPD_parallel_master_taskloop:
15635 case OMPD_parallel_masked_taskloop:
15636 case OMPD_parallel_master_taskloop_simd:
15637 case OMPD_parallel_masked_taskloop_simd:
15638 case OMPD_target_data:
15639 case OMPD_target_enter_data:
15640 case OMPD_target_exit_data:
15641 case OMPD_target_update:
15642 case OMPD_teams:
15643 case OMPD_teams_distribute:
15644 case OMPD_teams_distribute_simd:
15645 case OMPD_target_teams_distribute:
15646 case OMPD_target_teams_distribute_simd:
15647 case OMPD_target:
15648 case OMPD_target_simd:
15649 case OMPD_target_parallel:
15650 case OMPD_cancel:
15651 case OMPD_parallel:
15652 case OMPD_parallel_master:
15653 case OMPD_parallel_masked:
15654 case OMPD_parallel_sections:
15655 case OMPD_threadprivate:
15656 case OMPD_allocate:
15657 case OMPD_taskyield:
15658 case OMPD_barrier:
15659 case OMPD_taskwait:
15660 case OMPD_cancellation_point:
15661 case OMPD_flush:
15662 case OMPD_depobj:
15663 case OMPD_scan:
15664 case OMPD_declare_reduction:
15665 case OMPD_declare_mapper:
15666 case OMPD_declare_simd:
15667 case OMPD_declare_variant:
15668 case OMPD_begin_declare_variant:
15669 case OMPD_end_declare_variant:
15670 case OMPD_declare_target:
15671 case OMPD_end_declare_target:
15672 case OMPD_loop:
15673 case OMPD_teams_loop:
15674 case OMPD_target_teams_loop:
15675 case OMPD_parallel_loop:
15676 case OMPD_target_parallel_loop:
15677 case OMPD_simd:
15678 case OMPD_tile:
15679 case OMPD_unroll:
15680 case OMPD_sections:
15681 case OMPD_section:
15682 case OMPD_single:
15683 case OMPD_master:
15684 case OMPD_masked:
15685 case OMPD_critical:
15686 case OMPD_taskgroup:
15687 case OMPD_distribute:
15688 case OMPD_ordered:
15689 case OMPD_atomic:
15690 case OMPD_distribute_simd:
15691 case OMPD_target_teams:
15692 case OMPD_requires:
15693 case OMPD_metadirective:
15694 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
15695 case OMPD_unknown:
15696 default:
15697 llvm_unreachable("Unknown OpenMP directive");
15698 }
15699 break;
15700 case OMPC_dist_schedule:
15701 switch (DKind) {
15702 case OMPD_teams_distribute_parallel_for:
15703 case OMPD_teams_distribute_parallel_for_simd:
15704 case OMPD_teams_distribute:
15705 case OMPD_teams_distribute_simd:
15706 case OMPD_target_teams_distribute_parallel_for:
15707 case OMPD_target_teams_distribute_parallel_for_simd:
15708 case OMPD_target_teams_distribute:
15709 case OMPD_target_teams_distribute_simd:
15710 CaptureRegion = OMPD_teams;
15711 break;
15712 case OMPD_distribute_parallel_for:
15713 case OMPD_distribute_parallel_for_simd:
15714 case OMPD_distribute:
15715 case OMPD_distribute_simd:
15716 // Do not capture dist_schedule-clause expressions.
15717 break;
15718 case OMPD_parallel_for:
15719 case OMPD_parallel_for_simd:
15720 case OMPD_target_parallel_for_simd:
15721 case OMPD_target_parallel_for:
15722 case OMPD_task:
15723 case OMPD_taskloop:
15724 case OMPD_taskloop_simd:
15725 case OMPD_master_taskloop:
15726 case OMPD_masked_taskloop:
15727 case OMPD_master_taskloop_simd:
15728 case OMPD_masked_taskloop_simd:
15729 case OMPD_parallel_master_taskloop:
15730 case OMPD_parallel_masked_taskloop:
15731 case OMPD_parallel_master_taskloop_simd:
15732 case OMPD_parallel_masked_taskloop_simd:
15733 case OMPD_target_data:
15734 case OMPD_target_enter_data:
15735 case OMPD_target_exit_data:
15736 case OMPD_target_update:
15737 case OMPD_teams:
15738 case OMPD_target:
15739 case OMPD_target_simd:
15740 case OMPD_target_parallel:
15741 case OMPD_cancel:
15742 case OMPD_parallel:
15743 case OMPD_parallel_master:
15744 case OMPD_parallel_masked:
15745 case OMPD_parallel_sections:
15746 case OMPD_threadprivate:
15747 case OMPD_allocate:
15748 case OMPD_taskyield:
15749 case OMPD_barrier:
15750 case OMPD_taskwait:
15751 case OMPD_cancellation_point:
15752 case OMPD_flush:
15753 case OMPD_depobj:
15754 case OMPD_scan:
15755 case OMPD_declare_reduction:
15756 case OMPD_declare_mapper:
15757 case OMPD_declare_simd:
15758 case OMPD_declare_variant:
15759 case OMPD_begin_declare_variant:
15760 case OMPD_end_declare_variant:
15761 case OMPD_declare_target:
15762 case OMPD_end_declare_target:
15763 case OMPD_loop:
15764 case OMPD_teams_loop:
15765 case OMPD_target_teams_loop:
15766 case OMPD_parallel_loop:
15767 case OMPD_target_parallel_loop:
15768 case OMPD_simd:
15769 case OMPD_tile:
15770 case OMPD_unroll:
15771 case OMPD_for:
15772 case OMPD_for_simd:
15773 case OMPD_sections:
15774 case OMPD_section:
15775 case OMPD_single:
15776 case OMPD_master:
15777 case OMPD_masked:
15778 case OMPD_critical:
15779 case OMPD_taskgroup:
15780 case OMPD_ordered:
15781 case OMPD_atomic:
15782 case OMPD_target_teams:
15783 case OMPD_requires:
15784 case OMPD_metadirective:
15785 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
15786 case OMPD_unknown:
15787 default:
15788 llvm_unreachable("Unknown OpenMP directive");
15789 }
15790 break;
15791 case OMPC_device:
15792 switch (DKind) {
15793 case OMPD_target_update:
15794 case OMPD_target_enter_data:
15795 case OMPD_target_exit_data:
15796 case OMPD_target:
15797 case OMPD_target_simd:
15798 case OMPD_target_teams:
15799 case OMPD_target_parallel:
15800 case OMPD_target_teams_distribute:
15801 case OMPD_target_teams_distribute_simd:
15802 case OMPD_target_parallel_for:
15803 case OMPD_target_parallel_for_simd:
15804 case OMPD_target_parallel_loop:
15805 case OMPD_target_teams_distribute_parallel_for:
15806 case OMPD_target_teams_distribute_parallel_for_simd:
15807 case OMPD_target_teams_loop:
15808 case OMPD_dispatch:
15809 CaptureRegion = OMPD_task;
15810 break;
15811 case OMPD_target_data:
15812 case OMPD_interop:
15813 // Do not capture device-clause expressions.
15814 break;
15815 case OMPD_teams_distribute_parallel_for:
15816 case OMPD_teams_distribute_parallel_for_simd:
15817 case OMPD_teams:
15818 case OMPD_teams_distribute:
15819 case OMPD_teams_distribute_simd:
15820 case OMPD_distribute_parallel_for:
15821 case OMPD_distribute_parallel_for_simd:
15822 case OMPD_task:
15823 case OMPD_taskloop:
15824 case OMPD_taskloop_simd:
15825 case OMPD_master_taskloop:
15826 case OMPD_masked_taskloop:
15827 case OMPD_master_taskloop_simd:
15828 case OMPD_masked_taskloop_simd:
15829 case OMPD_parallel_master_taskloop:
15830 case OMPD_parallel_masked_taskloop:
15831 case OMPD_parallel_master_taskloop_simd:
15832 case OMPD_parallel_masked_taskloop_simd:
15833 case OMPD_cancel:
15834 case OMPD_parallel:
15835 case OMPD_parallel_master:
15836 case OMPD_parallel_masked:
15837 case OMPD_parallel_sections:
15838 case OMPD_parallel_for:
15839 case OMPD_parallel_for_simd:
15840 case OMPD_threadprivate:
15841 case OMPD_allocate:
15842 case OMPD_taskyield:
15843 case OMPD_barrier:
15844 case OMPD_taskwait:
15845 case OMPD_cancellation_point:
15846 case OMPD_flush:
15847 case OMPD_depobj:
15848 case OMPD_scan:
15849 case OMPD_declare_reduction:
15850 case OMPD_declare_mapper:
15851 case OMPD_declare_simd:
15852 case OMPD_declare_variant:
15853 case OMPD_begin_declare_variant:
15854 case OMPD_end_declare_variant:
15855 case OMPD_declare_target:
15856 case OMPD_end_declare_target:
15857 case OMPD_loop:
15858 case OMPD_teams_loop:
15859 case OMPD_parallel_loop:
15860 case OMPD_simd:
15861 case OMPD_tile:
15862 case OMPD_unroll:
15863 case OMPD_for:
15864 case OMPD_for_simd:
15865 case OMPD_sections:
15866 case OMPD_section:
15867 case OMPD_single:
15868 case OMPD_master:
15869 case OMPD_masked:
15870 case OMPD_critical:
15871 case OMPD_taskgroup:
15872 case OMPD_distribute:
15873 case OMPD_ordered:
15874 case OMPD_atomic:
15875 case OMPD_distribute_simd:
15876 case OMPD_requires:
15877 case OMPD_metadirective:
15878 llvm_unreachable("Unexpected OpenMP directive with device-clause");
15879 case OMPD_unknown:
15880 default:
15881 llvm_unreachable("Unknown OpenMP directive");
15882 }
15883 break;
15884 case OMPC_grainsize:
15885 case OMPC_num_tasks:
15886 case OMPC_final:
15887 case OMPC_priority:
15888 switch (DKind) {
15889 case OMPD_task:
15890 case OMPD_taskloop:
15891 case OMPD_taskloop_simd:
15892 case OMPD_master_taskloop:
15893 case OMPD_masked_taskloop:
15894 case OMPD_master_taskloop_simd:
15895 case OMPD_masked_taskloop_simd:
15896 break;
15897 case OMPD_parallel_masked_taskloop:
15898 case OMPD_parallel_masked_taskloop_simd:
15899 case OMPD_parallel_master_taskloop:
15900 case OMPD_parallel_master_taskloop_simd:
15901 CaptureRegion = OMPD_parallel;
15902 break;
15903 case OMPD_target_update:
15904 case OMPD_target_enter_data:
15905 case OMPD_target_exit_data:
15906 case OMPD_target:
15907 case OMPD_target_simd:
15908 case OMPD_target_teams:
15909 case OMPD_target_parallel:
15910 case OMPD_target_teams_distribute:
15911 case OMPD_target_teams_distribute_simd:
15912 case OMPD_target_parallel_for:
15913 case OMPD_target_parallel_for_simd:
15914 case OMPD_target_teams_distribute_parallel_for:
15915 case OMPD_target_teams_distribute_parallel_for_simd:
15916 case OMPD_target_data:
15917 case OMPD_teams_distribute_parallel_for:
15918 case OMPD_teams_distribute_parallel_for_simd:
15919 case OMPD_teams:
15920 case OMPD_teams_distribute:
15921 case OMPD_teams_distribute_simd:
15922 case OMPD_distribute_parallel_for:
15923 case OMPD_distribute_parallel_for_simd:
15924 case OMPD_cancel:
15925 case OMPD_parallel:
15926 case OMPD_parallel_master:
15927 case OMPD_parallel_masked:
15928 case OMPD_parallel_sections:
15929 case OMPD_parallel_for:
15930 case OMPD_parallel_for_simd:
15931 case OMPD_threadprivate:
15932 case OMPD_allocate:
15933 case OMPD_taskyield:
15934 case OMPD_barrier:
15935 case OMPD_taskwait:
15936 case OMPD_cancellation_point:
15937 case OMPD_flush:
15938 case OMPD_depobj:
15939 case OMPD_scan:
15940 case OMPD_declare_reduction:
15941 case OMPD_declare_mapper:
15942 case OMPD_declare_simd:
15943 case OMPD_declare_variant:
15944 case OMPD_begin_declare_variant:
15945 case OMPD_end_declare_variant:
15946 case OMPD_declare_target:
15947 case OMPD_end_declare_target:
15948 case OMPD_loop:
15949 case OMPD_teams_loop:
15950 case OMPD_target_teams_loop:
15951 case OMPD_parallel_loop:
15952 case OMPD_target_parallel_loop:
15953 case OMPD_simd:
15954 case OMPD_tile:
15955 case OMPD_unroll:
15956 case OMPD_for:
15957 case OMPD_for_simd:
15958 case OMPD_sections:
15959 case OMPD_section:
15960 case OMPD_single:
15961 case OMPD_master:
15962 case OMPD_masked:
15963 case OMPD_critical:
15964 case OMPD_taskgroup:
15965 case OMPD_distribute:
15966 case OMPD_ordered:
15967 case OMPD_atomic:
15968 case OMPD_distribute_simd:
15969 case OMPD_requires:
15970 case OMPD_metadirective:
15971 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
15972 case OMPD_unknown:
15973 default:
15974 llvm_unreachable("Unknown OpenMP directive");
15975 }
15976 break;
15977 case OMPC_novariants:
15978 case OMPC_nocontext:
15979 switch (DKind) {
15980 case OMPD_dispatch:
15981 CaptureRegion = OMPD_task;
15982 break;
15983 default:
15984 llvm_unreachable("Unexpected OpenMP directive");
15985 }
15986 break;
15987 case OMPC_filter:
15988 // Do not capture filter-clause expressions.
15989 break;
15990 case OMPC_when:
15991 if (DKind == OMPD_metadirective) {
15992 CaptureRegion = OMPD_metadirective;
15993 } else if (DKind == OMPD_unknown) {
15994 llvm_unreachable("Unknown OpenMP directive");
15995 } else {
15996 llvm_unreachable("Unexpected OpenMP directive with when clause");
15997 }
15998 break;
15999 case OMPC_firstprivate:
16000 case OMPC_lastprivate:
16001 case OMPC_reduction:
16002 case OMPC_task_reduction:
16003 case OMPC_in_reduction:
16004 case OMPC_linear:
16005 case OMPC_default:
16006 case OMPC_proc_bind:
16007 case OMPC_safelen:
16008 case OMPC_simdlen:
16009 case OMPC_sizes:
16010 case OMPC_allocator:
16011 case OMPC_collapse:
16012 case OMPC_private:
16013 case OMPC_shared:
16014 case OMPC_aligned:
16015 case OMPC_copyin:
16016 case OMPC_copyprivate:
16017 case OMPC_ordered:
16018 case OMPC_nowait:
16019 case OMPC_untied:
16020 case OMPC_mergeable:
16021 case OMPC_threadprivate:
16022 case OMPC_allocate:
16023 case OMPC_flush:
16024 case OMPC_depobj:
16025 case OMPC_read:
16026 case OMPC_write:
16027 case OMPC_update:
16028 case OMPC_capture:
16029 case OMPC_compare:
16030 case OMPC_seq_cst:
16031 case OMPC_acq_rel:
16032 case OMPC_acquire:
16033 case OMPC_release:
16034 case OMPC_relaxed:
16035 case OMPC_depend:
16036 case OMPC_threads:
16037 case OMPC_simd:
16038 case OMPC_map:
16039 case OMPC_nogroup:
16040 case OMPC_hint:
16041 case OMPC_defaultmap:
16042 case OMPC_unknown:
16043 case OMPC_uniform:
16044 case OMPC_to:
16045 case OMPC_from:
16046 case OMPC_use_device_ptr:
16047 case OMPC_use_device_addr:
16048 case OMPC_is_device_ptr:
16049 case OMPC_unified_address:
16050 case OMPC_unified_shared_memory:
16051 case OMPC_reverse_offload:
16052 case OMPC_dynamic_allocators:
16053 case OMPC_atomic_default_mem_order:
16054 case OMPC_device_type:
16055 case OMPC_match:
16056 case OMPC_nontemporal:
16057 case OMPC_order:
16058 case OMPC_destroy:
16059 case OMPC_detach:
16060 case OMPC_inclusive:
16061 case OMPC_exclusive:
16062 case OMPC_uses_allocators:
16063 case OMPC_affinity:
16064 case OMPC_bind:
16065 default:
16066 llvm_unreachable("Unexpected OpenMP clause.");
16067 }
16068 return CaptureRegion;
16069 }
16070
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)16071 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16072 Expr *Condition, SourceLocation StartLoc,
16073 SourceLocation LParenLoc,
16074 SourceLocation NameModifierLoc,
16075 SourceLocation ColonLoc,
16076 SourceLocation EndLoc) {
16077 Expr *ValExpr = Condition;
16078 Stmt *HelperValStmt = nullptr;
16079 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16080 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16081 !Condition->isInstantiationDependent() &&
16082 !Condition->containsUnexpandedParameterPack()) {
16083 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16084 if (Val.isInvalid())
16085 return nullptr;
16086
16087 ValExpr = Val.get();
16088
16089 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16090 CaptureRegion = getOpenMPCaptureRegionForClause(
16091 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16092 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16093 ValExpr = MakeFullExpr(ValExpr).get();
16094 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16095 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16096 HelperValStmt = buildPreInits(Context, Captures);
16097 }
16098 }
16099
16100 return new (Context)
16101 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16102 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16103 }
16104
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16105 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16106 SourceLocation StartLoc,
16107 SourceLocation LParenLoc,
16108 SourceLocation EndLoc) {
16109 Expr *ValExpr = Condition;
16110 Stmt *HelperValStmt = nullptr;
16111 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16112 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16113 !Condition->isInstantiationDependent() &&
16114 !Condition->containsUnexpandedParameterPack()) {
16115 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16116 if (Val.isInvalid())
16117 return nullptr;
16118
16119 ValExpr = MakeFullExpr(Val.get()).get();
16120
16121 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16122 CaptureRegion =
16123 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16124 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16125 ValExpr = MakeFullExpr(ValExpr).get();
16126 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16127 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16128 HelperValStmt = buildPreInits(Context, Captures);
16129 }
16130 }
16131
16132 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16133 StartLoc, LParenLoc, EndLoc);
16134 }
16135
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)16136 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16137 Expr *Op) {
16138 if (!Op)
16139 return ExprError();
16140
16141 class IntConvertDiagnoser : public ICEConvertDiagnoser {
16142 public:
16143 IntConvertDiagnoser()
16144 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16145 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16146 QualType T) override {
16147 return S.Diag(Loc, diag::err_omp_not_integral) << T;
16148 }
16149 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16150 QualType T) override {
16151 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16152 }
16153 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16154 QualType T,
16155 QualType ConvTy) override {
16156 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16157 }
16158 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16159 QualType ConvTy) override {
16160 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16161 << ConvTy->isEnumeralType() << ConvTy;
16162 }
16163 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16164 QualType T) override {
16165 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16166 }
16167 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16168 QualType ConvTy) override {
16169 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16170 << ConvTy->isEnumeralType() << ConvTy;
16171 }
16172 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16173 QualType) override {
16174 llvm_unreachable("conversion functions are permitted");
16175 }
16176 } ConvertDiagnoser;
16177 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16178 }
16179
16180 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)16181 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16182 bool StrictlyPositive, bool BuildCapture = false,
16183 OpenMPDirectiveKind DKind = OMPD_unknown,
16184 OpenMPDirectiveKind *CaptureRegion = nullptr,
16185 Stmt **HelperValStmt = nullptr) {
16186 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16187 !ValExpr->isInstantiationDependent()) {
16188 SourceLocation Loc = ValExpr->getExprLoc();
16189 ExprResult Value =
16190 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16191 if (Value.isInvalid())
16192 return false;
16193
16194 ValExpr = Value.get();
16195 // The expression must evaluate to a non-negative integer value.
16196 if (Optional<llvm::APSInt> Result =
16197 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16198 if (Result->isSigned() &&
16199 !((!StrictlyPositive && Result->isNonNegative()) ||
16200 (StrictlyPositive && Result->isStrictlyPositive()))) {
16201 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16202 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16203 << ValExpr->getSourceRange();
16204 return false;
16205 }
16206 }
16207 if (!BuildCapture)
16208 return true;
16209 *CaptureRegion =
16210 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16211 if (*CaptureRegion != OMPD_unknown &&
16212 !SemaRef.CurContext->isDependentContext()) {
16213 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16214 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16215 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16216 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16217 }
16218 }
16219 return true;
16220 }
16221
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16222 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16223 SourceLocation StartLoc,
16224 SourceLocation LParenLoc,
16225 SourceLocation EndLoc) {
16226 Expr *ValExpr = NumThreads;
16227 Stmt *HelperValStmt = nullptr;
16228
16229 // OpenMP [2.5, Restrictions]
16230 // The num_threads expression must evaluate to a positive integer value.
16231 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16232 /*StrictlyPositive=*/true))
16233 return nullptr;
16234
16235 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16236 OpenMPDirectiveKind CaptureRegion =
16237 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16238 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16239 ValExpr = MakeFullExpr(ValExpr).get();
16240 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16241 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16242 HelperValStmt = buildPreInits(Context, Captures);
16243 }
16244
16245 return new (Context) OMPNumThreadsClause(
16246 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16247 }
16248
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive,bool SuppressExprDiags)16249 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16250 OpenMPClauseKind CKind,
16251 bool StrictlyPositive,
16252 bool SuppressExprDiags) {
16253 if (!E)
16254 return ExprError();
16255 if (E->isValueDependent() || E->isTypeDependent() ||
16256 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16257 return E;
16258
16259 llvm::APSInt Result;
16260 ExprResult ICE;
16261 if (SuppressExprDiags) {
16262 // Use a custom diagnoser that suppresses 'note' diagnostics about the
16263 // expression.
16264 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16265 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16266 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16267 SourceLocation Loc) override {
16268 llvm_unreachable("Diagnostic suppressed");
16269 }
16270 } Diagnoser;
16271 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16272 } else {
16273 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16274 }
16275 if (ICE.isInvalid())
16276 return ExprError();
16277
16278 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16279 (!StrictlyPositive && !Result.isNonNegative())) {
16280 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16281 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16282 << E->getSourceRange();
16283 return ExprError();
16284 }
16285 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16286 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16287 << E->getSourceRange();
16288 return ExprError();
16289 }
16290 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16291 DSAStack->setAssociatedLoops(Result.getExtValue());
16292 else if (CKind == OMPC_ordered)
16293 DSAStack->setAssociatedLoops(Result.getExtValue());
16294 return ICE;
16295 }
16296
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16297 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16298 SourceLocation LParenLoc,
16299 SourceLocation EndLoc) {
16300 // OpenMP [2.8.1, simd construct, Description]
16301 // The parameter of the safelen clause must be a constant
16302 // positive integer expression.
16303 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16304 if (Safelen.isInvalid())
16305 return nullptr;
16306 return new (Context)
16307 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16308 }
16309
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16310 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16311 SourceLocation LParenLoc,
16312 SourceLocation EndLoc) {
16313 // OpenMP [2.8.1, simd construct, Description]
16314 // The parameter of the simdlen clause must be a constant
16315 // positive integer expression.
16316 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16317 if (Simdlen.isInvalid())
16318 return nullptr;
16319 return new (Context)
16320 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16321 }
16322
16323 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)16324 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16325 DSAStackTy *Stack) {
16326 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
16327 if (!OMPAllocatorHandleT.isNull())
16328 return true;
16329 // Build the predefined allocator expressions.
16330 bool ErrorFound = false;
16331 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16332 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16333 StringRef Allocator =
16334 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16335 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16336 auto *VD = dyn_cast_or_null<ValueDecl>(
16337 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16338 if (!VD) {
16339 ErrorFound = true;
16340 break;
16341 }
16342 QualType AllocatorType =
16343 VD->getType().getNonLValueExprType(S.getASTContext());
16344 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16345 if (!Res.isUsable()) {
16346 ErrorFound = true;
16347 break;
16348 }
16349 if (OMPAllocatorHandleT.isNull())
16350 OMPAllocatorHandleT = AllocatorType;
16351 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
16352 ErrorFound = true;
16353 break;
16354 }
16355 Stack->setAllocator(AllocatorKind, Res.get());
16356 }
16357 if (ErrorFound) {
16358 S.Diag(Loc, diag::err_omp_implied_type_not_found)
16359 << "omp_allocator_handle_t";
16360 return false;
16361 }
16362 OMPAllocatorHandleT.addConst();
16363 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
16364 return true;
16365 }
16366
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16367 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16368 SourceLocation LParenLoc,
16369 SourceLocation EndLoc) {
16370 // OpenMP [2.11.3, allocate Directive, Description]
16371 // allocator is an expression of omp_allocator_handle_t type.
16372 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16373 return nullptr;
16374
16375 ExprResult Allocator = DefaultLvalueConversion(A);
16376 if (Allocator.isInvalid())
16377 return nullptr;
16378 Allocator = PerformImplicitConversion(Allocator.get(),
16379 DSAStack->getOMPAllocatorHandleT(),
16380 Sema::AA_Initializing,
16381 /*AllowExplicit=*/true);
16382 if (Allocator.isInvalid())
16383 return nullptr;
16384 return new (Context)
16385 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16386 }
16387
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16388 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16389 SourceLocation StartLoc,
16390 SourceLocation LParenLoc,
16391 SourceLocation EndLoc) {
16392 // OpenMP [2.7.1, loop construct, Description]
16393 // OpenMP [2.8.1, simd construct, Description]
16394 // OpenMP [2.9.6, distribute construct, Description]
16395 // The parameter of the collapse clause must be a constant
16396 // positive integer expression.
16397 ExprResult NumForLoopsResult =
16398 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16399 if (NumForLoopsResult.isInvalid())
16400 return nullptr;
16401 return new (Context)
16402 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16403 }
16404
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)16405 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16406 SourceLocation EndLoc,
16407 SourceLocation LParenLoc,
16408 Expr *NumForLoops) {
16409 // OpenMP [2.7.1, loop construct, Description]
16410 // OpenMP [2.8.1, simd construct, Description]
16411 // OpenMP [2.9.6, distribute construct, Description]
16412 // The parameter of the ordered clause must be a constant
16413 // positive integer expression if any.
16414 if (NumForLoops && LParenLoc.isValid()) {
16415 ExprResult NumForLoopsResult =
16416 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16417 if (NumForLoopsResult.isInvalid())
16418 return nullptr;
16419 NumForLoops = NumForLoopsResult.get();
16420 } else {
16421 NumForLoops = nullptr;
16422 }
16423 auto *Clause = OMPOrderedClause::Create(
16424 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16425 StartLoc, LParenLoc, EndLoc);
16426 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16427 return Clause;
16428 }
16429
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16430 OMPClause *Sema::ActOnOpenMPSimpleClause(
16431 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16432 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16433 OMPClause *Res = nullptr;
16434 switch (Kind) {
16435 case OMPC_default:
16436 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16437 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16438 break;
16439 case OMPC_proc_bind:
16440 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16441 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16442 break;
16443 case OMPC_atomic_default_mem_order:
16444 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16445 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16446 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16447 break;
16448 case OMPC_order:
16449 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
16450 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16451 break;
16452 case OMPC_update:
16453 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16454 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16455 break;
16456 case OMPC_bind:
16457 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16458 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16459 break;
16460 case OMPC_if:
16461 case OMPC_final:
16462 case OMPC_num_threads:
16463 case OMPC_safelen:
16464 case OMPC_simdlen:
16465 case OMPC_sizes:
16466 case OMPC_allocator:
16467 case OMPC_collapse:
16468 case OMPC_schedule:
16469 case OMPC_private:
16470 case OMPC_firstprivate:
16471 case OMPC_lastprivate:
16472 case OMPC_shared:
16473 case OMPC_reduction:
16474 case OMPC_task_reduction:
16475 case OMPC_in_reduction:
16476 case OMPC_linear:
16477 case OMPC_aligned:
16478 case OMPC_copyin:
16479 case OMPC_copyprivate:
16480 case OMPC_ordered:
16481 case OMPC_nowait:
16482 case OMPC_untied:
16483 case OMPC_mergeable:
16484 case OMPC_threadprivate:
16485 case OMPC_allocate:
16486 case OMPC_flush:
16487 case OMPC_depobj:
16488 case OMPC_read:
16489 case OMPC_write:
16490 case OMPC_capture:
16491 case OMPC_compare:
16492 case OMPC_seq_cst:
16493 case OMPC_acq_rel:
16494 case OMPC_acquire:
16495 case OMPC_release:
16496 case OMPC_relaxed:
16497 case OMPC_depend:
16498 case OMPC_device:
16499 case OMPC_threads:
16500 case OMPC_simd:
16501 case OMPC_map:
16502 case OMPC_num_teams:
16503 case OMPC_thread_limit:
16504 case OMPC_priority:
16505 case OMPC_grainsize:
16506 case OMPC_nogroup:
16507 case OMPC_num_tasks:
16508 case OMPC_hint:
16509 case OMPC_dist_schedule:
16510 case OMPC_defaultmap:
16511 case OMPC_unknown:
16512 case OMPC_uniform:
16513 case OMPC_to:
16514 case OMPC_from:
16515 case OMPC_use_device_ptr:
16516 case OMPC_use_device_addr:
16517 case OMPC_is_device_ptr:
16518 case OMPC_has_device_addr:
16519 case OMPC_unified_address:
16520 case OMPC_unified_shared_memory:
16521 case OMPC_reverse_offload:
16522 case OMPC_dynamic_allocators:
16523 case OMPC_device_type:
16524 case OMPC_match:
16525 case OMPC_nontemporal:
16526 case OMPC_destroy:
16527 case OMPC_novariants:
16528 case OMPC_nocontext:
16529 case OMPC_detach:
16530 case OMPC_inclusive:
16531 case OMPC_exclusive:
16532 case OMPC_uses_allocators:
16533 case OMPC_affinity:
16534 case OMPC_when:
16535 default:
16536 llvm_unreachable("Clause is not allowed.");
16537 }
16538 return Res;
16539 }
16540
16541 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)16542 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
16543 ArrayRef<unsigned> Exclude = llvm::None) {
16544 SmallString<256> Buffer;
16545 llvm::raw_svector_ostream Out(Buffer);
16546 unsigned Skipped = Exclude.size();
16547 auto S = Exclude.begin(), E = Exclude.end();
16548 for (unsigned I = First; I < Last; ++I) {
16549 if (std::find(S, E, I) != E) {
16550 --Skipped;
16551 continue;
16552 }
16553 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
16554 if (I + Skipped + 2 == Last)
16555 Out << " or ";
16556 else if (I + Skipped + 1 != Last)
16557 Out << ", ";
16558 }
16559 return std::string(Out.str());
16560 }
16561
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16562 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
16563 SourceLocation KindKwLoc,
16564 SourceLocation StartLoc,
16565 SourceLocation LParenLoc,
16566 SourceLocation EndLoc) {
16567 if (Kind == OMP_DEFAULT_unknown) {
16568 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16569 << getListOfPossibleValues(OMPC_default, /*First=*/0,
16570 /*Last=*/unsigned(OMP_DEFAULT_unknown))
16571 << getOpenMPClauseName(OMPC_default);
16572 return nullptr;
16573 }
16574
16575 switch (Kind) {
16576 case OMP_DEFAULT_none:
16577 DSAStack->setDefaultDSANone(KindKwLoc);
16578 break;
16579 case OMP_DEFAULT_shared:
16580 DSAStack->setDefaultDSAShared(KindKwLoc);
16581 break;
16582 case OMP_DEFAULT_firstprivate:
16583 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
16584 break;
16585 case OMP_DEFAULT_private:
16586 DSAStack->setDefaultDSAPrivate(KindKwLoc);
16587 break;
16588 default:
16589 llvm_unreachable("DSA unexpected in OpenMP default clause");
16590 }
16591
16592 return new (Context)
16593 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16594 }
16595
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16596 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
16597 SourceLocation KindKwLoc,
16598 SourceLocation StartLoc,
16599 SourceLocation LParenLoc,
16600 SourceLocation EndLoc) {
16601 if (Kind == OMP_PROC_BIND_unknown) {
16602 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16603 << getListOfPossibleValues(OMPC_proc_bind,
16604 /*First=*/unsigned(OMP_PROC_BIND_master),
16605 /*Last=*/
16606 unsigned(LangOpts.OpenMP > 50
16607 ? OMP_PROC_BIND_primary
16608 : OMP_PROC_BIND_spread) +
16609 1)
16610 << getOpenMPClauseName(OMPC_proc_bind);
16611 return nullptr;
16612 }
16613 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16614 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16615 << getListOfPossibleValues(OMPC_proc_bind,
16616 /*First=*/unsigned(OMP_PROC_BIND_master),
16617 /*Last=*/
16618 unsigned(OMP_PROC_BIND_spread) + 1)
16619 << getOpenMPClauseName(OMPC_proc_bind);
16620 return new (Context)
16621 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16622 }
16623
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16624 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
16625 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
16626 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16627 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
16628 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16629 << getListOfPossibleValues(
16630 OMPC_atomic_default_mem_order, /*First=*/0,
16631 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
16632 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16633 return nullptr;
16634 }
16635 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16636 LParenLoc, EndLoc);
16637 }
16638
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16639 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
16640 SourceLocation KindKwLoc,
16641 SourceLocation StartLoc,
16642 SourceLocation LParenLoc,
16643 SourceLocation EndLoc) {
16644 if (Kind == OMPC_ORDER_unknown) {
16645 static_assert(OMPC_ORDER_unknown > 0,
16646 "OMPC_ORDER_unknown not greater than 0");
16647 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16648 << getListOfPossibleValues(OMPC_order, /*First=*/0,
16649 /*Last=*/OMPC_ORDER_unknown)
16650 << getOpenMPClauseName(OMPC_order);
16651 return nullptr;
16652 }
16653 return new (Context)
16654 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16655 }
16656
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16657 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
16658 SourceLocation KindKwLoc,
16659 SourceLocation StartLoc,
16660 SourceLocation LParenLoc,
16661 SourceLocation EndLoc) {
16662 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16663 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16664 SmallVector<unsigned> Except = {
16665 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16666 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16667 if (LangOpts.OpenMP < 51)
16668 Except.push_back(OMPC_DEPEND_inoutset);
16669 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16670 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16671 /*Last=*/OMPC_DEPEND_unknown, Except)
16672 << getOpenMPClauseName(OMPC_update);
16673 return nullptr;
16674 }
16675 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
16676 EndLoc);
16677 }
16678
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16679 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
16680 SourceLocation StartLoc,
16681 SourceLocation LParenLoc,
16682 SourceLocation EndLoc) {
16683 for (Expr *SizeExpr : SizeExprs) {
16684 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16685 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
16686 if (!NumForLoopsResult.isUsable())
16687 return nullptr;
16688 }
16689
16690 DSAStack->setAssociatedLoops(SizeExprs.size());
16691 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16692 SizeExprs);
16693 }
16694
ActOnOpenMPFullClause(SourceLocation StartLoc,SourceLocation EndLoc)16695 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
16696 SourceLocation EndLoc) {
16697 return OMPFullClause::Create(Context, StartLoc, EndLoc);
16698 }
16699
ActOnOpenMPPartialClause(Expr * FactorExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16700 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
16701 SourceLocation StartLoc,
16702 SourceLocation LParenLoc,
16703 SourceLocation EndLoc) {
16704 if (FactorExpr) {
16705 // If an argument is specified, it must be a constant (or an unevaluated
16706 // template expression).
16707 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16708 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16709 if (FactorResult.isInvalid())
16710 return nullptr;
16711 FactorExpr = FactorResult.get();
16712 }
16713
16714 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16715 FactorExpr);
16716 }
16717
ActOnOpenMPAlignClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16718 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
16719 SourceLocation LParenLoc,
16720 SourceLocation EndLoc) {
16721 ExprResult AlignVal;
16722 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16723 if (AlignVal.isInvalid())
16724 return nullptr;
16725 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
16726 EndLoc);
16727 }
16728
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)16729 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
16730 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
16731 SourceLocation StartLoc, SourceLocation LParenLoc,
16732 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
16733 SourceLocation EndLoc) {
16734 OMPClause *Res = nullptr;
16735 switch (Kind) {
16736 case OMPC_schedule:
16737 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16738 assert(Argument.size() == NumberOfElements &&
16739 ArgumentLoc.size() == NumberOfElements);
16740 Res = ActOnOpenMPScheduleClause(
16741 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
16742 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
16743 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
16744 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16745 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16746 break;
16747 case OMPC_if:
16748 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16749 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
16750 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16751 DelimLoc, EndLoc);
16752 break;
16753 case OMPC_dist_schedule:
16754 Res = ActOnOpenMPDistScheduleClause(
16755 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
16756 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16757 break;
16758 case OMPC_defaultmap:
16759 enum { Modifier, DefaultmapKind };
16760 Res = ActOnOpenMPDefaultmapClause(
16761 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
16762 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
16763 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16764 EndLoc);
16765 break;
16766 case OMPC_device:
16767 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16768 Res = ActOnOpenMPDeviceClause(
16769 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
16770 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16771 break;
16772 case OMPC_final:
16773 case OMPC_num_threads:
16774 case OMPC_safelen:
16775 case OMPC_simdlen:
16776 case OMPC_sizes:
16777 case OMPC_allocator:
16778 case OMPC_collapse:
16779 case OMPC_default:
16780 case OMPC_proc_bind:
16781 case OMPC_private:
16782 case OMPC_firstprivate:
16783 case OMPC_lastprivate:
16784 case OMPC_shared:
16785 case OMPC_reduction:
16786 case OMPC_task_reduction:
16787 case OMPC_in_reduction:
16788 case OMPC_linear:
16789 case OMPC_aligned:
16790 case OMPC_copyin:
16791 case OMPC_copyprivate:
16792 case OMPC_ordered:
16793 case OMPC_nowait:
16794 case OMPC_untied:
16795 case OMPC_mergeable:
16796 case OMPC_threadprivate:
16797 case OMPC_allocate:
16798 case OMPC_flush:
16799 case OMPC_depobj:
16800 case OMPC_read:
16801 case OMPC_write:
16802 case OMPC_update:
16803 case OMPC_capture:
16804 case OMPC_compare:
16805 case OMPC_seq_cst:
16806 case OMPC_acq_rel:
16807 case OMPC_acquire:
16808 case OMPC_release:
16809 case OMPC_relaxed:
16810 case OMPC_depend:
16811 case OMPC_threads:
16812 case OMPC_simd:
16813 case OMPC_map:
16814 case OMPC_num_teams:
16815 case OMPC_thread_limit:
16816 case OMPC_priority:
16817 case OMPC_grainsize:
16818 case OMPC_nogroup:
16819 case OMPC_num_tasks:
16820 case OMPC_hint:
16821 case OMPC_unknown:
16822 case OMPC_uniform:
16823 case OMPC_to:
16824 case OMPC_from:
16825 case OMPC_use_device_ptr:
16826 case OMPC_use_device_addr:
16827 case OMPC_is_device_ptr:
16828 case OMPC_has_device_addr:
16829 case OMPC_unified_address:
16830 case OMPC_unified_shared_memory:
16831 case OMPC_reverse_offload:
16832 case OMPC_dynamic_allocators:
16833 case OMPC_atomic_default_mem_order:
16834 case OMPC_device_type:
16835 case OMPC_match:
16836 case OMPC_nontemporal:
16837 case OMPC_order:
16838 case OMPC_destroy:
16839 case OMPC_novariants:
16840 case OMPC_nocontext:
16841 case OMPC_detach:
16842 case OMPC_inclusive:
16843 case OMPC_exclusive:
16844 case OMPC_uses_allocators:
16845 case OMPC_affinity:
16846 case OMPC_when:
16847 case OMPC_bind:
16848 default:
16849 llvm_unreachable("Clause is not allowed.");
16850 }
16851 return Res;
16852 }
16853
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)16854 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
16855 OpenMPScheduleClauseModifier M2,
16856 SourceLocation M1Loc, SourceLocation M2Loc) {
16857 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
16858 SmallVector<unsigned, 2> Excluded;
16859 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
16860 Excluded.push_back(M2);
16861 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16862 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16863 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16864 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16865 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16866 << getListOfPossibleValues(OMPC_schedule,
16867 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
16868 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16869 Excluded)
16870 << getOpenMPClauseName(OMPC_schedule);
16871 return true;
16872 }
16873 return false;
16874 }
16875
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)16876 OMPClause *Sema::ActOnOpenMPScheduleClause(
16877 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
16878 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16879 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
16880 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
16881 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
16882 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
16883 return nullptr;
16884 // OpenMP, 2.7.1, Loop Construct, Restrictions
16885 // Either the monotonic modifier or the nonmonotonic modifier can be specified
16886 // but not both.
16887 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
16888 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16889 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16890 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16891 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16892 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16893 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
16894 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
16895 return nullptr;
16896 }
16897 if (Kind == OMPC_SCHEDULE_unknown) {
16898 std::string Values;
16899 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
16900 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
16901 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16902 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16903 Exclude);
16904 } else {
16905 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16906 /*Last=*/OMPC_SCHEDULE_unknown);
16907 }
16908 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16909 << Values << getOpenMPClauseName(OMPC_schedule);
16910 return nullptr;
16911 }
16912 // OpenMP, 2.7.1, Loop Construct, Restrictions
16913 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16914 // schedule(guided).
16915 // OpenMP 5.0 does not have this restriction.
16916 if (LangOpts.OpenMP < 50 &&
16917 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16918 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16919 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16920 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16921 diag::err_omp_schedule_nonmonotonic_static);
16922 return nullptr;
16923 }
16924 Expr *ValExpr = ChunkSize;
16925 Stmt *HelperValStmt = nullptr;
16926 if (ChunkSize) {
16927 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16928 !ChunkSize->isInstantiationDependent() &&
16929 !ChunkSize->containsUnexpandedParameterPack()) {
16930 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16931 ExprResult Val =
16932 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16933 if (Val.isInvalid())
16934 return nullptr;
16935
16936 ValExpr = Val.get();
16937
16938 // OpenMP [2.7.1, Restrictions]
16939 // chunk_size must be a loop invariant integer expression with a positive
16940 // value.
16941 if (Optional<llvm::APSInt> Result =
16942 ValExpr->getIntegerConstantExpr(Context)) {
16943 if (Result->isSigned() && !Result->isStrictlyPositive()) {
16944 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16945 << "schedule" << 1 << ChunkSize->getSourceRange();
16946 return nullptr;
16947 }
16948 } else if (getOpenMPCaptureRegionForClause(
16949 DSAStack->getCurrentDirective(), OMPC_schedule,
16950 LangOpts.OpenMP) != OMPD_unknown &&
16951 !CurContext->isDependentContext()) {
16952 ValExpr = MakeFullExpr(ValExpr).get();
16953 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16954 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16955 HelperValStmt = buildPreInits(Context, Captures);
16956 }
16957 }
16958 }
16959
16960 return new (Context)
16961 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
16962 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16963 }
16964
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)16965 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
16966 SourceLocation StartLoc,
16967 SourceLocation EndLoc) {
16968 OMPClause *Res = nullptr;
16969 switch (Kind) {
16970 case OMPC_ordered:
16971 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
16972 break;
16973 case OMPC_nowait:
16974 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
16975 break;
16976 case OMPC_untied:
16977 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
16978 break;
16979 case OMPC_mergeable:
16980 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
16981 break;
16982 case OMPC_read:
16983 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
16984 break;
16985 case OMPC_write:
16986 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
16987 break;
16988 case OMPC_update:
16989 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
16990 break;
16991 case OMPC_capture:
16992 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
16993 break;
16994 case OMPC_compare:
16995 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
16996 break;
16997 case OMPC_seq_cst:
16998 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
16999 break;
17000 case OMPC_acq_rel:
17001 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17002 break;
17003 case OMPC_acquire:
17004 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17005 break;
17006 case OMPC_release:
17007 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17008 break;
17009 case OMPC_relaxed:
17010 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17011 break;
17012 case OMPC_threads:
17013 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17014 break;
17015 case OMPC_simd:
17016 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17017 break;
17018 case OMPC_nogroup:
17019 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17020 break;
17021 case OMPC_unified_address:
17022 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17023 break;
17024 case OMPC_unified_shared_memory:
17025 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17026 break;
17027 case OMPC_reverse_offload:
17028 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17029 break;
17030 case OMPC_dynamic_allocators:
17031 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17032 break;
17033 case OMPC_destroy:
17034 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17035 /*LParenLoc=*/SourceLocation(),
17036 /*VarLoc=*/SourceLocation(), EndLoc);
17037 break;
17038 case OMPC_full:
17039 Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17040 break;
17041 case OMPC_partial:
17042 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17043 break;
17044 case OMPC_if:
17045 case OMPC_final:
17046 case OMPC_num_threads:
17047 case OMPC_safelen:
17048 case OMPC_simdlen:
17049 case OMPC_sizes:
17050 case OMPC_allocator:
17051 case OMPC_collapse:
17052 case OMPC_schedule:
17053 case OMPC_private:
17054 case OMPC_firstprivate:
17055 case OMPC_lastprivate:
17056 case OMPC_shared:
17057 case OMPC_reduction:
17058 case OMPC_task_reduction:
17059 case OMPC_in_reduction:
17060 case OMPC_linear:
17061 case OMPC_aligned:
17062 case OMPC_copyin:
17063 case OMPC_copyprivate:
17064 case OMPC_default:
17065 case OMPC_proc_bind:
17066 case OMPC_threadprivate:
17067 case OMPC_allocate:
17068 case OMPC_flush:
17069 case OMPC_depobj:
17070 case OMPC_depend:
17071 case OMPC_device:
17072 case OMPC_map:
17073 case OMPC_num_teams:
17074 case OMPC_thread_limit:
17075 case OMPC_priority:
17076 case OMPC_grainsize:
17077 case OMPC_num_tasks:
17078 case OMPC_hint:
17079 case OMPC_dist_schedule:
17080 case OMPC_defaultmap:
17081 case OMPC_unknown:
17082 case OMPC_uniform:
17083 case OMPC_to:
17084 case OMPC_from:
17085 case OMPC_use_device_ptr:
17086 case OMPC_use_device_addr:
17087 case OMPC_is_device_ptr:
17088 case OMPC_has_device_addr:
17089 case OMPC_atomic_default_mem_order:
17090 case OMPC_device_type:
17091 case OMPC_match:
17092 case OMPC_nontemporal:
17093 case OMPC_order:
17094 case OMPC_novariants:
17095 case OMPC_nocontext:
17096 case OMPC_detach:
17097 case OMPC_inclusive:
17098 case OMPC_exclusive:
17099 case OMPC_uses_allocators:
17100 case OMPC_affinity:
17101 case OMPC_when:
17102 default:
17103 llvm_unreachable("Clause is not allowed.");
17104 }
17105 return Res;
17106 }
17107
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)17108 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17109 SourceLocation EndLoc) {
17110 DSAStack->setNowaitRegion();
17111 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17112 }
17113
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)17114 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17115 SourceLocation EndLoc) {
17116 DSAStack->setUntiedRegion();
17117 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17118 }
17119
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)17120 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17121 SourceLocation EndLoc) {
17122 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17123 }
17124
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)17125 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17126 SourceLocation EndLoc) {
17127 return new (Context) OMPReadClause(StartLoc, EndLoc);
17128 }
17129
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)17130 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17131 SourceLocation EndLoc) {
17132 return new (Context) OMPWriteClause(StartLoc, EndLoc);
17133 }
17134
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)17135 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17136 SourceLocation EndLoc) {
17137 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17138 }
17139
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)17140 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17141 SourceLocation EndLoc) {
17142 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17143 }
17144
ActOnOpenMPCompareClause(SourceLocation StartLoc,SourceLocation EndLoc)17145 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17146 SourceLocation EndLoc) {
17147 return new (Context) OMPCompareClause(StartLoc, EndLoc);
17148 }
17149
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)17150 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17151 SourceLocation EndLoc) {
17152 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17153 }
17154
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)17155 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17156 SourceLocation EndLoc) {
17157 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17158 }
17159
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)17160 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17161 SourceLocation EndLoc) {
17162 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17163 }
17164
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)17165 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17166 SourceLocation EndLoc) {
17167 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17168 }
17169
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)17170 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17171 SourceLocation EndLoc) {
17172 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17173 }
17174
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)17175 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17176 SourceLocation EndLoc) {
17177 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17178 }
17179
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)17180 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17181 SourceLocation EndLoc) {
17182 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17183 }
17184
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)17185 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17186 SourceLocation EndLoc) {
17187 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17188 }
17189
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)17190 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17191 SourceLocation EndLoc) {
17192 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17193 }
17194
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)17195 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17196 SourceLocation EndLoc) {
17197 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17198 }
17199
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)17200 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17201 SourceLocation EndLoc) {
17202 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17203 }
17204
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)17205 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17206 SourceLocation EndLoc) {
17207 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17208 }
17209
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)17210 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17211 SourceLocation StartLoc,
17212 SourceLocation EndLoc) {
17213
17214 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17215 // At least one action-clause must appear on a directive.
17216 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17217 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17218 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17219 << Expected << getOpenMPDirectiveName(OMPD_interop);
17220 return StmtError();
17221 }
17222
17223 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17224 // A depend clause can only appear on the directive if a targetsync
17225 // interop-type is present or the interop-var was initialized with
17226 // the targetsync interop-type.
17227
17228 // If there is any 'init' clause diagnose if there is no 'init' clause with
17229 // interop-type of 'targetsync'. Cases involving other directives cannot be
17230 // diagnosed.
17231 const OMPDependClause *DependClause = nullptr;
17232 bool HasInitClause = false;
17233 bool IsTargetSync = false;
17234 for (const OMPClause *C : Clauses) {
17235 if (IsTargetSync)
17236 break;
17237 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17238 HasInitClause = true;
17239 if (InitClause->getIsTargetSync())
17240 IsTargetSync = true;
17241 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17242 DependClause = DC;
17243 }
17244 }
17245 if (DependClause && HasInitClause && !IsTargetSync) {
17246 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17247 return StmtError();
17248 }
17249
17250 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17251 // Each interop-var may be specified for at most one action-clause of each
17252 // interop construct.
17253 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
17254 for (const OMPClause *C : Clauses) {
17255 OpenMPClauseKind ClauseKind = C->getClauseKind();
17256 const DeclRefExpr *DRE = nullptr;
17257 SourceLocation VarLoc;
17258
17259 if (ClauseKind == OMPC_init) {
17260 const auto *IC = cast<OMPInitClause>(C);
17261 VarLoc = IC->getVarLoc();
17262 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
17263 } else if (ClauseKind == OMPC_use) {
17264 const auto *UC = cast<OMPUseClause>(C);
17265 VarLoc = UC->getVarLoc();
17266 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
17267 } else if (ClauseKind == OMPC_destroy) {
17268 const auto *DC = cast<OMPDestroyClause>(C);
17269 VarLoc = DC->getVarLoc();
17270 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
17271 }
17272
17273 if (!DRE)
17274 continue;
17275
17276 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
17277 if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
17278 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
17279 return StmtError();
17280 }
17281 }
17282 }
17283
17284 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17285 }
17286
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)17287 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17288 SourceLocation VarLoc,
17289 OpenMPClauseKind Kind) {
17290 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
17291 InteropVarExpr->isInstantiationDependent() ||
17292 InteropVarExpr->containsUnexpandedParameterPack())
17293 return true;
17294
17295 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
17296 if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
17297 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
17298 return false;
17299 }
17300
17301 // Interop variable should be of type omp_interop_t.
17302 bool HasError = false;
17303 QualType InteropType;
17304 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17305 VarLoc, Sema::LookupOrdinaryName);
17306 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17307 NamedDecl *ND = Result.getFoundDecl();
17308 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17309 InteropType = QualType(TD->getTypeForDecl(), 0);
17310 } else {
17311 HasError = true;
17312 }
17313 } else {
17314 HasError = true;
17315 }
17316
17317 if (HasError) {
17318 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17319 << "omp_interop_t";
17320 return false;
17321 }
17322
17323 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17324 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17325 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17326 return false;
17327 }
17328
17329 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17330 // The interop-var passed to init or destroy must be non-const.
17331 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17332 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17333 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17334 << /*non-const*/ 1;
17335 return false;
17336 }
17337 return true;
17338 }
17339
17340 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,ArrayRef<Expr * > PrefExprs,bool IsTarget,bool IsTargetSync,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17341 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
17342 bool IsTarget, bool IsTargetSync,
17343 SourceLocation StartLoc, SourceLocation LParenLoc,
17344 SourceLocation VarLoc, SourceLocation EndLoc) {
17345
17346 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17347 return nullptr;
17348
17349 // Check prefer_type values. These foreign-runtime-id values are either
17350 // string literals or constant integral expressions.
17351 for (const Expr *E : PrefExprs) {
17352 if (E->isValueDependent() || E->isTypeDependent() ||
17353 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17354 continue;
17355 if (E->isIntegerConstantExpr(Context))
17356 continue;
17357 if (isa<StringLiteral>(E))
17358 continue;
17359 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17360 return nullptr;
17361 }
17362
17363 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
17364 IsTargetSync, StartLoc, LParenLoc, VarLoc,
17365 EndLoc);
17366 }
17367
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17368 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17369 SourceLocation LParenLoc,
17370 SourceLocation VarLoc,
17371 SourceLocation EndLoc) {
17372
17373 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17374 return nullptr;
17375
17376 return new (Context)
17377 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17378 }
17379
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17380 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17381 SourceLocation StartLoc,
17382 SourceLocation LParenLoc,
17383 SourceLocation VarLoc,
17384 SourceLocation EndLoc) {
17385 if (InteropVar &&
17386 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
17387 return nullptr;
17388
17389 return new (Context)
17390 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17391 }
17392
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17393 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
17394 SourceLocation StartLoc,
17395 SourceLocation LParenLoc,
17396 SourceLocation EndLoc) {
17397 Expr *ValExpr = Condition;
17398 Stmt *HelperValStmt = nullptr;
17399 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17400 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17401 !Condition->isInstantiationDependent() &&
17402 !Condition->containsUnexpandedParameterPack()) {
17403 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17404 if (Val.isInvalid())
17405 return nullptr;
17406
17407 ValExpr = MakeFullExpr(Val.get()).get();
17408
17409 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17410 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17411 LangOpts.OpenMP);
17412 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17413 ValExpr = MakeFullExpr(ValExpr).get();
17414 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17415 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17416 HelperValStmt = buildPreInits(Context, Captures);
17417 }
17418 }
17419
17420 return new (Context) OMPNovariantsClause(
17421 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17422 }
17423
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17424 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
17425 SourceLocation StartLoc,
17426 SourceLocation LParenLoc,
17427 SourceLocation EndLoc) {
17428 Expr *ValExpr = Condition;
17429 Stmt *HelperValStmt = nullptr;
17430 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17431 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17432 !Condition->isInstantiationDependent() &&
17433 !Condition->containsUnexpandedParameterPack()) {
17434 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17435 if (Val.isInvalid())
17436 return nullptr;
17437
17438 ValExpr = MakeFullExpr(Val.get()).get();
17439
17440 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17441 CaptureRegion =
17442 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
17443 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17444 ValExpr = MakeFullExpr(ValExpr).get();
17445 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17446 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17447 HelperValStmt = buildPreInits(Context, Captures);
17448 }
17449 }
17450
17451 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
17452 StartLoc, LParenLoc, EndLoc);
17453 }
17454
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17455 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
17456 SourceLocation StartLoc,
17457 SourceLocation LParenLoc,
17458 SourceLocation EndLoc) {
17459 Expr *ValExpr = ThreadID;
17460 Stmt *HelperValStmt = nullptr;
17461
17462 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17463 OpenMPDirectiveKind CaptureRegion =
17464 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
17465 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17466 ValExpr = MakeFullExpr(ValExpr).get();
17467 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17468 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17469 HelperValStmt = buildPreInits(Context, Captures);
17470 }
17471
17472 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
17473 StartLoc, LParenLoc, EndLoc);
17474 }
17475
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,OpenMPVarListDataTy & Data)17476 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
17477 ArrayRef<Expr *> VarList,
17478 const OMPVarListLocTy &Locs,
17479 OpenMPVarListDataTy &Data) {
17480 SourceLocation StartLoc = Locs.StartLoc;
17481 SourceLocation LParenLoc = Locs.LParenLoc;
17482 SourceLocation EndLoc = Locs.EndLoc;
17483 OMPClause *Res = nullptr;
17484 int ExtraModifier = Data.ExtraModifier;
17485 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
17486 SourceLocation ColonLoc = Data.ColonLoc;
17487 switch (Kind) {
17488 case OMPC_private:
17489 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17490 break;
17491 case OMPC_firstprivate:
17492 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17493 break;
17494 case OMPC_lastprivate:
17495 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
17496 "Unexpected lastprivate modifier.");
17497 Res = ActOnOpenMPLastprivateClause(
17498 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
17499 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17500 break;
17501 case OMPC_shared:
17502 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
17503 break;
17504 case OMPC_reduction:
17505 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
17506 "Unexpected lastprivate modifier.");
17507 Res = ActOnOpenMPReductionClause(
17508 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
17509 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17510 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17511 break;
17512 case OMPC_task_reduction:
17513 Res = ActOnOpenMPTaskReductionClause(
17514 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17515 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17516 break;
17517 case OMPC_in_reduction:
17518 Res = ActOnOpenMPInReductionClause(
17519 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17520 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17521 break;
17522 case OMPC_linear:
17523 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
17524 "Unexpected linear modifier.");
17525 Res = ActOnOpenMPLinearClause(
17526 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
17527 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
17528 ColonLoc, EndLoc);
17529 break;
17530 case OMPC_aligned:
17531 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
17532 LParenLoc, ColonLoc, EndLoc);
17533 break;
17534 case OMPC_copyin:
17535 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
17536 break;
17537 case OMPC_copyprivate:
17538 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17539 break;
17540 case OMPC_flush:
17541 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
17542 break;
17543 case OMPC_depend:
17544 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
17545 "Unexpected depend modifier.");
17546 Res = ActOnOpenMPDependClause(
17547 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
17548 ColonLoc, Data.OmpAllMemoryLoc},
17549 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
17550 break;
17551 case OMPC_map:
17552 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
17553 "Unexpected map modifier.");
17554 Res = ActOnOpenMPMapClause(
17555 Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
17556 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
17557 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
17558 ExtraModifierLoc, ColonLoc, VarList, Locs);
17559 break;
17560 case OMPC_to:
17561 Res =
17562 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17563 Data.ReductionOrMapperIdScopeSpec,
17564 Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
17565 break;
17566 case OMPC_from:
17567 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17568 Data.ReductionOrMapperIdScopeSpec,
17569 Data.ReductionOrMapperId, ColonLoc, VarList,
17570 Locs);
17571 break;
17572 case OMPC_use_device_ptr:
17573 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17574 break;
17575 case OMPC_use_device_addr:
17576 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17577 break;
17578 case OMPC_is_device_ptr:
17579 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17580 break;
17581 case OMPC_has_device_addr:
17582 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17583 break;
17584 case OMPC_allocate:
17585 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
17586 LParenLoc, ColonLoc, EndLoc);
17587 break;
17588 case OMPC_nontemporal:
17589 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17590 break;
17591 case OMPC_inclusive:
17592 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17593 break;
17594 case OMPC_exclusive:
17595 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17596 break;
17597 case OMPC_affinity:
17598 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17599 Data.DepModOrTailExpr, VarList);
17600 break;
17601 case OMPC_if:
17602 case OMPC_depobj:
17603 case OMPC_final:
17604 case OMPC_num_threads:
17605 case OMPC_safelen:
17606 case OMPC_simdlen:
17607 case OMPC_sizes:
17608 case OMPC_allocator:
17609 case OMPC_collapse:
17610 case OMPC_default:
17611 case OMPC_proc_bind:
17612 case OMPC_schedule:
17613 case OMPC_ordered:
17614 case OMPC_nowait:
17615 case OMPC_untied:
17616 case OMPC_mergeable:
17617 case OMPC_threadprivate:
17618 case OMPC_read:
17619 case OMPC_write:
17620 case OMPC_update:
17621 case OMPC_capture:
17622 case OMPC_compare:
17623 case OMPC_seq_cst:
17624 case OMPC_acq_rel:
17625 case OMPC_acquire:
17626 case OMPC_release:
17627 case OMPC_relaxed:
17628 case OMPC_device:
17629 case OMPC_threads:
17630 case OMPC_simd:
17631 case OMPC_num_teams:
17632 case OMPC_thread_limit:
17633 case OMPC_priority:
17634 case OMPC_grainsize:
17635 case OMPC_nogroup:
17636 case OMPC_num_tasks:
17637 case OMPC_hint:
17638 case OMPC_dist_schedule:
17639 case OMPC_defaultmap:
17640 case OMPC_unknown:
17641 case OMPC_uniform:
17642 case OMPC_unified_address:
17643 case OMPC_unified_shared_memory:
17644 case OMPC_reverse_offload:
17645 case OMPC_dynamic_allocators:
17646 case OMPC_atomic_default_mem_order:
17647 case OMPC_device_type:
17648 case OMPC_match:
17649 case OMPC_order:
17650 case OMPC_destroy:
17651 case OMPC_novariants:
17652 case OMPC_nocontext:
17653 case OMPC_detach:
17654 case OMPC_uses_allocators:
17655 case OMPC_when:
17656 case OMPC_bind:
17657 default:
17658 llvm_unreachable("Clause is not allowed.");
17659 }
17660 return Res;
17661 }
17662
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)17663 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
17664 ExprObjectKind OK, SourceLocation Loc) {
17665 ExprResult Res = BuildDeclRefExpr(
17666 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17667 if (!Res.isUsable())
17668 return ExprError();
17669 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17670 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17671 if (!Res.isUsable())
17672 return ExprError();
17673 }
17674 if (VK != VK_LValue && Res.get()->isGLValue()) {
17675 Res = DefaultLvalueConversion(Res.get());
17676 if (!Res.isUsable())
17677 return ExprError();
17678 }
17679 return Res;
17680 }
17681
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17682 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
17683 SourceLocation StartLoc,
17684 SourceLocation LParenLoc,
17685 SourceLocation EndLoc) {
17686 SmallVector<Expr *, 8> Vars;
17687 SmallVector<Expr *, 8> PrivateCopies;
17688 bool IsImplicitClause =
17689 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17690 for (Expr *RefExpr : VarList) {
17691 assert(RefExpr && "NULL expr in OpenMP private clause.");
17692 SourceLocation ELoc;
17693 SourceRange ERange;
17694 Expr *SimpleRefExpr = RefExpr;
17695 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17696 if (Res.second) {
17697 // It will be analyzed later.
17698 Vars.push_back(RefExpr);
17699 PrivateCopies.push_back(nullptr);
17700 }
17701 ValueDecl *D = Res.first;
17702 if (!D)
17703 continue;
17704
17705 QualType Type = D->getType();
17706 auto *VD = dyn_cast<VarDecl>(D);
17707
17708 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17709 // A variable that appears in a private clause must not have an incomplete
17710 // type or a reference type.
17711 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
17712 continue;
17713 Type = Type.getNonReferenceType();
17714
17715 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17716 // A variable that is privatized must not have a const-qualified type
17717 // unless it is of class type with a mutable member. This restriction does
17718 // not apply to the firstprivate clause.
17719 //
17720 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17721 // A variable that appears in a private clause must not have a
17722 // const-qualified type unless it is of class type with a mutable member.
17723 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
17724 continue;
17725
17726 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17727 // in a Construct]
17728 // Variables with the predetermined data-sharing attributes may not be
17729 // listed in data-sharing attributes clauses, except for the cases
17730 // listed below. For these exceptions only, listing a predetermined
17731 // variable in a data-sharing attribute clause is allowed and overrides
17732 // the variable's predetermined data-sharing attributes.
17733 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17734 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17735 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17736 << getOpenMPClauseName(OMPC_private);
17737 reportOriginalDsa(*this, DSAStack, D, DVar);
17738 continue;
17739 }
17740
17741 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17742 // Variably modified types are not supported for tasks.
17743 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17744 isOpenMPTaskingDirective(CurrDir)) {
17745 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17746 << getOpenMPClauseName(OMPC_private) << Type
17747 << getOpenMPDirectiveName(CurrDir);
17748 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17749 VarDecl::DeclarationOnly;
17750 Diag(D->getLocation(),
17751 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17752 << D;
17753 continue;
17754 }
17755
17756 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17757 // A list item cannot appear in both a map clause and a data-sharing
17758 // attribute clause on the same construct
17759 //
17760 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17761 // A list item cannot appear in both a map clause and a data-sharing
17762 // attribute clause on the same construct unless the construct is a
17763 // combined construct.
17764 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
17765 CurrDir == OMPD_target) {
17766 OpenMPClauseKind ConflictKind;
17767 if (DSAStack->checkMappableExprComponentListsForDecl(
17768 VD, /*CurrentRegionOnly=*/true,
17769 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
17770 OpenMPClauseKind WhereFoundClauseKind) -> bool {
17771 ConflictKind = WhereFoundClauseKind;
17772 return true;
17773 })) {
17774 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17775 << getOpenMPClauseName(OMPC_private)
17776 << getOpenMPClauseName(ConflictKind)
17777 << getOpenMPDirectiveName(CurrDir);
17778 reportOriginalDsa(*this, DSAStack, D, DVar);
17779 continue;
17780 }
17781 }
17782
17783 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17784 // A variable of class type (or array thereof) that appears in a private
17785 // clause requires an accessible, unambiguous default constructor for the
17786 // class type.
17787 // Generate helper private variable and initialize it with the default
17788 // value. The address of the original variable is replaced by the address of
17789 // the new private variable in CodeGen. This new variable is not added to
17790 // IdResolver, so the code in the OpenMP region uses original variable for
17791 // proper diagnostics.
17792 Type = Type.getUnqualifiedType();
17793 VarDecl *VDPrivate =
17794 buildVarDecl(*this, ELoc, Type, D->getName(),
17795 D->hasAttrs() ? &D->getAttrs() : nullptr,
17796 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17797 ActOnUninitializedDecl(VDPrivate);
17798 if (VDPrivate->isInvalidDecl())
17799 continue;
17800 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17801 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17802
17803 DeclRefExpr *Ref = nullptr;
17804 if (!VD && !CurContext->isDependentContext()) {
17805 auto *FD = dyn_cast<FieldDecl>(D);
17806 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
17807 if (VD)
17808 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
17809 RefExpr->getExprLoc());
17810 else
17811 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17812 }
17813 if (!IsImplicitClause)
17814 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
17815 Vars.push_back((VD || CurContext->isDependentContext())
17816 ? RefExpr->IgnoreParens()
17817 : Ref);
17818 PrivateCopies.push_back(VDPrivateRefExpr);
17819 }
17820
17821 if (Vars.empty())
17822 return nullptr;
17823
17824 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17825 PrivateCopies);
17826 }
17827
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17828 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
17829 SourceLocation StartLoc,
17830 SourceLocation LParenLoc,
17831 SourceLocation EndLoc) {
17832 SmallVector<Expr *, 8> Vars;
17833 SmallVector<Expr *, 8> PrivateCopies;
17834 SmallVector<Expr *, 8> Inits;
17835 SmallVector<Decl *, 4> ExprCaptures;
17836 bool IsImplicitClause =
17837 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17838 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
17839
17840 for (Expr *RefExpr : VarList) {
17841 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
17842 SourceLocation ELoc;
17843 SourceRange ERange;
17844 Expr *SimpleRefExpr = RefExpr;
17845 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17846 if (Res.second) {
17847 // It will be analyzed later.
17848 Vars.push_back(RefExpr);
17849 PrivateCopies.push_back(nullptr);
17850 Inits.push_back(nullptr);
17851 }
17852 ValueDecl *D = Res.first;
17853 if (!D)
17854 continue;
17855
17856 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
17857 QualType Type = D->getType();
17858 auto *VD = dyn_cast<VarDecl>(D);
17859
17860 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17861 // A variable that appears in a private clause must not have an incomplete
17862 // type or a reference type.
17863 if (RequireCompleteType(ELoc, Type,
17864 diag::err_omp_firstprivate_incomplete_type))
17865 continue;
17866 Type = Type.getNonReferenceType();
17867
17868 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
17869 // A variable of class type (or array thereof) that appears in a private
17870 // clause requires an accessible, unambiguous copy constructor for the
17871 // class type.
17872 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17873
17874 // If an implicit firstprivate variable found it was checked already.
17875 DSAStackTy::DSAVarData TopDVar;
17876 if (!IsImplicitClause) {
17877 DSAStackTy::DSAVarData DVar =
17878 DSAStack->getTopDSA(D, /*FromParent=*/false);
17879 TopDVar = DVar;
17880 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17881 bool IsConstant = ElemType.isConstant(Context);
17882 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17883 // A list item that specifies a given variable may not appear in more
17884 // than one clause on the same directive, except that a variable may be
17885 // specified in both firstprivate and lastprivate clauses.
17886 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17887 // A list item may appear in a firstprivate or lastprivate clause but not
17888 // both.
17889 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17890 (isOpenMPDistributeDirective(CurrDir) ||
17891 DVar.CKind != OMPC_lastprivate) &&
17892 DVar.RefExpr) {
17893 Diag(ELoc, diag::err_omp_wrong_dsa)
17894 << getOpenMPClauseName(DVar.CKind)
17895 << getOpenMPClauseName(OMPC_firstprivate);
17896 reportOriginalDsa(*this, DSAStack, D, DVar);
17897 continue;
17898 }
17899
17900 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17901 // in a Construct]
17902 // Variables with the predetermined data-sharing attributes may not be
17903 // listed in data-sharing attributes clauses, except for the cases
17904 // listed below. For these exceptions only, listing a predetermined
17905 // variable in a data-sharing attribute clause is allowed and overrides
17906 // the variable's predetermined data-sharing attributes.
17907 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17908 // in a Construct, C/C++, p.2]
17909 // Variables with const-qualified type having no mutable member may be
17910 // listed in a firstprivate clause, even if they are static data members.
17911 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17912 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17913 Diag(ELoc, diag::err_omp_wrong_dsa)
17914 << getOpenMPClauseName(DVar.CKind)
17915 << getOpenMPClauseName(OMPC_firstprivate);
17916 reportOriginalDsa(*this, DSAStack, D, DVar);
17917 continue;
17918 }
17919
17920 // OpenMP [2.9.3.4, Restrictions, p.2]
17921 // A list item that is private within a parallel region must not appear
17922 // in a firstprivate clause on a worksharing construct if any of the
17923 // worksharing regions arising from the worksharing construct ever bind
17924 // to any of the parallel regions arising from the parallel construct.
17925 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17926 // A list item that is private within a teams region must not appear in a
17927 // firstprivate clause on a distribute construct if any of the distribute
17928 // regions arising from the distribute construct ever bind to any of the
17929 // teams regions arising from the teams construct.
17930 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17931 // A list item that appears in a reduction clause of a teams construct
17932 // must not appear in a firstprivate clause on a distribute construct if
17933 // any of the distribute regions arising from the distribute construct
17934 // ever bind to any of the teams regions arising from the teams construct.
17935 if ((isOpenMPWorksharingDirective(CurrDir) ||
17936 isOpenMPDistributeDirective(CurrDir)) &&
17937 !isOpenMPParallelDirective(CurrDir) &&
17938 !isOpenMPTeamsDirective(CurrDir)) {
17939 DVar = DSAStack->getImplicitDSA(D, true);
17940 if (DVar.CKind != OMPC_shared &&
17941 (isOpenMPParallelDirective(DVar.DKind) ||
17942 isOpenMPTeamsDirective(DVar.DKind) ||
17943 DVar.DKind == OMPD_unknown)) {
17944 Diag(ELoc, diag::err_omp_required_access)
17945 << getOpenMPClauseName(OMPC_firstprivate)
17946 << getOpenMPClauseName(OMPC_shared);
17947 reportOriginalDsa(*this, DSAStack, D, DVar);
17948 continue;
17949 }
17950 }
17951 // OpenMP [2.9.3.4, Restrictions, p.3]
17952 // A list item that appears in a reduction clause of a parallel construct
17953 // must not appear in a firstprivate clause on a worksharing or task
17954 // construct if any of the worksharing or task regions arising from the
17955 // worksharing or task construct ever bind to any of the parallel regions
17956 // arising from the parallel construct.
17957 // OpenMP [2.9.3.4, Restrictions, p.4]
17958 // A list item that appears in a reduction clause in worksharing
17959 // construct must not appear in a firstprivate clause in a task construct
17960 // encountered during execution of any of the worksharing regions arising
17961 // from the worksharing construct.
17962 if (isOpenMPTaskingDirective(CurrDir)) {
17963 DVar = DSAStack->hasInnermostDSA(
17964 D,
17965 [](OpenMPClauseKind C, bool AppliedToPointee) {
17966 return C == OMPC_reduction && !AppliedToPointee;
17967 },
17968 [](OpenMPDirectiveKind K) {
17969 return isOpenMPParallelDirective(K) ||
17970 isOpenMPWorksharingDirective(K) ||
17971 isOpenMPTeamsDirective(K);
17972 },
17973 /*FromParent=*/true);
17974 if (DVar.CKind == OMPC_reduction &&
17975 (isOpenMPParallelDirective(DVar.DKind) ||
17976 isOpenMPWorksharingDirective(DVar.DKind) ||
17977 isOpenMPTeamsDirective(DVar.DKind))) {
17978 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17979 << getOpenMPDirectiveName(DVar.DKind);
17980 reportOriginalDsa(*this, DSAStack, D, DVar);
17981 continue;
17982 }
17983 }
17984
17985 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17986 // A list item cannot appear in both a map clause and a data-sharing
17987 // attribute clause on the same construct
17988 //
17989 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17990 // A list item cannot appear in both a map clause and a data-sharing
17991 // attribute clause on the same construct unless the construct is a
17992 // combined construct.
17993 if ((LangOpts.OpenMP <= 45 &&
17994 isOpenMPTargetExecutionDirective(CurrDir)) ||
17995 CurrDir == OMPD_target) {
17996 OpenMPClauseKind ConflictKind;
17997 if (DSAStack->checkMappableExprComponentListsForDecl(
17998 VD, /*CurrentRegionOnly=*/true,
17999 [&ConflictKind](
18000 OMPClauseMappableExprCommon::MappableExprComponentListRef,
18001 OpenMPClauseKind WhereFoundClauseKind) {
18002 ConflictKind = WhereFoundClauseKind;
18003 return true;
18004 })) {
18005 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18006 << getOpenMPClauseName(OMPC_firstprivate)
18007 << getOpenMPClauseName(ConflictKind)
18008 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18009 reportOriginalDsa(*this, DSAStack, D, DVar);
18010 continue;
18011 }
18012 }
18013 }
18014
18015 // Variably modified types are not supported for tasks.
18016 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18017 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18018 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18019 << getOpenMPClauseName(OMPC_firstprivate) << Type
18020 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18021 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18022 VarDecl::DeclarationOnly;
18023 Diag(D->getLocation(),
18024 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18025 << D;
18026 continue;
18027 }
18028
18029 Type = Type.getUnqualifiedType();
18030 VarDecl *VDPrivate =
18031 buildVarDecl(*this, ELoc, Type, D->getName(),
18032 D->hasAttrs() ? &D->getAttrs() : nullptr,
18033 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18034 // Generate helper private variable and initialize it with the value of the
18035 // original variable. The address of the original variable is replaced by
18036 // the address of the new private variable in the CodeGen. This new variable
18037 // is not added to IdResolver, so the code in the OpenMP region uses
18038 // original variable for proper diagnostics and variable capturing.
18039 Expr *VDInitRefExpr = nullptr;
18040 // For arrays generate initializer for single element and replace it by the
18041 // original array element in CodeGen.
18042 if (Type->isArrayType()) {
18043 VarDecl *VDInit =
18044 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18045 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18046 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18047 ElemType = ElemType.getUnqualifiedType();
18048 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18049 ".firstprivate.temp");
18050 InitializedEntity Entity =
18051 InitializedEntity::InitializeVariable(VDInitTemp);
18052 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18053
18054 InitializationSequence InitSeq(*this, Entity, Kind, Init);
18055 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18056 if (Result.isInvalid())
18057 VDPrivate->setInvalidDecl();
18058 else
18059 VDPrivate->setInit(Result.getAs<Expr>());
18060 // Remove temp variable declaration.
18061 Context.Deallocate(VDInitTemp);
18062 } else {
18063 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18064 ".firstprivate.temp");
18065 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18066 RefExpr->getExprLoc());
18067 AddInitializerToDecl(VDPrivate,
18068 DefaultLvalueConversion(VDInitRefExpr).get(),
18069 /*DirectInit=*/false);
18070 }
18071 if (VDPrivate->isInvalidDecl()) {
18072 if (IsImplicitClause) {
18073 Diag(RefExpr->getExprLoc(),
18074 diag::note_omp_task_predetermined_firstprivate_here);
18075 }
18076 continue;
18077 }
18078 CurContext->addDecl(VDPrivate);
18079 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18080 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18081 RefExpr->getExprLoc());
18082 DeclRefExpr *Ref = nullptr;
18083 if (!VD && !CurContext->isDependentContext()) {
18084 if (TopDVar.CKind == OMPC_lastprivate) {
18085 Ref = TopDVar.PrivateCopy;
18086 } else {
18087 auto *FD = dyn_cast<FieldDecl>(D);
18088 VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18089 if (VD)
18090 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18091 RefExpr->getExprLoc());
18092 else
18093 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18094 if (VD || !isOpenMPCapturedDecl(D))
18095 ExprCaptures.push_back(Ref->getDecl());
18096 }
18097 }
18098 if (!IsImplicitClause)
18099 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18100 Vars.push_back((VD || CurContext->isDependentContext())
18101 ? RefExpr->IgnoreParens()
18102 : Ref);
18103 PrivateCopies.push_back(VDPrivateRefExpr);
18104 Inits.push_back(VDInitRefExpr);
18105 }
18106
18107 if (Vars.empty())
18108 return nullptr;
18109
18110 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18111 Vars, PrivateCopies, Inits,
18112 buildPreInits(Context, ExprCaptures));
18113 }
18114
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18115 OMPClause *Sema::ActOnOpenMPLastprivateClause(
18116 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18117 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18118 SourceLocation LParenLoc, SourceLocation EndLoc) {
18119 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18120 assert(ColonLoc.isValid() && "Colon location must be valid.");
18121 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18122 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18123 /*Last=*/OMPC_LASTPRIVATE_unknown)
18124 << getOpenMPClauseName(OMPC_lastprivate);
18125 return nullptr;
18126 }
18127
18128 SmallVector<Expr *, 8> Vars;
18129 SmallVector<Expr *, 8> SrcExprs;
18130 SmallVector<Expr *, 8> DstExprs;
18131 SmallVector<Expr *, 8> AssignmentOps;
18132 SmallVector<Decl *, 4> ExprCaptures;
18133 SmallVector<Expr *, 4> ExprPostUpdates;
18134 for (Expr *RefExpr : VarList) {
18135 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18136 SourceLocation ELoc;
18137 SourceRange ERange;
18138 Expr *SimpleRefExpr = RefExpr;
18139 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18140 if (Res.second) {
18141 // It will be analyzed later.
18142 Vars.push_back(RefExpr);
18143 SrcExprs.push_back(nullptr);
18144 DstExprs.push_back(nullptr);
18145 AssignmentOps.push_back(nullptr);
18146 }
18147 ValueDecl *D = Res.first;
18148 if (!D)
18149 continue;
18150
18151 QualType Type = D->getType();
18152 auto *VD = dyn_cast<VarDecl>(D);
18153
18154 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18155 // A variable that appears in a lastprivate clause must not have an
18156 // incomplete type or a reference type.
18157 if (RequireCompleteType(ELoc, Type,
18158 diag::err_omp_lastprivate_incomplete_type))
18159 continue;
18160 Type = Type.getNonReferenceType();
18161
18162 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18163 // A variable that is privatized must not have a const-qualified type
18164 // unless it is of class type with a mutable member. This restriction does
18165 // not apply to the firstprivate clause.
18166 //
18167 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18168 // A variable that appears in a lastprivate clause must not have a
18169 // const-qualified type unless it is of class type with a mutable member.
18170 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18171 continue;
18172
18173 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18174 // A list item that appears in a lastprivate clause with the conditional
18175 // modifier must be a scalar variable.
18176 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18177 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18178 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18179 VarDecl::DeclarationOnly;
18180 Diag(D->getLocation(),
18181 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18182 << D;
18183 continue;
18184 }
18185
18186 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18187 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18188 // in a Construct]
18189 // Variables with the predetermined data-sharing attributes may not be
18190 // listed in data-sharing attributes clauses, except for the cases
18191 // listed below.
18192 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18193 // A list item may appear in a firstprivate or lastprivate clause but not
18194 // both.
18195 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18196 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18197 (isOpenMPDistributeDirective(CurrDir) ||
18198 DVar.CKind != OMPC_firstprivate) &&
18199 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18200 Diag(ELoc, diag::err_omp_wrong_dsa)
18201 << getOpenMPClauseName(DVar.CKind)
18202 << getOpenMPClauseName(OMPC_lastprivate);
18203 reportOriginalDsa(*this, DSAStack, D, DVar);
18204 continue;
18205 }
18206
18207 // OpenMP [2.14.3.5, Restrictions, p.2]
18208 // A list item that is private within a parallel region, or that appears in
18209 // the reduction clause of a parallel construct, must not appear in a
18210 // lastprivate clause on a worksharing construct if any of the corresponding
18211 // worksharing regions ever binds to any of the corresponding parallel
18212 // regions.
18213 DSAStackTy::DSAVarData TopDVar = DVar;
18214 if (isOpenMPWorksharingDirective(CurrDir) &&
18215 !isOpenMPParallelDirective(CurrDir) &&
18216 !isOpenMPTeamsDirective(CurrDir)) {
18217 DVar = DSAStack->getImplicitDSA(D, true);
18218 if (DVar.CKind != OMPC_shared) {
18219 Diag(ELoc, diag::err_omp_required_access)
18220 << getOpenMPClauseName(OMPC_lastprivate)
18221 << getOpenMPClauseName(OMPC_shared);
18222 reportOriginalDsa(*this, DSAStack, D, DVar);
18223 continue;
18224 }
18225 }
18226
18227 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18228 // A variable of class type (or array thereof) that appears in a
18229 // lastprivate clause requires an accessible, unambiguous default
18230 // constructor for the class type, unless the list item is also specified
18231 // in a firstprivate clause.
18232 // A variable of class type (or array thereof) that appears in a
18233 // lastprivate clause requires an accessible, unambiguous copy assignment
18234 // operator for the class type.
18235 Type = Context.getBaseElementType(Type).getNonReferenceType();
18236 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18237 Type.getUnqualifiedType(), ".lastprivate.src",
18238 D->hasAttrs() ? &D->getAttrs() : nullptr);
18239 DeclRefExpr *PseudoSrcExpr =
18240 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18241 VarDecl *DstVD =
18242 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18243 D->hasAttrs() ? &D->getAttrs() : nullptr);
18244 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18245 // For arrays generate assignment operation for single element and replace
18246 // it by the original array element in CodeGen.
18247 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18248 PseudoDstExpr, PseudoSrcExpr);
18249 if (AssignmentOp.isInvalid())
18250 continue;
18251 AssignmentOp =
18252 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18253 if (AssignmentOp.isInvalid())
18254 continue;
18255
18256 DeclRefExpr *Ref = nullptr;
18257 if (!VD && !CurContext->isDependentContext()) {
18258 if (TopDVar.CKind == OMPC_firstprivate) {
18259 Ref = TopDVar.PrivateCopy;
18260 } else {
18261 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18262 if (!isOpenMPCapturedDecl(D))
18263 ExprCaptures.push_back(Ref->getDecl());
18264 }
18265 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18266 (!isOpenMPCapturedDecl(D) &&
18267 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18268 ExprResult RefRes = DefaultLvalueConversion(Ref);
18269 if (!RefRes.isUsable())
18270 continue;
18271 ExprResult PostUpdateRes =
18272 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18273 RefRes.get());
18274 if (!PostUpdateRes.isUsable())
18275 continue;
18276 ExprPostUpdates.push_back(
18277 IgnoredValueConversions(PostUpdateRes.get()).get());
18278 }
18279 }
18280 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18281 Vars.push_back((VD || CurContext->isDependentContext())
18282 ? RefExpr->IgnoreParens()
18283 : Ref);
18284 SrcExprs.push_back(PseudoSrcExpr);
18285 DstExprs.push_back(PseudoDstExpr);
18286 AssignmentOps.push_back(AssignmentOp.get());
18287 }
18288
18289 if (Vars.empty())
18290 return nullptr;
18291
18292 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18293 Vars, SrcExprs, DstExprs, AssignmentOps,
18294 LPKind, LPKindLoc, ColonLoc,
18295 buildPreInits(Context, ExprCaptures),
18296 buildPostUpdate(*this, ExprPostUpdates));
18297 }
18298
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18299 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18300 SourceLocation StartLoc,
18301 SourceLocation LParenLoc,
18302 SourceLocation EndLoc) {
18303 SmallVector<Expr *, 8> Vars;
18304 for (Expr *RefExpr : VarList) {
18305 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18306 SourceLocation ELoc;
18307 SourceRange ERange;
18308 Expr *SimpleRefExpr = RefExpr;
18309 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18310 if (Res.second) {
18311 // It will be analyzed later.
18312 Vars.push_back(RefExpr);
18313 }
18314 ValueDecl *D = Res.first;
18315 if (!D)
18316 continue;
18317
18318 auto *VD = dyn_cast<VarDecl>(D);
18319 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18320 // in a Construct]
18321 // Variables with the predetermined data-sharing attributes may not be
18322 // listed in data-sharing attributes clauses, except for the cases
18323 // listed below. For these exceptions only, listing a predetermined
18324 // variable in a data-sharing attribute clause is allowed and overrides
18325 // the variable's predetermined data-sharing attributes.
18326 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18327 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18328 DVar.RefExpr) {
18329 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18330 << getOpenMPClauseName(OMPC_shared);
18331 reportOriginalDsa(*this, DSAStack, D, DVar);
18332 continue;
18333 }
18334
18335 DeclRefExpr *Ref = nullptr;
18336 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18337 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18338 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18339 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18340 ? RefExpr->IgnoreParens()
18341 : Ref);
18342 }
18343
18344 if (Vars.empty())
18345 return nullptr;
18346
18347 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18348 }
18349
18350 namespace {
18351 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18352 DSAStackTy *Stack;
18353
18354 public:
VisitDeclRefExpr(DeclRefExpr * E)18355 bool VisitDeclRefExpr(DeclRefExpr *E) {
18356 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18357 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18358 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18359 return false;
18360 if (DVar.CKind != OMPC_unknown)
18361 return true;
18362 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18363 VD,
18364 [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18365 return isOpenMPPrivate(C) && !AppliedToPointee;
18366 },
18367 [](OpenMPDirectiveKind) { return true; },
18368 /*FromParent=*/true);
18369 return DVarPrivate.CKind != OMPC_unknown;
18370 }
18371 return false;
18372 }
VisitStmt(Stmt * S)18373 bool VisitStmt(Stmt *S) {
18374 for (Stmt *Child : S->children()) {
18375 if (Child && Visit(Child))
18376 return true;
18377 }
18378 return false;
18379 }
DSARefChecker(DSAStackTy * S)18380 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18381 };
18382 } // namespace
18383
18384 namespace {
18385 // Transform MemberExpression for specified FieldDecl of current class to
18386 // DeclRefExpr to specified OMPCapturedExprDecl.
18387 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18388 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18389 ValueDecl *Field = nullptr;
18390 DeclRefExpr *CapturedExpr = nullptr;
18391
18392 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)18393 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18394 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18395
TransformMemberExpr(MemberExpr * E)18396 ExprResult TransformMemberExpr(MemberExpr *E) {
18397 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18398 E->getMemberDecl() == Field) {
18399 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18400 return CapturedExpr;
18401 }
18402 return BaseTransform::TransformMemberExpr(E);
18403 }
getCapturedExpr()18404 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18405 };
18406 } // namespace
18407
18408 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)18409 static T filterLookupForUDReductionAndMapper(
18410 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18411 for (U &Set : Lookups) {
18412 for (auto *D : Set) {
18413 if (T Res = Gen(cast<ValueDecl>(D)))
18414 return Res;
18415 }
18416 }
18417 return T();
18418 }
18419
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)18420 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
18421 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
18422
18423 for (auto RD : D->redecls()) {
18424 // Don't bother with extra checks if we already know this one isn't visible.
18425 if (RD == D)
18426 continue;
18427
18428 auto ND = cast<NamedDecl>(RD);
18429 if (LookupResult::isVisible(SemaRef, ND))
18430 return ND;
18431 }
18432
18433 return nullptr;
18434 }
18435
18436 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)18437 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
18438 SourceLocation Loc, QualType Ty,
18439 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18440 // Find all of the associated namespaces and classes based on the
18441 // arguments we have.
18442 Sema::AssociatedNamespaceSet AssociatedNamespaces;
18443 Sema::AssociatedClassSet AssociatedClasses;
18444 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18445 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18446 AssociatedClasses);
18447
18448 // C++ [basic.lookup.argdep]p3:
18449 // Let X be the lookup set produced by unqualified lookup (3.4.1)
18450 // and let Y be the lookup set produced by argument dependent
18451 // lookup (defined as follows). If X contains [...] then Y is
18452 // empty. Otherwise Y is the set of declarations found in the
18453 // namespaces associated with the argument types as described
18454 // below. The set of declarations found by the lookup of the name
18455 // is the union of X and Y.
18456 //
18457 // Here, we compute Y and add its members to the overloaded
18458 // candidate set.
18459 for (auto *NS : AssociatedNamespaces) {
18460 // When considering an associated namespace, the lookup is the
18461 // same as the lookup performed when the associated namespace is
18462 // used as a qualifier (3.4.3.2) except that:
18463 //
18464 // -- Any using-directives in the associated namespace are
18465 // ignored.
18466 //
18467 // -- Any namespace-scope friend functions declared in
18468 // associated classes are visible within their respective
18469 // namespaces even if they are not visible during an ordinary
18470 // lookup (11.4).
18471 DeclContext::lookup_result R = NS->lookup(Id.getName());
18472 for (auto *D : R) {
18473 auto *Underlying = D;
18474 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18475 Underlying = USD->getTargetDecl();
18476
18477 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18478 !isa<OMPDeclareMapperDecl>(Underlying))
18479 continue;
18480
18481 if (!SemaRef.isVisible(D)) {
18482 D = findAcceptableDecl(SemaRef, D);
18483 if (!D)
18484 continue;
18485 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18486 Underlying = USD->getTargetDecl();
18487 }
18488 Lookups.emplace_back();
18489 Lookups.back().addDecl(Underlying);
18490 }
18491 }
18492 }
18493
18494 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)18495 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
18496 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
18497 const DeclarationNameInfo &ReductionId, QualType Ty,
18498 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
18499 if (ReductionIdScopeSpec.isInvalid())
18500 return ExprError();
18501 SmallVector<UnresolvedSet<8>, 4> Lookups;
18502 if (S) {
18503 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18504 Lookup.suppressDiagnostics();
18505 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
18506 NamedDecl *D = Lookup.getRepresentativeDecl();
18507 do {
18508 S = S->getParent();
18509 } while (S && !S->isDeclScope(D));
18510 if (S)
18511 S = S->getParent();
18512 Lookups.emplace_back();
18513 Lookups.back().append(Lookup.begin(), Lookup.end());
18514 Lookup.clear();
18515 }
18516 } else if (auto *ULE =
18517 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18518 Lookups.push_back(UnresolvedSet<8>());
18519 Decl *PrevD = nullptr;
18520 for (NamedDecl *D : ULE->decls()) {
18521 if (D == PrevD)
18522 Lookups.push_back(UnresolvedSet<8>());
18523 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18524 Lookups.back().addDecl(DRD);
18525 PrevD = D;
18526 }
18527 }
18528 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
18529 Ty->isInstantiationDependentType() ||
18530 Ty->containsUnexpandedParameterPack() ||
18531 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18532 return !D->isInvalidDecl() &&
18533 (D->getType()->isDependentType() ||
18534 D->getType()->isInstantiationDependentType() ||
18535 D->getType()->containsUnexpandedParameterPack());
18536 })) {
18537 UnresolvedSet<8> ResSet;
18538 for (const UnresolvedSet<8> &Set : Lookups) {
18539 if (Set.empty())
18540 continue;
18541 ResSet.append(Set.begin(), Set.end());
18542 // The last item marks the end of all declarations at the specified scope.
18543 ResSet.addDecl(Set[Set.size() - 1]);
18544 }
18545 return UnresolvedLookupExpr::Create(
18546 SemaRef.Context, /*NamingClass=*/nullptr,
18547 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
18548 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
18549 }
18550 // Lookup inside the classes.
18551 // C++ [over.match.oper]p3:
18552 // For a unary operator @ with an operand of a type whose
18553 // cv-unqualified version is T1, and for a binary operator @ with
18554 // a left operand of a type whose cv-unqualified version is T1 and
18555 // a right operand of a type whose cv-unqualified version is T2,
18556 // three sets of candidate functions, designated member
18557 // candidates, non-member candidates and built-in candidates, are
18558 // constructed as follows:
18559 // -- If T1 is a complete class type or a class currently being
18560 // defined, the set of member candidates is the result of the
18561 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18562 // the set of member candidates is empty.
18563 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18564 Lookup.suppressDiagnostics();
18565 if (const auto *TyRec = Ty->getAs<RecordType>()) {
18566 // Complete the type if it can be completed.
18567 // If the type is neither complete nor being defined, bail out now.
18568 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18569 TyRec->getDecl()->getDefinition()) {
18570 Lookup.clear();
18571 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
18572 if (Lookup.empty()) {
18573 Lookups.emplace_back();
18574 Lookups.back().append(Lookup.begin(), Lookup.end());
18575 }
18576 }
18577 }
18578 // Perform ADL.
18579 if (SemaRef.getLangOpts().CPlusPlus)
18580 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18581 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18582 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18583 if (!D->isInvalidDecl() &&
18584 SemaRef.Context.hasSameType(D->getType(), Ty))
18585 return D;
18586 return nullptr;
18587 }))
18588 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18589 VK_LValue, Loc);
18590 if (SemaRef.getLangOpts().CPlusPlus) {
18591 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18592 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18593 if (!D->isInvalidDecl() &&
18594 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18595 !Ty.isMoreQualifiedThan(D->getType()))
18596 return D;
18597 return nullptr;
18598 })) {
18599 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18600 /*DetectVirtual=*/false);
18601 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18602 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18603 VD->getType().getUnqualifiedType()))) {
18604 if (SemaRef.CheckBaseClassAccess(
18605 Loc, VD->getType(), Ty, Paths.front(),
18606 /*DiagID=*/0) != Sema::AR_inaccessible) {
18607 SemaRef.BuildBasePathArray(Paths, BasePath);
18608 return SemaRef.BuildDeclRefExpr(
18609 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18610 }
18611 }
18612 }
18613 }
18614 }
18615 if (ReductionIdScopeSpec.isSet()) {
18616 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18617 << Ty << Range;
18618 return ExprError();
18619 }
18620 return ExprEmpty();
18621 }
18622
18623 namespace {
18624 /// Data for the reduction-based clauses.
18625 struct ReductionData {
18626 /// List of original reduction items.
18627 SmallVector<Expr *, 8> Vars;
18628 /// List of private copies of the reduction items.
18629 SmallVector<Expr *, 8> Privates;
18630 /// LHS expressions for the reduction_op expressions.
18631 SmallVector<Expr *, 8> LHSs;
18632 /// RHS expressions for the reduction_op expressions.
18633 SmallVector<Expr *, 8> RHSs;
18634 /// Reduction operation expression.
18635 SmallVector<Expr *, 8> ReductionOps;
18636 /// inscan copy operation expressions.
18637 SmallVector<Expr *, 8> InscanCopyOps;
18638 /// inscan copy temp array expressions for prefix sums.
18639 SmallVector<Expr *, 8> InscanCopyArrayTemps;
18640 /// inscan copy temp array element expressions for prefix sums.
18641 SmallVector<Expr *, 8> InscanCopyArrayElems;
18642 /// Taskgroup descriptors for the corresponding reduction items in
18643 /// in_reduction clauses.
18644 SmallVector<Expr *, 8> TaskgroupDescriptors;
18645 /// List of captures for clause.
18646 SmallVector<Decl *, 4> ExprCaptures;
18647 /// List of postupdate expressions.
18648 SmallVector<Expr *, 4> ExprPostUpdates;
18649 /// Reduction modifier.
18650 unsigned RedModifier = 0;
18651 ReductionData() = delete;
18652 /// Reserves required memory for the reduction data.
ReductionData__anon296aa5745b11::ReductionData18653 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18654 Vars.reserve(Size);
18655 Privates.reserve(Size);
18656 LHSs.reserve(Size);
18657 RHSs.reserve(Size);
18658 ReductionOps.reserve(Size);
18659 if (RedModifier == OMPC_REDUCTION_inscan) {
18660 InscanCopyOps.reserve(Size);
18661 InscanCopyArrayTemps.reserve(Size);
18662 InscanCopyArrayElems.reserve(Size);
18663 }
18664 TaskgroupDescriptors.reserve(Size);
18665 ExprCaptures.reserve(Size);
18666 ExprPostUpdates.reserve(Size);
18667 }
18668 /// Stores reduction item and reduction operation only (required for dependent
18669 /// reduction item).
push__anon296aa5745b11::ReductionData18670 void push(Expr *Item, Expr *ReductionOp) {
18671 Vars.emplace_back(Item);
18672 Privates.emplace_back(nullptr);
18673 LHSs.emplace_back(nullptr);
18674 RHSs.emplace_back(nullptr);
18675 ReductionOps.emplace_back(ReductionOp);
18676 TaskgroupDescriptors.emplace_back(nullptr);
18677 if (RedModifier == OMPC_REDUCTION_inscan) {
18678 InscanCopyOps.push_back(nullptr);
18679 InscanCopyArrayTemps.push_back(nullptr);
18680 InscanCopyArrayElems.push_back(nullptr);
18681 }
18682 }
18683 /// Stores reduction data.
push__anon296aa5745b11::ReductionData18684 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18685 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18686 Expr *CopyArrayElem) {
18687 Vars.emplace_back(Item);
18688 Privates.emplace_back(Private);
18689 LHSs.emplace_back(LHS);
18690 RHSs.emplace_back(RHS);
18691 ReductionOps.emplace_back(ReductionOp);
18692 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18693 if (RedModifier == OMPC_REDUCTION_inscan) {
18694 InscanCopyOps.push_back(CopyOp);
18695 InscanCopyArrayTemps.push_back(CopyArrayTemp);
18696 InscanCopyArrayElems.push_back(CopyArrayElem);
18697 } else {
18698 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
18699 CopyArrayElem == nullptr &&
18700 "Copy operation must be used for inscan reductions only.");
18701 }
18702 }
18703 };
18704 } // namespace
18705
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)18706 static bool checkOMPArraySectionConstantForReduction(
18707 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
18708 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
18709 const Expr *Length = OASE->getLength();
18710 if (Length == nullptr) {
18711 // For array sections of the form [1:] or [:], we would need to analyze
18712 // the lower bound...
18713 if (OASE->getColonLocFirst().isValid())
18714 return false;
18715
18716 // This is an array subscript which has implicit length 1!
18717 SingleElement = true;
18718 ArraySizes.push_back(llvm::APSInt::get(1));
18719 } else {
18720 Expr::EvalResult Result;
18721 if (!Length->EvaluateAsInt(Result, Context))
18722 return false;
18723
18724 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18725 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18726 ArraySizes.push_back(ConstantLengthValue);
18727 }
18728
18729 // Get the base of this array section and walk up from there.
18730 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
18731
18732 // We require length = 1 for all array sections except the right-most to
18733 // guarantee that the memory region is contiguous and has no holes in it.
18734 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
18735 Length = TempOASE->getLength();
18736 if (Length == nullptr) {
18737 // For array sections of the form [1:] or [:], we would need to analyze
18738 // the lower bound...
18739 if (OASE->getColonLocFirst().isValid())
18740 return false;
18741
18742 // This is an array subscript which has implicit length 1!
18743 ArraySizes.push_back(llvm::APSInt::get(1));
18744 } else {
18745 Expr::EvalResult Result;
18746 if (!Length->EvaluateAsInt(Result, Context))
18747 return false;
18748
18749 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18750 if (ConstantLengthValue.getSExtValue() != 1)
18751 return false;
18752
18753 ArraySizes.push_back(ConstantLengthValue);
18754 }
18755 Base = TempOASE->getBase()->IgnoreParenImpCasts();
18756 }
18757
18758 // If we have a single element, we don't need to add the implicit lengths.
18759 if (!SingleElement) {
18760 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
18761 // Has implicit length 1!
18762 ArraySizes.push_back(llvm::APSInt::get(1));
18763 Base = TempASE->getBase()->IgnoreParenImpCasts();
18764 }
18765 }
18766
18767 // This array section can be privatized as a single value or as a constant
18768 // sized array.
18769 return true;
18770 }
18771
18772 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)18773 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
18774 if (BOK == BO_Add)
18775 return BO_AddAssign;
18776 if (BOK == BO_Mul)
18777 return BO_MulAssign;
18778 if (BOK == BO_And)
18779 return BO_AndAssign;
18780 if (BOK == BO_Or)
18781 return BO_OrAssign;
18782 if (BOK == BO_Xor)
18783 return BO_XorAssign;
18784 return BOK;
18785 }
18786
actOnOMPReductionKindClause(Sema & S,DSAStackTy * Stack,OpenMPClauseKind ClauseKind,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions,ReductionData & RD)18787 static bool actOnOMPReductionKindClause(
18788 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
18789 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18790 SourceLocation ColonLoc, SourceLocation EndLoc,
18791 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18792 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
18793 DeclarationName DN = ReductionId.getName();
18794 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
18795 BinaryOperatorKind BOK = BO_Comma;
18796
18797 ASTContext &Context = S.Context;
18798 // OpenMP [2.14.3.6, reduction clause]
18799 // C
18800 // reduction-identifier is either an identifier or one of the following
18801 // operators: +, -, *, &, |, ^, && and ||
18802 // C++
18803 // reduction-identifier is either an id-expression or one of the following
18804 // operators: +, -, *, &, |, ^, && and ||
18805 switch (OOK) {
18806 case OO_Plus:
18807 case OO_Minus:
18808 BOK = BO_Add;
18809 break;
18810 case OO_Star:
18811 BOK = BO_Mul;
18812 break;
18813 case OO_Amp:
18814 BOK = BO_And;
18815 break;
18816 case OO_Pipe:
18817 BOK = BO_Or;
18818 break;
18819 case OO_Caret:
18820 BOK = BO_Xor;
18821 break;
18822 case OO_AmpAmp:
18823 BOK = BO_LAnd;
18824 break;
18825 case OO_PipePipe:
18826 BOK = BO_LOr;
18827 break;
18828 case OO_New:
18829 case OO_Delete:
18830 case OO_Array_New:
18831 case OO_Array_Delete:
18832 case OO_Slash:
18833 case OO_Percent:
18834 case OO_Tilde:
18835 case OO_Exclaim:
18836 case OO_Equal:
18837 case OO_Less:
18838 case OO_Greater:
18839 case OO_LessEqual:
18840 case OO_GreaterEqual:
18841 case OO_PlusEqual:
18842 case OO_MinusEqual:
18843 case OO_StarEqual:
18844 case OO_SlashEqual:
18845 case OO_PercentEqual:
18846 case OO_CaretEqual:
18847 case OO_AmpEqual:
18848 case OO_PipeEqual:
18849 case OO_LessLess:
18850 case OO_GreaterGreater:
18851 case OO_LessLessEqual:
18852 case OO_GreaterGreaterEqual:
18853 case OO_EqualEqual:
18854 case OO_ExclaimEqual:
18855 case OO_Spaceship:
18856 case OO_PlusPlus:
18857 case OO_MinusMinus:
18858 case OO_Comma:
18859 case OO_ArrowStar:
18860 case OO_Arrow:
18861 case OO_Call:
18862 case OO_Subscript:
18863 case OO_Conditional:
18864 case OO_Coawait:
18865 case NUM_OVERLOADED_OPERATORS:
18866 llvm_unreachable("Unexpected reduction identifier");
18867 case OO_None:
18868 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
18869 if (II->isStr("max"))
18870 BOK = BO_GT;
18871 else if (II->isStr("min"))
18872 BOK = BO_LT;
18873 }
18874 break;
18875 }
18876 SourceRange ReductionIdRange;
18877 if (ReductionIdScopeSpec.isValid())
18878 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
18879 else
18880 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
18881 ReductionIdRange.setEnd(ReductionId.getEndLoc());
18882
18883 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18884 bool FirstIter = true;
18885 for (Expr *RefExpr : VarList) {
18886 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
18887 // OpenMP [2.1, C/C++]
18888 // A list item is a variable or array section, subject to the restrictions
18889 // specified in Section 2.4 on page 42 and in each of the sections
18890 // describing clauses and directives for which a list appears.
18891 // OpenMP [2.14.3.3, Restrictions, p.1]
18892 // A variable that is part of another variable (as an array or
18893 // structure element) cannot appear in a private clause.
18894 if (!FirstIter && IR != ER)
18895 ++IR;
18896 FirstIter = false;
18897 SourceLocation ELoc;
18898 SourceRange ERange;
18899 Expr *SimpleRefExpr = RefExpr;
18900 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
18901 /*AllowArraySection=*/true);
18902 if (Res.second) {
18903 // Try to find 'declare reduction' corresponding construct before using
18904 // builtin/overloaded operators.
18905 QualType Type = Context.DependentTy;
18906 CXXCastPath BasePath;
18907 ExprResult DeclareReductionRef = buildDeclareReductionRef(
18908 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18909 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18910 Expr *ReductionOp = nullptr;
18911 if (S.CurContext->isDependentContext() &&
18912 (DeclareReductionRef.isUnset() ||
18913 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
18914 ReductionOp = DeclareReductionRef.get();
18915 // It will be analyzed later.
18916 RD.push(RefExpr, ReductionOp);
18917 }
18918 ValueDecl *D = Res.first;
18919 if (!D)
18920 continue;
18921
18922 Expr *TaskgroupDescriptor = nullptr;
18923 QualType Type;
18924 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18925 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
18926 if (ASE) {
18927 Type = ASE->getType().getNonReferenceType();
18928 } else if (OASE) {
18929 QualType BaseType =
18930 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18931 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18932 Type = ATy->getElementType();
18933 else
18934 Type = BaseType->getPointeeType();
18935 Type = Type.getNonReferenceType();
18936 } else {
18937 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
18938 }
18939 auto *VD = dyn_cast<VarDecl>(D);
18940
18941 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18942 // A variable that appears in a private clause must not have an incomplete
18943 // type or a reference type.
18944 if (S.RequireCompleteType(ELoc, D->getType(),
18945 diag::err_omp_reduction_incomplete_type))
18946 continue;
18947 // OpenMP [2.14.3.6, reduction clause, Restrictions]
18948 // A list item that appears in a reduction clause must not be
18949 // const-qualified.
18950 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
18951 /*AcceptIfMutable*/ false, ASE || OASE))
18952 continue;
18953
18954 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18955 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18956 // If a list-item is a reference type then it must bind to the same object
18957 // for all threads of the team.
18958 if (!ASE && !OASE) {
18959 if (VD) {
18960 VarDecl *VDDef = VD->getDefinition();
18961 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
18962 DSARefChecker Check(Stack);
18963 if (Check.Visit(VDDef->getInit())) {
18964 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18965 << getOpenMPClauseName(ClauseKind) << ERange;
18966 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
18967 continue;
18968 }
18969 }
18970 }
18971
18972 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18973 // in a Construct]
18974 // Variables with the predetermined data-sharing attributes may not be
18975 // listed in data-sharing attributes clauses, except for the cases
18976 // listed below. For these exceptions only, listing a predetermined
18977 // variable in a data-sharing attribute clause is allowed and overrides
18978 // the variable's predetermined data-sharing attributes.
18979 // OpenMP [2.14.3.6, Restrictions, p.3]
18980 // Any number of reduction clauses can be specified on the directive,
18981 // but a list item can appear only once in the reduction clauses for that
18982 // directive.
18983 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18984 if (DVar.CKind == OMPC_reduction) {
18985 S.Diag(ELoc, diag::err_omp_once_referenced)
18986 << getOpenMPClauseName(ClauseKind);
18987 if (DVar.RefExpr)
18988 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
18989 continue;
18990 }
18991 if (DVar.CKind != OMPC_unknown) {
18992 S.Diag(ELoc, diag::err_omp_wrong_dsa)
18993 << getOpenMPClauseName(DVar.CKind)
18994 << getOpenMPClauseName(OMPC_reduction);
18995 reportOriginalDsa(S, Stack, D, DVar);
18996 continue;
18997 }
18998
18999 // OpenMP [2.14.3.6, Restrictions, p.1]
19000 // A list item that appears in a reduction clause of a worksharing
19001 // construct must be shared in the parallel regions to which any of the
19002 // worksharing regions arising from the worksharing construct bind.
19003 if (isOpenMPWorksharingDirective(CurrDir) &&
19004 !isOpenMPParallelDirective(CurrDir) &&
19005 !isOpenMPTeamsDirective(CurrDir)) {
19006 DVar = Stack->getImplicitDSA(D, true);
19007 if (DVar.CKind != OMPC_shared) {
19008 S.Diag(ELoc, diag::err_omp_required_access)
19009 << getOpenMPClauseName(OMPC_reduction)
19010 << getOpenMPClauseName(OMPC_shared);
19011 reportOriginalDsa(S, Stack, D, DVar);
19012 continue;
19013 }
19014 }
19015 } else {
19016 // Threadprivates cannot be shared between threads, so dignose if the base
19017 // is a threadprivate variable.
19018 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19019 if (DVar.CKind == OMPC_threadprivate) {
19020 S.Diag(ELoc, diag::err_omp_wrong_dsa)
19021 << getOpenMPClauseName(DVar.CKind)
19022 << getOpenMPClauseName(OMPC_reduction);
19023 reportOriginalDsa(S, Stack, D, DVar);
19024 continue;
19025 }
19026 }
19027
19028 // Try to find 'declare reduction' corresponding construct before using
19029 // builtin/overloaded operators.
19030 CXXCastPath BasePath;
19031 ExprResult DeclareReductionRef = buildDeclareReductionRef(
19032 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19033 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19034 if (DeclareReductionRef.isInvalid())
19035 continue;
19036 if (S.CurContext->isDependentContext() &&
19037 (DeclareReductionRef.isUnset() ||
19038 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19039 RD.push(RefExpr, DeclareReductionRef.get());
19040 continue;
19041 }
19042 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19043 // Not allowed reduction identifier is found.
19044 S.Diag(ReductionId.getBeginLoc(),
19045 diag::err_omp_unknown_reduction_identifier)
19046 << Type << ReductionIdRange;
19047 continue;
19048 }
19049
19050 // OpenMP [2.14.3.6, reduction clause, Restrictions]
19051 // The type of a list item that appears in a reduction clause must be valid
19052 // for the reduction-identifier. For a max or min reduction in C, the type
19053 // of the list item must be an allowed arithmetic data type: char, int,
19054 // float, double, or _Bool, possibly modified with long, short, signed, or
19055 // unsigned. For a max or min reduction in C++, the type of the list item
19056 // must be an allowed arithmetic data type: char, wchar_t, int, float,
19057 // double, or bool, possibly modified with long, short, signed, or unsigned.
19058 if (DeclareReductionRef.isUnset()) {
19059 if ((BOK == BO_GT || BOK == BO_LT) &&
19060 !(Type->isScalarType() ||
19061 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19062 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19063 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19064 if (!ASE && !OASE) {
19065 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19066 VarDecl::DeclarationOnly;
19067 S.Diag(D->getLocation(),
19068 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19069 << D;
19070 }
19071 continue;
19072 }
19073 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19074 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19075 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19076 << getOpenMPClauseName(ClauseKind);
19077 if (!ASE && !OASE) {
19078 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19079 VarDecl::DeclarationOnly;
19080 S.Diag(D->getLocation(),
19081 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19082 << D;
19083 }
19084 continue;
19085 }
19086 }
19087
19088 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19089 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19090 D->hasAttrs() ? &D->getAttrs() : nullptr);
19091 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19092 D->hasAttrs() ? &D->getAttrs() : nullptr);
19093 QualType PrivateTy = Type;
19094
19095 // Try if we can determine constant lengths for all array sections and avoid
19096 // the VLA.
19097 bool ConstantLengthOASE = false;
19098 if (OASE) {
19099 bool SingleElement;
19100 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19101 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19102 Context, OASE, SingleElement, ArraySizes);
19103
19104 // If we don't have a single element, we must emit a constant array type.
19105 if (ConstantLengthOASE && !SingleElement) {
19106 for (llvm::APSInt &Size : ArraySizes)
19107 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19108 ArrayType::Normal,
19109 /*IndexTypeQuals=*/0);
19110 }
19111 }
19112
19113 if ((OASE && !ConstantLengthOASE) ||
19114 (!OASE && !ASE &&
19115 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19116 if (!Context.getTargetInfo().isVLASupported()) {
19117 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19118 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19119 S.Diag(ELoc, diag::note_vla_unsupported);
19120 continue;
19121 } else {
19122 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19123 S.targetDiag(ELoc, diag::note_vla_unsupported);
19124 }
19125 }
19126 // For arrays/array sections only:
19127 // Create pseudo array type for private copy. The size for this array will
19128 // be generated during codegen.
19129 // For array subscripts or single variables Private Ty is the same as Type
19130 // (type of the variable or single array element).
19131 PrivateTy = Context.getVariableArrayType(
19132 Type,
19133 new (Context)
19134 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19135 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
19136 } else if (!ASE && !OASE &&
19137 Context.getAsArrayType(D->getType().getNonReferenceType())) {
19138 PrivateTy = D->getType().getNonReferenceType();
19139 }
19140 // Private copy.
19141 VarDecl *PrivateVD =
19142 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19143 D->hasAttrs() ? &D->getAttrs() : nullptr,
19144 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19145 // Add initializer for private variable.
19146 Expr *Init = nullptr;
19147 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19148 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19149 if (DeclareReductionRef.isUsable()) {
19150 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19151 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19152 if (DRD->getInitializer()) {
19153 Init = DRDRef;
19154 RHSVD->setInit(DRDRef);
19155 RHSVD->setInitStyle(VarDecl::CallInit);
19156 }
19157 } else {
19158 switch (BOK) {
19159 case BO_Add:
19160 case BO_Xor:
19161 case BO_Or:
19162 case BO_LOr:
19163 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19164 if (Type->isScalarType() || Type->isAnyComplexType())
19165 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19166 break;
19167 case BO_Mul:
19168 case BO_LAnd:
19169 if (Type->isScalarType() || Type->isAnyComplexType()) {
19170 // '*' and '&&' reduction ops - initializer is '1'.
19171 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19172 }
19173 break;
19174 case BO_And: {
19175 // '&' reduction op - initializer is '~0'.
19176 QualType OrigType = Type;
19177 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19178 Type = ComplexTy->getElementType();
19179 if (Type->isRealFloatingType()) {
19180 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19181 Context.getFloatTypeSemantics(Type));
19182 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19183 Type, ELoc);
19184 } else if (Type->isScalarType()) {
19185 uint64_t Size = Context.getTypeSize(Type);
19186 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19187 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19188 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19189 }
19190 if (Init && OrigType->isAnyComplexType()) {
19191 // Init = 0xFFFF + 0xFFFFi;
19192 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19193 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19194 }
19195 Type = OrigType;
19196 break;
19197 }
19198 case BO_LT:
19199 case BO_GT: {
19200 // 'min' reduction op - initializer is 'Largest representable number in
19201 // the reduction list item type'.
19202 // 'max' reduction op - initializer is 'Least representable number in
19203 // the reduction list item type'.
19204 if (Type->isIntegerType() || Type->isPointerType()) {
19205 bool IsSigned = Type->hasSignedIntegerRepresentation();
19206 uint64_t Size = Context.getTypeSize(Type);
19207 QualType IntTy =
19208 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19209 llvm::APInt InitValue =
19210 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19211 : llvm::APInt::getMinValue(Size)
19212 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19213 : llvm::APInt::getMaxValue(Size);
19214 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19215 if (Type->isPointerType()) {
19216 // Cast to pointer type.
19217 ExprResult CastExpr = S.BuildCStyleCastExpr(
19218 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19219 if (CastExpr.isInvalid())
19220 continue;
19221 Init = CastExpr.get();
19222 }
19223 } else if (Type->isRealFloatingType()) {
19224 llvm::APFloat InitValue = llvm::APFloat::getLargest(
19225 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19226 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19227 Type, ELoc);
19228 }
19229 break;
19230 }
19231 case BO_PtrMemD:
19232 case BO_PtrMemI:
19233 case BO_MulAssign:
19234 case BO_Div:
19235 case BO_Rem:
19236 case BO_Sub:
19237 case BO_Shl:
19238 case BO_Shr:
19239 case BO_LE:
19240 case BO_GE:
19241 case BO_EQ:
19242 case BO_NE:
19243 case BO_Cmp:
19244 case BO_AndAssign:
19245 case BO_XorAssign:
19246 case BO_OrAssign:
19247 case BO_Assign:
19248 case BO_AddAssign:
19249 case BO_SubAssign:
19250 case BO_DivAssign:
19251 case BO_RemAssign:
19252 case BO_ShlAssign:
19253 case BO_ShrAssign:
19254 case BO_Comma:
19255 llvm_unreachable("Unexpected reduction operation");
19256 }
19257 }
19258 if (Init && DeclareReductionRef.isUnset()) {
19259 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19260 // Store initializer for single element in private copy. Will be used
19261 // during codegen.
19262 PrivateVD->setInit(RHSVD->getInit());
19263 PrivateVD->setInitStyle(RHSVD->getInitStyle());
19264 } else if (!Init) {
19265 S.ActOnUninitializedDecl(RHSVD);
19266 // Store initializer for single element in private copy. Will be used
19267 // during codegen.
19268 PrivateVD->setInit(RHSVD->getInit());
19269 PrivateVD->setInitStyle(RHSVD->getInitStyle());
19270 }
19271 if (RHSVD->isInvalidDecl())
19272 continue;
19273 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19274 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19275 << Type << ReductionIdRange;
19276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19277 VarDecl::DeclarationOnly;
19278 S.Diag(D->getLocation(),
19279 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19280 << D;
19281 continue;
19282 }
19283 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19284 ExprResult ReductionOp;
19285 if (DeclareReductionRef.isUsable()) {
19286 QualType RedTy = DeclareReductionRef.get()->getType();
19287 QualType PtrRedTy = Context.getPointerType(RedTy);
19288 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19289 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19290 if (!BasePath.empty()) {
19291 LHS = S.DefaultLvalueConversion(LHS.get());
19292 RHS = S.DefaultLvalueConversion(RHS.get());
19293 LHS = ImplicitCastExpr::Create(
19294 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19295 LHS.get()->getValueKind(), FPOptionsOverride());
19296 RHS = ImplicitCastExpr::Create(
19297 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19298 RHS.get()->getValueKind(), FPOptionsOverride());
19299 }
19300 FunctionProtoType::ExtProtoInfo EPI;
19301 QualType Params[] = {PtrRedTy, PtrRedTy};
19302 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19303 auto *OVE = new (Context) OpaqueValueExpr(
19304 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19305 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19306 Expr *Args[] = {LHS.get(), RHS.get()};
19307 ReductionOp =
19308 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19309 S.CurFPFeatureOverrides());
19310 } else {
19311 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19312 if (Type->isRecordType() && CombBOK != BOK) {
19313 Sema::TentativeAnalysisScope Trap(S);
19314 ReductionOp =
19315 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19316 CombBOK, LHSDRE, RHSDRE);
19317 }
19318 if (!ReductionOp.isUsable()) {
19319 ReductionOp =
19320 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19321 LHSDRE, RHSDRE);
19322 if (ReductionOp.isUsable()) {
19323 if (BOK != BO_LT && BOK != BO_GT) {
19324 ReductionOp =
19325 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19326 BO_Assign, LHSDRE, ReductionOp.get());
19327 } else {
19328 auto *ConditionalOp = new (Context)
19329 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19330 RHSDRE, Type, VK_LValue, OK_Ordinary);
19331 ReductionOp =
19332 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19333 BO_Assign, LHSDRE, ConditionalOp);
19334 }
19335 }
19336 }
19337 if (ReductionOp.isUsable())
19338 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19339 /*DiscardedValue*/ false);
19340 if (!ReductionOp.isUsable())
19341 continue;
19342 }
19343
19344 // Add copy operations for inscan reductions.
19345 // LHS = RHS;
19346 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19347 if (ClauseKind == OMPC_reduction &&
19348 RD.RedModifier == OMPC_REDUCTION_inscan) {
19349 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19350 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19351 RHS.get());
19352 if (!CopyOpRes.isUsable())
19353 continue;
19354 CopyOpRes =
19355 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19356 if (!CopyOpRes.isUsable())
19357 continue;
19358 // For simd directive and simd-based directives in simd mode no need to
19359 // construct temp array, need just a single temp element.
19360 if (Stack->getCurrentDirective() == OMPD_simd ||
19361 (S.getLangOpts().OpenMPSimd &&
19362 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
19363 VarDecl *TempArrayVD =
19364 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19365 D->hasAttrs() ? &D->getAttrs() : nullptr);
19366 // Add a constructor to the temp decl.
19367 S.ActOnUninitializedDecl(TempArrayVD);
19368 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19369 } else {
19370 // Build temp array for prefix sum.
19371 auto *Dim = new (S.Context)
19372 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19373 QualType ArrayTy =
19374 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
19375 /*IndexTypeQuals=*/0, {ELoc, ELoc});
19376 VarDecl *TempArrayVD =
19377 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19378 D->hasAttrs() ? &D->getAttrs() : nullptr);
19379 // Add a constructor to the temp decl.
19380 S.ActOnUninitializedDecl(TempArrayVD);
19381 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19382 TempArrayElem =
19383 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19384 auto *Idx = new (S.Context)
19385 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19386 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19387 ELoc, Idx, ELoc);
19388 }
19389 }
19390
19391 // OpenMP [2.15.4.6, Restrictions, p.2]
19392 // A list item that appears in an in_reduction clause of a task construct
19393 // must appear in a task_reduction clause of a construct associated with a
19394 // taskgroup region that includes the participating task in its taskgroup
19395 // set. The construct associated with the innermost region that meets this
19396 // condition must specify the same reduction-identifier as the in_reduction
19397 // clause.
19398 if (ClauseKind == OMPC_in_reduction) {
19399 SourceRange ParentSR;
19400 BinaryOperatorKind ParentBOK;
19401 const Expr *ParentReductionOp = nullptr;
19402 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19403 DSAStackTy::DSAVarData ParentBOKDSA =
19404 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19405 ParentBOKTD);
19406 DSAStackTy::DSAVarData ParentReductionOpDSA =
19407 Stack->getTopMostTaskgroupReductionData(
19408 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19409 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19410 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19411 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
19412 (DeclareReductionRef.isUsable() && IsParentBOK) ||
19413 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19414 bool EmitError = true;
19415 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
19416 llvm::FoldingSetNodeID RedId, ParentRedId;
19417 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19418 DeclareReductionRef.get()->Profile(RedId, Context,
19419 /*Canonical=*/true);
19420 EmitError = RedId != ParentRedId;
19421 }
19422 if (EmitError) {
19423 S.Diag(ReductionId.getBeginLoc(),
19424 diag::err_omp_reduction_identifier_mismatch)
19425 << ReductionIdRange << RefExpr->getSourceRange();
19426 S.Diag(ParentSR.getBegin(),
19427 diag::note_omp_previous_reduction_identifier)
19428 << ParentSR
19429 << (IsParentBOK ? ParentBOKDSA.RefExpr
19430 : ParentReductionOpDSA.RefExpr)
19431 ->getSourceRange();
19432 continue;
19433 }
19434 }
19435 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19436 }
19437
19438 DeclRefExpr *Ref = nullptr;
19439 Expr *VarsExpr = RefExpr->IgnoreParens();
19440 if (!VD && !S.CurContext->isDependentContext()) {
19441 if (ASE || OASE) {
19442 TransformExprToCaptures RebuildToCapture(S, D);
19443 VarsExpr =
19444 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19445 Ref = RebuildToCapture.getCapturedExpr();
19446 } else {
19447 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
19448 }
19449 if (!S.isOpenMPCapturedDecl(D)) {
19450 RD.ExprCaptures.emplace_back(Ref->getDecl());
19451 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19452 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
19453 if (!RefRes.isUsable())
19454 continue;
19455 ExprResult PostUpdateRes =
19456 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19457 RefRes.get());
19458 if (!PostUpdateRes.isUsable())
19459 continue;
19460 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
19461 Stack->getCurrentDirective() == OMPD_taskgroup) {
19462 S.Diag(RefExpr->getExprLoc(),
19463 diag::err_omp_reduction_non_addressable_expression)
19464 << RefExpr->getSourceRange();
19465 continue;
19466 }
19467 RD.ExprPostUpdates.emplace_back(
19468 S.IgnoredValueConversions(PostUpdateRes.get()).get());
19469 }
19470 }
19471 }
19472 // All reduction items are still marked as reduction (to do not increase
19473 // code base size).
19474 unsigned Modifier = RD.RedModifier;
19475 // Consider task_reductions as reductions with task modifier. Required for
19476 // correct analysis of in_reduction clauses.
19477 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19478 Modifier = OMPC_REDUCTION_task;
19479 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19480 ASE || OASE);
19481 if (Modifier == OMPC_REDUCTION_task &&
19482 (CurrDir == OMPD_taskgroup ||
19483 ((isOpenMPParallelDirective(CurrDir) ||
19484 isOpenMPWorksharingDirective(CurrDir)) &&
19485 !isOpenMPSimdDirective(CurrDir)))) {
19486 if (DeclareReductionRef.isUsable())
19487 Stack->addTaskgroupReductionData(D, ReductionIdRange,
19488 DeclareReductionRef.get());
19489 else
19490 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19491 }
19492 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
19493 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19494 TempArrayElem.get());
19495 }
19496 return RD.Vars.empty();
19497 }
19498
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)19499 OMPClause *Sema::ActOnOpenMPReductionClause(
19500 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
19501 SourceLocation StartLoc, SourceLocation LParenLoc,
19502 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
19503 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19504 ArrayRef<Expr *> UnresolvedReductions) {
19505 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
19506 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19507 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
19508 /*Last=*/OMPC_REDUCTION_unknown)
19509 << getOpenMPClauseName(OMPC_reduction);
19510 return nullptr;
19511 }
19512 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19513 // A reduction clause with the inscan reduction-modifier may only appear on a
19514 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19515 // construct, a parallel worksharing-loop construct or a parallel
19516 // worksharing-loop SIMD construct.
19517 if (Modifier == OMPC_REDUCTION_inscan &&
19518 (DSAStack->getCurrentDirective() != OMPD_for &&
19519 DSAStack->getCurrentDirective() != OMPD_for_simd &&
19520 DSAStack->getCurrentDirective() != OMPD_simd &&
19521 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
19522 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
19523 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19524 return nullptr;
19525 }
19526
19527 ReductionData RD(VarList.size(), Modifier);
19528 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
19529 StartLoc, LParenLoc, ColonLoc, EndLoc,
19530 ReductionIdScopeSpec, ReductionId,
19531 UnresolvedReductions, RD))
19532 return nullptr;
19533
19534 return OMPReductionClause::Create(
19535 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
19536 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19537 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19538 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19539 buildPreInits(Context, RD.ExprCaptures),
19540 buildPostUpdate(*this, RD.ExprPostUpdates));
19541 }
19542
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)19543 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
19544 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19545 SourceLocation ColonLoc, SourceLocation EndLoc,
19546 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19547 ArrayRef<Expr *> UnresolvedReductions) {
19548 ReductionData RD(VarList.size());
19549 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
19550 StartLoc, LParenLoc, ColonLoc, EndLoc,
19551 ReductionIdScopeSpec, ReductionId,
19552 UnresolvedReductions, RD))
19553 return nullptr;
19554
19555 return OMPTaskReductionClause::Create(
19556 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19557 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19558 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19559 buildPreInits(Context, RD.ExprCaptures),
19560 buildPostUpdate(*this, RD.ExprPostUpdates));
19561 }
19562
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)19563 OMPClause *Sema::ActOnOpenMPInReductionClause(
19564 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19565 SourceLocation ColonLoc, SourceLocation EndLoc,
19566 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19567 ArrayRef<Expr *> UnresolvedReductions) {
19568 ReductionData RD(VarList.size());
19569 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
19570 StartLoc, LParenLoc, ColonLoc, EndLoc,
19571 ReductionIdScopeSpec, ReductionId,
19572 UnresolvedReductions, RD))
19573 return nullptr;
19574
19575 return OMPInReductionClause::Create(
19576 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19577 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19578 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19579 buildPreInits(Context, RD.ExprCaptures),
19580 buildPostUpdate(*this, RD.ExprPostUpdates));
19581 }
19582
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)19583 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
19584 SourceLocation LinLoc) {
19585 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19586 LinKind == OMPC_LINEAR_unknown) {
19587 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19588 return true;
19589 }
19590 return false;
19591 }
19592
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)19593 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
19594 OpenMPLinearClauseKind LinKind, QualType Type,
19595 bool IsDeclareSimd) {
19596 const auto *VD = dyn_cast_or_null<VarDecl>(D);
19597 // A variable must not have an incomplete type or a reference type.
19598 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19599 return true;
19600 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19601 !Type->isReferenceType()) {
19602 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19603 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19604 return true;
19605 }
19606 Type = Type.getNonReferenceType();
19607
19608 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19609 // A variable that is privatized must not have a const-qualified type
19610 // unless it is of class type with a mutable member. This restriction does
19611 // not apply to the firstprivate clause, nor to the linear clause on
19612 // declarative directives (like declare simd).
19613 if (!IsDeclareSimd &&
19614 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19615 return true;
19616
19617 // A list item must be of integral or pointer type.
19618 Type = Type.getUnqualifiedType().getCanonicalType();
19619 const auto *Ty = Type.getTypePtrOrNull();
19620 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19621 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
19622 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19623 if (D) {
19624 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19625 VarDecl::DeclarationOnly;
19626 Diag(D->getLocation(),
19627 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19628 << D;
19629 }
19630 return true;
19631 }
19632 return false;
19633 }
19634
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)19635 OMPClause *Sema::ActOnOpenMPLinearClause(
19636 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19637 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19638 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19639 SmallVector<Expr *, 8> Vars;
19640 SmallVector<Expr *, 8> Privates;
19641 SmallVector<Expr *, 8> Inits;
19642 SmallVector<Decl *, 4> ExprCaptures;
19643 SmallVector<Expr *, 4> ExprPostUpdates;
19644 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19645 LinKind = OMPC_LINEAR_val;
19646 for (Expr *RefExpr : VarList) {
19647 assert(RefExpr && "NULL expr in OpenMP linear clause.");
19648 SourceLocation ELoc;
19649 SourceRange ERange;
19650 Expr *SimpleRefExpr = RefExpr;
19651 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19652 if (Res.second) {
19653 // It will be analyzed later.
19654 Vars.push_back(RefExpr);
19655 Privates.push_back(nullptr);
19656 Inits.push_back(nullptr);
19657 }
19658 ValueDecl *D = Res.first;
19659 if (!D)
19660 continue;
19661
19662 QualType Type = D->getType();
19663 auto *VD = dyn_cast<VarDecl>(D);
19664
19665 // OpenMP [2.14.3.7, linear clause]
19666 // A list-item cannot appear in more than one linear clause.
19667 // A list-item that appears in a linear clause cannot appear in any
19668 // other data-sharing attribute clause.
19669 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19670 if (DVar.RefExpr) {
19671 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19672 << getOpenMPClauseName(OMPC_linear);
19673 reportOriginalDsa(*this, DSAStack, D, DVar);
19674 continue;
19675 }
19676
19677 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19678 continue;
19679 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19680
19681 // Build private copy of original var.
19682 VarDecl *Private =
19683 buildVarDecl(*this, ELoc, Type, D->getName(),
19684 D->hasAttrs() ? &D->getAttrs() : nullptr,
19685 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19686 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
19687 // Build var to save initial value.
19688 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
19689 Expr *InitExpr;
19690 DeclRefExpr *Ref = nullptr;
19691 if (!VD && !CurContext->isDependentContext()) {
19692 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19693 if (!isOpenMPCapturedDecl(D)) {
19694 ExprCaptures.push_back(Ref->getDecl());
19695 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19696 ExprResult RefRes = DefaultLvalueConversion(Ref);
19697 if (!RefRes.isUsable())
19698 continue;
19699 ExprResult PostUpdateRes =
19700 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
19701 SimpleRefExpr, RefRes.get());
19702 if (!PostUpdateRes.isUsable())
19703 continue;
19704 ExprPostUpdates.push_back(
19705 IgnoredValueConversions(PostUpdateRes.get()).get());
19706 }
19707 }
19708 }
19709 if (LinKind == OMPC_LINEAR_uval)
19710 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19711 else
19712 InitExpr = VD ? SimpleRefExpr : Ref;
19713 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
19714 /*DirectInit=*/false);
19715 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
19716
19717 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19718 Vars.push_back((VD || CurContext->isDependentContext())
19719 ? RefExpr->IgnoreParens()
19720 : Ref);
19721 Privates.push_back(PrivateRef);
19722 Inits.push_back(InitRef);
19723 }
19724
19725 if (Vars.empty())
19726 return nullptr;
19727
19728 Expr *StepExpr = Step;
19729 Expr *CalcStepExpr = nullptr;
19730 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
19731 !Step->isInstantiationDependent() &&
19732 !Step->containsUnexpandedParameterPack()) {
19733 SourceLocation StepLoc = Step->getBeginLoc();
19734 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
19735 if (Val.isInvalid())
19736 return nullptr;
19737 StepExpr = Val.get();
19738
19739 // Build var to save the step value.
19740 VarDecl *SaveVar =
19741 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
19742 ExprResult SaveRef =
19743 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
19744 ExprResult CalcStep =
19745 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
19746 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
19747
19748 // Warn about zero linear step (it would be probably better specified as
19749 // making corresponding variables 'const').
19750 if (Optional<llvm::APSInt> Result =
19751 StepExpr->getIntegerConstantExpr(Context)) {
19752 if (!Result->isNegative() && !Result->isStrictlyPositive())
19753 Diag(StepLoc, diag::warn_omp_linear_step_zero)
19754 << Vars[0] << (Vars.size() > 1);
19755 } else if (CalcStep.isUsable()) {
19756 // Calculate the step beforehand instead of doing this on each iteration.
19757 // (This is not used if the number of iterations may be kfold-ed).
19758 CalcStepExpr = CalcStep.get();
19759 }
19760 }
19761
19762 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
19763 ColonLoc, EndLoc, Vars, Privates, Inits,
19764 StepExpr, CalcStepExpr,
19765 buildPreInits(Context, ExprCaptures),
19766 buildPostUpdate(*this, ExprPostUpdates));
19767 }
19768
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)19769 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
19770 Expr *NumIterations, Sema &SemaRef,
19771 Scope *S, DSAStackTy *Stack) {
19772 // Walk the vars and build update/final expressions for the CodeGen.
19773 SmallVector<Expr *, 8> Updates;
19774 SmallVector<Expr *, 8> Finals;
19775 SmallVector<Expr *, 8> UsedExprs;
19776 Expr *Step = Clause.getStep();
19777 Expr *CalcStep = Clause.getCalcStep();
19778 // OpenMP [2.14.3.7, linear clause]
19779 // If linear-step is not specified it is assumed to be 1.
19780 if (!Step)
19781 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
19782 else if (CalcStep)
19783 Step = cast<BinaryOperator>(CalcStep)->getLHS();
19784 bool HasErrors = false;
19785 auto CurInit = Clause.inits().begin();
19786 auto CurPrivate = Clause.privates().begin();
19787 OpenMPLinearClauseKind LinKind = Clause.getModifier();
19788 for (Expr *RefExpr : Clause.varlists()) {
19789 SourceLocation ELoc;
19790 SourceRange ERange;
19791 Expr *SimpleRefExpr = RefExpr;
19792 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19793 ValueDecl *D = Res.first;
19794 if (Res.second || !D) {
19795 Updates.push_back(nullptr);
19796 Finals.push_back(nullptr);
19797 HasErrors = true;
19798 continue;
19799 }
19800 auto &&Info = Stack->isLoopControlVariable(D);
19801 // OpenMP [2.15.11, distribute simd Construct]
19802 // A list item may not appear in a linear clause, unless it is the loop
19803 // iteration variable.
19804 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
19805 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
19806 SemaRef.Diag(ELoc,
19807 diag::err_omp_linear_distribute_var_non_loop_iteration);
19808 Updates.push_back(nullptr);
19809 Finals.push_back(nullptr);
19810 HasErrors = true;
19811 continue;
19812 }
19813 Expr *InitExpr = *CurInit;
19814
19815 // Build privatized reference to the current linear var.
19816 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
19817 Expr *CapturedRef;
19818 if (LinKind == OMPC_LINEAR_uval)
19819 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
19820 else
19821 CapturedRef =
19822 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
19823 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
19824 /*RefersToCapture=*/true);
19825
19826 // Build update: Var = InitExpr + IV * Step
19827 ExprResult Update;
19828 if (!Info.first)
19829 Update = buildCounterUpdate(
19830 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
19831 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
19832 else
19833 Update = *CurPrivate;
19834 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
19835 /*DiscardedValue*/ false);
19836
19837 // Build final: Var = PrivCopy;
19838 ExprResult Final;
19839 if (!Info.first)
19840 Final = SemaRef.BuildBinOp(
19841 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
19842 SemaRef.DefaultLvalueConversion(*CurPrivate).get());
19843 else
19844 Final = *CurPrivate;
19845 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
19846 /*DiscardedValue*/ false);
19847
19848 if (!Update.isUsable() || !Final.isUsable()) {
19849 Updates.push_back(nullptr);
19850 Finals.push_back(nullptr);
19851 UsedExprs.push_back(nullptr);
19852 HasErrors = true;
19853 } else {
19854 Updates.push_back(Update.get());
19855 Finals.push_back(Final.get());
19856 if (!Info.first)
19857 UsedExprs.push_back(SimpleRefExpr);
19858 }
19859 ++CurInit;
19860 ++CurPrivate;
19861 }
19862 if (Expr *S = Clause.getStep())
19863 UsedExprs.push_back(S);
19864 // Fill the remaining part with the nullptr.
19865 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
19866 Clause.setUpdates(Updates);
19867 Clause.setFinals(Finals);
19868 Clause.setUsedExprs(UsedExprs);
19869 return HasErrors;
19870 }
19871
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)19872 OMPClause *Sema::ActOnOpenMPAlignedClause(
19873 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
19874 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19875 SmallVector<Expr *, 8> Vars;
19876 for (Expr *RefExpr : VarList) {
19877 assert(RefExpr && "NULL expr in OpenMP linear clause.");
19878 SourceLocation ELoc;
19879 SourceRange ERange;
19880 Expr *SimpleRefExpr = RefExpr;
19881 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19882 if (Res.second) {
19883 // It will be analyzed later.
19884 Vars.push_back(RefExpr);
19885 }
19886 ValueDecl *D = Res.first;
19887 if (!D)
19888 continue;
19889
19890 QualType QType = D->getType();
19891 auto *VD = dyn_cast<VarDecl>(D);
19892
19893 // OpenMP [2.8.1, simd construct, Restrictions]
19894 // The type of list items appearing in the aligned clause must be
19895 // array, pointer, reference to array, or reference to pointer.
19896 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19897 const Type *Ty = QType.getTypePtrOrNull();
19898 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
19899 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19900 << QType << getLangOpts().CPlusPlus << ERange;
19901 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19902 VarDecl::DeclarationOnly;
19903 Diag(D->getLocation(),
19904 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19905 << D;
19906 continue;
19907 }
19908
19909 // OpenMP [2.8.1, simd construct, Restrictions]
19910 // A list-item cannot appear in more than one aligned clause.
19911 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
19912 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19913 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19914 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19915 << getOpenMPClauseName(OMPC_aligned);
19916 continue;
19917 }
19918
19919 DeclRefExpr *Ref = nullptr;
19920 if (!VD && isOpenMPCapturedDecl(D))
19921 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19922 Vars.push_back(DefaultFunctionArrayConversion(
19923 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19924 .get());
19925 }
19926
19927 // OpenMP [2.8.1, simd construct, Description]
19928 // The parameter of the aligned clause, alignment, must be a constant
19929 // positive integer expression.
19930 // If no optional parameter is specified, implementation-defined default
19931 // alignments for SIMD instructions on the target platforms are assumed.
19932 if (Alignment != nullptr) {
19933 ExprResult AlignResult =
19934 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19935 if (AlignResult.isInvalid())
19936 return nullptr;
19937 Alignment = AlignResult.get();
19938 }
19939 if (Vars.empty())
19940 return nullptr;
19941
19942 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19943 EndLoc, Vars, Alignment);
19944 }
19945
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19946 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
19947 SourceLocation StartLoc,
19948 SourceLocation LParenLoc,
19949 SourceLocation EndLoc) {
19950 SmallVector<Expr *, 8> Vars;
19951 SmallVector<Expr *, 8> SrcExprs;
19952 SmallVector<Expr *, 8> DstExprs;
19953 SmallVector<Expr *, 8> AssignmentOps;
19954 for (Expr *RefExpr : VarList) {
19955 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
19956 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19957 // It will be analyzed later.
19958 Vars.push_back(RefExpr);
19959 SrcExprs.push_back(nullptr);
19960 DstExprs.push_back(nullptr);
19961 AssignmentOps.push_back(nullptr);
19962 continue;
19963 }
19964
19965 SourceLocation ELoc = RefExpr->getExprLoc();
19966 // OpenMP [2.1, C/C++]
19967 // A list item is a variable name.
19968 // OpenMP [2.14.4.1, Restrictions, p.1]
19969 // A list item that appears in a copyin clause must be threadprivate.
19970 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19971 if (!DE || !isa<VarDecl>(DE->getDecl())) {
19972 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19973 << 0 << RefExpr->getSourceRange();
19974 continue;
19975 }
19976
19977 Decl *D = DE->getDecl();
19978 auto *VD = cast<VarDecl>(D);
19979
19980 QualType Type = VD->getType();
19981 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
19982 // It will be analyzed later.
19983 Vars.push_back(DE);
19984 SrcExprs.push_back(nullptr);
19985 DstExprs.push_back(nullptr);
19986 AssignmentOps.push_back(nullptr);
19987 continue;
19988 }
19989
19990 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19991 // A list item that appears in a copyin clause must be threadprivate.
19992 if (!DSAStack->isThreadPrivate(VD)) {
19993 Diag(ELoc, diag::err_omp_required_access)
19994 << getOpenMPClauseName(OMPC_copyin)
19995 << getOpenMPDirectiveName(OMPD_threadprivate);
19996 continue;
19997 }
19998
19999 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20000 // A variable of class type (or array thereof) that appears in a
20001 // copyin clause requires an accessible, unambiguous copy assignment
20002 // operator for the class type.
20003 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20004 VarDecl *SrcVD =
20005 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20006 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20007 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20008 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20009 VarDecl *DstVD =
20010 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20011 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20012 DeclRefExpr *PseudoDstExpr =
20013 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20014 // For arrays generate assignment operation for single element and replace
20015 // it by the original array element in CodeGen.
20016 ExprResult AssignmentOp =
20017 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20018 PseudoSrcExpr);
20019 if (AssignmentOp.isInvalid())
20020 continue;
20021 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20022 /*DiscardedValue*/ false);
20023 if (AssignmentOp.isInvalid())
20024 continue;
20025
20026 DSAStack->addDSA(VD, DE, OMPC_copyin);
20027 Vars.push_back(DE);
20028 SrcExprs.push_back(PseudoSrcExpr);
20029 DstExprs.push_back(PseudoDstExpr);
20030 AssignmentOps.push_back(AssignmentOp.get());
20031 }
20032
20033 if (Vars.empty())
20034 return nullptr;
20035
20036 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20037 SrcExprs, DstExprs, AssignmentOps);
20038 }
20039
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20040 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20041 SourceLocation StartLoc,
20042 SourceLocation LParenLoc,
20043 SourceLocation EndLoc) {
20044 SmallVector<Expr *, 8> Vars;
20045 SmallVector<Expr *, 8> SrcExprs;
20046 SmallVector<Expr *, 8> DstExprs;
20047 SmallVector<Expr *, 8> AssignmentOps;
20048 for (Expr *RefExpr : VarList) {
20049 assert(RefExpr && "NULL expr in OpenMP linear clause.");
20050 SourceLocation ELoc;
20051 SourceRange ERange;
20052 Expr *SimpleRefExpr = RefExpr;
20053 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20054 if (Res.second) {
20055 // It will be analyzed later.
20056 Vars.push_back(RefExpr);
20057 SrcExprs.push_back(nullptr);
20058 DstExprs.push_back(nullptr);
20059 AssignmentOps.push_back(nullptr);
20060 }
20061 ValueDecl *D = Res.first;
20062 if (!D)
20063 continue;
20064
20065 QualType Type = D->getType();
20066 auto *VD = dyn_cast<VarDecl>(D);
20067
20068 // OpenMP [2.14.4.2, Restrictions, p.2]
20069 // A list item that appears in a copyprivate clause may not appear in a
20070 // private or firstprivate clause on the single construct.
20071 if (!VD || !DSAStack->isThreadPrivate(VD)) {
20072 DSAStackTy::DSAVarData DVar =
20073 DSAStack->getTopDSA(D, /*FromParent=*/false);
20074 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20075 DVar.RefExpr) {
20076 Diag(ELoc, diag::err_omp_wrong_dsa)
20077 << getOpenMPClauseName(DVar.CKind)
20078 << getOpenMPClauseName(OMPC_copyprivate);
20079 reportOriginalDsa(*this, DSAStack, D, DVar);
20080 continue;
20081 }
20082
20083 // OpenMP [2.11.4.2, Restrictions, p.1]
20084 // All list items that appear in a copyprivate clause must be either
20085 // threadprivate or private in the enclosing context.
20086 if (DVar.CKind == OMPC_unknown) {
20087 DVar = DSAStack->getImplicitDSA(D, false);
20088 if (DVar.CKind == OMPC_shared) {
20089 Diag(ELoc, diag::err_omp_required_access)
20090 << getOpenMPClauseName(OMPC_copyprivate)
20091 << "threadprivate or private in the enclosing context";
20092 reportOriginalDsa(*this, DSAStack, D, DVar);
20093 continue;
20094 }
20095 }
20096 }
20097
20098 // Variably modified types are not supported.
20099 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20100 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20101 << getOpenMPClauseName(OMPC_copyprivate) << Type
20102 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20103 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20104 VarDecl::DeclarationOnly;
20105 Diag(D->getLocation(),
20106 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20107 << D;
20108 continue;
20109 }
20110
20111 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20112 // A variable of class type (or array thereof) that appears in a
20113 // copyin clause requires an accessible, unambiguous copy assignment
20114 // operator for the class type.
20115 Type = Context.getBaseElementType(Type.getNonReferenceType())
20116 .getUnqualifiedType();
20117 VarDecl *SrcVD =
20118 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20119 D->hasAttrs() ? &D->getAttrs() : nullptr);
20120 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20121 VarDecl *DstVD =
20122 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20123 D->hasAttrs() ? &D->getAttrs() : nullptr);
20124 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20125 ExprResult AssignmentOp = BuildBinOp(
20126 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20127 if (AssignmentOp.isInvalid())
20128 continue;
20129 AssignmentOp =
20130 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20131 if (AssignmentOp.isInvalid())
20132 continue;
20133
20134 // No need to mark vars as copyprivate, they are already threadprivate or
20135 // implicitly private.
20136 assert(VD || isOpenMPCapturedDecl(D));
20137 Vars.push_back(
20138 VD ? RefExpr->IgnoreParens()
20139 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20140 SrcExprs.push_back(PseudoSrcExpr);
20141 DstExprs.push_back(PseudoDstExpr);
20142 AssignmentOps.push_back(AssignmentOp.get());
20143 }
20144
20145 if (Vars.empty())
20146 return nullptr;
20147
20148 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20149 Vars, SrcExprs, DstExprs, AssignmentOps);
20150 }
20151
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20152 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20153 SourceLocation StartLoc,
20154 SourceLocation LParenLoc,
20155 SourceLocation EndLoc) {
20156 if (VarList.empty())
20157 return nullptr;
20158
20159 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20160 }
20161
20162 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)20163 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20164 bool Diagnose = true) {
20165 QualType OMPDependT = Stack->getOMPDependT();
20166 if (!OMPDependT.isNull())
20167 return true;
20168 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20169 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20170 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20171 if (Diagnose)
20172 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20173 return false;
20174 }
20175 Stack->setOMPDependT(PT.get());
20176 return true;
20177 }
20178
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20179 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20180 SourceLocation LParenLoc,
20181 SourceLocation EndLoc) {
20182 if (!Depobj)
20183 return nullptr;
20184
20185 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20186
20187 // OpenMP 5.0, 2.17.10.1 depobj Construct
20188 // depobj is an lvalue expression of type omp_depend_t.
20189 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20190 !Depobj->isInstantiationDependent() &&
20191 !Depobj->containsUnexpandedParameterPack() &&
20192 (OMPDependTFound &&
20193 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20194 /*CompareUnqualified=*/true))) {
20195 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20196 << 0 << Depobj->getType() << Depobj->getSourceRange();
20197 }
20198
20199 if (!Depobj->isLValue()) {
20200 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20201 << 1 << Depobj->getSourceRange();
20202 }
20203
20204 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20205 }
20206
20207 OMPClause *
ActOnOpenMPDependClause(const OMPDependClause::DependDataTy & Data,Expr * DepModifier,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20208 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20209 Expr *DepModifier, ArrayRef<Expr *> VarList,
20210 SourceLocation StartLoc, SourceLocation LParenLoc,
20211 SourceLocation EndLoc) {
20212 OpenMPDependClauseKind DepKind = Data.DepKind;
20213 SourceLocation DepLoc = Data.DepLoc;
20214 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20215 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20216 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20217 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20218 return nullptr;
20219 }
20220 if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20221 DepKind == OMPC_DEPEND_mutexinoutset) {
20222 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20223 return nullptr;
20224 }
20225 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20226 DSAStack->getCurrentDirective() == OMPD_depobj) &&
20227 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20228 DepKind == OMPC_DEPEND_sink ||
20229 ((LangOpts.OpenMP < 50 ||
20230 DSAStack->getCurrentDirective() == OMPD_depobj) &&
20231 DepKind == OMPC_DEPEND_depobj))) {
20232 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20233 OMPC_DEPEND_outallmemory,
20234 OMPC_DEPEND_inoutallmemory};
20235 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
20236 Except.push_back(OMPC_DEPEND_depobj);
20237 if (LangOpts.OpenMP < 51)
20238 Except.push_back(OMPC_DEPEND_inoutset);
20239 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
20240 ? "depend modifier(iterator) or "
20241 : "";
20242 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20243 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20244 /*Last=*/OMPC_DEPEND_unknown,
20245 Except)
20246 << getOpenMPClauseName(OMPC_depend);
20247 return nullptr;
20248 }
20249 if (DepModifier &&
20250 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20251 Diag(DepModifier->getExprLoc(),
20252 diag::err_omp_depend_sink_source_with_modifier);
20253 return nullptr;
20254 }
20255 if (DepModifier &&
20256 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
20257 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20258
20259 SmallVector<Expr *, 8> Vars;
20260 DSAStackTy::OperatorOffsetTy OpsOffs;
20261 llvm::APSInt DepCounter(/*BitWidth=*/32);
20262 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20263 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20264 if (const Expr *OrderedCountExpr =
20265 DSAStack->getParentOrderedRegionParam().first) {
20266 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
20267 TotalDepCount.setIsUnsigned(/*Val=*/true);
20268 }
20269 }
20270 for (Expr *RefExpr : VarList) {
20271 assert(RefExpr && "NULL expr in OpenMP shared clause.");
20272 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20273 // It will be analyzed later.
20274 Vars.push_back(RefExpr);
20275 continue;
20276 }
20277
20278 SourceLocation ELoc = RefExpr->getExprLoc();
20279 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20280 if (DepKind == OMPC_DEPEND_sink) {
20281 if (DSAStack->getParentOrderedRegionParam().first &&
20282 DepCounter >= TotalDepCount) {
20283 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20284 continue;
20285 }
20286 ++DepCounter;
20287 // OpenMP [2.13.9, Summary]
20288 // depend(dependence-type : vec), where dependence-type is:
20289 // 'sink' and where vec is the iteration vector, which has the form:
20290 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20291 // where n is the value specified by the ordered clause in the loop
20292 // directive, xi denotes the loop iteration variable of the i-th nested
20293 // loop associated with the loop directive, and di is a constant
20294 // non-negative integer.
20295 if (CurContext->isDependentContext()) {
20296 // It will be analyzed later.
20297 Vars.push_back(RefExpr);
20298 continue;
20299 }
20300 SimpleExpr = SimpleExpr->IgnoreImplicit();
20301 OverloadedOperatorKind OOK = OO_None;
20302 SourceLocation OOLoc;
20303 Expr *LHS = SimpleExpr;
20304 Expr *RHS = nullptr;
20305 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20306 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20307 OOLoc = BO->getOperatorLoc();
20308 LHS = BO->getLHS()->IgnoreParenImpCasts();
20309 RHS = BO->getRHS()->IgnoreParenImpCasts();
20310 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20311 OOK = OCE->getOperator();
20312 OOLoc = OCE->getOperatorLoc();
20313 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20314 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20315 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20316 OOK = MCE->getMethodDecl()
20317 ->getNameInfo()
20318 .getName()
20319 .getCXXOverloadedOperator();
20320 OOLoc = MCE->getCallee()->getExprLoc();
20321 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20322 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20323 }
20324 SourceLocation ELoc;
20325 SourceRange ERange;
20326 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
20327 if (Res.second) {
20328 // It will be analyzed later.
20329 Vars.push_back(RefExpr);
20330 }
20331 ValueDecl *D = Res.first;
20332 if (!D)
20333 continue;
20334
20335 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20336 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20337 continue;
20338 }
20339 if (RHS) {
20340 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
20341 RHS, OMPC_depend, /*StrictlyPositive=*/false);
20342 if (RHSRes.isInvalid())
20343 continue;
20344 }
20345 if (!CurContext->isDependentContext() &&
20346 DSAStack->getParentOrderedRegionParam().first &&
20347 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
20348 const ValueDecl *VD =
20349 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
20350 if (VD)
20351 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20352 << 1 << VD;
20353 else
20354 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
20355 continue;
20356 }
20357 OpsOffs.emplace_back(RHS, OOK);
20358 } else {
20359 bool OMPDependTFound = LangOpts.OpenMP >= 50;
20360 if (OMPDependTFound)
20361 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
20362 DepKind == OMPC_DEPEND_depobj);
20363 if (DepKind == OMPC_DEPEND_depobj) {
20364 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20365 // List items used in depend clauses with the depobj dependence type
20366 // must be expressions of the omp_depend_t type.
20367 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20368 !RefExpr->isInstantiationDependent() &&
20369 !RefExpr->containsUnexpandedParameterPack() &&
20370 (OMPDependTFound &&
20371 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
20372 RefExpr->getType()))) {
20373 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20374 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20375 continue;
20376 }
20377 if (!RefExpr->isLValue()) {
20378 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20379 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20380 continue;
20381 }
20382 } else {
20383 // OpenMP 5.0 [2.17.11, Restrictions]
20384 // List items used in depend clauses cannot be zero-length array
20385 // sections.
20386 QualType ExprTy = RefExpr->getType().getNonReferenceType();
20387 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
20388 if (OASE) {
20389 QualType BaseType =
20390 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
20391 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20392 ExprTy = ATy->getElementType();
20393 else
20394 ExprTy = BaseType->getPointeeType();
20395 ExprTy = ExprTy.getNonReferenceType();
20396 const Expr *Length = OASE->getLength();
20397 Expr::EvalResult Result;
20398 if (Length && !Length->isValueDependent() &&
20399 Length->EvaluateAsInt(Result, Context) &&
20400 Result.Val.getInt().isZero()) {
20401 Diag(ELoc,
20402 diag::err_omp_depend_zero_length_array_section_not_allowed)
20403 << SimpleExpr->getSourceRange();
20404 continue;
20405 }
20406 }
20407
20408 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20409 // List items used in depend clauses with the in, out, inout,
20410 // inoutset, or mutexinoutset dependence types cannot be
20411 // expressions of the omp_depend_t type.
20412 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20413 !RefExpr->isInstantiationDependent() &&
20414 !RefExpr->containsUnexpandedParameterPack() &&
20415 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20416 (OMPDependTFound &&
20417 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
20418 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20419 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20420 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20421 continue;
20422 }
20423
20424 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20425 if (ASE && !ASE->getBase()->isTypeDependent() &&
20426 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
20427 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20428 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20429 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20430 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20431 continue;
20432 }
20433
20434 ExprResult Res;
20435 {
20436 Sema::TentativeAnalysisScope Trap(*this);
20437 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
20438 RefExpr->IgnoreParenImpCasts());
20439 }
20440 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20441 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20442 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20443 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20444 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20445 continue;
20446 }
20447 }
20448 }
20449 Vars.push_back(RefExpr->IgnoreParenImpCasts());
20450 }
20451
20452 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
20453 TotalDepCount > VarList.size() &&
20454 DSAStack->getParentOrderedRegionParam().first &&
20455 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
20456 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20457 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
20458 }
20459 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20460 DepKind != OMPC_DEPEND_outallmemory &&
20461 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20462 return nullptr;
20463
20464 auto *C = OMPDependClause::Create(
20465 Context, StartLoc, LParenLoc, EndLoc,
20466 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
20467 TotalDepCount.getZExtValue());
20468 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20469 DSAStack->isParentOrderedRegion())
20470 DSAStack->addDoacrossDependClause(C, OpsOffs);
20471 return C;
20472 }
20473
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)20474 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
20475 Expr *Device, SourceLocation StartLoc,
20476 SourceLocation LParenLoc,
20477 SourceLocation ModifierLoc,
20478 SourceLocation EndLoc) {
20479 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
20480 "Unexpected device modifier in OpenMP < 50.");
20481
20482 bool ErrorFound = false;
20483 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
20484 std::string Values =
20485 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
20486 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20487 << Values << getOpenMPClauseName(OMPC_device);
20488 ErrorFound = true;
20489 }
20490
20491 Expr *ValExpr = Device;
20492 Stmt *HelperValStmt = nullptr;
20493
20494 // OpenMP [2.9.1, Restrictions]
20495 // The device expression must evaluate to a non-negative integer value.
20496 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
20497 /*StrictlyPositive=*/false) ||
20498 ErrorFound;
20499 if (ErrorFound)
20500 return nullptr;
20501
20502 // OpenMP 5.0 [2.12.5, Restrictions]
20503 // In case of ancestor device-modifier, a requires directive with
20504 // the reverse_offload clause must be specified.
20505 if (Modifier == OMPC_DEVICE_ancestor) {
20506 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
20507 targetDiag(
20508 StartLoc,
20509 diag::err_omp_device_ancestor_without_requires_reverse_offload);
20510 ErrorFound = true;
20511 }
20512 }
20513
20514 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20515 OpenMPDirectiveKind CaptureRegion =
20516 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
20517 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20518 ValExpr = MakeFullExpr(ValExpr).get();
20519 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20520 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20521 HelperValStmt = buildPreInits(Context, Captures);
20522 }
20523
20524 return new (Context)
20525 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20526 LParenLoc, ModifierLoc, EndLoc);
20527 }
20528
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)20529 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
20530 DSAStackTy *Stack, QualType QTy,
20531 bool FullCheck = true) {
20532 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
20533 return false;
20534 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
20535 !QTy.isTriviallyCopyableType(SemaRef.Context))
20536 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20537 return true;
20538 }
20539
20540 /// Return true if it can be proven that the provided array expression
20541 /// (array section or array subscript) does NOT specify the whole size of the
20542 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)20543 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
20544 const Expr *E,
20545 QualType BaseQTy) {
20546 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20547
20548 // If this is an array subscript, it refers to the whole size if the size of
20549 // the dimension is constant and equals 1. Also, an array section assumes the
20550 // format of an array subscript if no colon is used.
20551 if (isa<ArraySubscriptExpr>(E) ||
20552 (OASE && OASE->getColonLocFirst().isInvalid())) {
20553 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20554 return ATy->getSize().getSExtValue() != 1;
20555 // Size can't be evaluated statically.
20556 return false;
20557 }
20558
20559 assert(OASE && "Expecting array section if not an array subscript.");
20560 const Expr *LowerBound = OASE->getLowerBound();
20561 const Expr *Length = OASE->getLength();
20562
20563 // If there is a lower bound that does not evaluates to zero, we are not
20564 // covering the whole dimension.
20565 if (LowerBound) {
20566 Expr::EvalResult Result;
20567 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
20568 return false; // Can't get the integer value as a constant.
20569
20570 llvm::APSInt ConstLowerBound = Result.Val.getInt();
20571 if (ConstLowerBound.getSExtValue())
20572 return true;
20573 }
20574
20575 // If we don't have a length we covering the whole dimension.
20576 if (!Length)
20577 return false;
20578
20579 // If the base is a pointer, we don't have a way to get the size of the
20580 // pointee.
20581 if (BaseQTy->isPointerType())
20582 return false;
20583
20584 // We can only check if the length is the same as the size of the dimension
20585 // if we have a constant array.
20586 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20587 if (!CATy)
20588 return false;
20589
20590 Expr::EvalResult Result;
20591 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20592 return false; // Can't get the integer value as a constant.
20593
20594 llvm::APSInt ConstLength = Result.Val.getInt();
20595 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20596 }
20597
20598 // Return true if it can be proven that the provided array expression (array
20599 // section or array subscript) does NOT specify a single element of the array
20600 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)20601 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
20602 const Expr *E,
20603 QualType BaseQTy) {
20604 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20605
20606 // An array subscript always refer to a single element. Also, an array section
20607 // assumes the format of an array subscript if no colon is used.
20608 if (isa<ArraySubscriptExpr>(E) ||
20609 (OASE && OASE->getColonLocFirst().isInvalid()))
20610 return false;
20611
20612 assert(OASE && "Expecting array section if not an array subscript.");
20613 const Expr *Length = OASE->getLength();
20614
20615 // If we don't have a length we have to check if the array has unitary size
20616 // for this dimension. Also, we should always expect a length if the base type
20617 // is pointer.
20618 if (!Length) {
20619 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20620 return ATy->getSize().getSExtValue() != 1;
20621 // We cannot assume anything.
20622 return false;
20623 }
20624
20625 // Check if the length evaluates to 1.
20626 Expr::EvalResult Result;
20627 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20628 return false; // Can't get the integer value as a constant.
20629
20630 llvm::APSInt ConstLength = Result.Val.getInt();
20631 return ConstLength.getSExtValue() != 1;
20632 }
20633
20634 // The base of elements of list in a map clause have to be either:
20635 // - a reference to variable or field.
20636 // - a member expression.
20637 // - an array expression.
20638 //
20639 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20640 // reference to 'r'.
20641 //
20642 // If we have:
20643 //
20644 // struct SS {
20645 // Bla S;
20646 // foo() {
20647 // #pragma omp target map (S.Arr[:12]);
20648 // }
20649 // }
20650 //
20651 // We want to retrieve the member expression 'this->S';
20652
20653 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20654 // If a list item is an array section, it must specify contiguous storage.
20655 //
20656 // For this restriction it is sufficient that we make sure only references
20657 // to variables or fields and array expressions, and that no array sections
20658 // exist except in the rightmost expression (unless they cover the whole
20659 // dimension of the array). E.g. these would be invalid:
20660 //
20661 // r.ArrS[3:5].Arr[6:7]
20662 //
20663 // r.ArrS[3:5].x
20664 //
20665 // but these would be valid:
20666 // r.ArrS[3].Arr[6:7]
20667 //
20668 // r.ArrS[3].x
20669 namespace {
20670 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20671 Sema &SemaRef;
20672 OpenMPClauseKind CKind = OMPC_unknown;
20673 OpenMPDirectiveKind DKind = OMPD_unknown;
20674 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
20675 bool IsNonContiguous = false;
20676 bool NoDiagnose = false;
20677 const Expr *RelevantExpr = nullptr;
20678 bool AllowUnitySizeArraySection = true;
20679 bool AllowWholeSizeArraySection = true;
20680 bool AllowAnotherPtr = true;
20681 SourceLocation ELoc;
20682 SourceRange ERange;
20683
emitErrorMsg()20684 void emitErrorMsg() {
20685 // If nothing else worked, this is not a valid map clause expression.
20686 if (SemaRef.getLangOpts().OpenMP < 50) {
20687 SemaRef.Diag(ELoc,
20688 diag::err_omp_expected_named_var_member_or_array_expression)
20689 << ERange;
20690 } else {
20691 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20692 << getOpenMPClauseName(CKind) << ERange;
20693 }
20694 }
20695
20696 public:
VisitDeclRefExpr(DeclRefExpr * DRE)20697 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
20698 if (!isa<VarDecl>(DRE->getDecl())) {
20699 emitErrorMsg();
20700 return false;
20701 }
20702 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20703 RelevantExpr = DRE;
20704 // Record the component.
20705 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
20706 return true;
20707 }
20708
VisitMemberExpr(MemberExpr * ME)20709 bool VisitMemberExpr(MemberExpr *ME) {
20710 Expr *E = ME;
20711 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
20712
20713 if (isa<CXXThisExpr>(BaseE)) {
20714 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20715 // We found a base expression: this->Val.
20716 RelevantExpr = ME;
20717 } else {
20718 E = BaseE;
20719 }
20720
20721 if (!isa<FieldDecl>(ME->getMemberDecl())) {
20722 if (!NoDiagnose) {
20723 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20724 << ME->getSourceRange();
20725 return false;
20726 }
20727 if (RelevantExpr)
20728 return false;
20729 return Visit(E);
20730 }
20731
20732 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
20733
20734 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20735 // A bit-field cannot appear in a map clause.
20736 //
20737 if (FD->isBitField()) {
20738 if (!NoDiagnose) {
20739 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20740 << ME->getSourceRange() << getOpenMPClauseName(CKind);
20741 return false;
20742 }
20743 if (RelevantExpr)
20744 return false;
20745 return Visit(E);
20746 }
20747
20748 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20749 // If the type of a list item is a reference to a type T then the type
20750 // will be considered to be T for all purposes of this clause.
20751 QualType CurType = BaseE->getType().getNonReferenceType();
20752
20753 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20754 // A list item cannot be a variable that is a member of a structure with
20755 // a union type.
20756 //
20757 if (CurType->isUnionType()) {
20758 if (!NoDiagnose) {
20759 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20760 << ME->getSourceRange();
20761 return false;
20762 }
20763 return RelevantExpr || Visit(E);
20764 }
20765
20766 // If we got a member expression, we should not expect any array section
20767 // before that:
20768 //
20769 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20770 // If a list item is an element of a structure, only the rightmost symbol
20771 // of the variable reference can be an array section.
20772 //
20773 AllowUnitySizeArraySection = false;
20774 AllowWholeSizeArraySection = false;
20775
20776 // Record the component.
20777 Components.emplace_back(ME, FD, IsNonContiguous);
20778 return RelevantExpr || Visit(E);
20779 }
20780
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)20781 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
20782 Expr *E = AE->getBase()->IgnoreParenImpCasts();
20783
20784 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
20785 if (!NoDiagnose) {
20786 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20787 << 0 << AE->getSourceRange();
20788 return false;
20789 }
20790 return RelevantExpr || Visit(E);
20791 }
20792
20793 // If we got an array subscript that express the whole dimension we
20794 // can have any array expressions before. If it only expressing part of
20795 // the dimension, we can only have unitary-size array expressions.
20796 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
20797 AllowWholeSizeArraySection = false;
20798
20799 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
20800 Expr::EvalResult Result;
20801 if (!AE->getIdx()->isValueDependent() &&
20802 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
20803 !Result.Val.getInt().isZero()) {
20804 SemaRef.Diag(AE->getIdx()->getExprLoc(),
20805 diag::err_omp_invalid_map_this_expr);
20806 SemaRef.Diag(AE->getIdx()->getExprLoc(),
20807 diag::note_omp_invalid_subscript_on_this_ptr_map);
20808 }
20809 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20810 RelevantExpr = TE;
20811 }
20812
20813 // Record the component - we don't have any declaration associated.
20814 Components.emplace_back(AE, nullptr, IsNonContiguous);
20815
20816 return RelevantExpr || Visit(E);
20817 }
20818
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)20819 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
20820 // After OMP 5.0 Array section in reduction clause will be implicitly
20821 // mapped
20822 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
20823 "Array sections cannot be implicitly mapped.");
20824 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20825 QualType CurType =
20826 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20827
20828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20829 // If the type of a list item is a reference to a type T then the type
20830 // will be considered to be T for all purposes of this clause.
20831 if (CurType->isReferenceType())
20832 CurType = CurType->getPointeeType();
20833
20834 bool IsPointer = CurType->isAnyPointerType();
20835
20836 if (!IsPointer && !CurType->isArrayType()) {
20837 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20838 << 0 << OASE->getSourceRange();
20839 return false;
20840 }
20841
20842 bool NotWhole =
20843 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
20844 bool NotUnity =
20845 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
20846
20847 if (AllowWholeSizeArraySection) {
20848 // Any array section is currently allowed. Allowing a whole size array
20849 // section implies allowing a unity array section as well.
20850 //
20851 // If this array section refers to the whole dimension we can still
20852 // accept other array sections before this one, except if the base is a
20853 // pointer. Otherwise, only unitary sections are accepted.
20854 if (NotWhole || IsPointer)
20855 AllowWholeSizeArraySection = false;
20856 } else if (DKind == OMPD_target_update &&
20857 SemaRef.getLangOpts().OpenMP >= 50) {
20858 if (IsPointer && !AllowAnotherPtr)
20859 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
20860 << /*array of unknown bound */ 1;
20861 else
20862 IsNonContiguous = true;
20863 } else if (AllowUnitySizeArraySection && NotUnity) {
20864 // A unity or whole array section is not allowed and that is not
20865 // compatible with the properties of the current array section.
20866 if (NoDiagnose)
20867 return false;
20868 SemaRef.Diag(ELoc,
20869 diag::err_array_section_does_not_specify_contiguous_storage)
20870 << OASE->getSourceRange();
20871 return false;
20872 }
20873
20874 if (IsPointer)
20875 AllowAnotherPtr = false;
20876
20877 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
20878 Expr::EvalResult ResultR;
20879 Expr::EvalResult ResultL;
20880 if (!OASE->getLength()->isValueDependent() &&
20881 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
20882 !ResultR.Val.getInt().isOne()) {
20883 SemaRef.Diag(OASE->getLength()->getExprLoc(),
20884 diag::err_omp_invalid_map_this_expr);
20885 SemaRef.Diag(OASE->getLength()->getExprLoc(),
20886 diag::note_omp_invalid_length_on_this_ptr_mapping);
20887 }
20888 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
20889 OASE->getLowerBound()->EvaluateAsInt(ResultL,
20890 SemaRef.getASTContext()) &&
20891 !ResultL.Val.getInt().isZero()) {
20892 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20893 diag::err_omp_invalid_map_this_expr);
20894 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20895 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20896 }
20897 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20898 RelevantExpr = TE;
20899 }
20900
20901 // Record the component - we don't have any declaration associated.
20902 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
20903 return RelevantExpr || Visit(E);
20904 }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)20905 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
20906 Expr *Base = E->getBase();
20907
20908 // Record the component - we don't have any declaration associated.
20909 Components.emplace_back(E, nullptr, IsNonContiguous);
20910
20911 return Visit(Base->IgnoreParenImpCasts());
20912 }
20913
VisitUnaryOperator(UnaryOperator * UO)20914 bool VisitUnaryOperator(UnaryOperator *UO) {
20915 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
20916 UO->getOpcode() != UO_Deref) {
20917 emitErrorMsg();
20918 return false;
20919 }
20920 if (!RelevantExpr) {
20921 // Record the component if haven't found base decl.
20922 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
20923 }
20924 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
20925 }
VisitBinaryOperator(BinaryOperator * BO)20926 bool VisitBinaryOperator(BinaryOperator *BO) {
20927 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
20928 emitErrorMsg();
20929 return false;
20930 }
20931
20932 // Pointer arithmetic is the only thing we expect to happen here so after we
20933 // make sure the binary operator is a pointer type, the we only thing need
20934 // to to is to visit the subtree that has the same type as root (so that we
20935 // know the other subtree is just an offset)
20936 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
20937 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
20938 Components.emplace_back(BO, nullptr, false);
20939 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
20940 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
20941 "Either LHS or RHS have base decl inside");
20942 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
20943 return RelevantExpr || Visit(LE);
20944 return RelevantExpr || Visit(RE);
20945 }
VisitCXXThisExpr(CXXThisExpr * CTE)20946 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
20947 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20948 RelevantExpr = CTE;
20949 Components.emplace_back(CTE, nullptr, IsNonContiguous);
20950 return true;
20951 }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)20952 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
20953 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20954 Components.emplace_back(COCE, nullptr, IsNonContiguous);
20955 return true;
20956 }
VisitOpaqueValueExpr(OpaqueValueExpr * E)20957 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
20958 Expr *Source = E->getSourceExpr();
20959 if (!Source) {
20960 emitErrorMsg();
20961 return false;
20962 }
20963 return Visit(Source);
20964 }
VisitStmt(Stmt *)20965 bool VisitStmt(Stmt *) {
20966 emitErrorMsg();
20967 return false;
20968 }
getFoundBase() const20969 const Expr *getFoundBase() const { return RelevantExpr; }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)20970 explicit MapBaseChecker(
20971 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
20972 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
20973 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
20974 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20975 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20976 };
20977 } // namespace
20978
20979 /// Return the expression of the base of the mappable expression or null if it
20980 /// cannot be determined and do all the necessary checks to see if the
20981 /// expression is valid as a standalone mappable expression. In the process,
20982 /// record all the components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)20983 static const Expr *checkMapClauseExpressionBase(
20984 Sema &SemaRef, Expr *E,
20985 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
20986 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
20987 SourceLocation ELoc = E->getExprLoc();
20988 SourceRange ERange = E->getSourceRange();
20989 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20990 ERange);
20991 if (Checker.Visit(E->IgnoreParens())) {
20992 // Check if the highest dimension array section has length specified
20993 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20994 (CKind == OMPC_to || CKind == OMPC_from)) {
20995 auto CI = CurComponents.rbegin();
20996 auto CE = CurComponents.rend();
20997 for (; CI != CE; ++CI) {
20998 const auto *OASE =
20999 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21000 if (!OASE)
21001 continue;
21002 if (OASE && OASE->getLength())
21003 break;
21004 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21005 << ERange;
21006 }
21007 }
21008 return Checker.getFoundBase();
21009 }
21010 return nullptr;
21011 }
21012
21013 // Return true if expression E associated with value VD has conflicts with other
21014 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)21015 static bool checkMapConflicts(
21016 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21017 bool CurrentRegionOnly,
21018 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21019 OpenMPClauseKind CKind) {
21020 assert(VD && E);
21021 SourceLocation ELoc = E->getExprLoc();
21022 SourceRange ERange = E->getSourceRange();
21023
21024 // In order to easily check the conflicts we need to match each component of
21025 // the expression under test with the components of the expressions that are
21026 // already in the stack.
21027
21028 assert(!CurComponents.empty() && "Map clause expression with no components!");
21029 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21030 "Map clause expression with unexpected base!");
21031
21032 // Variables to help detecting enclosing problems in data environment nests.
21033 bool IsEnclosedByDataEnvironmentExpr = false;
21034 const Expr *EnclosingExpr = nullptr;
21035
21036 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21037 VD, CurrentRegionOnly,
21038 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21039 ERange, CKind, &EnclosingExpr,
21040 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21041 StackComponents,
21042 OpenMPClauseKind Kind) {
21043 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21044 return false;
21045 assert(!StackComponents.empty() &&
21046 "Map clause expression with no components!");
21047 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21048 "Map clause expression with unexpected base!");
21049 (void)VD;
21050
21051 // The whole expression in the stack.
21052 const Expr *RE = StackComponents.front().getAssociatedExpression();
21053
21054 // Expressions must start from the same base. Here we detect at which
21055 // point both expressions diverge from each other and see if we can
21056 // detect if the memory referred to both expressions is contiguous and
21057 // do not overlap.
21058 auto CI = CurComponents.rbegin();
21059 auto CE = CurComponents.rend();
21060 auto SI = StackComponents.rbegin();
21061 auto SE = StackComponents.rend();
21062 for (; CI != CE && SI != SE; ++CI, ++SI) {
21063
21064 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21065 // At most one list item can be an array item derived from a given
21066 // variable in map clauses of the same construct.
21067 if (CurrentRegionOnly &&
21068 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21069 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21070 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21071 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21072 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21073 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21074 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21075 diag::err_omp_multiple_array_items_in_map_clause)
21076 << CI->getAssociatedExpression()->getSourceRange();
21077 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21078 diag::note_used_here)
21079 << SI->getAssociatedExpression()->getSourceRange();
21080 return true;
21081 }
21082
21083 // Do both expressions have the same kind?
21084 if (CI->getAssociatedExpression()->getStmtClass() !=
21085 SI->getAssociatedExpression()->getStmtClass())
21086 break;
21087
21088 // Are we dealing with different variables/fields?
21089 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21090 break;
21091 }
21092 // Check if the extra components of the expressions in the enclosing
21093 // data environment are redundant for the current base declaration.
21094 // If they are, the maps completely overlap, which is legal.
21095 for (; SI != SE; ++SI) {
21096 QualType Type;
21097 if (const auto *ASE =
21098 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21099 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21100 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21101 SI->getAssociatedExpression())) {
21102 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21103 Type =
21104 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21105 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21106 SI->getAssociatedExpression())) {
21107 Type = OASE->getBase()->getType()->getPointeeType();
21108 }
21109 if (Type.isNull() || Type->isAnyPointerType() ||
21110 checkArrayExpressionDoesNotReferToWholeSize(
21111 SemaRef, SI->getAssociatedExpression(), Type))
21112 break;
21113 }
21114
21115 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21116 // List items of map clauses in the same construct must not share
21117 // original storage.
21118 //
21119 // If the expressions are exactly the same or one is a subset of the
21120 // other, it means they are sharing storage.
21121 if (CI == CE && SI == SE) {
21122 if (CurrentRegionOnly) {
21123 if (CKind == OMPC_map) {
21124 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21125 } else {
21126 assert(CKind == OMPC_to || CKind == OMPC_from);
21127 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21128 << ERange;
21129 }
21130 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21131 << RE->getSourceRange();
21132 return true;
21133 }
21134 // If we find the same expression in the enclosing data environment,
21135 // that is legal.
21136 IsEnclosedByDataEnvironmentExpr = true;
21137 return false;
21138 }
21139
21140 QualType DerivedType =
21141 std::prev(CI)->getAssociatedDeclaration()->getType();
21142 SourceLocation DerivedLoc =
21143 std::prev(CI)->getAssociatedExpression()->getExprLoc();
21144
21145 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21146 // If the type of a list item is a reference to a type T then the type
21147 // will be considered to be T for all purposes of this clause.
21148 DerivedType = DerivedType.getNonReferenceType();
21149
21150 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21151 // A variable for which the type is pointer and an array section
21152 // derived from that variable must not appear as list items of map
21153 // clauses of the same construct.
21154 //
21155 // Also, cover one of the cases in:
21156 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21157 // If any part of the original storage of a list item has corresponding
21158 // storage in the device data environment, all of the original storage
21159 // must have corresponding storage in the device data environment.
21160 //
21161 if (DerivedType->isAnyPointerType()) {
21162 if (CI == CE || SI == SE) {
21163 SemaRef.Diag(
21164 DerivedLoc,
21165 diag::err_omp_pointer_mapped_along_with_derived_section)
21166 << DerivedLoc;
21167 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21168 << RE->getSourceRange();
21169 return true;
21170 }
21171 if (CI->getAssociatedExpression()->getStmtClass() !=
21172 SI->getAssociatedExpression()->getStmtClass() ||
21173 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21174 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21175 assert(CI != CE && SI != SE);
21176 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21177 << DerivedLoc;
21178 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21179 << RE->getSourceRange();
21180 return true;
21181 }
21182 }
21183
21184 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21185 // List items of map clauses in the same construct must not share
21186 // original storage.
21187 //
21188 // An expression is a subset of the other.
21189 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21190 if (CKind == OMPC_map) {
21191 if (CI != CE || SI != SE) {
21192 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21193 // a pointer.
21194 auto Begin =
21195 CI != CE ? CurComponents.begin() : StackComponents.begin();
21196 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21197 auto It = Begin;
21198 while (It != End && !It->getAssociatedDeclaration())
21199 std::advance(It, 1);
21200 assert(It != End &&
21201 "Expected at least one component with the declaration.");
21202 if (It != Begin && It->getAssociatedDeclaration()
21203 ->getType()
21204 .getCanonicalType()
21205 ->isAnyPointerType()) {
21206 IsEnclosedByDataEnvironmentExpr = false;
21207 EnclosingExpr = nullptr;
21208 return false;
21209 }
21210 }
21211 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21212 } else {
21213 assert(CKind == OMPC_to || CKind == OMPC_from);
21214 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21215 << ERange;
21216 }
21217 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21218 << RE->getSourceRange();
21219 return true;
21220 }
21221
21222 // The current expression uses the same base as other expression in the
21223 // data environment but does not contain it completely.
21224 if (!CurrentRegionOnly && SI != SE)
21225 EnclosingExpr = RE;
21226
21227 // The current expression is a subset of the expression in the data
21228 // environment.
21229 IsEnclosedByDataEnvironmentExpr |=
21230 (!CurrentRegionOnly && CI != CE && SI == SE);
21231
21232 return false;
21233 });
21234
21235 if (CurrentRegionOnly)
21236 return FoundError;
21237
21238 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21239 // If any part of the original storage of a list item has corresponding
21240 // storage in the device data environment, all of the original storage must
21241 // have corresponding storage in the device data environment.
21242 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21243 // If a list item is an element of a structure, and a different element of
21244 // the structure has a corresponding list item in the device data environment
21245 // prior to a task encountering the construct associated with the map clause,
21246 // then the list item must also have a corresponding list item in the device
21247 // data environment prior to the task encountering the construct.
21248 //
21249 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21250 SemaRef.Diag(ELoc,
21251 diag::err_omp_original_storage_is_shared_and_does_not_contain)
21252 << ERange;
21253 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21254 << EnclosingExpr->getSourceRange();
21255 return true;
21256 }
21257
21258 return FoundError;
21259 }
21260
21261 // Look up the user-defined mapper given the mapper name and mapped type, and
21262 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)21263 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21264 CXXScopeSpec &MapperIdScopeSpec,
21265 const DeclarationNameInfo &MapperId,
21266 QualType Type,
21267 Expr *UnresolvedMapper) {
21268 if (MapperIdScopeSpec.isInvalid())
21269 return ExprError();
21270 // Get the actual type for the array type.
21271 if (Type->isArrayType()) {
21272 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21273 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21274 }
21275 // Find all user-defined mappers with the given MapperId.
21276 SmallVector<UnresolvedSet<8>, 4> Lookups;
21277 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21278 Lookup.suppressDiagnostics();
21279 if (S) {
21280 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21281 NamedDecl *D = Lookup.getRepresentativeDecl();
21282 while (S && !S->isDeclScope(D))
21283 S = S->getParent();
21284 if (S)
21285 S = S->getParent();
21286 Lookups.emplace_back();
21287 Lookups.back().append(Lookup.begin(), Lookup.end());
21288 Lookup.clear();
21289 }
21290 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21291 // Extract the user-defined mappers with the given MapperId.
21292 Lookups.push_back(UnresolvedSet<8>());
21293 for (NamedDecl *D : ULE->decls()) {
21294 auto *DMD = cast<OMPDeclareMapperDecl>(D);
21295 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21296 Lookups.back().addDecl(DMD);
21297 }
21298 }
21299 // Defer the lookup for dependent types. The results will be passed through
21300 // UnresolvedMapper on instantiation.
21301 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21302 Type->isInstantiationDependentType() ||
21303 Type->containsUnexpandedParameterPack() ||
21304 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21305 return !D->isInvalidDecl() &&
21306 (D->getType()->isDependentType() ||
21307 D->getType()->isInstantiationDependentType() ||
21308 D->getType()->containsUnexpandedParameterPack());
21309 })) {
21310 UnresolvedSet<8> URS;
21311 for (const UnresolvedSet<8> &Set : Lookups) {
21312 if (Set.empty())
21313 continue;
21314 URS.append(Set.begin(), Set.end());
21315 }
21316 return UnresolvedLookupExpr::Create(
21317 SemaRef.Context, /*NamingClass=*/nullptr,
21318 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21319 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21320 }
21321 SourceLocation Loc = MapperId.getLoc();
21322 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21323 // The type must be of struct, union or class type in C and C++
21324 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21325 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21326 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21327 return ExprError();
21328 }
21329 // Perform argument dependent lookup.
21330 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21331 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21332 // Return the first user-defined mapper with the desired type.
21333 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21334 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21335 if (!D->isInvalidDecl() &&
21336 SemaRef.Context.hasSameType(D->getType(), Type))
21337 return D;
21338 return nullptr;
21339 }))
21340 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21341 // Find the first user-defined mapper with a type derived from the desired
21342 // type.
21343 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21344 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21345 if (!D->isInvalidDecl() &&
21346 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21347 !Type.isMoreQualifiedThan(D->getType()))
21348 return D;
21349 return nullptr;
21350 })) {
21351 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21352 /*DetectVirtual=*/false);
21353 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21354 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21355 VD->getType().getUnqualifiedType()))) {
21356 if (SemaRef.CheckBaseClassAccess(
21357 Loc, VD->getType(), Type, Paths.front(),
21358 /*DiagID=*/0) != Sema::AR_inaccessible) {
21359 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21360 }
21361 }
21362 }
21363 }
21364 // Report error if a mapper is specified, but cannot be found.
21365 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
21366 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21367 << Type << MapperId.getName();
21368 return ExprError();
21369 }
21370 return ExprEmpty();
21371 }
21372
21373 namespace {
21374 // Utility struct that gathers all the related lists associated with a mappable
21375 // expression.
21376 struct MappableVarListInfo {
21377 // The list of expressions.
21378 ArrayRef<Expr *> VarList;
21379 // The list of processed expressions.
21380 SmallVector<Expr *, 16> ProcessedVarList;
21381 // The mappble components for each expression.
21382 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
21383 // The base declaration of the variable.
21384 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
21385 // The reference to the user-defined mapper associated with every expression.
21386 SmallVector<Expr *, 16> UDMapperList;
21387
MappableVarListInfo__anon296aa5746111::MappableVarListInfo21388 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
21389 // We have a list of components and base declarations for each entry in the
21390 // variable list.
21391 VarComponents.reserve(VarList.size());
21392 VarBaseDeclarations.reserve(VarList.size());
21393 }
21394 };
21395 } // namespace
21396
21397 // Check the validity of the provided variable list for the provided clause kind
21398 // \a CKind. In the check process the valid expressions, mappable expression
21399 // components, variables, and user-defined mappers are extracted and used to
21400 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21401 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21402 // and \a MapperId are expected to be valid if the clause kind is 'map'.
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo MapperId,ArrayRef<Expr * > UnresolvedMappers,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,ArrayRef<OpenMPMapModifierKind> Modifiers=None,bool IsMapTypeImplicit=false,bool NoDiagnose=false)21403 static void checkMappableExpressionList(
21404 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
21405 MappableVarListInfo &MVLI, SourceLocation StartLoc,
21406 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
21407 ArrayRef<Expr *> UnresolvedMappers,
21408 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
21409 ArrayRef<OpenMPMapModifierKind> Modifiers = None,
21410 bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
21411 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21412 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
21413 "Unexpected clause kind with mappable expressions!");
21414
21415 // If the identifier of user-defined mapper is not specified, it is "default".
21416 // We do not change the actual name in this clause to distinguish whether a
21417 // mapper is specified explicitly, i.e., it is not explicitly specified when
21418 // MapperId.getName() is empty.
21419 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
21420 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
21421 MapperId.setName(DeclNames.getIdentifier(
21422 &SemaRef.getASTContext().Idents.get("default")));
21423 MapperId.setLoc(StartLoc);
21424 }
21425
21426 // Iterators to find the current unresolved mapper expression.
21427 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21428 bool UpdateUMIt = false;
21429 Expr *UnresolvedMapper = nullptr;
21430
21431 bool HasHoldModifier =
21432 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21433
21434 // Keep track of the mappable components and base declarations in this clause.
21435 // Each entry in the list is going to have a list of components associated. We
21436 // record each set of the components so that we can build the clause later on.
21437 // In the end we should have the same amount of declarations and component
21438 // lists.
21439
21440 for (Expr *RE : MVLI.VarList) {
21441 assert(RE && "Null expr in omp to/from/map clause");
21442 SourceLocation ELoc = RE->getExprLoc();
21443
21444 // Find the current unresolved mapper expression.
21445 if (UpdateUMIt && UMIt != UMEnd) {
21446 UMIt++;
21447 assert(
21448 UMIt != UMEnd &&
21449 "Expect the size of UnresolvedMappers to match with that of VarList");
21450 }
21451 UpdateUMIt = true;
21452 if (UMIt != UMEnd)
21453 UnresolvedMapper = *UMIt;
21454
21455 const Expr *VE = RE->IgnoreParenLValueCasts();
21456
21457 if (VE->isValueDependent() || VE->isTypeDependent() ||
21458 VE->isInstantiationDependent() ||
21459 VE->containsUnexpandedParameterPack()) {
21460 // Try to find the associated user-defined mapper.
21461 ExprResult ER = buildUserDefinedMapperRef(
21462 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21463 VE->getType().getCanonicalType(), UnresolvedMapper);
21464 if (ER.isInvalid())
21465 continue;
21466 MVLI.UDMapperList.push_back(ER.get());
21467 // We can only analyze this information once the missing information is
21468 // resolved.
21469 MVLI.ProcessedVarList.push_back(RE);
21470 continue;
21471 }
21472
21473 Expr *SimpleExpr = RE->IgnoreParenCasts();
21474
21475 if (!RE->isLValue()) {
21476 if (SemaRef.getLangOpts().OpenMP < 50) {
21477 SemaRef.Diag(
21478 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21479 << RE->getSourceRange();
21480 } else {
21481 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21482 << getOpenMPClauseName(CKind) << RE->getSourceRange();
21483 }
21484 continue;
21485 }
21486
21487 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
21488 ValueDecl *CurDeclaration = nullptr;
21489
21490 // Obtain the array or member expression bases if required. Also, fill the
21491 // components array with all the components identified in the process.
21492 const Expr *BE =
21493 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
21494 DSAS->getCurrentDirective(), NoDiagnose);
21495 if (!BE)
21496 continue;
21497
21498 assert(!CurComponents.empty() &&
21499 "Invalid mappable expression information.");
21500
21501 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21502 // Add store "this" pointer to class in DSAStackTy for future checking
21503 DSAS->addMappedClassesQualTypes(TE->getType());
21504 // Try to find the associated user-defined mapper.
21505 ExprResult ER = buildUserDefinedMapperRef(
21506 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21507 VE->getType().getCanonicalType(), UnresolvedMapper);
21508 if (ER.isInvalid())
21509 continue;
21510 MVLI.UDMapperList.push_back(ER.get());
21511 // Skip restriction checking for variable or field declarations
21512 MVLI.ProcessedVarList.push_back(RE);
21513 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21514 MVLI.VarComponents.back().append(CurComponents.begin(),
21515 CurComponents.end());
21516 MVLI.VarBaseDeclarations.push_back(nullptr);
21517 continue;
21518 }
21519
21520 // For the following checks, we rely on the base declaration which is
21521 // expected to be associated with the last component. The declaration is
21522 // expected to be a variable or a field (if 'this' is being mapped).
21523 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21524 assert(CurDeclaration && "Null decl on map clause.");
21525 assert(
21526 CurDeclaration->isCanonicalDecl() &&
21527 "Expecting components to have associated only canonical declarations.");
21528
21529 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21530 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21531
21532 assert((VD || FD) && "Only variables or fields are expected here!");
21533 (void)FD;
21534
21535 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21536 // threadprivate variables cannot appear in a map clause.
21537 // OpenMP 4.5 [2.10.5, target update Construct]
21538 // threadprivate variables cannot appear in a from clause.
21539 if (VD && DSAS->isThreadPrivate(VD)) {
21540 if (NoDiagnose)
21541 continue;
21542 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21543 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21544 << getOpenMPClauseName(CKind);
21545 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
21546 continue;
21547 }
21548
21549 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21550 // A list item cannot appear in both a map clause and a data-sharing
21551 // attribute clause on the same construct.
21552
21553 // Check conflicts with other map clause expressions. We check the conflicts
21554 // with the current construct separately from the enclosing data
21555 // environment, because the restrictions are different. We only have to
21556 // check conflicts across regions for the map clauses.
21557 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21558 /*CurrentRegionOnly=*/true, CurComponents, CKind))
21559 break;
21560 if (CKind == OMPC_map &&
21561 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
21562 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21563 /*CurrentRegionOnly=*/false, CurComponents, CKind))
21564 break;
21565
21566 // OpenMP 4.5 [2.10.5, target update Construct]
21567 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21568 // If the type of a list item is a reference to a type T then the type will
21569 // be considered to be T for all purposes of this clause.
21570 auto I = llvm::find_if(
21571 CurComponents,
21572 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
21573 return MC.getAssociatedDeclaration();
21574 });
21575 assert(I != CurComponents.end() && "Null decl on map clause.");
21576 (void)I;
21577 QualType Type;
21578 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
21579 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
21580 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
21581 if (ASE) {
21582 Type = ASE->getType().getNonReferenceType();
21583 } else if (OASE) {
21584 QualType BaseType =
21585 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21586 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21587 Type = ATy->getElementType();
21588 else
21589 Type = BaseType->getPointeeType();
21590 Type = Type.getNonReferenceType();
21591 } else if (OAShE) {
21592 Type = OAShE->getBase()->getType()->getPointeeType();
21593 } else {
21594 Type = VE->getType();
21595 }
21596
21597 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21598 // A list item in a to or from clause must have a mappable type.
21599 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21600 // A list item must have a mappable type.
21601 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21602 DSAS, Type, /*FullCheck=*/true))
21603 continue;
21604
21605 if (CKind == OMPC_map) {
21606 // target enter data
21607 // OpenMP [2.10.2, Restrictions, p. 99]
21608 // A map-type must be specified in all map clauses and must be either
21609 // to or alloc.
21610 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21611 if (DKind == OMPD_target_enter_data &&
21612 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
21613 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21614 << (IsMapTypeImplicit ? 1 : 0)
21615 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21616 << getOpenMPDirectiveName(DKind);
21617 continue;
21618 }
21619
21620 // target exit_data
21621 // OpenMP [2.10.3, Restrictions, p. 102]
21622 // A map-type must be specified in all map clauses and must be either
21623 // from, release, or delete.
21624 if (DKind == OMPD_target_exit_data &&
21625 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21626 MapType == OMPC_MAP_delete)) {
21627 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21628 << (IsMapTypeImplicit ? 1 : 0)
21629 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21630 << getOpenMPDirectiveName(DKind);
21631 continue;
21632 }
21633
21634 // The 'ompx_hold' modifier is specifically intended to be used on a
21635 // 'target' or 'target data' directive to prevent data from being unmapped
21636 // during the associated statement. It is not permitted on a 'target
21637 // enter data' or 'target exit data' directive, which have no associated
21638 // statement.
21639 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21640 HasHoldModifier) {
21641 SemaRef.Diag(StartLoc,
21642 diag::err_omp_invalid_map_type_modifier_for_directive)
21643 << getOpenMPSimpleClauseTypeName(OMPC_map,
21644 OMPC_MAP_MODIFIER_ompx_hold)
21645 << getOpenMPDirectiveName(DKind);
21646 continue;
21647 }
21648
21649 // target, target data
21650 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21651 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21652 // A map-type in a map clause must be to, from, tofrom or alloc
21653 if ((DKind == OMPD_target_data ||
21654 isOpenMPTargetExecutionDirective(DKind)) &&
21655 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21656 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21657 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21658 << (IsMapTypeImplicit ? 1 : 0)
21659 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21660 << getOpenMPDirectiveName(DKind);
21661 continue;
21662 }
21663
21664 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21665 // A list item cannot appear in both a map clause and a data-sharing
21666 // attribute clause on the same construct
21667 //
21668 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21669 // A list item cannot appear in both a map clause and a data-sharing
21670 // attribute clause on the same construct unless the construct is a
21671 // combined construct.
21672 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21673 isOpenMPTargetExecutionDirective(DKind)) ||
21674 DKind == OMPD_target)) {
21675 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21676 if (isOpenMPPrivate(DVar.CKind)) {
21677 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21678 << getOpenMPClauseName(DVar.CKind)
21679 << getOpenMPClauseName(OMPC_map)
21680 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21681 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21682 continue;
21683 }
21684 }
21685 }
21686
21687 // Try to find the associated user-defined mapper.
21688 ExprResult ER = buildUserDefinedMapperRef(
21689 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21690 Type.getCanonicalType(), UnresolvedMapper);
21691 if (ER.isInvalid())
21692 continue;
21693 MVLI.UDMapperList.push_back(ER.get());
21694
21695 // Save the current expression.
21696 MVLI.ProcessedVarList.push_back(RE);
21697
21698 // Store the components in the stack so that they can be used to check
21699 // against other clauses later on.
21700 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21701 /*WhereFoundClauseKind=*/OMPC_map);
21702
21703 // Save the components and declaration to create the clause. For purposes of
21704 // the clause creation, any component list that has has base 'this' uses
21705 // null as base declaration.
21706 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21707 MVLI.VarComponents.back().append(CurComponents.begin(),
21708 CurComponents.end());
21709 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
21710 : CurDeclaration);
21711 }
21712 }
21713
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,bool NoDiagnose,ArrayRef<Expr * > UnresolvedMappers)21714 OMPClause *Sema::ActOnOpenMPMapClause(
21715 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
21716 ArrayRef<SourceLocation> MapTypeModifiersLoc,
21717 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21718 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
21719 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21720 const OMPVarListLocTy &Locs, bool NoDiagnose,
21721 ArrayRef<Expr *> UnresolvedMappers) {
21722 OpenMPMapModifierKind Modifiers[] = {
21723 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21724 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21725 OMPC_MAP_MODIFIER_unknown};
21726 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
21727
21728 // Process map-type-modifiers, flag errors for duplicate modifiers.
21729 unsigned Count = 0;
21730 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21731 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
21732 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21733 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21734 continue;
21735 }
21736 assert(Count < NumberOfOMPMapClauseModifiers &&
21737 "Modifiers exceed the allowed number of map type modifiers");
21738 Modifiers[Count] = MapTypeModifiers[I];
21739 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21740 ++Count;
21741 }
21742
21743 MappableVarListInfo MVLI(VarList);
21744 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
21745 MapperIdScopeSpec, MapperId, UnresolvedMappers,
21746 MapType, Modifiers, IsMapTypeImplicit,
21747 NoDiagnose);
21748
21749 // We need to produce a map clause even if we don't have variables so that
21750 // other diagnostics related with non-existing map clauses are accurate.
21751 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
21752 MVLI.VarBaseDeclarations, MVLI.VarComponents,
21753 MVLI.UDMapperList, Modifiers, ModifiersLoc,
21754 MapperIdScopeSpec.getWithLocInContext(Context),
21755 MapperId, MapType, IsMapTypeImplicit, MapLoc);
21756 }
21757
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)21758 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
21759 TypeResult ParsedType) {
21760 assert(ParsedType.isUsable());
21761
21762 QualType ReductionType = GetTypeFromParser(ParsedType.get());
21763 if (ReductionType.isNull())
21764 return QualType();
21765
21766 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21767 // A type name in a declare reduction directive cannot be a function type, an
21768 // array type, a reference type, or a type qualified with const, volatile or
21769 // restrict.
21770 if (ReductionType.hasQualifiers()) {
21771 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21772 return QualType();
21773 }
21774
21775 if (ReductionType->isFunctionType()) {
21776 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21777 return QualType();
21778 }
21779 if (ReductionType->isReferenceType()) {
21780 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21781 return QualType();
21782 }
21783 if (ReductionType->isArrayType()) {
21784 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
21785 return QualType();
21786 }
21787 return ReductionType;
21788 }
21789
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)21790 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
21791 Scope *S, DeclContext *DC, DeclarationName Name,
21792 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
21793 AccessSpecifier AS, Decl *PrevDeclInScope) {
21794 SmallVector<Decl *, 8> Decls;
21795 Decls.reserve(ReductionTypes.size());
21796
21797 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
21798 forRedeclarationInCurContext());
21799 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
21800 // A reduction-identifier may not be re-declared in the current scope for the
21801 // same type or for a type that is compatible according to the base language
21802 // rules.
21803 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21804 OMPDeclareReductionDecl *PrevDRD = nullptr;
21805 bool InCompoundScope = true;
21806 if (S != nullptr) {
21807 // Find previous declaration with the same name not referenced in other
21808 // declarations.
21809 FunctionScopeInfo *ParentFn = getEnclosingFunction();
21810 InCompoundScope =
21811 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21812 LookupName(Lookup, S);
21813 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21814 /*AllowInlineNamespace=*/false);
21815 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
21816 LookupResult::Filter Filter = Lookup.makeFilter();
21817 while (Filter.hasNext()) {
21818 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
21819 if (InCompoundScope) {
21820 auto I = UsedAsPrevious.find(PrevDecl);
21821 if (I == UsedAsPrevious.end())
21822 UsedAsPrevious[PrevDecl] = false;
21823 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
21824 UsedAsPrevious[D] = true;
21825 }
21826 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21827 PrevDecl->getLocation();
21828 }
21829 Filter.done();
21830 if (InCompoundScope) {
21831 for (const auto &PrevData : UsedAsPrevious) {
21832 if (!PrevData.second) {
21833 PrevDRD = PrevData.first;
21834 break;
21835 }
21836 }
21837 }
21838 } else if (PrevDeclInScope != nullptr) {
21839 auto *PrevDRDInScope = PrevDRD =
21840 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
21841 do {
21842 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
21843 PrevDRDInScope->getLocation();
21844 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
21845 } while (PrevDRDInScope != nullptr);
21846 }
21847 for (const auto &TyData : ReductionTypes) {
21848 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
21849 bool Invalid = false;
21850 if (I != PreviousRedeclTypes.end()) {
21851 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
21852 << TyData.first;
21853 Diag(I->second, diag::note_previous_definition);
21854 Invalid = true;
21855 }
21856 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
21857 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
21858 Name, TyData.first, PrevDRD);
21859 DC->addDecl(DRD);
21860 DRD->setAccess(AS);
21861 Decls.push_back(DRD);
21862 if (Invalid)
21863 DRD->setInvalidDecl();
21864 else
21865 PrevDRD = DRD;
21866 }
21867
21868 return DeclGroupPtrTy::make(
21869 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
21870 }
21871
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)21872 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
21873 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21874
21875 // Enter new function scope.
21876 PushFunctionScope();
21877 setFunctionHasBranchProtectedScope();
21878 getCurFunction()->setHasOMPDeclareReductionCombiner();
21879
21880 if (S != nullptr)
21881 PushDeclContext(S, DRD);
21882 else
21883 CurContext = DRD;
21884
21885 PushExpressionEvaluationContext(
21886 ExpressionEvaluationContext::PotentiallyEvaluated);
21887
21888 QualType ReductionType = DRD->getType();
21889 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21890 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21891 // uses semantics of argument handles by value, but it should be passed by
21892 // reference. C lang does not support references, so pass all parameters as
21893 // pointers.
21894 // Create 'T omp_in;' variable.
21895 VarDecl *OmpInParm =
21896 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
21897 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21898 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21899 // uses semantics of argument handles by value, but it should be passed by
21900 // reference. C lang does not support references, so pass all parameters as
21901 // pointers.
21902 // Create 'T omp_out;' variable.
21903 VarDecl *OmpOutParm =
21904 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
21905 if (S != nullptr) {
21906 PushOnScopeChains(OmpInParm, S);
21907 PushOnScopeChains(OmpOutParm, S);
21908 } else {
21909 DRD->addDecl(OmpInParm);
21910 DRD->addDecl(OmpOutParm);
21911 }
21912 Expr *InE =
21913 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
21914 Expr *OutE =
21915 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
21916 DRD->setCombinerData(InE, OutE);
21917 }
21918
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)21919 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
21920 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21921 DiscardCleanupsInEvaluationContext();
21922 PopExpressionEvaluationContext();
21923
21924 PopDeclContext();
21925 PopFunctionScopeInfo();
21926
21927 if (Combiner != nullptr)
21928 DRD->setCombiner(Combiner);
21929 else
21930 DRD->setInvalidDecl();
21931 }
21932
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)21933 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
21934 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21935
21936 // Enter new function scope.
21937 PushFunctionScope();
21938 setFunctionHasBranchProtectedScope();
21939
21940 if (S != nullptr)
21941 PushDeclContext(S, DRD);
21942 else
21943 CurContext = DRD;
21944
21945 PushExpressionEvaluationContext(
21946 ExpressionEvaluationContext::PotentiallyEvaluated);
21947
21948 QualType ReductionType = DRD->getType();
21949 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21950 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21951 // uses semantics of argument handles by value, but it should be passed by
21952 // reference. C lang does not support references, so pass all parameters as
21953 // pointers.
21954 // Create 'T omp_priv;' variable.
21955 VarDecl *OmpPrivParm =
21956 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
21957 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21958 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21959 // uses semantics of argument handles by value, but it should be passed by
21960 // reference. C lang does not support references, so pass all parameters as
21961 // pointers.
21962 // Create 'T omp_orig;' variable.
21963 VarDecl *OmpOrigParm =
21964 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
21965 if (S != nullptr) {
21966 PushOnScopeChains(OmpPrivParm, S);
21967 PushOnScopeChains(OmpOrigParm, S);
21968 } else {
21969 DRD->addDecl(OmpPrivParm);
21970 DRD->addDecl(OmpOrigParm);
21971 }
21972 Expr *OrigE =
21973 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
21974 Expr *PrivE =
21975 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
21976 DRD->setInitializerData(OrigE, PrivE);
21977 return OmpPrivParm;
21978 }
21979
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)21980 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
21981 VarDecl *OmpPrivParm) {
21982 auto *DRD = cast<OMPDeclareReductionDecl>(D);
21983 DiscardCleanupsInEvaluationContext();
21984 PopExpressionEvaluationContext();
21985
21986 PopDeclContext();
21987 PopFunctionScopeInfo();
21988
21989 if (Initializer != nullptr) {
21990 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
21991 } else if (OmpPrivParm->hasInit()) {
21992 DRD->setInitializer(OmpPrivParm->getInit(),
21993 OmpPrivParm->isDirectInit()
21994 ? OMPDeclareReductionDecl::DirectInit
21995 : OMPDeclareReductionDecl::CopyInit);
21996 } else {
21997 DRD->setInvalidDecl();
21998 }
21999 }
22000
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)22001 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22002 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22003 for (Decl *D : DeclReductions.get()) {
22004 if (IsValid) {
22005 if (S)
22006 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22007 /*AddToContext=*/false);
22008 } else {
22009 D->setInvalidDecl();
22010 }
22011 }
22012 return DeclReductions;
22013 }
22014
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)22015 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22016 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22017 QualType T = TInfo->getType();
22018 if (D.isInvalidType())
22019 return true;
22020
22021 if (getLangOpts().CPlusPlus) {
22022 // Check that there are no default arguments (C++ only).
22023 CheckExtraCXXDefaultArguments(D);
22024 }
22025
22026 return CreateParsedType(T, TInfo);
22027 }
22028
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)22029 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22030 TypeResult ParsedType) {
22031 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22032
22033 QualType MapperType = GetTypeFromParser(ParsedType.get());
22034 assert(!MapperType.isNull() && "Expect valid mapper type");
22035
22036 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22037 // The type must be of struct, union or class type in C and C++
22038 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22039 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22040 return QualType();
22041 }
22042 return MapperType;
22043 }
22044
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)22045 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22046 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22047 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22048 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22049 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22050 forRedeclarationInCurContext());
22051 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22052 // A mapper-identifier may not be redeclared in the current scope for the
22053 // same type or for a type that is compatible according to the base language
22054 // rules.
22055 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22056 OMPDeclareMapperDecl *PrevDMD = nullptr;
22057 bool InCompoundScope = true;
22058 if (S != nullptr) {
22059 // Find previous declaration with the same name not referenced in other
22060 // declarations.
22061 FunctionScopeInfo *ParentFn = getEnclosingFunction();
22062 InCompoundScope =
22063 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22064 LookupName(Lookup, S);
22065 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22066 /*AllowInlineNamespace=*/false);
22067 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22068 LookupResult::Filter Filter = Lookup.makeFilter();
22069 while (Filter.hasNext()) {
22070 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22071 if (InCompoundScope) {
22072 auto I = UsedAsPrevious.find(PrevDecl);
22073 if (I == UsedAsPrevious.end())
22074 UsedAsPrevious[PrevDecl] = false;
22075 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22076 UsedAsPrevious[D] = true;
22077 }
22078 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22079 PrevDecl->getLocation();
22080 }
22081 Filter.done();
22082 if (InCompoundScope) {
22083 for (const auto &PrevData : UsedAsPrevious) {
22084 if (!PrevData.second) {
22085 PrevDMD = PrevData.first;
22086 break;
22087 }
22088 }
22089 }
22090 } else if (PrevDeclInScope) {
22091 auto *PrevDMDInScope = PrevDMD =
22092 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22093 do {
22094 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22095 PrevDMDInScope->getLocation();
22096 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22097 } while (PrevDMDInScope != nullptr);
22098 }
22099 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22100 bool Invalid = false;
22101 if (I != PreviousRedeclTypes.end()) {
22102 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22103 << MapperType << Name;
22104 Diag(I->second, diag::note_previous_definition);
22105 Invalid = true;
22106 }
22107 // Build expressions for implicit maps of data members with 'default'
22108 // mappers.
22109 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22110 Clauses.end());
22111 if (LangOpts.OpenMP >= 50)
22112 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22113 auto *DMD =
22114 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22115 ClausesWithImplicit, PrevDMD);
22116 if (S)
22117 PushOnScopeChains(DMD, S);
22118 else
22119 DC->addDecl(DMD);
22120 DMD->setAccess(AS);
22121 if (Invalid)
22122 DMD->setInvalidDecl();
22123
22124 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22125 VD->setDeclContext(DMD);
22126 VD->setLexicalDeclContext(DMD);
22127 DMD->addDecl(VD);
22128 DMD->setMapperVarRef(MapperVarRef);
22129
22130 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22131 }
22132
22133 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)22134 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22135 SourceLocation StartLoc,
22136 DeclarationName VN) {
22137 TypeSourceInfo *TInfo =
22138 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22139 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22140 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22141 MapperType, TInfo, SC_None);
22142 if (S)
22143 PushOnScopeChains(VD, S, /*AddToContext=*/false);
22144 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22145 DSAStack->addDeclareMapperVarRef(E);
22146 return E;
22147 }
22148
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const22149 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22150 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22151 const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22152 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22153 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22154 return true;
22155 if (VD->isUsableInConstantExpressions(Context))
22156 return true;
22157 return false;
22158 }
22159 return true;
22160 }
22161
getOpenMPDeclareMapperVarName() const22162 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22163 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22164 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22165 }
22166
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22167 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22168 SourceLocation StartLoc,
22169 SourceLocation LParenLoc,
22170 SourceLocation EndLoc) {
22171 Expr *ValExpr = NumTeams;
22172 Stmt *HelperValStmt = nullptr;
22173
22174 // OpenMP [teams Constrcut, Restrictions]
22175 // The num_teams expression must evaluate to a positive integer value.
22176 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22177 /*StrictlyPositive=*/true))
22178 return nullptr;
22179
22180 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22181 OpenMPDirectiveKind CaptureRegion =
22182 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22183 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22184 ValExpr = MakeFullExpr(ValExpr).get();
22185 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22186 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22187 HelperValStmt = buildPreInits(Context, Captures);
22188 }
22189
22190 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22191 StartLoc, LParenLoc, EndLoc);
22192 }
22193
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22194 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22195 SourceLocation StartLoc,
22196 SourceLocation LParenLoc,
22197 SourceLocation EndLoc) {
22198 Expr *ValExpr = ThreadLimit;
22199 Stmt *HelperValStmt = nullptr;
22200
22201 // OpenMP [teams Constrcut, Restrictions]
22202 // The thread_limit expression must evaluate to a positive integer value.
22203 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22204 /*StrictlyPositive=*/true))
22205 return nullptr;
22206
22207 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22208 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22209 DKind, OMPC_thread_limit, LangOpts.OpenMP);
22210 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22211 ValExpr = MakeFullExpr(ValExpr).get();
22212 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22213 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22214 HelperValStmt = buildPreInits(Context, Captures);
22215 }
22216
22217 return new (Context) OMPThreadLimitClause(
22218 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22219 }
22220
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22221 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22222 SourceLocation StartLoc,
22223 SourceLocation LParenLoc,
22224 SourceLocation EndLoc) {
22225 Expr *ValExpr = Priority;
22226 Stmt *HelperValStmt = nullptr;
22227 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22228
22229 // OpenMP [2.9.1, task Constrcut]
22230 // The priority-value is a non-negative numerical scalar expression.
22231 if (!isNonNegativeIntegerValue(
22232 ValExpr, *this, OMPC_priority,
22233 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22234 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22235 return nullptr;
22236
22237 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22238 StartLoc, LParenLoc, EndLoc);
22239 }
22240
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22241 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
22242 SourceLocation StartLoc,
22243 SourceLocation LParenLoc,
22244 SourceLocation EndLoc) {
22245 Expr *ValExpr = Grainsize;
22246 Stmt *HelperValStmt = nullptr;
22247 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22248
22249 // OpenMP [2.9.2, taskloop Constrcut]
22250 // The parameter of the grainsize clause must be a positive integer
22251 // expression.
22252 if (!isNonNegativeIntegerValue(
22253 ValExpr, *this, OMPC_grainsize,
22254 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22255 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22256 return nullptr;
22257
22258 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
22259 StartLoc, LParenLoc, EndLoc);
22260 }
22261
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22262 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
22263 SourceLocation StartLoc,
22264 SourceLocation LParenLoc,
22265 SourceLocation EndLoc) {
22266 Expr *ValExpr = NumTasks;
22267 Stmt *HelperValStmt = nullptr;
22268 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22269
22270 // OpenMP [2.9.2, taskloop Constrcut]
22271 // The parameter of the num_tasks clause must be a positive integer
22272 // expression.
22273 if (!isNonNegativeIntegerValue(
22274 ValExpr, *this, OMPC_num_tasks,
22275 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22276 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22277 return nullptr;
22278
22279 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
22280 StartLoc, LParenLoc, EndLoc);
22281 }
22282
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22283 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
22284 SourceLocation LParenLoc,
22285 SourceLocation EndLoc) {
22286 // OpenMP [2.13.2, critical construct, Description]
22287 // ... where hint-expression is an integer constant expression that evaluates
22288 // to a valid lock hint.
22289 ExprResult HintExpr =
22290 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22291 if (HintExpr.isInvalid())
22292 return nullptr;
22293 return new (Context)
22294 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22295 }
22296
22297 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)22298 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
22299 DSAStackTy *Stack) {
22300 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22301 if (!OMPEventHandleT.isNull())
22302 return true;
22303 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22304 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22305 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22306 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22307 return false;
22308 }
22309 Stack->setOMPEventHandleT(PT.get());
22310 return true;
22311 }
22312
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22313 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
22314 SourceLocation LParenLoc,
22315 SourceLocation EndLoc) {
22316 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
22317 !Evt->isInstantiationDependent() &&
22318 !Evt->containsUnexpandedParameterPack()) {
22319 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
22320 return nullptr;
22321 // OpenMP 5.0, 2.10.1 task Construct.
22322 // event-handle is a variable of the omp_event_handle_t type.
22323 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22324 if (!Ref) {
22325 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22326 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22327 return nullptr;
22328 }
22329 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22330 if (!VD) {
22331 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22332 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22333 return nullptr;
22334 }
22335 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
22336 VD->getType()) ||
22337 VD->getType().isConstant(Context)) {
22338 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22339 << "omp_event_handle_t" << 1 << VD->getType()
22340 << Evt->getSourceRange();
22341 return nullptr;
22342 }
22343 // OpenMP 5.0, 2.10.1 task Construct
22344 // [detach clause]... The event-handle will be considered as if it was
22345 // specified on a firstprivate clause.
22346 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
22347 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22348 DVar.RefExpr) {
22349 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
22350 << getOpenMPClauseName(DVar.CKind)
22351 << getOpenMPClauseName(OMPC_firstprivate);
22352 reportOriginalDsa(*this, DSAStack, VD, DVar);
22353 return nullptr;
22354 }
22355 }
22356
22357 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
22358 }
22359
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)22360 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
22361 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
22362 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
22363 SourceLocation EndLoc) {
22364 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
22365 std::string Values;
22366 Values += "'";
22367 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
22368 Values += "'";
22369 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22370 << Values << getOpenMPClauseName(OMPC_dist_schedule);
22371 return nullptr;
22372 }
22373 Expr *ValExpr = ChunkSize;
22374 Stmt *HelperValStmt = nullptr;
22375 if (ChunkSize) {
22376 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
22377 !ChunkSize->isInstantiationDependent() &&
22378 !ChunkSize->containsUnexpandedParameterPack()) {
22379 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
22380 ExprResult Val =
22381 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
22382 if (Val.isInvalid())
22383 return nullptr;
22384
22385 ValExpr = Val.get();
22386
22387 // OpenMP [2.7.1, Restrictions]
22388 // chunk_size must be a loop invariant integer expression with a positive
22389 // value.
22390 if (Optional<llvm::APSInt> Result =
22391 ValExpr->getIntegerConstantExpr(Context)) {
22392 if (Result->isSigned() && !Result->isStrictlyPositive()) {
22393 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22394 << "dist_schedule" << ChunkSize->getSourceRange();
22395 return nullptr;
22396 }
22397 } else if (getOpenMPCaptureRegionForClause(
22398 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
22399 LangOpts.OpenMP) != OMPD_unknown &&
22400 !CurContext->isDependentContext()) {
22401 ValExpr = MakeFullExpr(ValExpr).get();
22402 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22403 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22404 HelperValStmt = buildPreInits(Context, Captures);
22405 }
22406 }
22407 }
22408
22409 return new (Context)
22410 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
22411 Kind, ValExpr, HelperValStmt);
22412 }
22413
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)22414 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
22415 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
22416 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
22417 SourceLocation KindLoc, SourceLocation EndLoc) {
22418 if (getLangOpts().OpenMP < 50) {
22419 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22420 Kind != OMPC_DEFAULTMAP_scalar) {
22421 std::string Value;
22422 SourceLocation Loc;
22423 Value += "'";
22424 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22425 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22426 OMPC_DEFAULTMAP_MODIFIER_tofrom);
22427 Loc = MLoc;
22428 } else {
22429 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22430 OMPC_DEFAULTMAP_scalar);
22431 Loc = KindLoc;
22432 }
22433 Value += "'";
22434 Diag(Loc, diag::err_omp_unexpected_clause_value)
22435 << Value << getOpenMPClauseName(OMPC_defaultmap);
22436 return nullptr;
22437 }
22438 } else {
22439 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
22440 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
22441 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
22442 if (!isDefaultmapKind || !isDefaultmapModifier) {
22443 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
22444 if (LangOpts.OpenMP == 50) {
22445 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
22446 "'firstprivate', 'none', 'default'";
22447 if (!isDefaultmapKind && isDefaultmapModifier) {
22448 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22449 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22450 } else if (isDefaultmapKind && !isDefaultmapModifier) {
22451 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22452 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22453 } else {
22454 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22455 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22456 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22457 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22458 }
22459 } else {
22460 StringRef ModifierValue =
22461 "'alloc', 'from', 'to', 'tofrom', "
22462 "'firstprivate', 'none', 'default', 'present'";
22463 if (!isDefaultmapKind && isDefaultmapModifier) {
22464 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22465 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22466 } else if (isDefaultmapKind && !isDefaultmapModifier) {
22467 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22468 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22469 } else {
22470 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22471 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22472 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22473 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22474 }
22475 }
22476 return nullptr;
22477 }
22478
22479 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22480 // At most one defaultmap clause for each category can appear on the
22481 // directive.
22482 if (DSAStack->checkDefaultmapCategory(Kind)) {
22483 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22484 return nullptr;
22485 }
22486 }
22487 if (Kind == OMPC_DEFAULTMAP_unknown) {
22488 // Variable category is not specified - mark all categories.
22489 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22490 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22491 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22492 } else {
22493 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
22494 }
22495
22496 return new (Context)
22497 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
22498 }
22499
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)22500 bool Sema::ActOnStartOpenMPDeclareTargetContext(
22501 DeclareTargetContextInfo &DTCI) {
22502 DeclContext *CurLexicalContext = getCurLexicalContext();
22503 if (!CurLexicalContext->isFileContext() &&
22504 !CurLexicalContext->isExternCContext() &&
22505 !CurLexicalContext->isExternCXXContext() &&
22506 !isa<CXXRecordDecl>(CurLexicalContext) &&
22507 !isa<ClassTemplateDecl>(CurLexicalContext) &&
22508 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22509 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22510 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22511 return false;
22512 }
22513 DeclareTargetNesting.push_back(DTCI);
22514 return true;
22515 }
22516
22517 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()22518 Sema::ActOnOpenMPEndDeclareTargetDirective() {
22519 assert(!DeclareTargetNesting.empty() &&
22520 "check isInOpenMPDeclareTargetContext() first!");
22521 return DeclareTargetNesting.pop_back_val();
22522 }
22523
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)22524 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
22525 DeclareTargetContextInfo &DTCI) {
22526 for (auto &It : DTCI.ExplicitlyMapped)
22527 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
22528 }
22529
DiagnoseUnterminatedOpenMPDeclareTarget()22530 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
22531 if (DeclareTargetNesting.empty())
22532 return;
22533 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22534 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
22535 << getOpenMPDirectiveName(DTCI.Kind);
22536 }
22537
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)22538 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
22539 CXXScopeSpec &ScopeSpec,
22540 const DeclarationNameInfo &Id) {
22541 LookupResult Lookup(*this, Id, LookupOrdinaryName);
22542 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
22543
22544 if (Lookup.isAmbiguous())
22545 return nullptr;
22546 Lookup.suppressDiagnostics();
22547
22548 if (!Lookup.isSingleResult()) {
22549 VarOrFuncDeclFilterCCC CCC(*this);
22550 if (TypoCorrection Corrected =
22551 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
22552 CTK_ErrorRecovery)) {
22553 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
22554 << Id.getName());
22555 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
22556 return nullptr;
22557 }
22558
22559 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
22560 return nullptr;
22561 }
22562
22563 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
22564 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
22565 !isa<FunctionTemplateDecl>(ND)) {
22566 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
22567 return nullptr;
22568 }
22569 return ND;
22570 }
22571
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,DeclareTargetContextInfo & DTCI)22572 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
22573 OMPDeclareTargetDeclAttr::MapTypeTy MT,
22574 DeclareTargetContextInfo &DTCI) {
22575 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
22576 isa<FunctionTemplateDecl>(ND)) &&
22577 "Expected variable, function or function template.");
22578
22579 // Diagnose marking after use as it may lead to incorrect diagnosis and
22580 // codegen.
22581 if (LangOpts.OpenMP >= 50 &&
22582 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
22583 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
22584
22585 // Explicit declare target lists have precedence.
22586 const unsigned Level = -1;
22587
22588 auto *VD = cast<ValueDecl>(ND);
22589 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22590 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22591 if (ActiveAttr && ActiveAttr.value()->getDevType() != DTCI.DT &&
22592 ActiveAttr.value()->getLevel() == Level) {
22593 Diag(Loc, diag::err_omp_device_type_mismatch)
22594 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22595 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22596 ActiveAttr.value()->getDevType());
22597 return;
22598 }
22599 if (ActiveAttr && ActiveAttr.value()->getMapType() != MT &&
22600 ActiveAttr.value()->getLevel() == Level) {
22601 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22602 return;
22603 }
22604
22605 if (ActiveAttr && ActiveAttr.value()->getLevel() == Level)
22606 return;
22607
22608 Expr *IndirectE = nullptr;
22609 bool IsIndirect = false;
22610 if (DTCI.Indirect) {
22611 IndirectE = DTCI.Indirect.value();
22612 if (!IndirectE)
22613 IsIndirect = true;
22614 }
22615 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22616 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22617 SourceRange(Loc, Loc));
22618 ND->addAttr(A);
22619 if (ASTMutationListener *ML = Context.getASTMutationListener())
22620 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22621 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22622 }
22623
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)22624 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
22625 Sema &SemaRef, Decl *D) {
22626 if (!D || !isa<VarDecl>(D))
22627 return;
22628 auto *VD = cast<VarDecl>(D);
22629 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
22630 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22631 if (SemaRef.LangOpts.OpenMP >= 50 &&
22632 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22633 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22634 VD->hasGlobalStorage()) {
22635 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
22636 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22637 // If a lambda declaration and definition appears between a
22638 // declare target directive and the matching end declare target
22639 // directive, all variables that are captured by the lambda
22640 // expression must also appear in a to clause.
22641 SemaRef.Diag(VD->getLocation(),
22642 diag::err_omp_lambda_capture_in_declare_target_not_to);
22643 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22644 << VD << 0 << SR;
22645 return;
22646 }
22647 }
22648 if (MapTy)
22649 return;
22650 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22651 SemaRef.Diag(SL, diag::note_used_here) << SR;
22652 }
22653
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)22654 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
22655 Sema &SemaRef, DSAStackTy *Stack,
22656 ValueDecl *VD) {
22657 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22658 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
22659 /*FullCheck=*/false);
22660 }
22661
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)22662 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
22663 SourceLocation IdLoc) {
22664 if (!D || D->isInvalidDecl())
22665 return;
22666 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
22667 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
22668 if (auto *VD = dyn_cast<VarDecl>(D)) {
22669 // Only global variables can be marked as declare target.
22670 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22671 !VD->isStaticDataMember())
22672 return;
22673 // 2.10.6: threadprivate variable cannot appear in a declare target
22674 // directive.
22675 if (DSAStack->isThreadPrivate(VD)) {
22676 Diag(SL, diag::err_omp_threadprivate_in_target);
22677 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
22678 return;
22679 }
22680 }
22681 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22682 D = FTD->getTemplatedDecl();
22683 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
22684 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
22685 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22686 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22687 Diag(IdLoc, diag::err_omp_function_in_link_clause);
22688 Diag(FD->getLocation(), diag::note_defined_here) << FD;
22689 return;
22690 }
22691 }
22692 if (auto *VD = dyn_cast<ValueDecl>(D)) {
22693 // Problem if any with var declared with incomplete type will be reported
22694 // as normal, so no need to check it here.
22695 if ((E || !VD->getType()->isIncompleteType()) &&
22696 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
22697 return;
22698 if (!E && isInOpenMPDeclareTargetContext()) {
22699 // Checking declaration inside declare target region.
22700 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22701 isa<FunctionTemplateDecl>(D)) {
22702 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22703 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22704 unsigned Level = DeclareTargetNesting.size();
22705 if (ActiveAttr && ActiveAttr.value()->getLevel() >= Level)
22706 return;
22707 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22708 Expr *IndirectE = nullptr;
22709 bool IsIndirect = false;
22710 if (DTCI.Indirect) {
22711 IndirectE = DTCI.Indirect.value();
22712 if (!IndirectE)
22713 IsIndirect = true;
22714 }
22715 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22716 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
22717 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc));
22718 D->addAttr(A);
22719 if (ASTMutationListener *ML = Context.getASTMutationListener())
22720 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22721 }
22722 return;
22723 }
22724 }
22725 if (!E)
22726 return;
22727 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
22728 }
22729
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)22730 OMPClause *Sema::ActOnOpenMPToClause(
22731 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22732 ArrayRef<SourceLocation> MotionModifiersLoc,
22733 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22734 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22735 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22736 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22737 OMPC_MOTION_MODIFIER_unknown};
22738 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22739
22740 // Process motion-modifiers, flag errors for duplicate modifiers.
22741 unsigned Count = 0;
22742 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22743 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22744 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22745 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22746 continue;
22747 }
22748 assert(Count < NumberOfOMPMotionModifiers &&
22749 "Modifiers exceed the allowed number of motion modifiers");
22750 Modifiers[Count] = MotionModifiers[I];
22751 ModifiersLoc[Count] = MotionModifiersLoc[I];
22752 ++Count;
22753 }
22754
22755 MappableVarListInfo MVLI(VarList);
22756 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
22757 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22758 if (MVLI.ProcessedVarList.empty())
22759 return nullptr;
22760
22761 return OMPToClause::Create(
22762 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22763 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22764 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22765 }
22766
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)22767 OMPClause *Sema::ActOnOpenMPFromClause(
22768 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22769 ArrayRef<SourceLocation> MotionModifiersLoc,
22770 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22771 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22772 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22773 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22774 OMPC_MOTION_MODIFIER_unknown};
22775 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22776
22777 // Process motion-modifiers, flag errors for duplicate modifiers.
22778 unsigned Count = 0;
22779 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22780 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22781 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22782 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22783 continue;
22784 }
22785 assert(Count < NumberOfOMPMotionModifiers &&
22786 "Modifiers exceed the allowed number of motion modifiers");
22787 Modifiers[Count] = MotionModifiers[I];
22788 ModifiersLoc[Count] = MotionModifiersLoc[I];
22789 ++Count;
22790 }
22791
22792 MappableVarListInfo MVLI(VarList);
22793 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
22794 MapperIdScopeSpec, MapperId, UnresolvedMappers);
22795 if (MVLI.ProcessedVarList.empty())
22796 return nullptr;
22797
22798 return OMPFromClause::Create(
22799 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22800 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22801 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
22802 }
22803
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)22804 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
22805 const OMPVarListLocTy &Locs) {
22806 MappableVarListInfo MVLI(VarList);
22807 SmallVector<Expr *, 8> PrivateCopies;
22808 SmallVector<Expr *, 8> Inits;
22809
22810 for (Expr *RefExpr : VarList) {
22811 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
22812 SourceLocation ELoc;
22813 SourceRange ERange;
22814 Expr *SimpleRefExpr = RefExpr;
22815 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22816 if (Res.second) {
22817 // It will be analyzed later.
22818 MVLI.ProcessedVarList.push_back(RefExpr);
22819 PrivateCopies.push_back(nullptr);
22820 Inits.push_back(nullptr);
22821 }
22822 ValueDecl *D = Res.first;
22823 if (!D)
22824 continue;
22825
22826 QualType Type = D->getType();
22827 Type = Type.getNonReferenceType().getUnqualifiedType();
22828
22829 auto *VD = dyn_cast<VarDecl>(D);
22830
22831 // Item should be a pointer or reference to pointer.
22832 if (!Type->isPointerType()) {
22833 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
22834 << 0 << RefExpr->getSourceRange();
22835 continue;
22836 }
22837
22838 // Build the private variable and the expression that refers to it.
22839 auto VDPrivate =
22840 buildVarDecl(*this, ELoc, Type, D->getName(),
22841 D->hasAttrs() ? &D->getAttrs() : nullptr,
22842 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
22843 if (VDPrivate->isInvalidDecl())
22844 continue;
22845
22846 CurContext->addDecl(VDPrivate);
22847 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
22848 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
22849
22850 // Add temporary variable to initialize the private copy of the pointer.
22851 VarDecl *VDInit =
22852 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
22853 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
22854 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
22855 AddInitializerToDecl(VDPrivate,
22856 DefaultLvalueConversion(VDInitRefExpr).get(),
22857 /*DirectInit=*/false);
22858
22859 // If required, build a capture to implement the privatization initialized
22860 // with the current list item value.
22861 DeclRefExpr *Ref = nullptr;
22862 if (!VD)
22863 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22864 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22865 PrivateCopies.push_back(VDPrivateRefExpr);
22866 Inits.push_back(VDInitRefExpr);
22867
22868 // We need to add a data sharing attribute for this variable to make sure it
22869 // is correctly captured. A variable that shows up in a use_device_ptr has
22870 // similar properties of a first private variable.
22871 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22872
22873 // Create a mappable component for the list item. List items in this clause
22874 // only need a component.
22875 MVLI.VarBaseDeclarations.push_back(D);
22876 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22877 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
22878 /*IsNonContiguous=*/false);
22879 }
22880
22881 if (MVLI.ProcessedVarList.empty())
22882 return nullptr;
22883
22884 return OMPUseDevicePtrClause::Create(
22885 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
22886 MVLI.VarBaseDeclarations, MVLI.VarComponents);
22887 }
22888
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)22889 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
22890 const OMPVarListLocTy &Locs) {
22891 MappableVarListInfo MVLI(VarList);
22892
22893 for (Expr *RefExpr : VarList) {
22894 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
22895 SourceLocation ELoc;
22896 SourceRange ERange;
22897 Expr *SimpleRefExpr = RefExpr;
22898 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22899 /*AllowArraySection=*/true);
22900 if (Res.second) {
22901 // It will be analyzed later.
22902 MVLI.ProcessedVarList.push_back(RefExpr);
22903 }
22904 ValueDecl *D = Res.first;
22905 if (!D)
22906 continue;
22907 auto *VD = dyn_cast<VarDecl>(D);
22908
22909 // If required, build a capture to implement the privatization initialized
22910 // with the current list item value.
22911 DeclRefExpr *Ref = nullptr;
22912 if (!VD)
22913 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22914 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22915
22916 // We need to add a data sharing attribute for this variable to make sure it
22917 // is correctly captured. A variable that shows up in a use_device_addr has
22918 // similar properties of a first private variable.
22919 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22920
22921 // Create a mappable component for the list item. List items in this clause
22922 // only need a component.
22923 MVLI.VarBaseDeclarations.push_back(D);
22924 MVLI.VarComponents.emplace_back();
22925 Expr *Component = SimpleRefExpr;
22926 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22927 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22928 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
22929 MVLI.VarComponents.back().emplace_back(Component, D,
22930 /*IsNonContiguous=*/false);
22931 }
22932
22933 if (MVLI.ProcessedVarList.empty())
22934 return nullptr;
22935
22936 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22937 MVLI.VarBaseDeclarations,
22938 MVLI.VarComponents);
22939 }
22940
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)22941 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
22942 const OMPVarListLocTy &Locs) {
22943 MappableVarListInfo MVLI(VarList);
22944 for (Expr *RefExpr : VarList) {
22945 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
22946 SourceLocation ELoc;
22947 SourceRange ERange;
22948 Expr *SimpleRefExpr = RefExpr;
22949 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22950 if (Res.second) {
22951 // It will be analyzed later.
22952 MVLI.ProcessedVarList.push_back(RefExpr);
22953 }
22954 ValueDecl *D = Res.first;
22955 if (!D)
22956 continue;
22957
22958 QualType Type = D->getType();
22959 // item should be a pointer or array or reference to pointer or array
22960 if (!Type.getNonReferenceType()->isPointerType() &&
22961 !Type.getNonReferenceType()->isArrayType()) {
22962 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
22963 << 0 << RefExpr->getSourceRange();
22964 continue;
22965 }
22966
22967 // Check if the declaration in the clause does not show up in any data
22968 // sharing attribute.
22969 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
22970 if (isOpenMPPrivate(DVar.CKind)) {
22971 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22972 << getOpenMPClauseName(DVar.CKind)
22973 << getOpenMPClauseName(OMPC_is_device_ptr)
22974 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
22975 reportOriginalDsa(*this, DSAStack, D, DVar);
22976 continue;
22977 }
22978
22979 const Expr *ConflictExpr;
22980 if (DSAStack->checkMappableExprComponentListsForDecl(
22981 D, /*CurrentRegionOnly=*/true,
22982 [&ConflictExpr](
22983 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
22984 OpenMPClauseKind) -> bool {
22985 ConflictExpr = R.front().getAssociatedExpression();
22986 return true;
22987 })) {
22988 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22989 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
22990 << ConflictExpr->getSourceRange();
22991 continue;
22992 }
22993
22994 // Store the components in the stack so that they can be used to check
22995 // against other clauses later on.
22996 OMPClauseMappableExprCommon::MappableComponent MC(
22997 SimpleRefExpr, D, /*IsNonContiguous=*/false);
22998 DSAStack->addMappableExpressionComponents(
22999 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23000
23001 // Record the expression we've just processed.
23002 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23003
23004 // Create a mappable component for the list item. List items in this clause
23005 // only need a component. We use a null declaration to signal fields in
23006 // 'this'.
23007 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23008 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23009 "Unexpected device pointer expression!");
23010 MVLI.VarBaseDeclarations.push_back(
23011 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23012 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23013 MVLI.VarComponents.back().push_back(MC);
23014 }
23015
23016 if (MVLI.ProcessedVarList.empty())
23017 return nullptr;
23018
23019 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23020 MVLI.VarBaseDeclarations,
23021 MVLI.VarComponents);
23022 }
23023
ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)23024 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23025 const OMPVarListLocTy &Locs) {
23026 MappableVarListInfo MVLI(VarList);
23027 for (Expr *RefExpr : VarList) {
23028 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23029 SourceLocation ELoc;
23030 SourceRange ERange;
23031 Expr *SimpleRefExpr = RefExpr;
23032 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23033 /*AllowArraySection=*/true);
23034 if (Res.second) {
23035 // It will be analyzed later.
23036 MVLI.ProcessedVarList.push_back(RefExpr);
23037 }
23038 ValueDecl *D = Res.first;
23039 if (!D)
23040 continue;
23041
23042 // Check if the declaration in the clause does not show up in any data
23043 // sharing attribute.
23044 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23045 if (isOpenMPPrivate(DVar.CKind)) {
23046 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23047 << getOpenMPClauseName(DVar.CKind)
23048 << getOpenMPClauseName(OMPC_has_device_addr)
23049 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23050 reportOriginalDsa(*this, DSAStack, D, DVar);
23051 continue;
23052 }
23053
23054 const Expr *ConflictExpr;
23055 if (DSAStack->checkMappableExprComponentListsForDecl(
23056 D, /*CurrentRegionOnly=*/true,
23057 [&ConflictExpr](
23058 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23059 OpenMPClauseKind) -> bool {
23060 ConflictExpr = R.front().getAssociatedExpression();
23061 return true;
23062 })) {
23063 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23064 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23065 << ConflictExpr->getSourceRange();
23066 continue;
23067 }
23068
23069 // Store the components in the stack so that they can be used to check
23070 // against other clauses later on.
23071 OMPClauseMappableExprCommon::MappableComponent MC(
23072 SimpleRefExpr, D, /*IsNonContiguous=*/false);
23073 DSAStack->addMappableExpressionComponents(
23074 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23075
23076 // Record the expression we've just processed.
23077 auto *VD = dyn_cast<VarDecl>(D);
23078 if (!VD && !CurContext->isDependentContext()) {
23079 DeclRefExpr *Ref =
23080 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23081 assert(Ref && "has_device_addr capture failed");
23082 MVLI.ProcessedVarList.push_back(Ref);
23083 } else
23084 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23085
23086 // Create a mappable component for the list item. List items in this clause
23087 // only need a component. We use a null declaration to signal fields in
23088 // 'this'.
23089 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23090 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23091 "Unexpected device pointer expression!");
23092 MVLI.VarBaseDeclarations.push_back(
23093 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23094 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23095 MVLI.VarComponents.back().push_back(MC);
23096 }
23097
23098 if (MVLI.ProcessedVarList.empty())
23099 return nullptr;
23100
23101 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23102 MVLI.VarBaseDeclarations,
23103 MVLI.VarComponents);
23104 }
23105
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23106 OMPClause *Sema::ActOnOpenMPAllocateClause(
23107 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23108 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23109 if (Allocator) {
23110 // OpenMP [2.11.4 allocate Clause, Description]
23111 // allocator is an expression of omp_allocator_handle_t type.
23112 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23113 return nullptr;
23114
23115 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23116 if (AllocatorRes.isInvalid())
23117 return nullptr;
23118 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23119 DSAStack->getOMPAllocatorHandleT(),
23120 Sema::AA_Initializing,
23121 /*AllowExplicit=*/true);
23122 if (AllocatorRes.isInvalid())
23123 return nullptr;
23124 Allocator = AllocatorRes.get();
23125 } else {
23126 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23127 // allocate clauses that appear on a target construct or on constructs in a
23128 // target region must specify an allocator expression unless a requires
23129 // directive with the dynamic_allocators clause is present in the same
23130 // compilation unit.
23131 if (LangOpts.OpenMPIsDevice &&
23132 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23133 targetDiag(StartLoc, diag::err_expected_allocator_expression);
23134 }
23135 // Analyze and build list of variables.
23136 SmallVector<Expr *, 8> Vars;
23137 for (Expr *RefExpr : VarList) {
23138 assert(RefExpr && "NULL expr in OpenMP private clause.");
23139 SourceLocation ELoc;
23140 SourceRange ERange;
23141 Expr *SimpleRefExpr = RefExpr;
23142 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23143 if (Res.second) {
23144 // It will be analyzed later.
23145 Vars.push_back(RefExpr);
23146 }
23147 ValueDecl *D = Res.first;
23148 if (!D)
23149 continue;
23150
23151 auto *VD = dyn_cast<VarDecl>(D);
23152 DeclRefExpr *Ref = nullptr;
23153 if (!VD && !CurContext->isDependentContext())
23154 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23155 Vars.push_back((VD || CurContext->isDependentContext())
23156 ? RefExpr->IgnoreParens()
23157 : Ref);
23158 }
23159
23160 if (Vars.empty())
23161 return nullptr;
23162
23163 if (Allocator)
23164 DSAStack->addInnerAllocatorExpr(Allocator);
23165 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23166 ColonLoc, EndLoc, Vars);
23167 }
23168
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23169 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23170 SourceLocation StartLoc,
23171 SourceLocation LParenLoc,
23172 SourceLocation EndLoc) {
23173 SmallVector<Expr *, 8> Vars;
23174 for (Expr *RefExpr : VarList) {
23175 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23176 SourceLocation ELoc;
23177 SourceRange ERange;
23178 Expr *SimpleRefExpr = RefExpr;
23179 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23180 if (Res.second)
23181 // It will be analyzed later.
23182 Vars.push_back(RefExpr);
23183 ValueDecl *D = Res.first;
23184 if (!D)
23185 continue;
23186
23187 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23188 // A list-item cannot appear in more than one nontemporal clause.
23189 if (const Expr *PrevRef =
23190 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23191 Diag(ELoc, diag::err_omp_used_in_clause_twice)
23192 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23193 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23194 << getOpenMPClauseName(OMPC_nontemporal);
23195 continue;
23196 }
23197
23198 Vars.push_back(RefExpr);
23199 }
23200
23201 if (Vars.empty())
23202 return nullptr;
23203
23204 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23205 Vars);
23206 }
23207
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23208 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
23209 SourceLocation StartLoc,
23210 SourceLocation LParenLoc,
23211 SourceLocation EndLoc) {
23212 SmallVector<Expr *, 8> Vars;
23213 for (Expr *RefExpr : VarList) {
23214 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23215 SourceLocation ELoc;
23216 SourceRange ERange;
23217 Expr *SimpleRefExpr = RefExpr;
23218 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23219 /*AllowArraySection=*/true);
23220 if (Res.second)
23221 // It will be analyzed later.
23222 Vars.push_back(RefExpr);
23223 ValueDecl *D = Res.first;
23224 if (!D)
23225 continue;
23226
23227 const DSAStackTy::DSAVarData DVar =
23228 DSAStack->getTopDSA(D, /*FromParent=*/true);
23229 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23230 // A list item that appears in the inclusive or exclusive clause must appear
23231 // in a reduction clause with the inscan modifier on the enclosing
23232 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23233 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23234 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23235 << RefExpr->getSourceRange();
23236
23237 if (DSAStack->getParentDirective() != OMPD_unknown)
23238 DSAStack->markDeclAsUsedInScanDirective(D);
23239 Vars.push_back(RefExpr);
23240 }
23241
23242 if (Vars.empty())
23243 return nullptr;
23244
23245 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23246 }
23247
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23248 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
23249 SourceLocation StartLoc,
23250 SourceLocation LParenLoc,
23251 SourceLocation EndLoc) {
23252 SmallVector<Expr *, 8> Vars;
23253 for (Expr *RefExpr : VarList) {
23254 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23255 SourceLocation ELoc;
23256 SourceRange ERange;
23257 Expr *SimpleRefExpr = RefExpr;
23258 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23259 /*AllowArraySection=*/true);
23260 if (Res.second)
23261 // It will be analyzed later.
23262 Vars.push_back(RefExpr);
23263 ValueDecl *D = Res.first;
23264 if (!D)
23265 continue;
23266
23267 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
23268 DSAStackTy::DSAVarData DVar;
23269 if (ParentDirective != OMPD_unknown)
23270 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
23271 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23272 // A list item that appears in the inclusive or exclusive clause must appear
23273 // in a reduction clause with the inscan modifier on the enclosing
23274 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23275 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23276 DVar.Modifier != OMPC_REDUCTION_inscan) {
23277 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23278 << RefExpr->getSourceRange();
23279 } else {
23280 DSAStack->markDeclAsUsedInScanDirective(D);
23281 }
23282 Vars.push_back(RefExpr);
23283 }
23284
23285 if (Vars.empty())
23286 return nullptr;
23287
23288 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23289 }
23290
23291 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)23292 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
23293 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23294 if (!OMPAlloctraitT.isNull())
23295 return true;
23296 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
23297 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
23298 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23299 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
23300 return false;
23301 }
23302 Stack->setOMPAlloctraitT(PT.get());
23303 return true;
23304 }
23305
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)23306 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
23307 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
23308 ArrayRef<UsesAllocatorsData> Data) {
23309 // OpenMP [2.12.5, target Construct]
23310 // allocator is an identifier of omp_allocator_handle_t type.
23311 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
23312 return nullptr;
23313 // OpenMP [2.12.5, target Construct]
23314 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23315 if (llvm::any_of(
23316 Data,
23317 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
23318 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
23319 return nullptr;
23320 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
23321 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23322 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
23323 StringRef Allocator =
23324 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23325 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
23326 PredefinedAllocators.insert(LookupSingleName(
23327 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
23328 }
23329
23330 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
23331 for (const UsesAllocatorsData &D : Data) {
23332 Expr *AllocatorExpr = nullptr;
23333 // Check allocator expression.
23334 if (D.Allocator->isTypeDependent()) {
23335 AllocatorExpr = D.Allocator;
23336 } else {
23337 // Traits were specified - need to assign new allocator to the specified
23338 // allocator, so it must be an lvalue.
23339 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
23340 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23341 bool IsPredefinedAllocator = false;
23342 if (DRE)
23343 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
23344 if (!DRE ||
23345 !(Context.hasSameUnqualifiedType(
23346 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
23347 Context.typesAreCompatible(AllocatorExpr->getType(),
23348 DSAStack->getOMPAllocatorHandleT(),
23349 /*CompareUnqualified=*/true)) ||
23350 (!IsPredefinedAllocator &&
23351 (AllocatorExpr->getType().isConstant(Context) ||
23352 !AllocatorExpr->isLValue()))) {
23353 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
23354 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
23355 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
23356 continue;
23357 }
23358 // OpenMP [2.12.5, target Construct]
23359 // Predefined allocators appearing in a uses_allocators clause cannot have
23360 // traits specified.
23361 if (IsPredefinedAllocator && D.AllocatorTraits) {
23362 Diag(D.AllocatorTraits->getExprLoc(),
23363 diag::err_omp_predefined_allocator_with_traits)
23364 << D.AllocatorTraits->getSourceRange();
23365 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
23366 << cast<NamedDecl>(DRE->getDecl())->getName()
23367 << D.Allocator->getSourceRange();
23368 continue;
23369 }
23370 // OpenMP [2.12.5, target Construct]
23371 // Non-predefined allocators appearing in a uses_allocators clause must
23372 // have traits specified.
23373 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
23374 Diag(D.Allocator->getExprLoc(),
23375 diag::err_omp_nonpredefined_allocator_without_traits);
23376 continue;
23377 }
23378 // No allocator traits - just convert it to rvalue.
23379 if (!D.AllocatorTraits)
23380 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
23381 DSAStack->addUsesAllocatorsDecl(
23382 DRE->getDecl(),
23383 IsPredefinedAllocator
23384 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23385 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23386 }
23387 Expr *AllocatorTraitsExpr = nullptr;
23388 if (D.AllocatorTraits) {
23389 if (D.AllocatorTraits->isTypeDependent()) {
23390 AllocatorTraitsExpr = D.AllocatorTraits;
23391 } else {
23392 // OpenMP [2.12.5, target Construct]
23393 // Arrays that contain allocator traits that appear in a uses_allocators
23394 // clause must be constant arrays, have constant values and be defined
23395 // in the same scope as the construct in which the clause appears.
23396 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
23397 // Check that traits expr is a constant array.
23398 QualType TraitTy;
23399 if (const ArrayType *Ty =
23400 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
23401 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23402 TraitTy = ConstArrayTy->getElementType();
23403 if (TraitTy.isNull() ||
23404 !(Context.hasSameUnqualifiedType(TraitTy,
23405 DSAStack->getOMPAlloctraitT()) ||
23406 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
23407 /*CompareUnqualified=*/true))) {
23408 Diag(D.AllocatorTraits->getExprLoc(),
23409 diag::err_omp_expected_array_alloctraits)
23410 << AllocatorTraitsExpr->getType();
23411 continue;
23412 }
23413 // Do not map by default allocator traits if it is a standalone
23414 // variable.
23415 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23416 DSAStack->addUsesAllocatorsDecl(
23417 DRE->getDecl(),
23418 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23419 }
23420 }
23421 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
23422 NewD.Allocator = AllocatorExpr;
23423 NewD.AllocatorTraits = AllocatorTraitsExpr;
23424 NewD.LParenLoc = D.LParenLoc;
23425 NewD.RParenLoc = D.RParenLoc;
23426 }
23427 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23428 NewData);
23429 }
23430
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)23431 OMPClause *Sema::ActOnOpenMPAffinityClause(
23432 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23433 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
23434 SmallVector<Expr *, 8> Vars;
23435 for (Expr *RefExpr : Locators) {
23436 assert(RefExpr && "NULL expr in OpenMP shared clause.");
23437 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23438 // It will be analyzed later.
23439 Vars.push_back(RefExpr);
23440 continue;
23441 }
23442
23443 SourceLocation ELoc = RefExpr->getExprLoc();
23444 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
23445
23446 if (!SimpleExpr->isLValue()) {
23447 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23448 << 1 << 0 << RefExpr->getSourceRange();
23449 continue;
23450 }
23451
23452 ExprResult Res;
23453 {
23454 Sema::TentativeAnalysisScope Trap(*this);
23455 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
23456 }
23457 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
23458 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
23459 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23460 << 1 << 0 << RefExpr->getSourceRange();
23461 continue;
23462 }
23463 Vars.push_back(SimpleExpr);
23464 }
23465
23466 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
23467 EndLoc, Modifier, Vars);
23468 }
23469
ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,SourceLocation KindLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23470 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
23471 SourceLocation KindLoc,
23472 SourceLocation StartLoc,
23473 SourceLocation LParenLoc,
23474 SourceLocation EndLoc) {
23475 if (Kind == OMPC_BIND_unknown) {
23476 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23477 << getListOfPossibleValues(OMPC_bind, /*First=*/0,
23478 /*Last=*/unsigned(OMPC_BIND_unknown))
23479 << getOpenMPClauseName(OMPC_bind);
23480 return nullptr;
23481 }
23482
23483 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
23484 EndLoc);
23485 }
23486