1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/ASTMutationListener.h"
18 #include "clang/AST/CXXInheritance.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.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/OpenMPKinds.h"
27 #include "clang/Sema/Initialization.h"
28 #include "clang/Sema/Lookup.h"
29 #include "clang/Sema/Scope.h"
30 #include "clang/Sema/ScopeInfo.h"
31 #include "clang/Sema/SemaInternal.h"
32 #include "llvm/ADT/PointerEmbeddedInt.h"
33 using namespace clang;
34
35 //===----------------------------------------------------------------------===//
36 // Stack of data-sharing attributes for variables
37 //===----------------------------------------------------------------------===//
38
39 static const Expr *checkMapClauseExpressionBase(
40 Sema &SemaRef, Expr *E,
41 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
42 OpenMPClauseKind CKind, bool NoDiagnose);
43
44 namespace {
45 /// Default data sharing attributes, which can be applied to directive.
46 enum DefaultDataSharingAttributes {
47 DSA_unspecified = 0, /// Data sharing attribute not specified.
48 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
49 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
50 };
51
52 /// Attributes of the defaultmap clause.
53 enum DefaultMapAttributes {
54 DMA_unspecified, /// Default mapping is not specified.
55 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
56 };
57
58 /// Stack for tracking declarations used in OpenMP directives and
59 /// clauses and their data-sharing attributes.
60 class DSAStackTy {
61 public:
62 struct DSAVarData {
63 OpenMPDirectiveKind DKind = OMPD_unknown;
64 OpenMPClauseKind CKind = OMPC_unknown;
65 const Expr *RefExpr = nullptr;
66 DeclRefExpr *PrivateCopy = nullptr;
67 SourceLocation ImplicitDSALoc;
68 DSAVarData() = default;
DSAVarData__anon523c83f20111::DSAStackTy::DSAVarData69 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
70 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
71 SourceLocation ImplicitDSALoc)
72 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
73 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
74 };
75 using OperatorOffsetTy =
76 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
77 using DoacrossDependMapTy =
78 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
79
80 private:
81 struct DSAInfo {
82 OpenMPClauseKind Attributes = OMPC_unknown;
83 /// Pointer to a reference expression and a flag which shows that the
84 /// variable is marked as lastprivate(true) or not (false).
85 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
86 DeclRefExpr *PrivateCopy = nullptr;
87 };
88 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
89 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
90 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
91 using LoopControlVariablesMapTy =
92 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
93 /// Struct that associates a component with the clause kind where they are
94 /// found.
95 struct MappedExprComponentTy {
96 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
97 OpenMPClauseKind Kind = OMPC_unknown;
98 };
99 using MappedExprComponentsTy =
100 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
101 using CriticalsWithHintsTy =
102 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
103 struct ReductionData {
104 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
105 SourceRange ReductionRange;
106 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
107 ReductionData() = default;
set__anon523c83f20111::DSAStackTy::ReductionData108 void set(BinaryOperatorKind BO, SourceRange RR) {
109 ReductionRange = RR;
110 ReductionOp = BO;
111 }
set__anon523c83f20111::DSAStackTy::ReductionData112 void set(const Expr *RefExpr, SourceRange RR) {
113 ReductionRange = RR;
114 ReductionOp = RefExpr;
115 }
116 };
117 using DeclReductionMapTy =
118 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
119
120 struct SharingMapTy {
121 DeclSAMapTy SharingMap;
122 DeclReductionMapTy ReductionMap;
123 AlignedMapTy AlignedMap;
124 MappedExprComponentsTy MappedExprComponents;
125 LoopControlVariablesMapTy LCVMap;
126 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
127 SourceLocation DefaultAttrLoc;
128 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
129 SourceLocation DefaultMapAttrLoc;
130 OpenMPDirectiveKind Directive = OMPD_unknown;
131 DeclarationNameInfo DirectiveName;
132 Scope *CurScope = nullptr;
133 SourceLocation ConstructLoc;
134 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
135 /// get the data (loop counters etc.) about enclosing loop-based construct.
136 /// This data is required during codegen.
137 DoacrossDependMapTy DoacrossDepends;
138 /// first argument (Expr *) contains optional argument of the
139 /// 'ordered' clause, the second one is true if the regions has 'ordered'
140 /// clause, false otherwise.
141 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
142 unsigned AssociatedLoops = 1;
143 const Decl *PossiblyLoopCounter = nullptr;
144 bool NowaitRegion = false;
145 bool CancelRegion = false;
146 bool LoopStart = false;
147 SourceLocation InnerTeamsRegionLoc;
148 /// Reference to the taskgroup task_reduction reference expression.
149 Expr *TaskgroupReductionRef = nullptr;
150 llvm::DenseSet<QualType> MappedClassesQualTypes;
SharingMapTy__anon523c83f20111::DSAStackTy::SharingMapTy151 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
152 Scope *CurScope, SourceLocation Loc)
153 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
154 ConstructLoc(Loc) {}
155 SharingMapTy() = default;
156 };
157
158 using StackTy = SmallVector<SharingMapTy, 4>;
159
160 /// Stack of used declaration and their data-sharing attributes.
161 DeclSAMapTy Threadprivates;
162 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
163 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
164 /// true, if check for DSA must be from parent directive, false, if
165 /// from current directive.
166 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
167 Sema &SemaRef;
168 bool ForceCapturing = false;
169 /// true if all the vaiables in the target executable directives must be
170 /// captured by reference.
171 bool ForceCaptureByReferenceInTargetExecutable = false;
172 CriticalsWithHintsTy Criticals;
173
174 using iterator = StackTy::const_reverse_iterator;
175
176 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
177
178 /// Checks if the variable is a local for OpenMP region.
179 bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
180
isStackEmpty() const181 bool isStackEmpty() const {
182 return Stack.empty() ||
183 Stack.back().second != CurrentNonCapturingFunctionScope ||
184 Stack.back().first.empty();
185 }
186
187 /// Vector of previously declared requires directives
188 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
189
190 public:
DSAStackTy(Sema & S)191 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
192
isClauseParsingMode() const193 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const194 OpenMPClauseKind getClauseParsingMode() const {
195 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
196 return ClauseKindMode;
197 }
setClauseParsingMode(OpenMPClauseKind K)198 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
199
isForceVarCapturing() const200 bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)201 void setForceVarCapturing(bool V) { ForceCapturing = V; }
202
setForceCaptureByReferenceInTargetExecutable(bool V)203 void setForceCaptureByReferenceInTargetExecutable(bool V) {
204 ForceCaptureByReferenceInTargetExecutable = V;
205 }
isForceCaptureByReferenceInTargetExecutable() const206 bool isForceCaptureByReferenceInTargetExecutable() const {
207 return ForceCaptureByReferenceInTargetExecutable;
208 }
209
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)210 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
211 Scope *CurScope, SourceLocation Loc) {
212 if (Stack.empty() ||
213 Stack.back().second != CurrentNonCapturingFunctionScope)
214 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
215 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
216 Stack.back().first.back().DefaultAttrLoc = Loc;
217 }
218
pop()219 void pop() {
220 assert(!Stack.back().first.empty() &&
221 "Data-sharing attributes stack is empty!");
222 Stack.back().first.pop_back();
223 }
224
225 /// Marks that we're started loop parsing.
loopInit()226 void loopInit() {
227 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
228 "Expected loop-based directive.");
229 Stack.back().first.back().LoopStart = true;
230 }
231 /// Start capturing of the variables in the loop context.
loopStart()232 void loopStart() {
233 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
234 "Expected loop-based directive.");
235 Stack.back().first.back().LoopStart = false;
236 }
237 /// true, if variables are captured, false otherwise.
isLoopStarted() const238 bool isLoopStarted() const {
239 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
240 "Expected loop-based directive.");
241 return !Stack.back().first.back().LoopStart;
242 }
243 /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)244 void resetPossibleLoopCounter(const Decl *D = nullptr) {
245 Stack.back().first.back().PossiblyLoopCounter =
246 D ? D->getCanonicalDecl() : D;
247 }
248 /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const249 const Decl *getPossiblyLoopCunter() const {
250 return Stack.back().first.back().PossiblyLoopCounter;
251 }
252 /// Start new OpenMP region stack in new non-capturing function.
pushFunction()253 void pushFunction() {
254 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
255 assert(!isa<CapturingScopeInfo>(CurFnScope));
256 CurrentNonCapturingFunctionScope = CurFnScope;
257 }
258 /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)259 void popFunction(const FunctionScopeInfo *OldFSI) {
260 if (!Stack.empty() && Stack.back().second == OldFSI) {
261 assert(Stack.back().first.empty());
262 Stack.pop_back();
263 }
264 CurrentNonCapturingFunctionScope = nullptr;
265 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
266 if (!isa<CapturingScopeInfo>(FSI)) {
267 CurrentNonCapturingFunctionScope = FSI;
268 break;
269 }
270 }
271 }
272
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)273 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
274 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
275 }
276 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const277 getCriticalWithHint(const DeclarationNameInfo &Name) const {
278 auto I = Criticals.find(Name.getAsString());
279 if (I != Criticals.end())
280 return I->second;
281 return std::make_pair(nullptr, llvm::APSInt());
282 }
283 /// If 'aligned' declaration for given variable \a D was not seen yet,
284 /// add it and return NULL; otherwise return previous occurrence's expression
285 /// for diagnostics.
286 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
287
288 /// Register specified variable as loop control variable.
289 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
290 /// Check if the specified variable is a loop control variable for
291 /// current region.
292 /// \return The index of the loop control variable in the list of associated
293 /// for-loops (from outer to inner).
294 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
295 /// Check if the specified variable is a loop control variable for
296 /// parent region.
297 /// \return The index of the loop control variable in the list of associated
298 /// for-loops (from outer to inner).
299 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
300 /// Get the loop control variable for the I-th loop (or nullptr) in
301 /// parent directive.
302 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
303
304 /// Adds explicit data sharing attribute to the specified declaration.
305 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
306 DeclRefExpr *PrivateCopy = nullptr);
307
308 /// Adds additional information for the reduction items with the reduction id
309 /// represented as an operator.
310 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
311 BinaryOperatorKind BOK);
312 /// Adds additional information for the reduction items with the reduction id
313 /// represented as reduction identifier.
314 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
315 const Expr *ReductionRef);
316 /// Returns the location and reduction operation from the innermost parent
317 /// region for the given \p D.
318 const DSAVarData
319 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
320 BinaryOperatorKind &BOK,
321 Expr *&TaskgroupDescriptor) const;
322 /// Returns the location and reduction operation from the innermost parent
323 /// region for the given \p D.
324 const DSAVarData
325 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
326 const Expr *&ReductionRef,
327 Expr *&TaskgroupDescriptor) const;
328 /// Return reduction reference expression for the current taskgroup.
getTaskgroupReductionRef() const329 Expr *getTaskgroupReductionRef() const {
330 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
331 "taskgroup reference expression requested for non taskgroup "
332 "directive.");
333 return Stack.back().first.back().TaskgroupReductionRef;
334 }
335 /// Checks if the given \p VD declaration is actually a taskgroup reduction
336 /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const337 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
338 return Stack.back().first[Level].TaskgroupReductionRef &&
339 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
340 ->getDecl() == VD;
341 }
342
343 /// Returns data sharing attributes from top of the stack for the
344 /// specified declaration.
345 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
346 /// Returns data-sharing attributes for the specified declaration.
347 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
348 /// Checks if the specified variables has data-sharing attributes which
349 /// match specified \a CPred predicate in any directive which matches \a DPred
350 /// predicate.
351 const DSAVarData
352 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
353 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
354 bool FromParent) const;
355 /// Checks if the specified variables has data-sharing attributes which
356 /// match specified \a CPred predicate in any innermost directive which
357 /// matches \a DPred predicate.
358 const DSAVarData
359 hasInnermostDSA(ValueDecl *D,
360 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
361 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
362 bool FromParent) const;
363 /// Checks if the specified variables has explicit data-sharing
364 /// attributes which match specified \a CPred predicate at the specified
365 /// OpenMP region.
366 bool hasExplicitDSA(const ValueDecl *D,
367 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
368 unsigned Level, bool NotLastprivate = false) const;
369
370 /// Returns true if the directive at level \Level matches in the
371 /// specified \a DPred predicate.
372 bool hasExplicitDirective(
373 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
374 unsigned Level) const;
375
376 /// Finds a directive which matches specified \a DPred predicate.
377 bool hasDirective(
378 const llvm::function_ref<bool(
379 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
380 DPred,
381 bool FromParent) const;
382
383 /// Returns currently analyzed directive.
getCurrentDirective() const384 OpenMPDirectiveKind getCurrentDirective() const {
385 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
386 }
387 /// Returns directive kind at specified level.
getDirective(unsigned Level) const388 OpenMPDirectiveKind getDirective(unsigned Level) const {
389 assert(!isStackEmpty() && "No directive at specified level.");
390 return Stack.back().first[Level].Directive;
391 }
392 /// Returns parent directive.
getParentDirective() const393 OpenMPDirectiveKind getParentDirective() const {
394 if (isStackEmpty() || Stack.back().first.size() == 1)
395 return OMPD_unknown;
396 return std::next(Stack.back().first.rbegin())->Directive;
397 }
398
399 /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)400 void addRequiresDecl(OMPRequiresDecl *RD) {
401 RequiresDecls.push_back(RD);
402 }
403
404 /// Checks for a duplicate clause amongst previously declared requires
405 /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const406 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
407 bool IsDuplicate = false;
408 for (OMPClause *CNew : ClauseList) {
409 for (const OMPRequiresDecl *D : RequiresDecls) {
410 for (const OMPClause *CPrev : D->clauselists()) {
411 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
412 SemaRef.Diag(CNew->getBeginLoc(),
413 diag::err_omp_requires_clause_redeclaration)
414 << getOpenMPClauseName(CNew->getClauseKind());
415 SemaRef.Diag(CPrev->getBeginLoc(),
416 diag::note_omp_requires_previous_clause)
417 << getOpenMPClauseName(CPrev->getClauseKind());
418 IsDuplicate = true;
419 }
420 }
421 }
422 }
423 return IsDuplicate;
424 }
425
426 /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)427 void setDefaultDSANone(SourceLocation Loc) {
428 assert(!isStackEmpty());
429 Stack.back().first.back().DefaultAttr = DSA_none;
430 Stack.back().first.back().DefaultAttrLoc = Loc;
431 }
432 /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)433 void setDefaultDSAShared(SourceLocation Loc) {
434 assert(!isStackEmpty());
435 Stack.back().first.back().DefaultAttr = DSA_shared;
436 Stack.back().first.back().DefaultAttrLoc = Loc;
437 }
438 /// Set default data mapping attribute to 'tofrom:scalar'.
setDefaultDMAToFromScalar(SourceLocation Loc)439 void setDefaultDMAToFromScalar(SourceLocation Loc) {
440 assert(!isStackEmpty());
441 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
442 Stack.back().first.back().DefaultMapAttrLoc = Loc;
443 }
444
getDefaultDSA() const445 DefaultDataSharingAttributes getDefaultDSA() const {
446 return isStackEmpty() ? DSA_unspecified
447 : Stack.back().first.back().DefaultAttr;
448 }
getDefaultDSALocation() const449 SourceLocation getDefaultDSALocation() const {
450 return isStackEmpty() ? SourceLocation()
451 : Stack.back().first.back().DefaultAttrLoc;
452 }
getDefaultDMA() const453 DefaultMapAttributes getDefaultDMA() const {
454 return isStackEmpty() ? DMA_unspecified
455 : Stack.back().first.back().DefaultMapAttr;
456 }
getDefaultDMAAtLevel(unsigned Level) const457 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
458 return Stack.back().first[Level].DefaultMapAttr;
459 }
getDefaultDMALocation() const460 SourceLocation getDefaultDMALocation() const {
461 return isStackEmpty() ? SourceLocation()
462 : Stack.back().first.back().DefaultMapAttrLoc;
463 }
464
465 /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)466 bool isThreadPrivate(VarDecl *D) {
467 const DSAVarData DVar = getTopDSA(D, false);
468 return isOpenMPThreadPrivate(DVar.CKind);
469 }
470
471 /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)472 void setOrderedRegion(bool IsOrdered, const Expr *Param,
473 OMPOrderedClause *Clause) {
474 assert(!isStackEmpty());
475 if (IsOrdered)
476 Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
477 else
478 Stack.back().first.back().OrderedRegion.reset();
479 }
480 /// Returns true, if region is ordered (has associated 'ordered' clause),
481 /// false - otherwise.
isOrderedRegion() const482 bool isOrderedRegion() const {
483 if (isStackEmpty())
484 return false;
485 return Stack.back().first.rbegin()->OrderedRegion.hasValue();
486 }
487 /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const488 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
489 if (isStackEmpty() ||
490 !Stack.back().first.rbegin()->OrderedRegion.hasValue())
491 return std::make_pair(nullptr, nullptr);
492 return Stack.back().first.rbegin()->OrderedRegion.getValue();
493 }
494 /// Returns true, if parent region is ordered (has associated
495 /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const496 bool isParentOrderedRegion() const {
497 if (isStackEmpty() || Stack.back().first.size() == 1)
498 return false;
499 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
500 }
501 /// Returns optional parameter for the ordered region.
502 std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const503 getParentOrderedRegionParam() const {
504 if (isStackEmpty() || Stack.back().first.size() == 1 ||
505 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
506 return std::make_pair(nullptr, nullptr);
507 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
508 }
509 /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)510 void setNowaitRegion(bool IsNowait = true) {
511 assert(!isStackEmpty());
512 Stack.back().first.back().NowaitRegion = IsNowait;
513 }
514 /// Returns true, if parent region is nowait (has associated
515 /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const516 bool isParentNowaitRegion() const {
517 if (isStackEmpty() || Stack.back().first.size() == 1)
518 return false;
519 return std::next(Stack.back().first.rbegin())->NowaitRegion;
520 }
521 /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)522 void setParentCancelRegion(bool Cancel = true) {
523 if (!isStackEmpty() && Stack.back().first.size() > 1) {
524 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
525 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
526 }
527 }
528 /// Return true if current region has inner cancel construct.
isCancelRegion() const529 bool isCancelRegion() const {
530 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
531 }
532
533 /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)534 void setAssociatedLoops(unsigned Val) {
535 assert(!isStackEmpty());
536 Stack.back().first.back().AssociatedLoops = Val;
537 }
538 /// Return collapse value for region.
getAssociatedLoops() const539 unsigned getAssociatedLoops() const {
540 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
541 }
542
543 /// Marks current target region as one with closely nested teams
544 /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)545 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
546 if (!isStackEmpty() && Stack.back().first.size() > 1) {
547 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
548 TeamsRegionLoc;
549 }
550 }
551 /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const552 bool hasInnerTeamsRegion() const {
553 return getInnerTeamsRegionLoc().isValid();
554 }
555 /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const556 SourceLocation getInnerTeamsRegionLoc() const {
557 return isStackEmpty() ? SourceLocation()
558 : Stack.back().first.back().InnerTeamsRegionLoc;
559 }
560
getCurScope() const561 Scope *getCurScope() const {
562 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
563 }
getConstructLoc() const564 SourceLocation getConstructLoc() const {
565 return isStackEmpty() ? SourceLocation()
566 : Stack.back().first.back().ConstructLoc;
567 }
568
569 /// Do the check specified in \a Check to all component lists and return true
570 /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const571 bool checkMappableExprComponentListsForDecl(
572 const ValueDecl *VD, bool CurrentRegionOnly,
573 const llvm::function_ref<
574 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
575 OpenMPClauseKind)>
576 Check) const {
577 if (isStackEmpty())
578 return false;
579 auto SI = Stack.back().first.rbegin();
580 auto SE = Stack.back().first.rend();
581
582 if (SI == SE)
583 return false;
584
585 if (CurrentRegionOnly)
586 SE = std::next(SI);
587 else
588 std::advance(SI, 1);
589
590 for (; SI != SE; ++SI) {
591 auto MI = SI->MappedExprComponents.find(VD);
592 if (MI != SI->MappedExprComponents.end())
593 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
594 MI->second.Components)
595 if (Check(L, MI->second.Kind))
596 return true;
597 }
598 return false;
599 }
600
601 /// Do the check specified in \a Check to all component lists at a given level
602 /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const603 bool checkMappableExprComponentListsForDeclAtLevel(
604 const ValueDecl *VD, unsigned Level,
605 const llvm::function_ref<
606 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
607 OpenMPClauseKind)>
608 Check) const {
609 if (isStackEmpty())
610 return false;
611
612 auto StartI = Stack.back().first.begin();
613 auto EndI = Stack.back().first.end();
614 if (std::distance(StartI, EndI) <= (int)Level)
615 return false;
616 std::advance(StartI, Level);
617
618 auto MI = StartI->MappedExprComponents.find(VD);
619 if (MI != StartI->MappedExprComponents.end())
620 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
621 MI->second.Components)
622 if (Check(L, MI->second.Kind))
623 return true;
624 return false;
625 }
626
627 /// Create a new mappable expression component list associated with a given
628 /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)629 void addMappableExpressionComponents(
630 const ValueDecl *VD,
631 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
632 OpenMPClauseKind WhereFoundClauseKind) {
633 assert(!isStackEmpty() &&
634 "Not expecting to retrieve components from a empty stack!");
635 MappedExprComponentTy &MEC =
636 Stack.back().first.back().MappedExprComponents[VD];
637 // Create new entry and append the new components there.
638 MEC.Components.resize(MEC.Components.size() + 1);
639 MEC.Components.back().append(Components.begin(), Components.end());
640 MEC.Kind = WhereFoundClauseKind;
641 }
642
getNestingLevel() const643 unsigned getNestingLevel() const {
644 assert(!isStackEmpty());
645 return Stack.back().first.size() - 1;
646 }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)647 void addDoacrossDependClause(OMPDependClause *C,
648 const OperatorOffsetTy &OpsOffs) {
649 assert(!isStackEmpty() && Stack.back().first.size() > 1);
650 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
651 assert(isOpenMPWorksharingDirective(StackElem.Directive));
652 StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
653 }
654 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const655 getDoacrossDependClauses() const {
656 assert(!isStackEmpty());
657 const SharingMapTy &StackElem = Stack.back().first.back();
658 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
659 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
660 return llvm::make_range(Ref.begin(), Ref.end());
661 }
662 return llvm::make_range(StackElem.DoacrossDepends.end(),
663 StackElem.DoacrossDepends.end());
664 }
665
666 // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)667 void addMappedClassesQualTypes(QualType QT) {
668 SharingMapTy &StackElem = Stack.back().first.back();
669 StackElem.MappedClassesQualTypes.insert(QT);
670 }
671
672 // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const673 bool isClassPreviouslyMapped(QualType QT) const {
674 const SharingMapTy &StackElem = Stack.back().first.back();
675 return StackElem.MappedClassesQualTypes.count(QT) != 0;
676 }
677
678 };
679
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)680 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
681 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
682 }
683
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)684 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
685 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
686 }
687
688 } // namespace
689
getExprAsWritten(const Expr * E)690 static const Expr *getExprAsWritten(const Expr *E) {
691 if (const auto *FE = dyn_cast<FullExpr>(E))
692 E = FE->getSubExpr();
693
694 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
695 E = MTE->GetTemporaryExpr();
696
697 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
698 E = Binder->getSubExpr();
699
700 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
701 E = ICE->getSubExprAsWritten();
702 return E->IgnoreParens();
703 }
704
getExprAsWritten(Expr * E)705 static Expr *getExprAsWritten(Expr *E) {
706 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
707 }
708
getCanonicalDecl(const ValueDecl * D)709 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
710 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
711 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
712 D = ME->getMemberDecl();
713 const auto *VD = dyn_cast<VarDecl>(D);
714 const auto *FD = dyn_cast<FieldDecl>(D);
715 if (VD != nullptr) {
716 VD = VD->getCanonicalDecl();
717 D = VD;
718 } else {
719 assert(FD);
720 FD = FD->getCanonicalDecl();
721 D = FD;
722 }
723 return D;
724 }
725
getCanonicalDecl(ValueDecl * D)726 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
727 return const_cast<ValueDecl *>(
728 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
729 }
730
getDSA(iterator & Iter,ValueDecl * D) const731 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
732 ValueDecl *D) const {
733 D = getCanonicalDecl(D);
734 auto *VD = dyn_cast<VarDecl>(D);
735 const auto *FD = dyn_cast<FieldDecl>(D);
736 DSAVarData DVar;
737 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
738 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
739 // in a region but not in construct]
740 // File-scope or namespace-scope variables referenced in called routines
741 // in the region are shared unless they appear in a threadprivate
742 // directive.
743 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
744 DVar.CKind = OMPC_shared;
745
746 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
747 // in a region but not in construct]
748 // Variables with static storage duration that are declared in called
749 // routines in the region are shared.
750 if (VD && VD->hasGlobalStorage())
751 DVar.CKind = OMPC_shared;
752
753 // Non-static data members are shared by default.
754 if (FD)
755 DVar.CKind = OMPC_shared;
756
757 return DVar;
758 }
759
760 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
761 // in a Construct, C/C++, predetermined, p.1]
762 // Variables with automatic storage duration that are declared in a scope
763 // inside the construct are private.
764 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
765 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
766 DVar.CKind = OMPC_private;
767 return DVar;
768 }
769
770 DVar.DKind = Iter->Directive;
771 // Explicitly specified attributes and local variables with predetermined
772 // attributes.
773 if (Iter->SharingMap.count(D)) {
774 const DSAInfo &Data = Iter->SharingMap.lookup(D);
775 DVar.RefExpr = Data.RefExpr.getPointer();
776 DVar.PrivateCopy = Data.PrivateCopy;
777 DVar.CKind = Data.Attributes;
778 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
779 return DVar;
780 }
781
782 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
783 // in a Construct, C/C++, implicitly determined, p.1]
784 // In a parallel or task construct, the data-sharing attributes of these
785 // variables are determined by the default clause, if present.
786 switch (Iter->DefaultAttr) {
787 case DSA_shared:
788 DVar.CKind = OMPC_shared;
789 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
790 return DVar;
791 case DSA_none:
792 return DVar;
793 case DSA_unspecified:
794 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
795 // in a Construct, implicitly determined, p.2]
796 // In a parallel construct, if no default clause is present, these
797 // variables are shared.
798 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
799 if (isOpenMPParallelDirective(DVar.DKind) ||
800 isOpenMPTeamsDirective(DVar.DKind)) {
801 DVar.CKind = OMPC_shared;
802 return DVar;
803 }
804
805 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
806 // in a Construct, implicitly determined, p.4]
807 // In a task construct, if no default clause is present, a variable that in
808 // the enclosing context is determined to be shared by all implicit tasks
809 // bound to the current team is shared.
810 if (isOpenMPTaskingDirective(DVar.DKind)) {
811 DSAVarData DVarTemp;
812 iterator I = Iter, E = Stack.back().first.rend();
813 do {
814 ++I;
815 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
816 // Referenced in a Construct, implicitly determined, p.6]
817 // In a task construct, if no default clause is present, a variable
818 // whose data-sharing attribute is not determined by the rules above is
819 // firstprivate.
820 DVarTemp = getDSA(I, D);
821 if (DVarTemp.CKind != OMPC_shared) {
822 DVar.RefExpr = nullptr;
823 DVar.CKind = OMPC_firstprivate;
824 return DVar;
825 }
826 } while (I != E && !isImplicitTaskingRegion(I->Directive));
827 DVar.CKind =
828 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
829 return DVar;
830 }
831 }
832 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
833 // in a Construct, implicitly determined, p.3]
834 // For constructs other than task, if no default clause is present, these
835 // variables inherit their data-sharing attributes from the enclosing
836 // context.
837 return getDSA(++Iter, D);
838 }
839
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)840 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
841 const Expr *NewDE) {
842 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
843 D = getCanonicalDecl(D);
844 SharingMapTy &StackElem = Stack.back().first.back();
845 auto It = StackElem.AlignedMap.find(D);
846 if (It == StackElem.AlignedMap.end()) {
847 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
848 StackElem.AlignedMap[D] = NewDE;
849 return nullptr;
850 }
851 assert(It->second && "Unexpected nullptr expr in the aligned map");
852 return It->second;
853 }
854
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)855 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
856 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
857 D = getCanonicalDecl(D);
858 SharingMapTy &StackElem = Stack.back().first.back();
859 StackElem.LCVMap.try_emplace(
860 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
861 }
862
863 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const864 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
865 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
866 D = getCanonicalDecl(D);
867 const SharingMapTy &StackElem = Stack.back().first.back();
868 auto It = StackElem.LCVMap.find(D);
869 if (It != StackElem.LCVMap.end())
870 return It->second;
871 return {0, nullptr};
872 }
873
874 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const875 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
876 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
877 "Data-sharing attributes stack is empty");
878 D = getCanonicalDecl(D);
879 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
880 auto It = StackElem.LCVMap.find(D);
881 if (It != StackElem.LCVMap.end())
882 return It->second;
883 return {0, nullptr};
884 }
885
getParentLoopControlVariable(unsigned I) const886 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
887 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
888 "Data-sharing attributes stack is empty");
889 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
890 if (StackElem.LCVMap.size() < I)
891 return nullptr;
892 for (const auto &Pair : StackElem.LCVMap)
893 if (Pair.second.first == I)
894 return Pair.first;
895 return nullptr;
896 }
897
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy)898 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
899 DeclRefExpr *PrivateCopy) {
900 D = getCanonicalDecl(D);
901 if (A == OMPC_threadprivate) {
902 DSAInfo &Data = Threadprivates[D];
903 Data.Attributes = A;
904 Data.RefExpr.setPointer(E);
905 Data.PrivateCopy = nullptr;
906 } else {
907 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
908 DSAInfo &Data = Stack.back().first.back().SharingMap[D];
909 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
910 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
911 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
912 (isLoopControlVariable(D).first && A == OMPC_private));
913 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
914 Data.RefExpr.setInt(/*IntVal=*/true);
915 return;
916 }
917 const bool IsLastprivate =
918 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
919 Data.Attributes = A;
920 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
921 Data.PrivateCopy = PrivateCopy;
922 if (PrivateCopy) {
923 DSAInfo &Data =
924 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
925 Data.Attributes = A;
926 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
927 Data.PrivateCopy = nullptr;
928 }
929 }
930 }
931
932 /// 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)933 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
934 StringRef Name, const AttrVec *Attrs = nullptr,
935 DeclRefExpr *OrigRef = nullptr) {
936 DeclContext *DC = SemaRef.CurContext;
937 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
938 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
939 auto *Decl =
940 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
941 if (Attrs) {
942 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
943 I != E; ++I)
944 Decl->addAttr(*I);
945 }
946 Decl->setImplicit();
947 if (OrigRef) {
948 Decl->addAttr(
949 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
950 }
951 return Decl;
952 }
953
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)954 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
955 SourceLocation Loc,
956 bool RefersToCapture = false) {
957 D->setReferenced();
958 D->markUsed(S.Context);
959 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
960 SourceLocation(), D, RefersToCapture, Loc, Ty,
961 VK_LValue);
962 }
963
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)964 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
965 BinaryOperatorKind BOK) {
966 D = getCanonicalDecl(D);
967 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
968 assert(
969 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
970 "Additional reduction info may be specified only for reduction items.");
971 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
972 assert(ReductionData.ReductionRange.isInvalid() &&
973 Stack.back().first.back().Directive == OMPD_taskgroup &&
974 "Additional reduction info may be specified only once for reduction "
975 "items.");
976 ReductionData.set(BOK, SR);
977 Expr *&TaskgroupReductionRef =
978 Stack.back().first.back().TaskgroupReductionRef;
979 if (!TaskgroupReductionRef) {
980 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
981 SemaRef.Context.VoidPtrTy, ".task_red.");
982 TaskgroupReductionRef =
983 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
984 }
985 }
986
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)987 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
988 const Expr *ReductionRef) {
989 D = getCanonicalDecl(D);
990 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
991 assert(
992 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
993 "Additional reduction info may be specified only for reduction items.");
994 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
995 assert(ReductionData.ReductionRange.isInvalid() &&
996 Stack.back().first.back().Directive == OMPD_taskgroup &&
997 "Additional reduction info may be specified only once for reduction "
998 "items.");
999 ReductionData.set(ReductionRef, SR);
1000 Expr *&TaskgroupReductionRef =
1001 Stack.back().first.back().TaskgroupReductionRef;
1002 if (!TaskgroupReductionRef) {
1003 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1004 SemaRef.Context.VoidPtrTy, ".task_red.");
1005 TaskgroupReductionRef =
1006 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1007 }
1008 }
1009
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1010 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1011 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1012 Expr *&TaskgroupDescriptor) const {
1013 D = getCanonicalDecl(D);
1014 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1015 if (Stack.back().first.empty())
1016 return DSAVarData();
1017 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1018 E = Stack.back().first.rend();
1019 I != E; std::advance(I, 1)) {
1020 const DSAInfo &Data = I->SharingMap.lookup(D);
1021 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1022 continue;
1023 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1024 if (!ReductionData.ReductionOp ||
1025 ReductionData.ReductionOp.is<const Expr *>())
1026 return DSAVarData();
1027 SR = ReductionData.ReductionRange;
1028 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1029 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1030 "expression for the descriptor is not "
1031 "set.");
1032 TaskgroupDescriptor = I->TaskgroupReductionRef;
1033 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1034 Data.PrivateCopy, I->DefaultAttrLoc);
1035 }
1036 return DSAVarData();
1037 }
1038
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1039 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1040 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1041 Expr *&TaskgroupDescriptor) const {
1042 D = getCanonicalDecl(D);
1043 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1044 if (Stack.back().first.empty())
1045 return DSAVarData();
1046 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1047 E = Stack.back().first.rend();
1048 I != E; std::advance(I, 1)) {
1049 const DSAInfo &Data = I->SharingMap.lookup(D);
1050 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1051 continue;
1052 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1053 if (!ReductionData.ReductionOp ||
1054 !ReductionData.ReductionOp.is<const Expr *>())
1055 return DSAVarData();
1056 SR = ReductionData.ReductionRange;
1057 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1058 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1059 "expression for the descriptor is not "
1060 "set.");
1061 TaskgroupDescriptor = I->TaskgroupReductionRef;
1062 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1063 Data.PrivateCopy, I->DefaultAttrLoc);
1064 }
1065 return DSAVarData();
1066 }
1067
isOpenMPLocal(VarDecl * D,iterator Iter) const1068 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
1069 D = D->getCanonicalDecl();
1070 if (!isStackEmpty()) {
1071 iterator I = Iter, E = Stack.back().first.rend();
1072 Scope *TopScope = nullptr;
1073 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
1074 !isOpenMPTargetExecutionDirective(I->Directive))
1075 ++I;
1076 if (I == E)
1077 return false;
1078 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1079 Scope *CurScope = getCurScope();
1080 while (CurScope != TopScope && !CurScope->isDeclScope(D))
1081 CurScope = CurScope->getParent();
1082 return CurScope != TopScope;
1083 }
1084 return false;
1085 }
1086
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1087 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1088 bool AcceptIfMutable = true,
1089 bool *IsClassType = nullptr) {
1090 ASTContext &Context = SemaRef.getASTContext();
1091 Type = Type.getNonReferenceType().getCanonicalType();
1092 bool IsConstant = Type.isConstant(Context);
1093 Type = Context.getBaseElementType(Type);
1094 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1095 ? Type->getAsCXXRecordDecl()
1096 : nullptr;
1097 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1098 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1099 RD = CTD->getTemplatedDecl();
1100 if (IsClassType)
1101 *IsClassType = RD;
1102 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1103 RD->hasDefinition() && RD->hasMutableFields());
1104 }
1105
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1106 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1107 QualType Type, OpenMPClauseKind CKind,
1108 SourceLocation ELoc,
1109 bool AcceptIfMutable = true,
1110 bool ListItemNotVar = false) {
1111 ASTContext &Context = SemaRef.getASTContext();
1112 bool IsClassType;
1113 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1114 unsigned Diag = ListItemNotVar
1115 ? diag::err_omp_const_list_item
1116 : IsClassType ? diag::err_omp_const_not_mutable_variable
1117 : diag::err_omp_const_variable;
1118 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1119 if (!ListItemNotVar && D) {
1120 const VarDecl *VD = dyn_cast<VarDecl>(D);
1121 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1122 VarDecl::DeclarationOnly;
1123 SemaRef.Diag(D->getLocation(),
1124 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1125 << D;
1126 }
1127 return true;
1128 }
1129 return false;
1130 }
1131
getTopDSA(ValueDecl * D,bool FromParent)1132 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1133 bool FromParent) {
1134 D = getCanonicalDecl(D);
1135 DSAVarData DVar;
1136
1137 auto *VD = dyn_cast<VarDecl>(D);
1138 auto TI = Threadprivates.find(D);
1139 if (TI != Threadprivates.end()) {
1140 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1141 DVar.CKind = OMPC_threadprivate;
1142 return DVar;
1143 }
1144 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1145 DVar.RefExpr = buildDeclRefExpr(
1146 SemaRef, VD, D->getType().getNonReferenceType(),
1147 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1148 DVar.CKind = OMPC_threadprivate;
1149 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1150 return DVar;
1151 }
1152 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1153 // in a Construct, C/C++, predetermined, p.1]
1154 // Variables appearing in threadprivate directives are threadprivate.
1155 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1156 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1157 SemaRef.getLangOpts().OpenMPUseTLS &&
1158 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1159 (VD && VD->getStorageClass() == SC_Register &&
1160 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1161 DVar.RefExpr = buildDeclRefExpr(
1162 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1163 DVar.CKind = OMPC_threadprivate;
1164 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1165 return DVar;
1166 }
1167 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1168 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1169 !isLoopControlVariable(D).first) {
1170 iterator IterTarget =
1171 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1172 [](const SharingMapTy &Data) {
1173 return isOpenMPTargetExecutionDirective(Data.Directive);
1174 });
1175 if (IterTarget != Stack.back().first.rend()) {
1176 iterator ParentIterTarget = std::next(IterTarget, 1);
1177 for (iterator Iter = Stack.back().first.rbegin();
1178 Iter != ParentIterTarget; std::advance(Iter, 1)) {
1179 if (isOpenMPLocal(VD, Iter)) {
1180 DVar.RefExpr =
1181 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1182 D->getLocation());
1183 DVar.CKind = OMPC_threadprivate;
1184 return DVar;
1185 }
1186 }
1187 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1188 auto DSAIter = IterTarget->SharingMap.find(D);
1189 if (DSAIter != IterTarget->SharingMap.end() &&
1190 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1191 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1192 DVar.CKind = OMPC_threadprivate;
1193 return DVar;
1194 }
1195 iterator End = Stack.back().first.rend();
1196 if (!SemaRef.isOpenMPCapturedByRef(
1197 D, std::distance(ParentIterTarget, End))) {
1198 DVar.RefExpr =
1199 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1200 IterTarget->ConstructLoc);
1201 DVar.CKind = OMPC_threadprivate;
1202 return DVar;
1203 }
1204 }
1205 }
1206 }
1207
1208 if (isStackEmpty())
1209 // Not in OpenMP execution region and top scope was already checked.
1210 return DVar;
1211
1212 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1213 // in a Construct, C/C++, predetermined, p.4]
1214 // Static data members are shared.
1215 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1216 // in a Construct, C/C++, predetermined, p.7]
1217 // Variables with static storage duration that are declared in a scope
1218 // inside the construct are shared.
1219 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1220 if (VD && VD->isStaticDataMember()) {
1221 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1222 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1223 return DVar;
1224
1225 DVar.CKind = OMPC_shared;
1226 return DVar;
1227 }
1228
1229 // The predetermined shared attribute for const-qualified types having no
1230 // mutable members was removed after OpenMP 3.1.
1231 if (SemaRef.LangOpts.OpenMP <= 31) {
1232 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1233 // in a Construct, C/C++, predetermined, p.6]
1234 // Variables with const qualified type having no mutable member are
1235 // shared.
1236 if (isConstNotMutableType(SemaRef, D->getType())) {
1237 // Variables with const-qualified type having no mutable member may be
1238 // listed in a firstprivate clause, even if they are static data members.
1239 DSAVarData DVarTemp = hasInnermostDSA(
1240 D,
1241 [](OpenMPClauseKind C) {
1242 return C == OMPC_firstprivate || C == OMPC_shared;
1243 },
1244 MatchesAlways, FromParent);
1245 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1246 return DVarTemp;
1247
1248 DVar.CKind = OMPC_shared;
1249 return DVar;
1250 }
1251 }
1252
1253 // Explicitly specified attributes and local variables with predetermined
1254 // attributes.
1255 iterator I = Stack.back().first.rbegin();
1256 iterator EndI = Stack.back().first.rend();
1257 if (FromParent && I != EndI)
1258 std::advance(I, 1);
1259 auto It = I->SharingMap.find(D);
1260 if (It != I->SharingMap.end()) {
1261 const DSAInfo &Data = It->getSecond();
1262 DVar.RefExpr = Data.RefExpr.getPointer();
1263 DVar.PrivateCopy = Data.PrivateCopy;
1264 DVar.CKind = Data.Attributes;
1265 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1266 DVar.DKind = I->Directive;
1267 }
1268
1269 return DVar;
1270 }
1271
getImplicitDSA(ValueDecl * D,bool FromParent) const1272 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1273 bool FromParent) const {
1274 if (isStackEmpty()) {
1275 iterator I;
1276 return getDSA(I, D);
1277 }
1278 D = getCanonicalDecl(D);
1279 iterator StartI = Stack.back().first.rbegin();
1280 iterator EndI = Stack.back().first.rend();
1281 if (FromParent && StartI != EndI)
1282 std::advance(StartI, 1);
1283 return getDSA(StartI, D);
1284 }
1285
1286 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1287 DSAStackTy::hasDSA(ValueDecl *D,
1288 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1289 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1290 bool FromParent) const {
1291 if (isStackEmpty())
1292 return {};
1293 D = getCanonicalDecl(D);
1294 iterator I = Stack.back().first.rbegin();
1295 iterator EndI = Stack.back().first.rend();
1296 if (FromParent && I != EndI)
1297 std::advance(I, 1);
1298 for (; I != EndI; std::advance(I, 1)) {
1299 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
1300 continue;
1301 iterator NewI = I;
1302 DSAVarData DVar = getDSA(NewI, D);
1303 if (I == NewI && CPred(DVar.CKind))
1304 return DVar;
1305 }
1306 return {};
1307 }
1308
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1309 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1310 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1311 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1312 bool FromParent) const {
1313 if (isStackEmpty())
1314 return {};
1315 D = getCanonicalDecl(D);
1316 iterator StartI = Stack.back().first.rbegin();
1317 iterator EndI = Stack.back().first.rend();
1318 if (FromParent && StartI != EndI)
1319 std::advance(StartI, 1);
1320 if (StartI == EndI || !DPred(StartI->Directive))
1321 return {};
1322 iterator NewI = StartI;
1323 DSAVarData DVar = getDSA(NewI, D);
1324 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1325 }
1326
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,unsigned Level,bool NotLastprivate) const1327 bool DSAStackTy::hasExplicitDSA(
1328 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1329 unsigned Level, bool NotLastprivate) const {
1330 if (isStackEmpty())
1331 return false;
1332 D = getCanonicalDecl(D);
1333 auto StartI = Stack.back().first.begin();
1334 auto EndI = Stack.back().first.end();
1335 if (std::distance(StartI, EndI) <= (int)Level)
1336 return false;
1337 std::advance(StartI, Level);
1338 auto I = StartI->SharingMap.find(D);
1339 if ((I != StartI->SharingMap.end()) &&
1340 I->getSecond().RefExpr.getPointer() &&
1341 CPred(I->getSecond().Attributes) &&
1342 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1343 return true;
1344 // Check predetermined rules for the loop control variables.
1345 auto LI = StartI->LCVMap.find(D);
1346 if (LI != StartI->LCVMap.end())
1347 return CPred(OMPC_private);
1348 return false;
1349 }
1350
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1351 bool DSAStackTy::hasExplicitDirective(
1352 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1353 unsigned Level) const {
1354 if (isStackEmpty())
1355 return false;
1356 auto StartI = Stack.back().first.begin();
1357 auto EndI = Stack.back().first.end();
1358 if (std::distance(StartI, EndI) <= (int)Level)
1359 return false;
1360 std::advance(StartI, Level);
1361 return DPred(StartI->Directive);
1362 }
1363
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1364 bool DSAStackTy::hasDirective(
1365 const llvm::function_ref<bool(OpenMPDirectiveKind,
1366 const DeclarationNameInfo &, SourceLocation)>
1367 DPred,
1368 bool FromParent) const {
1369 // We look only in the enclosing region.
1370 if (isStackEmpty())
1371 return false;
1372 auto StartI = std::next(Stack.back().first.rbegin());
1373 auto EndI = Stack.back().first.rend();
1374 if (FromParent && StartI != EndI)
1375 StartI = std::next(StartI);
1376 for (auto I = StartI, EE = EndI; I != EE; ++I) {
1377 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1378 return true;
1379 }
1380 return false;
1381 }
1382
InitDataSharingAttributesStack()1383 void Sema::InitDataSharingAttributesStack() {
1384 VarDataSharingAttributesStack = new DSAStackTy(*this);
1385 }
1386
1387 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1388
pushOpenMPFunctionRegion()1389 void Sema::pushOpenMPFunctionRegion() {
1390 DSAStack->pushFunction();
1391 }
1392
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1393 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1394 DSAStack->popFunction(OldFSI);
1395 }
1396
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level) const1397 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
1398 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1399
1400 ASTContext &Ctx = getASTContext();
1401 bool IsByRef = true;
1402
1403 // Find the directive that is associated with the provided scope.
1404 D = cast<ValueDecl>(D->getCanonicalDecl());
1405 QualType Ty = D->getType();
1406
1407 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1408 // This table summarizes how a given variable should be passed to the device
1409 // given its type and the clauses where it appears. This table is based on
1410 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1411 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1412 //
1413 // =========================================================================
1414 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1415 // | |(tofrom:scalar)| | pvt | | | |
1416 // =========================================================================
1417 // | scl | | | | - | | bycopy|
1418 // | scl | | - | x | - | - | bycopy|
1419 // | scl | | x | - | - | - | null |
1420 // | scl | x | | | - | | byref |
1421 // | scl | x | - | x | - | - | bycopy|
1422 // | scl | x | x | - | - | - | null |
1423 // | scl | | - | - | - | x | byref |
1424 // | scl | x | - | - | - | x | byref |
1425 //
1426 // | agg | n.a. | | | - | | byref |
1427 // | agg | n.a. | - | x | - | - | byref |
1428 // | agg | n.a. | x | - | - | - | null |
1429 // | agg | n.a. | - | - | - | x | byref |
1430 // | agg | n.a. | - | - | - | x[] | byref |
1431 //
1432 // | ptr | n.a. | | | - | | bycopy|
1433 // | ptr | n.a. | - | x | - | - | bycopy|
1434 // | ptr | n.a. | x | - | - | - | null |
1435 // | ptr | n.a. | - | - | - | x | byref |
1436 // | ptr | n.a. | - | - | - | x[] | bycopy|
1437 // | ptr | n.a. | - | - | x | | bycopy|
1438 // | ptr | n.a. | - | - | x | x | bycopy|
1439 // | ptr | n.a. | - | - | x | x[] | bycopy|
1440 // =========================================================================
1441 // Legend:
1442 // scl - scalar
1443 // ptr - pointer
1444 // agg - aggregate
1445 // x - applies
1446 // - - invalid in this combination
1447 // [] - mapped with an array section
1448 // byref - should be mapped by reference
1449 // byval - should be mapped by value
1450 // null - initialize a local variable to null on the device
1451 //
1452 // Observations:
1453 // - All scalar declarations that show up in a map clause have to be passed
1454 // by reference, because they may have been mapped in the enclosing data
1455 // environment.
1456 // - If the scalar value does not fit the size of uintptr, it has to be
1457 // passed by reference, regardless the result in the table above.
1458 // - For pointers mapped by value that have either an implicit map or an
1459 // array section, the runtime library may pass the NULL value to the
1460 // device instead of the value passed to it by the compiler.
1461
1462 if (Ty->isReferenceType())
1463 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1464
1465 // Locate map clauses and see if the variable being captured is referred to
1466 // in any of those clauses. Here we only care about variables, not fields,
1467 // because fields are part of aggregates.
1468 bool IsVariableUsedInMapClause = false;
1469 bool IsVariableAssociatedWithSection = false;
1470
1471 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1472 D, Level,
1473 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1474 OMPClauseMappableExprCommon::MappableExprComponentListRef
1475 MapExprComponents,
1476 OpenMPClauseKind WhereFoundClauseKind) {
1477 // Only the map clause information influences how a variable is
1478 // captured. E.g. is_device_ptr does not require changing the default
1479 // behavior.
1480 if (WhereFoundClauseKind != OMPC_map)
1481 return false;
1482
1483 auto EI = MapExprComponents.rbegin();
1484 auto EE = MapExprComponents.rend();
1485
1486 assert(EI != EE && "Invalid map expression!");
1487
1488 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1489 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1490
1491 ++EI;
1492 if (EI == EE)
1493 return false;
1494
1495 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1496 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1497 isa<MemberExpr>(EI->getAssociatedExpression())) {
1498 IsVariableAssociatedWithSection = true;
1499 // There is nothing more we need to know about this variable.
1500 return true;
1501 }
1502
1503 // Keep looking for more map info.
1504 return false;
1505 });
1506
1507 if (IsVariableUsedInMapClause) {
1508 // If variable is identified in a map clause it is always captured by
1509 // reference except if it is a pointer that is dereferenced somehow.
1510 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1511 } else {
1512 // By default, all the data that has a scalar type is mapped by copy
1513 // (except for reduction variables).
1514 IsByRef =
1515 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1516 !Ty->isAnyPointerType()) ||
1517 !Ty->isScalarType() ||
1518 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1519 DSAStack->hasExplicitDSA(
1520 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1521 }
1522 }
1523
1524 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1525 IsByRef =
1526 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1527 !Ty->isAnyPointerType()) ||
1528 !DSAStack->hasExplicitDSA(
1529 D,
1530 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1531 Level, /*NotLastprivate=*/true)) &&
1532 // If the variable is artificial and must be captured by value - try to
1533 // capture by value.
1534 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1535 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1536 }
1537
1538 // When passing data by copy, we need to make sure it fits the uintptr size
1539 // and alignment, because the runtime library only deals with uintptr types.
1540 // If it does not fit the uintptr size, we need to pass the data by reference
1541 // instead.
1542 if (!IsByRef &&
1543 (Ctx.getTypeSizeInChars(Ty) >
1544 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1545 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1546 IsByRef = true;
1547 }
1548
1549 return IsByRef;
1550 }
1551
getOpenMPNestingLevel() const1552 unsigned Sema::getOpenMPNestingLevel() const {
1553 assert(getLangOpts().OpenMP);
1554 return DSAStack->getNestingLevel();
1555 }
1556
isInOpenMPTargetExecutionDirective() const1557 bool Sema::isInOpenMPTargetExecutionDirective() const {
1558 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1559 !DSAStack->isClauseParsingMode()) ||
1560 DSAStack->hasDirective(
1561 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1562 SourceLocation) -> bool {
1563 return isOpenMPTargetExecutionDirective(K);
1564 },
1565 false);
1566 }
1567
isOpenMPCapturedDecl(ValueDecl * D)1568 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
1569 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1570 D = getCanonicalDecl(D);
1571
1572 // If we are attempting to capture a global variable in a directive with
1573 // 'target' we return true so that this global is also mapped to the device.
1574 //
1575 auto *VD = dyn_cast<VarDecl>(D);
1576 if (VD && !VD->hasLocalStorage()) {
1577 if (isInOpenMPDeclareTargetContext() &&
1578 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1579 // Try to mark variable as declare target if it is used in capturing
1580 // regions.
1581 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1582 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
1583 return nullptr;
1584 } else if (isInOpenMPTargetExecutionDirective()) {
1585 // If the declaration is enclosed in a 'declare target' directive,
1586 // then it should not be captured.
1587 //
1588 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1589 return nullptr;
1590 return VD;
1591 }
1592 }
1593 // Capture variables captured by reference in lambdas for target-based
1594 // directives.
1595 if (VD && !DSAStack->isClauseParsingMode()) {
1596 if (const auto *RD = VD->getType()
1597 .getCanonicalType()
1598 .getNonReferenceType()
1599 ->getAsCXXRecordDecl()) {
1600 bool SavedForceCaptureByReferenceInTargetExecutable =
1601 DSAStack->isForceCaptureByReferenceInTargetExecutable();
1602 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true);
1603 if (RD->isLambda()) {
1604 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
1605 FieldDecl *ThisCapture;
1606 RD->getCaptureFields(Captures, ThisCapture);
1607 for (const LambdaCapture &LC : RD->captures()) {
1608 if (LC.getCaptureKind() == LCK_ByRef) {
1609 VarDecl *VD = LC.getCapturedVar();
1610 DeclContext *VDC = VD->getDeclContext();
1611 if (!VDC->Encloses(CurContext))
1612 continue;
1613 DSAStackTy::DSAVarData DVarPrivate =
1614 DSAStack->getTopDSA(VD, /*FromParent=*/false);
1615 // Do not capture already captured variables.
1616 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
1617 DVarPrivate.CKind == OMPC_unknown &&
1618 !DSAStack->checkMappableExprComponentListsForDecl(
1619 D, /*CurrentRegionOnly=*/true,
1620 [](OMPClauseMappableExprCommon::
1621 MappableExprComponentListRef,
1622 OpenMPClauseKind) { return true; }))
1623 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar());
1624 } else if (LC.getCaptureKind() == LCK_This) {
1625 QualType ThisTy = getCurrentThisType();
1626 if (!ThisTy.isNull() &&
1627 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
1628 CheckCXXThisCapture(LC.getLocation());
1629 }
1630 }
1631 }
1632 DSAStack->setForceCaptureByReferenceInTargetExecutable(
1633 SavedForceCaptureByReferenceInTargetExecutable);
1634 }
1635 }
1636
1637 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1638 (!DSAStack->isClauseParsingMode() ||
1639 DSAStack->getParentDirective() != OMPD_unknown)) {
1640 auto &&Info = DSAStack->isLoopControlVariable(D);
1641 if (Info.first ||
1642 (VD && VD->hasLocalStorage() &&
1643 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
1644 (VD && DSAStack->isForceVarCapturing()))
1645 return VD ? VD : Info.second;
1646 DSAStackTy::DSAVarData DVarPrivate =
1647 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1648 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1649 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1650 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1651 [](OpenMPDirectiveKind) { return true; },
1652 DSAStack->isClauseParsingMode());
1653 if (DVarPrivate.CKind != OMPC_unknown)
1654 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1655 }
1656 return nullptr;
1657 }
1658
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const1659 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1660 unsigned Level) const {
1661 SmallVector<OpenMPDirectiveKind, 4> Regions;
1662 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1663 FunctionScopesIndex -= Regions.size();
1664 }
1665
startOpenMPLoop()1666 void Sema::startOpenMPLoop() {
1667 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1668 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1669 DSAStack->loopInit();
1670 }
1671
isOpenMPPrivateDecl(const ValueDecl * D,unsigned Level) const1672 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1673 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1674 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1675 if (DSAStack->getAssociatedLoops() > 0 &&
1676 !DSAStack->isLoopStarted()) {
1677 DSAStack->resetPossibleLoopCounter(D);
1678 DSAStack->loopStart();
1679 return true;
1680 }
1681 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
1682 DSAStack->isLoopControlVariable(D).first) &&
1683 !DSAStack->hasExplicitDSA(
1684 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
1685 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
1686 return true;
1687 }
1688 return DSAStack->hasExplicitDSA(
1689 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1690 (DSAStack->isClauseParsingMode() &&
1691 DSAStack->getClauseParsingMode() == OMPC_private) ||
1692 // Consider taskgroup reduction descriptor variable a private to avoid
1693 // possible capture in the region.
1694 (DSAStack->hasExplicitDirective(
1695 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1696 Level) &&
1697 DSAStack->isTaskgroupReductionRef(D, Level));
1698 }
1699
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)1700 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
1701 unsigned Level) {
1702 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1703 D = getCanonicalDecl(D);
1704 OpenMPClauseKind OMPC = OMPC_unknown;
1705 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1706 const unsigned NewLevel = I - 1;
1707 if (DSAStack->hasExplicitDSA(D,
1708 [&OMPC](const OpenMPClauseKind K) {
1709 if (isOpenMPPrivate(K)) {
1710 OMPC = K;
1711 return true;
1712 }
1713 return false;
1714 },
1715 NewLevel))
1716 break;
1717 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1718 D, NewLevel,
1719 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1720 OpenMPClauseKind) { return true; })) {
1721 OMPC = OMPC_map;
1722 break;
1723 }
1724 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1725 NewLevel)) {
1726 OMPC = OMPC_map;
1727 if (D->getType()->isScalarType() &&
1728 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1729 DefaultMapAttributes::DMA_tofrom_scalar)
1730 OMPC = OMPC_firstprivate;
1731 break;
1732 }
1733 }
1734 if (OMPC != OMPC_unknown)
1735 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1736 }
1737
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level) const1738 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
1739 unsigned Level) const {
1740 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1741 // Return true if the current level is no longer enclosed in a target region.
1742
1743 const auto *VD = dyn_cast<VarDecl>(D);
1744 return VD && !VD->hasLocalStorage() &&
1745 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1746 Level);
1747 }
1748
DestroyDataSharingAttributesStack()1749 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1750
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)1751 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1752 const DeclarationNameInfo &DirName,
1753 Scope *CurScope, SourceLocation Loc) {
1754 DSAStack->push(DKind, DirName, CurScope, Loc);
1755 PushExpressionEvaluationContext(
1756 ExpressionEvaluationContext::PotentiallyEvaluated);
1757 }
1758
StartOpenMPClause(OpenMPClauseKind K)1759 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1760 DSAStack->setClauseParsingMode(K);
1761 }
1762
EndOpenMPClause()1763 void Sema::EndOpenMPClause() {
1764 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1765 }
1766
EndOpenMPDSABlock(Stmt * CurDirective)1767 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1768 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1769 // A variable of class type (or array thereof) that appears in a lastprivate
1770 // clause requires an accessible, unambiguous default constructor for the
1771 // class type, unless the list item is also specified in a firstprivate
1772 // clause.
1773 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1774 for (OMPClause *C : D->clauses()) {
1775 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1776 SmallVector<Expr *, 8> PrivateCopies;
1777 for (Expr *DE : Clause->varlists()) {
1778 if (DE->isValueDependent() || DE->isTypeDependent()) {
1779 PrivateCopies.push_back(nullptr);
1780 continue;
1781 }
1782 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1783 auto *VD = cast<VarDecl>(DRE->getDecl());
1784 QualType Type = VD->getType().getNonReferenceType();
1785 const DSAStackTy::DSAVarData DVar =
1786 DSAStack->getTopDSA(VD, /*FromParent=*/false);
1787 if (DVar.CKind == OMPC_lastprivate) {
1788 // Generate helper private variable and initialize it with the
1789 // default value. The address of the original variable is replaced
1790 // by the address of the new private variable in CodeGen. This new
1791 // variable is not added to IdResolver, so the code in the OpenMP
1792 // region uses original variable for proper diagnostics.
1793 VarDecl *VDPrivate = buildVarDecl(
1794 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1795 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1796 ActOnUninitializedDecl(VDPrivate);
1797 if (VDPrivate->isInvalidDecl())
1798 continue;
1799 PrivateCopies.push_back(buildDeclRefExpr(
1800 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1801 } else {
1802 // The variable is also a firstprivate, so initialization sequence
1803 // for private copy is generated already.
1804 PrivateCopies.push_back(nullptr);
1805 }
1806 }
1807 // Set initializers to private copies if no errors were found.
1808 if (PrivateCopies.size() == Clause->varlist_size())
1809 Clause->setPrivateCopies(PrivateCopies);
1810 }
1811 }
1812 }
1813
1814 DSAStack->pop();
1815 DiscardCleanupsInEvaluationContext();
1816 PopExpressionEvaluationContext();
1817 }
1818
1819 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1820 Expr *NumIterations, Sema &SemaRef,
1821 Scope *S, DSAStackTy *Stack);
1822
1823 namespace {
1824
1825 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1826 private:
1827 Sema &SemaRef;
1828
1829 public:
VarDeclFilterCCC(Sema & S)1830 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)1831 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1832 NamedDecl *ND = Candidate.getCorrectionDecl();
1833 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1834 return VD->hasGlobalStorage() &&
1835 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1836 SemaRef.getCurScope());
1837 }
1838 return false;
1839 }
1840 };
1841
1842 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1843 private:
1844 Sema &SemaRef;
1845
1846 public:
VarOrFuncDeclFilterCCC(Sema & S)1847 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)1848 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1849 NamedDecl *ND = Candidate.getCorrectionDecl();
1850 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1851 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1852 SemaRef.getCurScope());
1853 }
1854 return false;
1855 }
1856 };
1857
1858 } // namespace
1859
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)1860 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1861 CXXScopeSpec &ScopeSpec,
1862 const DeclarationNameInfo &Id) {
1863 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1864 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1865
1866 if (Lookup.isAmbiguous())
1867 return ExprError();
1868
1869 VarDecl *VD;
1870 if (!Lookup.isSingleResult()) {
1871 if (TypoCorrection Corrected = CorrectTypo(
1872 Id, LookupOrdinaryName, CurScope, nullptr,
1873 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1874 diagnoseTypo(Corrected,
1875 PDiag(Lookup.empty()
1876 ? diag::err_undeclared_var_use_suggest
1877 : diag::err_omp_expected_var_arg_suggest)
1878 << Id.getName());
1879 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1880 } else {
1881 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1882 : diag::err_omp_expected_var_arg)
1883 << Id.getName();
1884 return ExprError();
1885 }
1886 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1887 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1888 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1889 return ExprError();
1890 }
1891 Lookup.suppressDiagnostics();
1892
1893 // OpenMP [2.9.2, Syntax, C/C++]
1894 // Variables must be file-scope, namespace-scope, or static block-scope.
1895 if (!VD->hasGlobalStorage()) {
1896 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1897 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1898 bool IsDecl =
1899 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1900 Diag(VD->getLocation(),
1901 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1902 << VD;
1903 return ExprError();
1904 }
1905
1906 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1907 NamedDecl *ND = CanonicalVD;
1908 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1909 // A threadprivate directive for file-scope variables must appear outside
1910 // any definition or declaration.
1911 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1912 !getCurLexicalContext()->isTranslationUnit()) {
1913 Diag(Id.getLoc(), diag::err_omp_var_scope)
1914 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1915 bool IsDecl =
1916 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1917 Diag(VD->getLocation(),
1918 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1919 << VD;
1920 return ExprError();
1921 }
1922 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1923 // A threadprivate directive for static class member variables must appear
1924 // in the class definition, in the same scope in which the member
1925 // variables are declared.
1926 if (CanonicalVD->isStaticDataMember() &&
1927 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1928 Diag(Id.getLoc(), diag::err_omp_var_scope)
1929 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1930 bool IsDecl =
1931 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1932 Diag(VD->getLocation(),
1933 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1934 << VD;
1935 return ExprError();
1936 }
1937 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1938 // A threadprivate directive for namespace-scope variables must appear
1939 // outside any definition or declaration other than the namespace
1940 // definition itself.
1941 if (CanonicalVD->getDeclContext()->isNamespace() &&
1942 (!getCurLexicalContext()->isFileContext() ||
1943 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1944 Diag(Id.getLoc(), diag::err_omp_var_scope)
1945 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1946 bool IsDecl =
1947 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1948 Diag(VD->getLocation(),
1949 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1950 << VD;
1951 return ExprError();
1952 }
1953 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1954 // A threadprivate directive for static block-scope variables must appear
1955 // in the scope of the variable and not in a nested scope.
1956 if (CanonicalVD->isStaticLocal() && CurScope &&
1957 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1958 Diag(Id.getLoc(), diag::err_omp_var_scope)
1959 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1960 bool IsDecl =
1961 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1962 Diag(VD->getLocation(),
1963 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1964 << VD;
1965 return ExprError();
1966 }
1967
1968 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1969 // A threadprivate directive must lexically precede all references to any
1970 // of the variables in its list.
1971 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1972 Diag(Id.getLoc(), diag::err_omp_var_used)
1973 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1974 return ExprError();
1975 }
1976
1977 QualType ExprType = VD->getType().getNonReferenceType();
1978 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1979 SourceLocation(), VD,
1980 /*RefersToEnclosingVariableOrCapture=*/false,
1981 Id.getLoc(), ExprType, VK_LValue);
1982 }
1983
1984 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)1985 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1986 ArrayRef<Expr *> VarList) {
1987 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1988 CurContext->addDecl(D);
1989 return DeclGroupPtrTy::make(DeclGroupRef(D));
1990 }
1991 return nullptr;
1992 }
1993
1994 namespace {
1995 class LocalVarRefChecker final
1996 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1997 Sema &SemaRef;
1998
1999 public:
VisitDeclRefExpr(const DeclRefExpr * E)2000 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2001 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2002 if (VD->hasLocalStorage()) {
2003 SemaRef.Diag(E->getBeginLoc(),
2004 diag::err_omp_local_var_in_threadprivate_init)
2005 << E->getSourceRange();
2006 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2007 << VD << VD->getSourceRange();
2008 return true;
2009 }
2010 }
2011 return false;
2012 }
VisitStmt(const Stmt * S)2013 bool VisitStmt(const Stmt *S) {
2014 for (const Stmt *Child : S->children()) {
2015 if (Child && Visit(Child))
2016 return true;
2017 }
2018 return false;
2019 }
LocalVarRefChecker(Sema & SemaRef)2020 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2021 };
2022 } // namespace
2023
2024 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2025 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2026 SmallVector<Expr *, 8> Vars;
2027 for (Expr *RefExpr : VarList) {
2028 auto *DE = cast<DeclRefExpr>(RefExpr);
2029 auto *VD = cast<VarDecl>(DE->getDecl());
2030 SourceLocation ILoc = DE->getExprLoc();
2031
2032 // Mark variable as used.
2033 VD->setReferenced();
2034 VD->markUsed(Context);
2035
2036 QualType QType = VD->getType();
2037 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2038 // It will be analyzed later.
2039 Vars.push_back(DE);
2040 continue;
2041 }
2042
2043 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2044 // A threadprivate variable must not have an incomplete type.
2045 if (RequireCompleteType(ILoc, VD->getType(),
2046 diag::err_omp_threadprivate_incomplete_type)) {
2047 continue;
2048 }
2049
2050 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2051 // A threadprivate variable must not have a reference type.
2052 if (VD->getType()->isReferenceType()) {
2053 Diag(ILoc, diag::err_omp_ref_type_arg)
2054 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2055 bool IsDecl =
2056 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2057 Diag(VD->getLocation(),
2058 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2059 << VD;
2060 continue;
2061 }
2062
2063 // Check if this is a TLS variable. If TLS is not being supported, produce
2064 // the corresponding diagnostic.
2065 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2066 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2067 getLangOpts().OpenMPUseTLS &&
2068 getASTContext().getTargetInfo().isTLSSupported())) ||
2069 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2070 !VD->isLocalVarDecl())) {
2071 Diag(ILoc, diag::err_omp_var_thread_local)
2072 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2073 bool IsDecl =
2074 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2075 Diag(VD->getLocation(),
2076 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2077 << VD;
2078 continue;
2079 }
2080
2081 // Check if initial value of threadprivate variable reference variable with
2082 // local storage (it is not supported by runtime).
2083 if (const Expr *Init = VD->getAnyInitializer()) {
2084 LocalVarRefChecker Checker(*this);
2085 if (Checker.Visit(Init))
2086 continue;
2087 }
2088
2089 Vars.push_back(RefExpr);
2090 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2091 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2092 Context, SourceRange(Loc, Loc)));
2093 if (ASTMutationListener *ML = Context.getASTMutationListener())
2094 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2095 }
2096 OMPThreadPrivateDecl *D = nullptr;
2097 if (!Vars.empty()) {
2098 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2099 Vars);
2100 D->setAccess(AS_public);
2101 }
2102 return D;
2103 }
2104
2105 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)2106 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2107 ArrayRef<OMPClause *> ClauseList) {
2108 OMPRequiresDecl *D = nullptr;
2109 if (!CurContext->isFileContext()) {
2110 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2111 } else {
2112 D = CheckOMPRequiresDecl(Loc, ClauseList);
2113 if (D) {
2114 CurContext->addDecl(D);
2115 DSAStack->addRequiresDecl(D);
2116 }
2117 }
2118 return DeclGroupPtrTy::make(DeclGroupRef(D));
2119 }
2120
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)2121 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2122 ArrayRef<OMPClause *> ClauseList) {
2123 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2124 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2125 ClauseList);
2126 return nullptr;
2127 }
2128
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar=false)2129 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2130 const ValueDecl *D,
2131 const DSAStackTy::DSAVarData &DVar,
2132 bool IsLoopIterVar = false) {
2133 if (DVar.RefExpr) {
2134 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2135 << getOpenMPClauseName(DVar.CKind);
2136 return;
2137 }
2138 enum {
2139 PDSA_StaticMemberShared,
2140 PDSA_StaticLocalVarShared,
2141 PDSA_LoopIterVarPrivate,
2142 PDSA_LoopIterVarLinear,
2143 PDSA_LoopIterVarLastprivate,
2144 PDSA_ConstVarShared,
2145 PDSA_GlobalVarShared,
2146 PDSA_TaskVarFirstprivate,
2147 PDSA_LocalVarPrivate,
2148 PDSA_Implicit
2149 } Reason = PDSA_Implicit;
2150 bool ReportHint = false;
2151 auto ReportLoc = D->getLocation();
2152 auto *VD = dyn_cast<VarDecl>(D);
2153 if (IsLoopIterVar) {
2154 if (DVar.CKind == OMPC_private)
2155 Reason = PDSA_LoopIterVarPrivate;
2156 else if (DVar.CKind == OMPC_lastprivate)
2157 Reason = PDSA_LoopIterVarLastprivate;
2158 else
2159 Reason = PDSA_LoopIterVarLinear;
2160 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2161 DVar.CKind == OMPC_firstprivate) {
2162 Reason = PDSA_TaskVarFirstprivate;
2163 ReportLoc = DVar.ImplicitDSALoc;
2164 } else if (VD && VD->isStaticLocal())
2165 Reason = PDSA_StaticLocalVarShared;
2166 else if (VD && VD->isStaticDataMember())
2167 Reason = PDSA_StaticMemberShared;
2168 else if (VD && VD->isFileVarDecl())
2169 Reason = PDSA_GlobalVarShared;
2170 else if (D->getType().isConstant(SemaRef.getASTContext()))
2171 Reason = PDSA_ConstVarShared;
2172 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2173 ReportHint = true;
2174 Reason = PDSA_LocalVarPrivate;
2175 }
2176 if (Reason != PDSA_Implicit) {
2177 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2178 << Reason << ReportHint
2179 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2180 } else if (DVar.ImplicitDSALoc.isValid()) {
2181 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2182 << getOpenMPClauseName(DVar.CKind);
2183 }
2184 }
2185
2186 namespace {
2187 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2188 DSAStackTy *Stack;
2189 Sema &SemaRef;
2190 bool ErrorFound = false;
2191 CapturedStmt *CS = nullptr;
2192 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2193 llvm::SmallVector<Expr *, 4> ImplicitMap;
2194 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2195 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2196
VisitSubCaptures(OMPExecutableDirective * S)2197 void VisitSubCaptures(OMPExecutableDirective *S) {
2198 // Check implicitly captured variables.
2199 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2200 return;
2201 for (const CapturedStmt::Capture &Cap :
2202 S->getInnermostCapturedStmt()->captures()) {
2203 if (!Cap.capturesVariable())
2204 continue;
2205 VarDecl *VD = Cap.getCapturedVar();
2206 // Do not try to map the variable if it or its sub-component was mapped
2207 // already.
2208 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2209 Stack->checkMappableExprComponentListsForDecl(
2210 VD, /*CurrentRegionOnly=*/true,
2211 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2212 OpenMPClauseKind) { return true; }))
2213 continue;
2214 DeclRefExpr *DRE = buildDeclRefExpr(
2215 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
2216 Cap.getLocation(), /*RefersToCapture=*/true);
2217 Visit(DRE);
2218 }
2219 }
2220
2221 public:
VisitDeclRefExpr(DeclRefExpr * E)2222 void VisitDeclRefExpr(DeclRefExpr *E) {
2223 if (E->isTypeDependent() || E->isValueDependent() ||
2224 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2225 return;
2226 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2227 VD = VD->getCanonicalDecl();
2228 // Skip internally declared variables.
2229 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
2230 return;
2231
2232 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2233 // Check if the variable has explicit DSA set and stop analysis if it so.
2234 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2235 return;
2236
2237 // Skip internally declared static variables.
2238 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2239 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2240 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
2241 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2242 return;
2243
2244 SourceLocation ELoc = E->getExprLoc();
2245 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2246 // The default(none) clause requires that each variable that is referenced
2247 // in the construct, and does not have a predetermined data-sharing
2248 // attribute, must have its data-sharing attribute explicitly determined
2249 // by being listed in a data-sharing attribute clause.
2250 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2251 isImplicitOrExplicitTaskingRegion(DKind) &&
2252 VarsWithInheritedDSA.count(VD) == 0) {
2253 VarsWithInheritedDSA[VD] = E;
2254 return;
2255 }
2256
2257 if (isOpenMPTargetExecutionDirective(DKind) &&
2258 !Stack->isLoopControlVariable(VD).first) {
2259 if (!Stack->checkMappableExprComponentListsForDecl(
2260 VD, /*CurrentRegionOnly=*/true,
2261 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2262 StackComponents,
2263 OpenMPClauseKind) {
2264 // Variable is used if it has been marked as an array, array
2265 // section or the variable iself.
2266 return StackComponents.size() == 1 ||
2267 std::all_of(
2268 std::next(StackComponents.rbegin()),
2269 StackComponents.rend(),
2270 [](const OMPClauseMappableExprCommon::
2271 MappableComponent &MC) {
2272 return MC.getAssociatedDeclaration() ==
2273 nullptr &&
2274 (isa<OMPArraySectionExpr>(
2275 MC.getAssociatedExpression()) ||
2276 isa<ArraySubscriptExpr>(
2277 MC.getAssociatedExpression()));
2278 });
2279 })) {
2280 bool IsFirstprivate = false;
2281 // By default lambdas are captured as firstprivates.
2282 if (const auto *RD =
2283 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2284 IsFirstprivate = RD->isLambda();
2285 IsFirstprivate =
2286 IsFirstprivate ||
2287 (VD->getType().getNonReferenceType()->isScalarType() &&
2288 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2289 if (IsFirstprivate)
2290 ImplicitFirstprivate.emplace_back(E);
2291 else
2292 ImplicitMap.emplace_back(E);
2293 return;
2294 }
2295 }
2296
2297 // OpenMP [2.9.3.6, Restrictions, p.2]
2298 // A list item that appears in a reduction clause of the innermost
2299 // enclosing worksharing or parallel construct may not be accessed in an
2300 // explicit task.
2301 DVar = Stack->hasInnermostDSA(
2302 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2303 [](OpenMPDirectiveKind K) {
2304 return isOpenMPParallelDirective(K) ||
2305 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2306 },
2307 /*FromParent=*/true);
2308 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2309 ErrorFound = true;
2310 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2311 reportOriginalDsa(SemaRef, Stack, VD, DVar);
2312 return;
2313 }
2314
2315 // Define implicit data-sharing attributes for task.
2316 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2317 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2318 !Stack->isLoopControlVariable(VD).first)
2319 ImplicitFirstprivate.push_back(E);
2320 }
2321 }
VisitMemberExpr(MemberExpr * E)2322 void VisitMemberExpr(MemberExpr *E) {
2323 if (E->isTypeDependent() || E->isValueDependent() ||
2324 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2325 return;
2326 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2327 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2328 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2329 if (!FD)
2330 return;
2331 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2332 // Check if the variable has explicit DSA set and stop analysis if it
2333 // so.
2334 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2335 return;
2336
2337 if (isOpenMPTargetExecutionDirective(DKind) &&
2338 !Stack->isLoopControlVariable(FD).first &&
2339 !Stack->checkMappableExprComponentListsForDecl(
2340 FD, /*CurrentRegionOnly=*/true,
2341 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2342 StackComponents,
2343 OpenMPClauseKind) {
2344 return isa<CXXThisExpr>(
2345 cast<MemberExpr>(
2346 StackComponents.back().getAssociatedExpression())
2347 ->getBase()
2348 ->IgnoreParens());
2349 })) {
2350 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2351 // A bit-field cannot appear in a map clause.
2352 //
2353 if (FD->isBitField())
2354 return;
2355
2356 // Check to see if the member expression is referencing a class that
2357 // has already been explicitly mapped
2358 if (Stack->isClassPreviouslyMapped(TE->getType()))
2359 return;
2360
2361 ImplicitMap.emplace_back(E);
2362 return;
2363 }
2364
2365 SourceLocation ELoc = E->getExprLoc();
2366 // OpenMP [2.9.3.6, Restrictions, p.2]
2367 // A list item that appears in a reduction clause of the innermost
2368 // enclosing worksharing or parallel construct may not be accessed in
2369 // an explicit task.
2370 DVar = Stack->hasInnermostDSA(
2371 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2372 [](OpenMPDirectiveKind K) {
2373 return isOpenMPParallelDirective(K) ||
2374 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2375 },
2376 /*FromParent=*/true);
2377 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2378 ErrorFound = true;
2379 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2380 reportOriginalDsa(SemaRef, Stack, FD, DVar);
2381 return;
2382 }
2383
2384 // Define implicit data-sharing attributes for task.
2385 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2386 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2387 !Stack->isLoopControlVariable(FD).first) {
2388 // Check if there is a captured expression for the current field in the
2389 // region. Do not mark it as firstprivate unless there is no captured
2390 // expression.
2391 // TODO: try to make it firstprivate.
2392 if (DVar.CKind != OMPC_unknown)
2393 ImplicitFirstprivate.push_back(E);
2394 }
2395 return;
2396 }
2397 if (isOpenMPTargetExecutionDirective(DKind)) {
2398 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2399 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2400 /*NoDiagnose=*/true))
2401 return;
2402 const auto *VD = cast<ValueDecl>(
2403 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2404 if (!Stack->checkMappableExprComponentListsForDecl(
2405 VD, /*CurrentRegionOnly=*/true,
2406 [&CurComponents](
2407 OMPClauseMappableExprCommon::MappableExprComponentListRef
2408 StackComponents,
2409 OpenMPClauseKind) {
2410 auto CCI = CurComponents.rbegin();
2411 auto CCE = CurComponents.rend();
2412 for (const auto &SC : llvm::reverse(StackComponents)) {
2413 // Do both expressions have the same kind?
2414 if (CCI->getAssociatedExpression()->getStmtClass() !=
2415 SC.getAssociatedExpression()->getStmtClass())
2416 if (!(isa<OMPArraySectionExpr>(
2417 SC.getAssociatedExpression()) &&
2418 isa<ArraySubscriptExpr>(
2419 CCI->getAssociatedExpression())))
2420 return false;
2421
2422 const Decl *CCD = CCI->getAssociatedDeclaration();
2423 const Decl *SCD = SC.getAssociatedDeclaration();
2424 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2425 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2426 if (SCD != CCD)
2427 return false;
2428 std::advance(CCI, 1);
2429 if (CCI == CCE)
2430 break;
2431 }
2432 return true;
2433 })) {
2434 Visit(E->getBase());
2435 }
2436 } else {
2437 Visit(E->getBase());
2438 }
2439 }
VisitOMPExecutableDirective(OMPExecutableDirective * S)2440 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2441 for (OMPClause *C : S->clauses()) {
2442 // Skip analysis of arguments of implicitly defined firstprivate clause
2443 // for task|target directives.
2444 // Skip analysis of arguments of implicitly defined map clause for target
2445 // directives.
2446 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2447 C->isImplicit())) {
2448 for (Stmt *CC : C->children()) {
2449 if (CC)
2450 Visit(CC);
2451 }
2452 }
2453 }
2454 // Check implicitly captured variables.
2455 VisitSubCaptures(S);
2456 }
VisitStmt(Stmt * S)2457 void VisitStmt(Stmt *S) {
2458 for (Stmt *C : S->children()) {
2459 if (C) {
2460 // Check implicitly captured variables in the task-based directives to
2461 // check if they must be firstprivatized.
2462 Visit(C);
2463 }
2464 }
2465 }
2466
isErrorFound() const2467 bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const2468 ArrayRef<Expr *> getImplicitFirstprivate() const {
2469 return ImplicitFirstprivate;
2470 }
getImplicitMap() const2471 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
getVarsWithInheritedDSA() const2472 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2473 return VarsWithInheritedDSA;
2474 }
2475
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)2476 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2477 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2478 };
2479 } // namespace
2480
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)2481 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2482 switch (DKind) {
2483 case OMPD_parallel:
2484 case OMPD_parallel_for:
2485 case OMPD_parallel_for_simd:
2486 case OMPD_parallel_sections:
2487 case OMPD_teams:
2488 case OMPD_teams_distribute:
2489 case OMPD_teams_distribute_simd: {
2490 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2491 QualType KmpInt32PtrTy =
2492 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2493 Sema::CapturedParamNameType Params[] = {
2494 std::make_pair(".global_tid.", KmpInt32PtrTy),
2495 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2496 std::make_pair(StringRef(), QualType()) // __context with shared vars
2497 };
2498 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2499 Params);
2500 break;
2501 }
2502 case OMPD_target_teams:
2503 case OMPD_target_parallel:
2504 case OMPD_target_parallel_for:
2505 case OMPD_target_parallel_for_simd:
2506 case OMPD_target_teams_distribute:
2507 case OMPD_target_teams_distribute_simd: {
2508 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2509 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2510 QualType KmpInt32PtrTy =
2511 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2512 QualType Args[] = {VoidPtrTy};
2513 FunctionProtoType::ExtProtoInfo EPI;
2514 EPI.Variadic = true;
2515 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2516 Sema::CapturedParamNameType Params[] = {
2517 std::make_pair(".global_tid.", KmpInt32Ty),
2518 std::make_pair(".part_id.", KmpInt32PtrTy),
2519 std::make_pair(".privates.", VoidPtrTy),
2520 std::make_pair(
2521 ".copy_fn.",
2522 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2523 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2524 std::make_pair(StringRef(), QualType()) // __context with shared vars
2525 };
2526 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2527 Params);
2528 // Mark this captured region as inlined, because we don't use outlined
2529 // function directly.
2530 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2531 AlwaysInlineAttr::CreateImplicit(
2532 Context, AlwaysInlineAttr::Keyword_forceinline));
2533 Sema::CapturedParamNameType ParamsTarget[] = {
2534 std::make_pair(StringRef(), QualType()) // __context with shared vars
2535 };
2536 // Start a captured region for 'target' with no implicit parameters.
2537 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2538 ParamsTarget);
2539 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2540 std::make_pair(".global_tid.", KmpInt32PtrTy),
2541 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2542 std::make_pair(StringRef(), QualType()) // __context with shared vars
2543 };
2544 // Start a captured region for 'teams' or 'parallel'. Both regions have
2545 // the same implicit parameters.
2546 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2547 ParamsTeamsOrParallel);
2548 break;
2549 }
2550 case OMPD_target:
2551 case OMPD_target_simd: {
2552 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2553 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2554 QualType KmpInt32PtrTy =
2555 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2556 QualType Args[] = {VoidPtrTy};
2557 FunctionProtoType::ExtProtoInfo EPI;
2558 EPI.Variadic = true;
2559 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2560 Sema::CapturedParamNameType Params[] = {
2561 std::make_pair(".global_tid.", KmpInt32Ty),
2562 std::make_pair(".part_id.", KmpInt32PtrTy),
2563 std::make_pair(".privates.", VoidPtrTy),
2564 std::make_pair(
2565 ".copy_fn.",
2566 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2567 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2568 std::make_pair(StringRef(), QualType()) // __context with shared vars
2569 };
2570 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2571 Params);
2572 // Mark this captured region as inlined, because we don't use outlined
2573 // function directly.
2574 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2575 AlwaysInlineAttr::CreateImplicit(
2576 Context, AlwaysInlineAttr::Keyword_forceinline));
2577 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2578 std::make_pair(StringRef(), QualType()));
2579 break;
2580 }
2581 case OMPD_simd:
2582 case OMPD_for:
2583 case OMPD_for_simd:
2584 case OMPD_sections:
2585 case OMPD_section:
2586 case OMPD_single:
2587 case OMPD_master:
2588 case OMPD_critical:
2589 case OMPD_taskgroup:
2590 case OMPD_distribute:
2591 case OMPD_distribute_simd:
2592 case OMPD_ordered:
2593 case OMPD_atomic:
2594 case OMPD_target_data: {
2595 Sema::CapturedParamNameType Params[] = {
2596 std::make_pair(StringRef(), QualType()) // __context with shared vars
2597 };
2598 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2599 Params);
2600 break;
2601 }
2602 case OMPD_task: {
2603 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2604 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2605 QualType KmpInt32PtrTy =
2606 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2607 QualType Args[] = {VoidPtrTy};
2608 FunctionProtoType::ExtProtoInfo EPI;
2609 EPI.Variadic = true;
2610 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2611 Sema::CapturedParamNameType Params[] = {
2612 std::make_pair(".global_tid.", KmpInt32Ty),
2613 std::make_pair(".part_id.", KmpInt32PtrTy),
2614 std::make_pair(".privates.", VoidPtrTy),
2615 std::make_pair(
2616 ".copy_fn.",
2617 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2618 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2619 std::make_pair(StringRef(), QualType()) // __context with shared vars
2620 };
2621 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2622 Params);
2623 // Mark this captured region as inlined, because we don't use outlined
2624 // function directly.
2625 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2626 AlwaysInlineAttr::CreateImplicit(
2627 Context, AlwaysInlineAttr::Keyword_forceinline));
2628 break;
2629 }
2630 case OMPD_taskloop:
2631 case OMPD_taskloop_simd: {
2632 QualType KmpInt32Ty =
2633 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
2634 .withConst();
2635 QualType KmpUInt64Ty =
2636 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
2637 .withConst();
2638 QualType KmpInt64Ty =
2639 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
2640 .withConst();
2641 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2642 QualType KmpInt32PtrTy =
2643 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2644 QualType Args[] = {VoidPtrTy};
2645 FunctionProtoType::ExtProtoInfo EPI;
2646 EPI.Variadic = true;
2647 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2648 Sema::CapturedParamNameType Params[] = {
2649 std::make_pair(".global_tid.", KmpInt32Ty),
2650 std::make_pair(".part_id.", KmpInt32PtrTy),
2651 std::make_pair(".privates.", VoidPtrTy),
2652 std::make_pair(
2653 ".copy_fn.",
2654 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2655 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2656 std::make_pair(".lb.", KmpUInt64Ty),
2657 std::make_pair(".ub.", KmpUInt64Ty),
2658 std::make_pair(".st.", KmpInt64Ty),
2659 std::make_pair(".liter.", KmpInt32Ty),
2660 std::make_pair(".reductions.", VoidPtrTy),
2661 std::make_pair(StringRef(), QualType()) // __context with shared vars
2662 };
2663 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2664 Params);
2665 // Mark this captured region as inlined, because we don't use outlined
2666 // function directly.
2667 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2668 AlwaysInlineAttr::CreateImplicit(
2669 Context, AlwaysInlineAttr::Keyword_forceinline));
2670 break;
2671 }
2672 case OMPD_distribute_parallel_for_simd:
2673 case OMPD_distribute_parallel_for: {
2674 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2675 QualType KmpInt32PtrTy =
2676 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2677 Sema::CapturedParamNameType Params[] = {
2678 std::make_pair(".global_tid.", KmpInt32PtrTy),
2679 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2680 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2681 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2682 std::make_pair(StringRef(), QualType()) // __context with shared vars
2683 };
2684 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2685 Params);
2686 break;
2687 }
2688 case OMPD_target_teams_distribute_parallel_for:
2689 case OMPD_target_teams_distribute_parallel_for_simd: {
2690 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2691 QualType KmpInt32PtrTy =
2692 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2693 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2694
2695 QualType Args[] = {VoidPtrTy};
2696 FunctionProtoType::ExtProtoInfo EPI;
2697 EPI.Variadic = true;
2698 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2699 Sema::CapturedParamNameType Params[] = {
2700 std::make_pair(".global_tid.", KmpInt32Ty),
2701 std::make_pair(".part_id.", KmpInt32PtrTy),
2702 std::make_pair(".privates.", VoidPtrTy),
2703 std::make_pair(
2704 ".copy_fn.",
2705 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2706 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2707 std::make_pair(StringRef(), QualType()) // __context with shared vars
2708 };
2709 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2710 Params);
2711 // Mark this captured region as inlined, because we don't use outlined
2712 // function directly.
2713 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2714 AlwaysInlineAttr::CreateImplicit(
2715 Context, AlwaysInlineAttr::Keyword_forceinline));
2716 Sema::CapturedParamNameType ParamsTarget[] = {
2717 std::make_pair(StringRef(), QualType()) // __context with shared vars
2718 };
2719 // Start a captured region for 'target' with no implicit parameters.
2720 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2721 ParamsTarget);
2722
2723 Sema::CapturedParamNameType ParamsTeams[] = {
2724 std::make_pair(".global_tid.", KmpInt32PtrTy),
2725 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2726 std::make_pair(StringRef(), QualType()) // __context with shared vars
2727 };
2728 // Start a captured region for 'target' with no implicit parameters.
2729 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2730 ParamsTeams);
2731
2732 Sema::CapturedParamNameType ParamsParallel[] = {
2733 std::make_pair(".global_tid.", KmpInt32PtrTy),
2734 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2735 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2736 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2737 std::make_pair(StringRef(), QualType()) // __context with shared vars
2738 };
2739 // Start a captured region for 'teams' or 'parallel'. Both regions have
2740 // the same implicit parameters.
2741 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2742 ParamsParallel);
2743 break;
2744 }
2745
2746 case OMPD_teams_distribute_parallel_for:
2747 case OMPD_teams_distribute_parallel_for_simd: {
2748 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2749 QualType KmpInt32PtrTy =
2750 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2751
2752 Sema::CapturedParamNameType ParamsTeams[] = {
2753 std::make_pair(".global_tid.", KmpInt32PtrTy),
2754 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2755 std::make_pair(StringRef(), QualType()) // __context with shared vars
2756 };
2757 // Start a captured region for 'target' with no implicit parameters.
2758 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2759 ParamsTeams);
2760
2761 Sema::CapturedParamNameType ParamsParallel[] = {
2762 std::make_pair(".global_tid.", KmpInt32PtrTy),
2763 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2764 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2765 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2766 std::make_pair(StringRef(), QualType()) // __context with shared vars
2767 };
2768 // Start a captured region for 'teams' or 'parallel'. Both regions have
2769 // the same implicit parameters.
2770 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2771 ParamsParallel);
2772 break;
2773 }
2774 case OMPD_target_update:
2775 case OMPD_target_enter_data:
2776 case OMPD_target_exit_data: {
2777 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2778 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2779 QualType KmpInt32PtrTy =
2780 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2781 QualType Args[] = {VoidPtrTy};
2782 FunctionProtoType::ExtProtoInfo EPI;
2783 EPI.Variadic = true;
2784 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2785 Sema::CapturedParamNameType Params[] = {
2786 std::make_pair(".global_tid.", KmpInt32Ty),
2787 std::make_pair(".part_id.", KmpInt32PtrTy),
2788 std::make_pair(".privates.", VoidPtrTy),
2789 std::make_pair(
2790 ".copy_fn.",
2791 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2792 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2793 std::make_pair(StringRef(), QualType()) // __context with shared vars
2794 };
2795 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2796 Params);
2797 // Mark this captured region as inlined, because we don't use outlined
2798 // function directly.
2799 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2800 AlwaysInlineAttr::CreateImplicit(
2801 Context, AlwaysInlineAttr::Keyword_forceinline));
2802 break;
2803 }
2804 case OMPD_threadprivate:
2805 case OMPD_taskyield:
2806 case OMPD_barrier:
2807 case OMPD_taskwait:
2808 case OMPD_cancellation_point:
2809 case OMPD_cancel:
2810 case OMPD_flush:
2811 case OMPD_declare_reduction:
2812 case OMPD_declare_simd:
2813 case OMPD_declare_target:
2814 case OMPD_end_declare_target:
2815 case OMPD_requires:
2816 llvm_unreachable("OpenMP Directive is not allowed");
2817 case OMPD_unknown:
2818 llvm_unreachable("Unknown OpenMP directive");
2819 }
2820 }
2821
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)2822 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2823 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2824 getOpenMPCaptureRegions(CaptureRegions, DKind);
2825 return CaptureRegions.size();
2826 }
2827
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)2828 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2829 Expr *CaptureExpr, bool WithInit,
2830 bool AsExpression) {
2831 assert(CaptureExpr);
2832 ASTContext &C = S.getASTContext();
2833 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2834 QualType Ty = Init->getType();
2835 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2836 if (S.getLangOpts().CPlusPlus) {
2837 Ty = C.getLValueReferenceType(Ty);
2838 } else {
2839 Ty = C.getPointerType(Ty);
2840 ExprResult Res =
2841 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2842 if (!Res.isUsable())
2843 return nullptr;
2844 Init = Res.get();
2845 }
2846 WithInit = true;
2847 }
2848 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2849 CaptureExpr->getBeginLoc());
2850 if (!WithInit)
2851 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2852 S.CurContext->addHiddenDecl(CED);
2853 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2854 return CED;
2855 }
2856
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)2857 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2858 bool WithInit) {
2859 OMPCapturedExprDecl *CD;
2860 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
2861 CD = cast<OMPCapturedExprDecl>(VD);
2862 else
2863 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2864 /*AsExpression=*/false);
2865 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2866 CaptureExpr->getExprLoc());
2867 }
2868
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)2869 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2870 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2871 if (!Ref) {
2872 OMPCapturedExprDecl *CD = buildCaptureDecl(
2873 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2874 /*WithInit=*/true, /*AsExpression=*/true);
2875 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2876 CaptureExpr->getExprLoc());
2877 }
2878 ExprResult Res = Ref;
2879 if (!S.getLangOpts().CPlusPlus &&
2880 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2881 Ref->getType()->isPointerType()) {
2882 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2883 if (!Res.isUsable())
2884 return ExprError();
2885 }
2886 return S.DefaultLvalueConversion(Res.get());
2887 }
2888
2889 namespace {
2890 // OpenMP directives parsed in this section are represented as a
2891 // CapturedStatement with an associated statement. If a syntax error
2892 // is detected during the parsing of the associated statement, the
2893 // compiler must abort processing and close the CapturedStatement.
2894 //
2895 // Combined directives such as 'target parallel' have more than one
2896 // nested CapturedStatements. This RAII ensures that we unwind out
2897 // of all the nested CapturedStatements when an error is found.
2898 class CaptureRegionUnwinderRAII {
2899 private:
2900 Sema &S;
2901 bool &ErrorFound;
2902 OpenMPDirectiveKind DKind = OMPD_unknown;
2903
2904 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)2905 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2906 OpenMPDirectiveKind DKind)
2907 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()2908 ~CaptureRegionUnwinderRAII() {
2909 if (ErrorFound) {
2910 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2911 while (--ThisCaptureLevel >= 0)
2912 S.ActOnCapturedRegionError();
2913 }
2914 }
2915 };
2916 } // namespace
2917
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)2918 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2919 ArrayRef<OMPClause *> Clauses) {
2920 bool ErrorFound = false;
2921 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2922 *this, ErrorFound, DSAStack->getCurrentDirective());
2923 if (!S.isUsable()) {
2924 ErrorFound = true;
2925 return StmtError();
2926 }
2927
2928 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2929 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2930 OMPOrderedClause *OC = nullptr;
2931 OMPScheduleClause *SC = nullptr;
2932 SmallVector<const OMPLinearClause *, 4> LCs;
2933 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
2934 // This is required for proper codegen.
2935 for (OMPClause *Clause : Clauses) {
2936 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2937 Clause->getClauseKind() == OMPC_in_reduction) {
2938 // Capture taskgroup task_reduction descriptors inside the tasking regions
2939 // with the corresponding in_reduction items.
2940 auto *IRC = cast<OMPInReductionClause>(Clause);
2941 for (Expr *E : IRC->taskgroup_descriptors())
2942 if (E)
2943 MarkDeclarationsReferencedInExpr(E);
2944 }
2945 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2946 Clause->getClauseKind() == OMPC_copyprivate ||
2947 (getLangOpts().OpenMPUseTLS &&
2948 getASTContext().getTargetInfo().isTLSSupported() &&
2949 Clause->getClauseKind() == OMPC_copyin)) {
2950 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2951 // Mark all variables in private list clauses as used in inner region.
2952 for (Stmt *VarRef : Clause->children()) {
2953 if (auto *E = cast_or_null<Expr>(VarRef)) {
2954 MarkDeclarationsReferencedInExpr(E);
2955 }
2956 }
2957 DSAStack->setForceVarCapturing(/*V=*/false);
2958 } else if (CaptureRegions.size() > 1 ||
2959 CaptureRegions.back() != OMPD_unknown) {
2960 if (auto *C = OMPClauseWithPreInit::get(Clause))
2961 PICs.push_back(C);
2962 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2963 if (Expr *E = C->getPostUpdateExpr())
2964 MarkDeclarationsReferencedInExpr(E);
2965 }
2966 }
2967 if (Clause->getClauseKind() == OMPC_schedule)
2968 SC = cast<OMPScheduleClause>(Clause);
2969 else if (Clause->getClauseKind() == OMPC_ordered)
2970 OC = cast<OMPOrderedClause>(Clause);
2971 else if (Clause->getClauseKind() == OMPC_linear)
2972 LCs.push_back(cast<OMPLinearClause>(Clause));
2973 }
2974 // OpenMP, 2.7.1 Loop Construct, Restrictions
2975 // The nonmonotonic modifier cannot be specified if an ordered clause is
2976 // specified.
2977 if (SC &&
2978 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2979 SC->getSecondScheduleModifier() ==
2980 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2981 OC) {
2982 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2983 ? SC->getFirstScheduleModifierLoc()
2984 : SC->getSecondScheduleModifierLoc(),
2985 diag::err_omp_schedule_nonmonotonic_ordered)
2986 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2987 ErrorFound = true;
2988 }
2989 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2990 for (const OMPLinearClause *C : LCs) {
2991 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
2992 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2993 }
2994 ErrorFound = true;
2995 }
2996 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2997 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2998 OC->getNumForLoops()) {
2999 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3000 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3001 ErrorFound = true;
3002 }
3003 if (ErrorFound) {
3004 return StmtError();
3005 }
3006 StmtResult SR = S;
3007 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3008 // Mark all variables in private list clauses as used in inner region.
3009 // Required for proper codegen of combined directives.
3010 // TODO: add processing for other clauses.
3011 if (ThisCaptureRegion != OMPD_unknown) {
3012 for (const clang::OMPClauseWithPreInit *C : PICs) {
3013 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3014 // Find the particular capture region for the clause if the
3015 // directive is a combined one with multiple capture regions.
3016 // If the directive is not a combined one, the capture region
3017 // associated with the clause is OMPD_unknown and is generated
3018 // only once.
3019 if (CaptureRegion == ThisCaptureRegion ||
3020 CaptureRegion == OMPD_unknown) {
3021 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3022 for (Decl *D : DS->decls())
3023 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3024 }
3025 }
3026 }
3027 }
3028 SR = ActOnCapturedRegionEnd(SR.get());
3029 }
3030 return SR;
3031 }
3032
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)3033 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3034 OpenMPDirectiveKind CancelRegion,
3035 SourceLocation StartLoc) {
3036 // CancelRegion is only needed for cancel and cancellation_point.
3037 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3038 return false;
3039
3040 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3041 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3042 return false;
3043
3044 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3045 << getOpenMPDirectiveName(CancelRegion);
3046 return true;
3047 }
3048
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)3049 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
3050 OpenMPDirectiveKind CurrentRegion,
3051 const DeclarationNameInfo &CurrentName,
3052 OpenMPDirectiveKind CancelRegion,
3053 SourceLocation StartLoc) {
3054 if (Stack->getCurScope()) {
3055 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3056 OpenMPDirectiveKind OffendingRegion = ParentRegion;
3057 bool NestingProhibited = false;
3058 bool CloseNesting = true;
3059 bool OrphanSeen = false;
3060 enum {
3061 NoRecommend,
3062 ShouldBeInParallelRegion,
3063 ShouldBeInOrderedRegion,
3064 ShouldBeInTargetRegion,
3065 ShouldBeInTeamsRegion
3066 } Recommend = NoRecommend;
3067 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
3068 // OpenMP [2.16, Nesting of Regions]
3069 // OpenMP constructs may not be nested inside a simd region.
3070 // OpenMP [2.8.1,simd Construct, Restrictions]
3071 // An ordered construct with the simd clause is the only OpenMP
3072 // construct that can appear in the simd region.
3073 // Allowing a SIMD construct nested in another SIMD construct is an
3074 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3075 // message.
3076 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3077 ? diag::err_omp_prohibited_region_simd
3078 : diag::warn_omp_nesting_simd);
3079 return CurrentRegion != OMPD_simd;
3080 }
3081 if (ParentRegion == OMPD_atomic) {
3082 // OpenMP [2.16, Nesting of Regions]
3083 // OpenMP constructs may not be nested inside an atomic region.
3084 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3085 return true;
3086 }
3087 if (CurrentRegion == OMPD_section) {
3088 // OpenMP [2.7.2, sections Construct, Restrictions]
3089 // Orphaned section directives are prohibited. That is, the section
3090 // directives must appear within the sections construct and must not be
3091 // encountered elsewhere in the sections region.
3092 if (ParentRegion != OMPD_sections &&
3093 ParentRegion != OMPD_parallel_sections) {
3094 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3095 << (ParentRegion != OMPD_unknown)
3096 << getOpenMPDirectiveName(ParentRegion);
3097 return true;
3098 }
3099 return false;
3100 }
3101 // Allow some constructs (except teams and cancellation constructs) to be
3102 // orphaned (they could be used in functions, called from OpenMP regions
3103 // with the required preconditions).
3104 if (ParentRegion == OMPD_unknown &&
3105 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3106 CurrentRegion != OMPD_cancellation_point &&
3107 CurrentRegion != OMPD_cancel)
3108 return false;
3109 if (CurrentRegion == OMPD_cancellation_point ||
3110 CurrentRegion == OMPD_cancel) {
3111 // OpenMP [2.16, Nesting of Regions]
3112 // A cancellation point construct for which construct-type-clause is
3113 // taskgroup must be nested inside a task construct. A cancellation
3114 // point construct for which construct-type-clause is not taskgroup must
3115 // be closely nested inside an OpenMP construct that matches the type
3116 // specified in construct-type-clause.
3117 // A cancel construct for which construct-type-clause is taskgroup must be
3118 // nested inside a task construct. A cancel construct for which
3119 // construct-type-clause is not taskgroup must be closely nested inside an
3120 // OpenMP construct that matches the type specified in
3121 // construct-type-clause.
3122 NestingProhibited =
3123 !((CancelRegion == OMPD_parallel &&
3124 (ParentRegion == OMPD_parallel ||
3125 ParentRegion == OMPD_target_parallel)) ||
3126 (CancelRegion == OMPD_for &&
3127 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3128 ParentRegion == OMPD_target_parallel_for ||
3129 ParentRegion == OMPD_distribute_parallel_for ||
3130 ParentRegion == OMPD_teams_distribute_parallel_for ||
3131 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3132 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3133 (CancelRegion == OMPD_sections &&
3134 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3135 ParentRegion == OMPD_parallel_sections)));
3136 OrphanSeen = ParentRegion == OMPD_unknown;
3137 } else if (CurrentRegion == OMPD_master) {
3138 // OpenMP [2.16, Nesting of Regions]
3139 // A master region may not be closely nested inside a worksharing,
3140 // atomic, or explicit task region.
3141 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3142 isOpenMPTaskingDirective(ParentRegion);
3143 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3144 // OpenMP [2.16, Nesting of Regions]
3145 // A critical region may not be nested (closely or otherwise) inside a
3146 // critical region with the same name. Note that this restriction is not
3147 // sufficient to prevent deadlock.
3148 SourceLocation PreviousCriticalLoc;
3149 bool DeadLock = Stack->hasDirective(
3150 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3151 const DeclarationNameInfo &DNI,
3152 SourceLocation Loc) {
3153 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3154 PreviousCriticalLoc = Loc;
3155 return true;
3156 }
3157 return false;
3158 },
3159 false /* skip top directive */);
3160 if (DeadLock) {
3161 SemaRef.Diag(StartLoc,
3162 diag::err_omp_prohibited_region_critical_same_name)
3163 << CurrentName.getName();
3164 if (PreviousCriticalLoc.isValid())
3165 SemaRef.Diag(PreviousCriticalLoc,
3166 diag::note_omp_previous_critical_region);
3167 return true;
3168 }
3169 } else if (CurrentRegion == OMPD_barrier) {
3170 // OpenMP [2.16, Nesting of Regions]
3171 // A barrier region may not be closely nested inside a worksharing,
3172 // explicit task, critical, ordered, atomic, or master region.
3173 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3174 isOpenMPTaskingDirective(ParentRegion) ||
3175 ParentRegion == OMPD_master ||
3176 ParentRegion == OMPD_critical ||
3177 ParentRegion == OMPD_ordered;
3178 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
3179 !isOpenMPParallelDirective(CurrentRegion) &&
3180 !isOpenMPTeamsDirective(CurrentRegion)) {
3181 // OpenMP [2.16, Nesting of Regions]
3182 // A worksharing region may not be closely nested inside a worksharing,
3183 // explicit task, critical, ordered, atomic, or master region.
3184 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3185 isOpenMPTaskingDirective(ParentRegion) ||
3186 ParentRegion == OMPD_master ||
3187 ParentRegion == OMPD_critical ||
3188 ParentRegion == OMPD_ordered;
3189 Recommend = ShouldBeInParallelRegion;
3190 } else if (CurrentRegion == OMPD_ordered) {
3191 // OpenMP [2.16, Nesting of Regions]
3192 // An ordered region may not be closely nested inside a critical,
3193 // atomic, or explicit task region.
3194 // An ordered region must be closely nested inside a loop region (or
3195 // parallel loop region) with an ordered clause.
3196 // OpenMP [2.8.1,simd Construct, Restrictions]
3197 // An ordered construct with the simd clause is the only OpenMP construct
3198 // that can appear in the simd region.
3199 NestingProhibited = ParentRegion == OMPD_critical ||
3200 isOpenMPTaskingDirective(ParentRegion) ||
3201 !(isOpenMPSimdDirective(ParentRegion) ||
3202 Stack->isParentOrderedRegion());
3203 Recommend = ShouldBeInOrderedRegion;
3204 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
3205 // OpenMP [2.16, Nesting of Regions]
3206 // If specified, a teams construct must be contained within a target
3207 // construct.
3208 NestingProhibited = ParentRegion != OMPD_target;
3209 OrphanSeen = ParentRegion == OMPD_unknown;
3210 Recommend = ShouldBeInTargetRegion;
3211 }
3212 if (!NestingProhibited &&
3213 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3214 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3215 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3216 // OpenMP [2.16, Nesting of Regions]
3217 // distribute, parallel, parallel sections, parallel workshare, and the
3218 // parallel loop and parallel loop SIMD constructs are the only OpenMP
3219 // constructs that can be closely nested in the teams region.
3220 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3221 !isOpenMPDistributeDirective(CurrentRegion);
3222 Recommend = ShouldBeInParallelRegion;
3223 }
3224 if (!NestingProhibited &&
3225 isOpenMPNestingDistributeDirective(CurrentRegion)) {
3226 // OpenMP 4.5 [2.17 Nesting of Regions]
3227 // The region associated with the distribute construct must be strictly
3228 // nested inside a teams region
3229 NestingProhibited =
3230 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3231 Recommend = ShouldBeInTeamsRegion;
3232 }
3233 if (!NestingProhibited &&
3234 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3235 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3236 // OpenMP 4.5 [2.17 Nesting of Regions]
3237 // If a target, target update, target data, target enter data, or
3238 // target exit data construct is encountered during execution of a
3239 // target region, the behavior is unspecified.
3240 NestingProhibited = Stack->hasDirective(
3241 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
3242 SourceLocation) {
3243 if (isOpenMPTargetExecutionDirective(K)) {
3244 OffendingRegion = K;
3245 return true;
3246 }
3247 return false;
3248 },
3249 false /* don't skip top directive */);
3250 CloseNesting = false;
3251 }
3252 if (NestingProhibited) {
3253 if (OrphanSeen) {
3254 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3255 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3256 } else {
3257 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3258 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3259 << Recommend << getOpenMPDirectiveName(CurrentRegion);
3260 }
3261 return true;
3262 }
3263 }
3264 return false;
3265 }
3266
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)3267 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
3268 ArrayRef<OMPClause *> Clauses,
3269 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3270 bool ErrorFound = false;
3271 unsigned NamedModifiersNumber = 0;
3272 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
3273 OMPD_unknown + 1);
3274 SmallVector<SourceLocation, 4> NameModifierLoc;
3275 for (const OMPClause *C : Clauses) {
3276 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3277 // At most one if clause without a directive-name-modifier can appear on
3278 // the directive.
3279 OpenMPDirectiveKind CurNM = IC->getNameModifier();
3280 if (FoundNameModifiers[CurNM]) {
3281 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
3282 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3283 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3284 ErrorFound = true;
3285 } else if (CurNM != OMPD_unknown) {
3286 NameModifierLoc.push_back(IC->getNameModifierLoc());
3287 ++NamedModifiersNumber;
3288 }
3289 FoundNameModifiers[CurNM] = IC;
3290 if (CurNM == OMPD_unknown)
3291 continue;
3292 // Check if the specified name modifier is allowed for the current
3293 // directive.
3294 // At most one if clause with the particular directive-name-modifier can
3295 // appear on the directive.
3296 bool MatchFound = false;
3297 for (auto NM : AllowedNameModifiers) {
3298 if (CurNM == NM) {
3299 MatchFound = true;
3300 break;
3301 }
3302 }
3303 if (!MatchFound) {
3304 S.Diag(IC->getNameModifierLoc(),
3305 diag::err_omp_wrong_if_directive_name_modifier)
3306 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
3307 ErrorFound = true;
3308 }
3309 }
3310 }
3311 // If any if clause on the directive includes a directive-name-modifier then
3312 // all if clauses on the directive must include a directive-name-modifier.
3313 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3314 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3315 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
3316 diag::err_omp_no_more_if_clause);
3317 } else {
3318 std::string Values;
3319 std::string Sep(", ");
3320 unsigned AllowedCnt = 0;
3321 unsigned TotalAllowedNum =
3322 AllowedNameModifiers.size() - NamedModifiersNumber;
3323 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3324 ++Cnt) {
3325 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3326 if (!FoundNameModifiers[NM]) {
3327 Values += "'";
3328 Values += getOpenMPDirectiveName(NM);
3329 Values += "'";
3330 if (AllowedCnt + 2 == TotalAllowedNum)
3331 Values += " or ";
3332 else if (AllowedCnt + 1 != TotalAllowedNum)
3333 Values += Sep;
3334 ++AllowedCnt;
3335 }
3336 }
3337 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
3338 diag::err_omp_unnamed_if_clause)
3339 << (TotalAllowedNum > 1) << Values;
3340 }
3341 for (SourceLocation Loc : NameModifierLoc) {
3342 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3343 }
3344 ErrorFound = true;
3345 }
3346 return ErrorFound;
3347 }
3348
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)3349 StmtResult Sema::ActOnOpenMPExecutableDirective(
3350 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
3351 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3352 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3353 StmtResult Res = StmtError();
3354 // First check CancelRegion which is then used in checkNestingOfRegions.
3355 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3356 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
3357 StartLoc))
3358 return StmtError();
3359
3360 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3361 VarsWithInheritedDSAType VarsWithInheritedDSA;
3362 bool ErrorFound = false;
3363 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3364 if (AStmt && !CurContext->isDependentContext()) {
3365 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3366
3367 // Check default data sharing attributes for referenced variables.
3368 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3369 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3370 Stmt *S = AStmt;
3371 while (--ThisCaptureLevel >= 0)
3372 S = cast<CapturedStmt>(S)->getCapturedStmt();
3373 DSAChecker.Visit(S);
3374 if (DSAChecker.isErrorFound())
3375 return StmtError();
3376 // Generate list of implicitly defined firstprivate variables.
3377 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3378
3379 SmallVector<Expr *, 4> ImplicitFirstprivates(
3380 DSAChecker.getImplicitFirstprivate().begin(),
3381 DSAChecker.getImplicitFirstprivate().end());
3382 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3383 DSAChecker.getImplicitMap().end());
3384 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3385 for (OMPClause *C : Clauses) {
3386 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3387 for (Expr *E : IRC->taskgroup_descriptors())
3388 if (E)
3389 ImplicitFirstprivates.emplace_back(E);
3390 }
3391 }
3392 if (!ImplicitFirstprivates.empty()) {
3393 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3394 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3395 SourceLocation())) {
3396 ClausesWithImplicit.push_back(Implicit);
3397 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3398 ImplicitFirstprivates.size();
3399 } else {
3400 ErrorFound = true;
3401 }
3402 }
3403 if (!ImplicitMaps.empty()) {
3404 if (OMPClause *Implicit = ActOnOpenMPMapClause(
3405 llvm::None, llvm::None, OMPC_MAP_tofrom,
3406 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
3407 ImplicitMaps, SourceLocation(), SourceLocation(),
3408 SourceLocation())) {
3409 ClausesWithImplicit.emplace_back(Implicit);
3410 ErrorFound |=
3411 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3412 } else {
3413 ErrorFound = true;
3414 }
3415 }
3416 }
3417
3418 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3419 switch (Kind) {
3420 case OMPD_parallel:
3421 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3422 EndLoc);
3423 AllowedNameModifiers.push_back(OMPD_parallel);
3424 break;
3425 case OMPD_simd:
3426 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3427 VarsWithInheritedDSA);
3428 break;
3429 case OMPD_for:
3430 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3431 VarsWithInheritedDSA);
3432 break;
3433 case OMPD_for_simd:
3434 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3435 EndLoc, VarsWithInheritedDSA);
3436 break;
3437 case OMPD_sections:
3438 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3439 EndLoc);
3440 break;
3441 case OMPD_section:
3442 assert(ClausesWithImplicit.empty() &&
3443 "No clauses are allowed for 'omp section' directive");
3444 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3445 break;
3446 case OMPD_single:
3447 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3448 EndLoc);
3449 break;
3450 case OMPD_master:
3451 assert(ClausesWithImplicit.empty() &&
3452 "No clauses are allowed for 'omp master' directive");
3453 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3454 break;
3455 case OMPD_critical:
3456 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3457 StartLoc, EndLoc);
3458 break;
3459 case OMPD_parallel_for:
3460 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3461 EndLoc, VarsWithInheritedDSA);
3462 AllowedNameModifiers.push_back(OMPD_parallel);
3463 break;
3464 case OMPD_parallel_for_simd:
3465 Res = ActOnOpenMPParallelForSimdDirective(
3466 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3467 AllowedNameModifiers.push_back(OMPD_parallel);
3468 break;
3469 case OMPD_parallel_sections:
3470 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3471 StartLoc, EndLoc);
3472 AllowedNameModifiers.push_back(OMPD_parallel);
3473 break;
3474 case OMPD_task:
3475 Res =
3476 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3477 AllowedNameModifiers.push_back(OMPD_task);
3478 break;
3479 case OMPD_taskyield:
3480 assert(ClausesWithImplicit.empty() &&
3481 "No clauses are allowed for 'omp taskyield' directive");
3482 assert(AStmt == nullptr &&
3483 "No associated statement allowed for 'omp taskyield' directive");
3484 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3485 break;
3486 case OMPD_barrier:
3487 assert(ClausesWithImplicit.empty() &&
3488 "No clauses are allowed for 'omp barrier' directive");
3489 assert(AStmt == nullptr &&
3490 "No associated statement allowed for 'omp barrier' directive");
3491 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3492 break;
3493 case OMPD_taskwait:
3494 assert(ClausesWithImplicit.empty() &&
3495 "No clauses are allowed for 'omp taskwait' directive");
3496 assert(AStmt == nullptr &&
3497 "No associated statement allowed for 'omp taskwait' directive");
3498 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3499 break;
3500 case OMPD_taskgroup:
3501 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3502 EndLoc);
3503 break;
3504 case OMPD_flush:
3505 assert(AStmt == nullptr &&
3506 "No associated statement allowed for 'omp flush' directive");
3507 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3508 break;
3509 case OMPD_ordered:
3510 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3511 EndLoc);
3512 break;
3513 case OMPD_atomic:
3514 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3515 EndLoc);
3516 break;
3517 case OMPD_teams:
3518 Res =
3519 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3520 break;
3521 case OMPD_target:
3522 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3523 EndLoc);
3524 AllowedNameModifiers.push_back(OMPD_target);
3525 break;
3526 case OMPD_target_parallel:
3527 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3528 StartLoc, EndLoc);
3529 AllowedNameModifiers.push_back(OMPD_target);
3530 AllowedNameModifiers.push_back(OMPD_parallel);
3531 break;
3532 case OMPD_target_parallel_for:
3533 Res = ActOnOpenMPTargetParallelForDirective(
3534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3535 AllowedNameModifiers.push_back(OMPD_target);
3536 AllowedNameModifiers.push_back(OMPD_parallel);
3537 break;
3538 case OMPD_cancellation_point:
3539 assert(ClausesWithImplicit.empty() &&
3540 "No clauses are allowed for 'omp cancellation point' directive");
3541 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3542 "cancellation point' directive");
3543 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3544 break;
3545 case OMPD_cancel:
3546 assert(AStmt == nullptr &&
3547 "No associated statement allowed for 'omp cancel' directive");
3548 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3549 CancelRegion);
3550 AllowedNameModifiers.push_back(OMPD_cancel);
3551 break;
3552 case OMPD_target_data:
3553 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3554 EndLoc);
3555 AllowedNameModifiers.push_back(OMPD_target_data);
3556 break;
3557 case OMPD_target_enter_data:
3558 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3559 EndLoc, AStmt);
3560 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3561 break;
3562 case OMPD_target_exit_data:
3563 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3564 EndLoc, AStmt);
3565 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3566 break;
3567 case OMPD_taskloop:
3568 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3569 EndLoc, VarsWithInheritedDSA);
3570 AllowedNameModifiers.push_back(OMPD_taskloop);
3571 break;
3572 case OMPD_taskloop_simd:
3573 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3574 EndLoc, VarsWithInheritedDSA);
3575 AllowedNameModifiers.push_back(OMPD_taskloop);
3576 break;
3577 case OMPD_distribute:
3578 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3579 EndLoc, VarsWithInheritedDSA);
3580 break;
3581 case OMPD_target_update:
3582 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3583 EndLoc, AStmt);
3584 AllowedNameModifiers.push_back(OMPD_target_update);
3585 break;
3586 case OMPD_distribute_parallel_for:
3587 Res = ActOnOpenMPDistributeParallelForDirective(
3588 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3589 AllowedNameModifiers.push_back(OMPD_parallel);
3590 break;
3591 case OMPD_distribute_parallel_for_simd:
3592 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3593 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3594 AllowedNameModifiers.push_back(OMPD_parallel);
3595 break;
3596 case OMPD_distribute_simd:
3597 Res = ActOnOpenMPDistributeSimdDirective(
3598 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3599 break;
3600 case OMPD_target_parallel_for_simd:
3601 Res = ActOnOpenMPTargetParallelForSimdDirective(
3602 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3603 AllowedNameModifiers.push_back(OMPD_target);
3604 AllowedNameModifiers.push_back(OMPD_parallel);
3605 break;
3606 case OMPD_target_simd:
3607 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3608 EndLoc, VarsWithInheritedDSA);
3609 AllowedNameModifiers.push_back(OMPD_target);
3610 break;
3611 case OMPD_teams_distribute:
3612 Res = ActOnOpenMPTeamsDistributeDirective(
3613 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3614 break;
3615 case OMPD_teams_distribute_simd:
3616 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3617 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3618 break;
3619 case OMPD_teams_distribute_parallel_for_simd:
3620 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3621 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3622 AllowedNameModifiers.push_back(OMPD_parallel);
3623 break;
3624 case OMPD_teams_distribute_parallel_for:
3625 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3626 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3627 AllowedNameModifiers.push_back(OMPD_parallel);
3628 break;
3629 case OMPD_target_teams:
3630 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3631 EndLoc);
3632 AllowedNameModifiers.push_back(OMPD_target);
3633 break;
3634 case OMPD_target_teams_distribute:
3635 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3636 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3637 AllowedNameModifiers.push_back(OMPD_target);
3638 break;
3639 case OMPD_target_teams_distribute_parallel_for:
3640 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3641 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3642 AllowedNameModifiers.push_back(OMPD_target);
3643 AllowedNameModifiers.push_back(OMPD_parallel);
3644 break;
3645 case OMPD_target_teams_distribute_parallel_for_simd:
3646 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3647 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3648 AllowedNameModifiers.push_back(OMPD_target);
3649 AllowedNameModifiers.push_back(OMPD_parallel);
3650 break;
3651 case OMPD_target_teams_distribute_simd:
3652 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3653 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3654 AllowedNameModifiers.push_back(OMPD_target);
3655 break;
3656 case OMPD_declare_target:
3657 case OMPD_end_declare_target:
3658 case OMPD_threadprivate:
3659 case OMPD_declare_reduction:
3660 case OMPD_declare_simd:
3661 case OMPD_requires:
3662 llvm_unreachable("OpenMP Directive is not allowed");
3663 case OMPD_unknown:
3664 llvm_unreachable("Unknown OpenMP directive");
3665 }
3666
3667 for (const auto &P : VarsWithInheritedDSA) {
3668 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3669 << P.first << P.second->getSourceRange();
3670 }
3671 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3672
3673 if (!AllowedNameModifiers.empty())
3674 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3675 ErrorFound;
3676
3677 if (ErrorFound)
3678 return StmtError();
3679 return Res;
3680 }
3681
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)3682 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3683 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3684 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3685 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3686 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3687 assert(Aligneds.size() == Alignments.size());
3688 assert(Linears.size() == LinModifiers.size());
3689 assert(Linears.size() == Steps.size());
3690 if (!DG || DG.get().isNull())
3691 return DeclGroupPtrTy();
3692
3693 if (!DG.get().isSingleDecl()) {
3694 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3695 return DG;
3696 }
3697 Decl *ADecl = DG.get().getSingleDecl();
3698 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3699 ADecl = FTD->getTemplatedDecl();
3700
3701 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3702 if (!FD) {
3703 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3704 return DeclGroupPtrTy();
3705 }
3706
3707 // OpenMP [2.8.2, declare simd construct, Description]
3708 // The parameter of the simdlen clause must be a constant positive integer
3709 // expression.
3710 ExprResult SL;
3711 if (Simdlen)
3712 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3713 // OpenMP [2.8.2, declare simd construct, Description]
3714 // The special this pointer can be used as if was one of the arguments to the
3715 // function in any of the linear, aligned, or uniform clauses.
3716 // The uniform clause declares one or more arguments to have an invariant
3717 // value for all concurrent invocations of the function in the execution of a
3718 // single SIMD loop.
3719 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3720 const Expr *UniformedLinearThis = nullptr;
3721 for (const Expr *E : Uniforms) {
3722 E = E->IgnoreParenImpCasts();
3723 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3724 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3725 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3726 FD->getParamDecl(PVD->getFunctionScopeIndex())
3727 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3728 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3729 continue;
3730 }
3731 if (isa<CXXThisExpr>(E)) {
3732 UniformedLinearThis = E;
3733 continue;
3734 }
3735 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3736 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3737 }
3738 // OpenMP [2.8.2, declare simd construct, Description]
3739 // The aligned clause declares that the object to which each list item points
3740 // is aligned to the number of bytes expressed in the optional parameter of
3741 // the aligned clause.
3742 // The special this pointer can be used as if was one of the arguments to the
3743 // function in any of the linear, aligned, or uniform clauses.
3744 // The type of list items appearing in the aligned clause must be array,
3745 // pointer, reference to array, or reference to pointer.
3746 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3747 const Expr *AlignedThis = nullptr;
3748 for (const Expr *E : Aligneds) {
3749 E = E->IgnoreParenImpCasts();
3750 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3751 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3752 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3753 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3754 FD->getParamDecl(PVD->getFunctionScopeIndex())
3755 ->getCanonicalDecl() == CanonPVD) {
3756 // OpenMP [2.8.1, simd construct, Restrictions]
3757 // A list-item cannot appear in more than one aligned clause.
3758 if (AlignedArgs.count(CanonPVD) > 0) {
3759 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3760 << 1 << E->getSourceRange();
3761 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3762 diag::note_omp_explicit_dsa)
3763 << getOpenMPClauseName(OMPC_aligned);
3764 continue;
3765 }
3766 AlignedArgs[CanonPVD] = E;
3767 QualType QTy = PVD->getType()
3768 .getNonReferenceType()
3769 .getUnqualifiedType()
3770 .getCanonicalType();
3771 const Type *Ty = QTy.getTypePtrOrNull();
3772 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3773 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3774 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3775 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3776 }
3777 continue;
3778 }
3779 }
3780 if (isa<CXXThisExpr>(E)) {
3781 if (AlignedThis) {
3782 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3783 << 2 << E->getSourceRange();
3784 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3785 << getOpenMPClauseName(OMPC_aligned);
3786 }
3787 AlignedThis = E;
3788 continue;
3789 }
3790 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3791 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3792 }
3793 // The optional parameter of the aligned clause, alignment, must be a constant
3794 // positive integer expression. If no optional parameter is specified,
3795 // implementation-defined default alignments for SIMD instructions on the
3796 // target platforms are assumed.
3797 SmallVector<const Expr *, 4> NewAligns;
3798 for (Expr *E : Alignments) {
3799 ExprResult Align;
3800 if (E)
3801 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3802 NewAligns.push_back(Align.get());
3803 }
3804 // OpenMP [2.8.2, declare simd construct, Description]
3805 // The linear clause declares one or more list items to be private to a SIMD
3806 // lane and to have a linear relationship with respect to the iteration space
3807 // of a loop.
3808 // The special this pointer can be used as if was one of the arguments to the
3809 // function in any of the linear, aligned, or uniform clauses.
3810 // When a linear-step expression is specified in a linear clause it must be
3811 // either a constant integer expression or an integer-typed parameter that is
3812 // specified in a uniform clause on the directive.
3813 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3814 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3815 auto MI = LinModifiers.begin();
3816 for (const Expr *E : Linears) {
3817 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3818 ++MI;
3819 E = E->IgnoreParenImpCasts();
3820 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3821 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3822 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3823 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3824 FD->getParamDecl(PVD->getFunctionScopeIndex())
3825 ->getCanonicalDecl() == CanonPVD) {
3826 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3827 // A list-item cannot appear in more than one linear clause.
3828 if (LinearArgs.count(CanonPVD) > 0) {
3829 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3830 << getOpenMPClauseName(OMPC_linear)
3831 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3832 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3833 diag::note_omp_explicit_dsa)
3834 << getOpenMPClauseName(OMPC_linear);
3835 continue;
3836 }
3837 // Each argument can appear in at most one uniform or linear clause.
3838 if (UniformedArgs.count(CanonPVD) > 0) {
3839 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3840 << getOpenMPClauseName(OMPC_linear)
3841 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3842 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3843 diag::note_omp_explicit_dsa)
3844 << getOpenMPClauseName(OMPC_uniform);
3845 continue;
3846 }
3847 LinearArgs[CanonPVD] = E;
3848 if (E->isValueDependent() || E->isTypeDependent() ||
3849 E->isInstantiationDependent() ||
3850 E->containsUnexpandedParameterPack())
3851 continue;
3852 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3853 PVD->getOriginalType());
3854 continue;
3855 }
3856 }
3857 if (isa<CXXThisExpr>(E)) {
3858 if (UniformedLinearThis) {
3859 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3860 << getOpenMPClauseName(OMPC_linear)
3861 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3862 << E->getSourceRange();
3863 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3864 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3865 : OMPC_linear);
3866 continue;
3867 }
3868 UniformedLinearThis = E;
3869 if (E->isValueDependent() || E->isTypeDependent() ||
3870 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3871 continue;
3872 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3873 E->getType());
3874 continue;
3875 }
3876 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3877 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3878 }
3879 Expr *Step = nullptr;
3880 Expr *NewStep = nullptr;
3881 SmallVector<Expr *, 4> NewSteps;
3882 for (Expr *E : Steps) {
3883 // Skip the same step expression, it was checked already.
3884 if (Step == E || !E) {
3885 NewSteps.push_back(E ? NewStep : nullptr);
3886 continue;
3887 }
3888 Step = E;
3889 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3890 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3891 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3892 if (UniformedArgs.count(CanonPVD) == 0) {
3893 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3894 << Step->getSourceRange();
3895 } else if (E->isValueDependent() || E->isTypeDependent() ||
3896 E->isInstantiationDependent() ||
3897 E->containsUnexpandedParameterPack() ||
3898 CanonPVD->getType()->hasIntegerRepresentation()) {
3899 NewSteps.push_back(Step);
3900 } else {
3901 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3902 << Step->getSourceRange();
3903 }
3904 continue;
3905 }
3906 NewStep = Step;
3907 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3908 !Step->isInstantiationDependent() &&
3909 !Step->containsUnexpandedParameterPack()) {
3910 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3911 .get();
3912 if (NewStep)
3913 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3914 }
3915 NewSteps.push_back(NewStep);
3916 }
3917 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3918 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3919 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3920 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3921 const_cast<Expr **>(Linears.data()), Linears.size(),
3922 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3923 NewSteps.data(), NewSteps.size(), SR);
3924 ADecl->addAttr(NewAttr);
3925 return ConvertDeclToDeclGroup(ADecl);
3926 }
3927
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)3928 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3929 Stmt *AStmt,
3930 SourceLocation StartLoc,
3931 SourceLocation EndLoc) {
3932 if (!AStmt)
3933 return StmtError();
3934
3935 auto *CS = cast<CapturedStmt>(AStmt);
3936 // 1.2.2 OpenMP Language Terminology
3937 // Structured block - An executable statement with a single entry at the
3938 // top and a single exit at the bottom.
3939 // The point of exit cannot be a branch out of the structured block.
3940 // longjmp() and throw() must not violate the entry/exit criteria.
3941 CS->getCapturedDecl()->setNothrow();
3942
3943 setFunctionHasBranchProtectedScope();
3944
3945 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3946 DSAStack->isCancelRegion());
3947 }
3948
3949 namespace {
3950 /// Helper class for checking canonical form of the OpenMP loops and
3951 /// extracting iteration space of each loop in the loop nest, that will be used
3952 /// for IR generation.
3953 class OpenMPIterationSpaceChecker {
3954 /// Reference to Sema.
3955 Sema &SemaRef;
3956 /// A location for diagnostics (when there is no some better location).
3957 SourceLocation DefaultLoc;
3958 /// A location for diagnostics (when increment is not compatible).
3959 SourceLocation ConditionLoc;
3960 /// A source location for referring to loop init later.
3961 SourceRange InitSrcRange;
3962 /// A source location for referring to condition later.
3963 SourceRange ConditionSrcRange;
3964 /// A source location for referring to increment later.
3965 SourceRange IncrementSrcRange;
3966 /// Loop variable.
3967 ValueDecl *LCDecl = nullptr;
3968 /// Reference to loop variable.
3969 Expr *LCRef = nullptr;
3970 /// Lower bound (initializer for the var).
3971 Expr *LB = nullptr;
3972 /// Upper bound.
3973 Expr *UB = nullptr;
3974 /// Loop step (increment).
3975 Expr *Step = nullptr;
3976 /// This flag is true when condition is one of:
3977 /// Var < UB
3978 /// Var <= UB
3979 /// UB > Var
3980 /// UB >= Var
3981 /// This will have no value when the condition is !=
3982 llvm::Optional<bool> TestIsLessOp;
3983 /// This flag is true when condition is strict ( < or > ).
3984 bool TestIsStrictOp = false;
3985 /// This flag is true when step is subtracted on each iteration.
3986 bool SubtractStep = false;
3987
3988 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,SourceLocation DefaultLoc)3989 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3990 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3991 /// Check init-expr for canonical loop form and save loop counter
3992 /// variable - #Var and its initialization value - #LB.
3993 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
3994 /// Check test-expr for canonical form, save upper-bound (#UB), flags
3995 /// for less/greater and for strict/non-strict comparison.
3996 bool checkAndSetCond(Expr *S);
3997 /// Check incr-expr for canonical loop form and return true if it
3998 /// does not conform, otherwise save loop step (#Step).
3999 bool checkAndSetInc(Expr *S);
4000 /// Return the loop counter variable.
getLoopDecl() const4001 ValueDecl *getLoopDecl() const { return LCDecl; }
4002 /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const4003 Expr *getLoopDeclRefExpr() const { return LCRef; }
4004 /// Source range of the loop init.
getInitSrcRange() const4005 SourceRange getInitSrcRange() const { return InitSrcRange; }
4006 /// Source range of the loop condition.
getConditionSrcRange() const4007 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
4008 /// Source range of the loop increment.
getIncrementSrcRange() const4009 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
4010 /// True if the step should be subtracted.
shouldSubtractStep() const4011 bool shouldSubtractStep() const { return SubtractStep; }
4012 /// Build the expression to calculate the number of iterations.
4013 Expr *buildNumIterations(
4014 Scope *S, const bool LimitedType,
4015 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
4016 /// Build the precondition expression for the loops.
4017 Expr *
4018 buildPreCond(Scope *S, Expr *Cond,
4019 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
4020 /// Build reference expression to the counter be used for codegen.
4021 DeclRefExpr *
4022 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4023 DSAStackTy &DSA) const;
4024 /// Build reference expression to the private counter be used for
4025 /// codegen.
4026 Expr *buildPrivateCounterVar() const;
4027 /// Build initialization of the counter be used for codegen.
4028 Expr *buildCounterInit() const;
4029 /// Build step of the counter be used for codegen.
4030 Expr *buildCounterStep() const;
4031 /// Build loop data with counter value for depend clauses in ordered
4032 /// directives.
4033 Expr *
4034 buildOrderedLoopData(Scope *S, Expr *Counter,
4035 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4036 SourceLocation Loc, Expr *Inc = nullptr,
4037 OverloadedOperatorKind OOK = OO_Amp);
4038 /// Return true if any expression is dependent.
4039 bool dependent() const;
4040
4041 private:
4042 /// Check the right-hand side of an assignment in the increment
4043 /// expression.
4044 bool checkAndSetIncRHS(Expr *RHS);
4045 /// Helper to set loop counter variable and its initializer.
4046 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
4047 /// Helper to set upper bound.
4048 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
4049 SourceRange SR, SourceLocation SL);
4050 /// Helper to set loop increment.
4051 bool setStep(Expr *NewStep, bool Subtract);
4052 };
4053
dependent() const4054 bool OpenMPIterationSpaceChecker::dependent() const {
4055 if (!LCDecl) {
4056 assert(!LB && !UB && !Step);
4057 return false;
4058 }
4059 return LCDecl->getType()->isDependentType() ||
4060 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4061 (Step && Step->isValueDependent());
4062 }
4063
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB)4064 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
4065 Expr *NewLCRefExpr,
4066 Expr *NewLB) {
4067 // State consistency checking to ensure correct usage.
4068 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
4069 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4070 if (!NewLCDecl || !NewLB)
4071 return true;
4072 LCDecl = getCanonicalDecl(NewLCDecl);
4073 LCRef = NewLCRefExpr;
4074 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4075 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4076 if ((Ctor->isCopyOrMoveConstructor() ||
4077 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4078 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4079 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
4080 LB = NewLB;
4081 return false;
4082 }
4083
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)4084 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp,
4085 bool StrictOp, SourceRange SR,
4086 SourceLocation SL) {
4087 // State consistency checking to ensure correct usage.
4088 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
4089 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4090 if (!NewUB)
4091 return true;
4092 UB = NewUB;
4093 if (LessOp)
4094 TestIsLessOp = LessOp;
4095 TestIsStrictOp = StrictOp;
4096 ConditionSrcRange = SR;
4097 ConditionLoc = SL;
4098 return false;
4099 }
4100
setStep(Expr * NewStep,bool Subtract)4101 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
4102 // State consistency checking to ensure correct usage.
4103 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
4104 if (!NewStep)
4105 return true;
4106 if (!NewStep->isValueDependent()) {
4107 // Check that the step is integer expression.
4108 SourceLocation StepLoc = NewStep->getBeginLoc();
4109 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
4110 StepLoc, getExprAsWritten(NewStep));
4111 if (Val.isInvalid())
4112 return true;
4113 NewStep = Val.get();
4114
4115 // OpenMP [2.6, Canonical Loop Form, Restrictions]
4116 // If test-expr is of form var relational-op b and relational-op is < or
4117 // <= then incr-expr must cause var to increase on each iteration of the
4118 // loop. If test-expr is of form var relational-op b and relational-op is
4119 // > or >= then incr-expr must cause var to decrease on each iteration of
4120 // the loop.
4121 // If test-expr is of form b relational-op var and relational-op is < or
4122 // <= then incr-expr must cause var to decrease on each iteration of the
4123 // loop. If test-expr is of form b relational-op var and relational-op is
4124 // > or >= then incr-expr must cause var to increase on each iteration of
4125 // the loop.
4126 llvm::APSInt Result;
4127 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
4128 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
4129 bool IsConstNeg =
4130 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4131 bool IsConstPos =
4132 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4133 bool IsConstZero = IsConstant && !Result.getBoolValue();
4134
4135 // != with increment is treated as <; != with decrement is treated as >
4136 if (!TestIsLessOp.hasValue())
4137 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
4138 if (UB && (IsConstZero ||
4139 (TestIsLessOp.getValue() ?
4140 (IsConstNeg || (IsUnsigned && Subtract)) :
4141 (IsConstPos || (IsUnsigned && !Subtract))))) {
4142 SemaRef.Diag(NewStep->getExprLoc(),
4143 diag::err_omp_loop_incr_not_compatible)
4144 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
4145 SemaRef.Diag(ConditionLoc,
4146 diag::note_omp_loop_cond_requres_compatible_incr)
4147 << TestIsLessOp.getValue() << ConditionSrcRange;
4148 return true;
4149 }
4150 if (TestIsLessOp.getValue() == Subtract) {
4151 NewStep =
4152 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
4153 .get();
4154 Subtract = !Subtract;
4155 }
4156 }
4157
4158 Step = NewStep;
4159 SubtractStep = Subtract;
4160 return false;
4161 }
4162
checkAndSetInit(Stmt * S,bool EmitDiags)4163 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
4164 // Check init-expr for canonical loop form and save loop counter
4165 // variable - #Var and its initialization value - #LB.
4166 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
4167 // var = lb
4168 // integer-type var = lb
4169 // random-access-iterator-type var = lb
4170 // pointer-type var = lb
4171 //
4172 if (!S) {
4173 if (EmitDiags) {
4174 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4175 }
4176 return true;
4177 }
4178 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4179 if (!ExprTemp->cleanupsHaveSideEffects())
4180 S = ExprTemp->getSubExpr();
4181
4182 InitSrcRange = S->getSourceRange();
4183 if (Expr *E = dyn_cast<Expr>(S))
4184 S = E->IgnoreParens();
4185 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4186 if (BO->getOpcode() == BO_Assign) {
4187 Expr *LHS = BO->getLHS()->IgnoreParens();
4188 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4189 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4190 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4191 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4192 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4193 }
4194 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4195 if (ME->isArrow() &&
4196 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4197 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4198 }
4199 }
4200 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
4201 if (DS->isSingleDecl()) {
4202 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4203 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4204 // Accept non-canonical init form here but emit ext. warning.
4205 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
4206 SemaRef.Diag(S->getBeginLoc(),
4207 diag::ext_omp_loop_not_canonical_init)
4208 << S->getSourceRange();
4209 return setLCDeclAndLB(
4210 Var,
4211 buildDeclRefExpr(SemaRef, Var,
4212 Var->getType().getNonReferenceType(),
4213 DS->getBeginLoc()),
4214 Var->getInit());
4215 }
4216 }
4217 }
4218 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4219 if (CE->getOperator() == OO_Equal) {
4220 Expr *LHS = CE->getArg(0);
4221 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4222 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4223 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4224 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4225 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4226 }
4227 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4228 if (ME->isArrow() &&
4229 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4230 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4231 }
4232 }
4233 }
4234
4235 if (dependent() || SemaRef.CurContext->isDependentContext())
4236 return false;
4237 if (EmitDiags) {
4238 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
4239 << S->getSourceRange();
4240 }
4241 return true;
4242 }
4243
4244 /// Ignore parenthesizes, implicit casts, copy constructor and return the
4245 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)4246 static const ValueDecl *getInitLCDecl(const Expr *E) {
4247 if (!E)
4248 return nullptr;
4249 E = getExprAsWritten(E);
4250 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4251 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4252 if ((Ctor->isCopyOrMoveConstructor() ||
4253 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4254 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4255 E = CE->getArg(0)->IgnoreParenImpCasts();
4256 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4257 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4258 return getCanonicalDecl(VD);
4259 }
4260 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
4261 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4262 return getCanonicalDecl(ME->getMemberDecl());
4263 return nullptr;
4264 }
4265
checkAndSetCond(Expr * S)4266 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
4267 // Check test-expr for canonical form, save upper-bound UB, flags for
4268 // less/greater and for strict/non-strict comparison.
4269 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4270 // var relational-op b
4271 // b relational-op var
4272 //
4273 if (!S) {
4274 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4275 return true;
4276 }
4277 S = getExprAsWritten(S);
4278 SourceLocation CondLoc = S->getBeginLoc();
4279 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4280 if (BO->isRelationalOp()) {
4281 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4282 return setUB(BO->getRHS(),
4283 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4284 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4285 BO->getSourceRange(), BO->getOperatorLoc());
4286 if (getInitLCDecl(BO->getRHS()) == LCDecl)
4287 return setUB(BO->getLHS(),
4288 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4289 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4290 BO->getSourceRange(), BO->getOperatorLoc());
4291 } else if (BO->getOpcode() == BO_NE)
4292 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
4293 BO->getRHS() : BO->getLHS(),
4294 /*LessOp=*/llvm::None,
4295 /*StrictOp=*/true,
4296 BO->getSourceRange(), BO->getOperatorLoc());
4297 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4298 if (CE->getNumArgs() == 2) {
4299 auto Op = CE->getOperator();
4300 switch (Op) {
4301 case OO_Greater:
4302 case OO_GreaterEqual:
4303 case OO_Less:
4304 case OO_LessEqual:
4305 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4306 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4307 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4308 CE->getOperatorLoc());
4309 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4310 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4311 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4312 CE->getOperatorLoc());
4313 break;
4314 case OO_ExclaimEqual:
4315 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
4316 CE->getArg(1) : CE->getArg(0),
4317 /*LessOp=*/llvm::None,
4318 /*StrictOp=*/true,
4319 CE->getSourceRange(),
4320 CE->getOperatorLoc());
4321 break;
4322 default:
4323 break;
4324 }
4325 }
4326 }
4327 if (dependent() || SemaRef.CurContext->isDependentContext())
4328 return false;
4329 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4330 << S->getSourceRange() << LCDecl;
4331 return true;
4332 }
4333
checkAndSetIncRHS(Expr * RHS)4334 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4335 // RHS of canonical loop form increment can be:
4336 // var + incr
4337 // incr + var
4338 // var - incr
4339 //
4340 RHS = RHS->IgnoreParenImpCasts();
4341 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4342 if (BO->isAdditiveOp()) {
4343 bool IsAdd = BO->getOpcode() == BO_Add;
4344 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4345 return setStep(BO->getRHS(), !IsAdd);
4346 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4347 return setStep(BO->getLHS(), /*Subtract=*/false);
4348 }
4349 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4350 bool IsAdd = CE->getOperator() == OO_Plus;
4351 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4352 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4353 return setStep(CE->getArg(1), !IsAdd);
4354 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4355 return setStep(CE->getArg(0), /*Subtract=*/false);
4356 }
4357 }
4358 if (dependent() || SemaRef.CurContext->isDependentContext())
4359 return false;
4360 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4361 << RHS->getSourceRange() << LCDecl;
4362 return true;
4363 }
4364
checkAndSetInc(Expr * S)4365 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4366 // Check incr-expr for canonical loop form and return true if it
4367 // does not conform.
4368 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4369 // ++var
4370 // var++
4371 // --var
4372 // var--
4373 // var += incr
4374 // var -= incr
4375 // var = var + incr
4376 // var = incr + var
4377 // var = var - incr
4378 //
4379 if (!S) {
4380 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4381 return true;
4382 }
4383 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4384 if (!ExprTemp->cleanupsHaveSideEffects())
4385 S = ExprTemp->getSubExpr();
4386
4387 IncrementSrcRange = S->getSourceRange();
4388 S = S->IgnoreParens();
4389 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4390 if (UO->isIncrementDecrementOp() &&
4391 getInitLCDecl(UO->getSubExpr()) == LCDecl)
4392 return setStep(SemaRef
4393 .ActOnIntegerConstant(UO->getBeginLoc(),
4394 (UO->isDecrementOp() ? -1 : 1))
4395 .get(),
4396 /*Subtract=*/false);
4397 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4398 switch (BO->getOpcode()) {
4399 case BO_AddAssign:
4400 case BO_SubAssign:
4401 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4402 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4403 break;
4404 case BO_Assign:
4405 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4406 return checkAndSetIncRHS(BO->getRHS());
4407 break;
4408 default:
4409 break;
4410 }
4411 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4412 switch (CE->getOperator()) {
4413 case OO_PlusPlus:
4414 case OO_MinusMinus:
4415 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4416 return setStep(SemaRef
4417 .ActOnIntegerConstant(
4418 CE->getBeginLoc(),
4419 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4420 .get(),
4421 /*Subtract=*/false);
4422 break;
4423 case OO_PlusEqual:
4424 case OO_MinusEqual:
4425 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4426 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4427 break;
4428 case OO_Equal:
4429 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4430 return checkAndSetIncRHS(CE->getArg(1));
4431 break;
4432 default:
4433 break;
4434 }
4435 }
4436 if (dependent() || SemaRef.CurContext->isDependentContext())
4437 return false;
4438 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4439 << S->getSourceRange() << LCDecl;
4440 return true;
4441 }
4442
4443 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4444 tryBuildCapture(Sema &SemaRef, Expr *Capture,
4445 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4446 if (SemaRef.CurContext->isDependentContext())
4447 return ExprResult(Capture);
4448 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4449 return SemaRef.PerformImplicitConversion(
4450 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4451 /*AllowExplicit=*/true);
4452 auto I = Captures.find(Capture);
4453 if (I != Captures.end())
4454 return buildCapture(SemaRef, Capture, I->second);
4455 DeclRefExpr *Ref = nullptr;
4456 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4457 Captures[Capture] = Ref;
4458 return Res;
4459 }
4460
4461 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,const bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const4462 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4463 Scope *S, const bool LimitedType,
4464 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4465 ExprResult Diff;
4466 QualType VarType = LCDecl->getType().getNonReferenceType();
4467 if (VarType->isIntegerType() || VarType->isPointerType() ||
4468 SemaRef.getLangOpts().CPlusPlus) {
4469 // Upper - Lower
4470 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
4471 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
4472 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4473 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4474 if (!Upper || !Lower)
4475 return nullptr;
4476
4477 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4478
4479 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4480 // BuildBinOp already emitted error, this one is to point user to upper
4481 // and lower bound, and to tell what is passed to 'operator-'.
4482 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4483 << Upper->getSourceRange() << Lower->getSourceRange();
4484 return nullptr;
4485 }
4486 }
4487
4488 if (!Diff.isUsable())
4489 return nullptr;
4490
4491 // Upper - Lower [- 1]
4492 if (TestIsStrictOp)
4493 Diff = SemaRef.BuildBinOp(
4494 S, DefaultLoc, BO_Sub, Diff.get(),
4495 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4496 if (!Diff.isUsable())
4497 return nullptr;
4498
4499 // Upper - Lower [- 1] + Step
4500 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4501 if (!NewStep.isUsable())
4502 return nullptr;
4503 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4504 if (!Diff.isUsable())
4505 return nullptr;
4506
4507 // Parentheses (for dumping/debugging purposes only).
4508 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4509 if (!Diff.isUsable())
4510 return nullptr;
4511
4512 // (Upper - Lower [- 1] + Step) / Step
4513 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4514 if (!Diff.isUsable())
4515 return nullptr;
4516
4517 // OpenMP runtime requires 32-bit or 64-bit loop variables.
4518 QualType Type = Diff.get()->getType();
4519 ASTContext &C = SemaRef.Context;
4520 bool UseVarType = VarType->hasIntegerRepresentation() &&
4521 C.getTypeSize(Type) > C.getTypeSize(VarType);
4522 if (!Type->isIntegerType() || UseVarType) {
4523 unsigned NewSize =
4524 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4525 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4526 : Type->hasSignedIntegerRepresentation();
4527 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4528 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4529 Diff = SemaRef.PerformImplicitConversion(
4530 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4531 if (!Diff.isUsable())
4532 return nullptr;
4533 }
4534 }
4535 if (LimitedType) {
4536 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4537 if (NewSize != C.getTypeSize(Type)) {
4538 if (NewSize < C.getTypeSize(Type)) {
4539 assert(NewSize == 64 && "incorrect loop var size");
4540 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4541 << InitSrcRange << ConditionSrcRange;
4542 }
4543 QualType NewType = C.getIntTypeForBitwidth(
4544 NewSize, Type->hasSignedIntegerRepresentation() ||
4545 C.getTypeSize(Type) < NewSize);
4546 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4547 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4548 Sema::AA_Converting, true);
4549 if (!Diff.isUsable())
4550 return nullptr;
4551 }
4552 }
4553 }
4554
4555 return Diff.get();
4556 }
4557
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const4558 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4559 Scope *S, Expr *Cond,
4560 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4561 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4562 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4563 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4564
4565 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4566 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4567 if (!NewLB.isUsable() || !NewUB.isUsable())
4568 return nullptr;
4569
4570 ExprResult CondExpr =
4571 SemaRef.BuildBinOp(S, DefaultLoc,
4572 TestIsLessOp.getValue() ?
4573 (TestIsStrictOp ? BO_LT : BO_LE) :
4574 (TestIsStrictOp ? BO_GT : BO_GE),
4575 NewLB.get(), NewUB.get());
4576 if (CondExpr.isUsable()) {
4577 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4578 SemaRef.Context.BoolTy))
4579 CondExpr = SemaRef.PerformImplicitConversion(
4580 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4581 /*AllowExplicit=*/true);
4582 }
4583 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4584 // Otherwise use original loop conditon and evaluate it in runtime.
4585 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4586 }
4587
4588 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const4589 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4590 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4591 DSAStackTy &DSA) const {
4592 auto *VD = dyn_cast<VarDecl>(LCDecl);
4593 if (!VD) {
4594 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4595 DeclRefExpr *Ref = buildDeclRefExpr(
4596 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4597 const DSAStackTy::DSAVarData Data =
4598 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4599 // If the loop control decl is explicitly marked as private, do not mark it
4600 // as captured again.
4601 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4602 Captures.insert(std::make_pair(LCRef, Ref));
4603 return Ref;
4604 }
4605 return cast<DeclRefExpr>(LCRef);
4606 }
4607
buildPrivateCounterVar() const4608 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4609 if (LCDecl && !LCDecl->isInvalidDecl()) {
4610 QualType Type = LCDecl->getType().getNonReferenceType();
4611 VarDecl *PrivateVar = buildVarDecl(
4612 SemaRef, DefaultLoc, Type, LCDecl->getName(),
4613 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4614 isa<VarDecl>(LCDecl)
4615 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4616 : nullptr);
4617 if (PrivateVar->isInvalidDecl())
4618 return nullptr;
4619 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4620 }
4621 return nullptr;
4622 }
4623
4624 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const4625 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
4626
4627 /// Build step of the counter be used for codegen.
buildCounterStep() const4628 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4629
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)4630 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4631 Scope *S, Expr *Counter,
4632 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
4633 Expr *Inc, OverloadedOperatorKind OOK) {
4634 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4635 if (!Cnt)
4636 return nullptr;
4637 if (Inc) {
4638 assert((OOK == OO_Plus || OOK == OO_Minus) &&
4639 "Expected only + or - operations for depend clauses.");
4640 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4641 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
4642 if (!Cnt)
4643 return nullptr;
4644 }
4645 ExprResult Diff;
4646 QualType VarType = LCDecl->getType().getNonReferenceType();
4647 if (VarType->isIntegerType() || VarType->isPointerType() ||
4648 SemaRef.getLangOpts().CPlusPlus) {
4649 // Upper - Lower
4650 Expr *Upper =
4651 TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4652 Expr *Lower =
4653 TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4654 if (!Upper || !Lower)
4655 return nullptr;
4656
4657 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4658
4659 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4660 // BuildBinOp already emitted error, this one is to point user to upper
4661 // and lower bound, and to tell what is passed to 'operator-'.
4662 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4663 << Upper->getSourceRange() << Lower->getSourceRange();
4664 return nullptr;
4665 }
4666 }
4667
4668 if (!Diff.isUsable())
4669 return nullptr;
4670
4671 // Parentheses (for dumping/debugging purposes only).
4672 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4673 if (!Diff.isUsable())
4674 return nullptr;
4675
4676 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4677 if (!NewStep.isUsable())
4678 return nullptr;
4679 // (Upper - Lower) / Step
4680 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4681 if (!Diff.isUsable())
4682 return nullptr;
4683
4684 return Diff.get();
4685 }
4686
4687 /// Iteration space of a single for loop.
4688 struct LoopIterationSpace final {
4689 /// Condition of the loop.
4690 Expr *PreCond = nullptr;
4691 /// This expression calculates the number of iterations in the loop.
4692 /// It is always possible to calculate it before starting the loop.
4693 Expr *NumIterations = nullptr;
4694 /// The loop counter variable.
4695 Expr *CounterVar = nullptr;
4696 /// Private loop counter variable.
4697 Expr *PrivateCounterVar = nullptr;
4698 /// This is initializer for the initial value of #CounterVar.
4699 Expr *CounterInit = nullptr;
4700 /// This is step for the #CounterVar used to generate its update:
4701 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4702 Expr *CounterStep = nullptr;
4703 /// Should step be subtracted?
4704 bool Subtract = false;
4705 /// Source range of the loop init.
4706 SourceRange InitSrcRange;
4707 /// Source range of the loop condition.
4708 SourceRange CondSrcRange;
4709 /// Source range of the loop increment.
4710 SourceRange IncSrcRange;
4711 };
4712
4713 } // namespace
4714
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)4715 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4716 assert(getLangOpts().OpenMP && "OpenMP is not active.");
4717 assert(Init && "Expected loop in canonical form.");
4718 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4719 if (AssociatedLoops > 0 &&
4720 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4721 DSAStack->loopStart();
4722 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4723 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
4724 if (ValueDecl *D = ISC.getLoopDecl()) {
4725 auto *VD = dyn_cast<VarDecl>(D);
4726 if (!VD) {
4727 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
4728 VD = Private;
4729 } else {
4730 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
4731 /*WithInit=*/false);
4732 VD = cast<VarDecl>(Ref->getDecl());
4733 }
4734 }
4735 DSAStack->addLoopControlVariable(D, VD);
4736 const Decl *LD = DSAStack->getPossiblyLoopCunter();
4737 if (LD != D->getCanonicalDecl()) {
4738 DSAStack->resetPossibleLoopCounter();
4739 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
4740 MarkDeclarationsReferencedInExpr(
4741 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
4742 Var->getType().getNonLValueExprType(Context),
4743 ForLoc, /*RefersToCapture=*/true));
4744 }
4745 }
4746 }
4747 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4748 }
4749 }
4750
4751 /// Called on a for stmt to check and extract its iteration space
4752 /// 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,LoopIterationSpace & ResultIterSpace,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4753 static bool checkOpenMPIterationSpace(
4754 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4755 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4756 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
4757 Expr *OrderedLoopCountExpr,
4758 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4759 LoopIterationSpace &ResultIterSpace,
4760 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4761 // OpenMP [2.6, Canonical Loop Form]
4762 // for (init-expr; test-expr; incr-expr) structured-block
4763 auto *For = dyn_cast_or_null<ForStmt>(S);
4764 if (!For) {
4765 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
4766 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4767 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
4768 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4769 if (TotalNestedLoopCount > 1) {
4770 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4771 SemaRef.Diag(DSA.getConstructLoc(),
4772 diag::note_omp_collapse_ordered_expr)
4773 << 2 << CollapseLoopCountExpr->getSourceRange()
4774 << OrderedLoopCountExpr->getSourceRange();
4775 else if (CollapseLoopCountExpr)
4776 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4777 diag::note_omp_collapse_ordered_expr)
4778 << 0 << CollapseLoopCountExpr->getSourceRange();
4779 else
4780 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4781 diag::note_omp_collapse_ordered_expr)
4782 << 1 << OrderedLoopCountExpr->getSourceRange();
4783 }
4784 return true;
4785 }
4786 assert(For->getBody());
4787
4788 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4789
4790 // Check init.
4791 Stmt *Init = For->getInit();
4792 if (ISC.checkAndSetInit(Init))
4793 return true;
4794
4795 bool HasErrors = false;
4796
4797 // Check loop variable's type.
4798 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
4799 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4800
4801 // OpenMP [2.6, Canonical Loop Form]
4802 // Var is one of the following:
4803 // A variable of signed or unsigned integer type.
4804 // For C++, a variable of a random access iterator type.
4805 // For C, a variable of a pointer type.
4806 QualType VarType = LCDecl->getType().getNonReferenceType();
4807 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4808 !VarType->isPointerType() &&
4809 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4810 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
4811 << SemaRef.getLangOpts().CPlusPlus;
4812 HasErrors = true;
4813 }
4814
4815 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4816 // a Construct
4817 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4818 // parallel for construct is (are) private.
4819 // The loop iteration variable in the associated for-loop of a simd
4820 // construct with just one associated for-loop is linear with a
4821 // constant-linear-step that is the increment of the associated for-loop.
4822 // Exclude loop var from the list of variables with implicitly defined data
4823 // sharing attributes.
4824 VarsWithImplicitDSA.erase(LCDecl);
4825
4826 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4827 // in a Construct, C/C++].
4828 // The loop iteration variable in the associated for-loop of a simd
4829 // construct with just one associated for-loop may be listed in a linear
4830 // clause with a constant-linear-step that is the increment of the
4831 // associated for-loop.
4832 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4833 // parallel for construct may be listed in a private or lastprivate clause.
4834 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4835 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4836 // declared in the loop and it is predetermined as a private.
4837 OpenMPClauseKind PredeterminedCKind =
4838 isOpenMPSimdDirective(DKind)
4839 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4840 : OMPC_private;
4841 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4842 DVar.CKind != PredeterminedCKind) ||
4843 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4844 isOpenMPDistributeDirective(DKind)) &&
4845 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4846 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4847 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4848 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
4849 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4850 << getOpenMPClauseName(PredeterminedCKind);
4851 if (DVar.RefExpr == nullptr)
4852 DVar.CKind = PredeterminedCKind;
4853 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4854 HasErrors = true;
4855 } else if (LoopDeclRefExpr != nullptr) {
4856 // Make the loop iteration variable private (for worksharing constructs),
4857 // linear (for simd directives with the only one associated loop) or
4858 // lastprivate (for simd directives with several collapsed or ordered
4859 // loops).
4860 if (DVar.CKind == OMPC_unknown)
4861 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4862 [](OpenMPDirectiveKind) -> bool { return true; },
4863 /*FromParent=*/false);
4864 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4865 }
4866
4867 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4868
4869 // Check test-expr.
4870 HasErrors |= ISC.checkAndSetCond(For->getCond());
4871
4872 // Check incr-expr.
4873 HasErrors |= ISC.checkAndSetInc(For->getInc());
4874 }
4875
4876 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4877 return HasErrors;
4878
4879 // Build the loop's iteration space representation.
4880 ResultIterSpace.PreCond =
4881 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4882 ResultIterSpace.NumIterations = ISC.buildNumIterations(
4883 DSA.getCurScope(),
4884 (isOpenMPWorksharingDirective(DKind) ||
4885 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4886 Captures);
4887 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4888 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4889 ResultIterSpace.CounterInit = ISC.buildCounterInit();
4890 ResultIterSpace.CounterStep = ISC.buildCounterStep();
4891 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4892 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4893 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4894 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4895
4896 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4897 ResultIterSpace.NumIterations == nullptr ||
4898 ResultIterSpace.CounterVar == nullptr ||
4899 ResultIterSpace.PrivateCounterVar == nullptr ||
4900 ResultIterSpace.CounterInit == nullptr ||
4901 ResultIterSpace.CounterStep == nullptr);
4902 if (!HasErrors && DSA.isOrderedRegion()) {
4903 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4904 if (CurrentNestedLoopCount <
4905 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4906 DSA.getOrderedRegionParam().second->setLoopNumIterations(
4907 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4908 DSA.getOrderedRegionParam().second->setLoopCounter(
4909 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4910 }
4911 }
4912 for (auto &Pair : DSA.getDoacrossDependClauses()) {
4913 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4914 // Erroneous case - clause has some problems.
4915 continue;
4916 }
4917 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4918 Pair.second.size() <= CurrentNestedLoopCount) {
4919 // Erroneous case - clause has some problems.
4920 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
4921 continue;
4922 }
4923 Expr *CntValue;
4924 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4925 CntValue = ISC.buildOrderedLoopData(
4926 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4927 Pair.first->getDependencyLoc());
4928 else
4929 CntValue = ISC.buildOrderedLoopData(
4930 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4931 Pair.first->getDependencyLoc(),
4932 Pair.second[CurrentNestedLoopCount].first,
4933 Pair.second[CurrentNestedLoopCount].second);
4934 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4935 }
4936 }
4937
4938 return HasErrors;
4939 }
4940
4941 /// Build 'VarRef = Start.
4942 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4943 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4944 ExprResult Start,
4945 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4946 // Build 'VarRef = Start.
4947 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4948 if (!NewStart.isUsable())
4949 return ExprError();
4950 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4951 VarRef.get()->getType())) {
4952 NewStart = SemaRef.PerformImplicitConversion(
4953 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4954 /*AllowExplicit=*/true);
4955 if (!NewStart.isUsable())
4956 return ExprError();
4957 }
4958
4959 ExprResult Init =
4960 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4961 return Init;
4962 }
4963
4964 /// Build 'VarRef = Start + Iter * Step'.
buildCounterUpdate(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,ExprResult Iter,ExprResult Step,bool Subtract,llvm::MapVector<const Expr *,DeclRefExpr * > * Captures=nullptr)4965 static ExprResult buildCounterUpdate(
4966 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4967 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
4968 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
4969 // Add parentheses (for debugging purposes only).
4970 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4971 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4972 !Step.isUsable())
4973 return ExprError();
4974
4975 ExprResult NewStep = Step;
4976 if (Captures)
4977 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4978 if (NewStep.isInvalid())
4979 return ExprError();
4980 ExprResult Update =
4981 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4982 if (!Update.isUsable())
4983 return ExprError();
4984
4985 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4986 // 'VarRef = Start (+|-) Iter * Step'.
4987 ExprResult NewStart = Start;
4988 if (Captures)
4989 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4990 if (NewStart.isInvalid())
4991 return ExprError();
4992
4993 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4994 ExprResult SavedUpdate = Update;
4995 ExprResult UpdateVal;
4996 if (VarRef.get()->getType()->isOverloadableType() ||
4997 NewStart.get()->getType()->isOverloadableType() ||
4998 Update.get()->getType()->isOverloadableType()) {
4999 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
5000 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
5001 Update =
5002 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
5003 if (Update.isUsable()) {
5004 UpdateVal =
5005 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
5006 VarRef.get(), SavedUpdate.get());
5007 if (UpdateVal.isUsable()) {
5008 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
5009 UpdateVal.get());
5010 }
5011 }
5012 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
5013 }
5014
5015 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
5016 if (!Update.isUsable() || !UpdateVal.isUsable()) {
5017 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
5018 NewStart.get(), SavedUpdate.get());
5019 if (!Update.isUsable())
5020 return ExprError();
5021
5022 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
5023 VarRef.get()->getType())) {
5024 Update = SemaRef.PerformImplicitConversion(
5025 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
5026 if (!Update.isUsable())
5027 return ExprError();
5028 }
5029
5030 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
5031 }
5032 return Update;
5033 }
5034
5035 /// Convert integer expression \a E to make it have at least \a Bits
5036 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)5037 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
5038 if (E == nullptr)
5039 return ExprError();
5040 ASTContext &C = SemaRef.Context;
5041 QualType OldType = E->getType();
5042 unsigned HasBits = C.getTypeSize(OldType);
5043 if (HasBits >= Bits)
5044 return ExprResult(E);
5045 // OK to convert to signed, because new type has more bits than old.
5046 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
5047 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
5048 true);
5049 }
5050
5051 /// Check if the given expression \a E is a constant integer that fits
5052 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)5053 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
5054 if (E == nullptr)
5055 return false;
5056 llvm::APSInt Result;
5057 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
5058 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5059 return false;
5060 }
5061
5062 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)5063 static Stmt *buildPreInits(ASTContext &Context,
5064 MutableArrayRef<Decl *> PreInits) {
5065 if (!PreInits.empty()) {
5066 return new (Context) DeclStmt(
5067 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
5068 SourceLocation(), SourceLocation());
5069 }
5070 return nullptr;
5071 }
5072
5073 /// Build preinits statement for the given declarations.
5074 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)5075 buildPreInits(ASTContext &Context,
5076 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5077 if (!Captures.empty()) {
5078 SmallVector<Decl *, 16> PreInits;
5079 for (const auto &Pair : Captures)
5080 PreInits.push_back(Pair.second->getDecl());
5081 return buildPreInits(Context, PreInits);
5082 }
5083 return nullptr;
5084 }
5085
5086 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)5087 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
5088 Expr *PostUpdate = nullptr;
5089 if (!PostUpdates.empty()) {
5090 for (Expr *E : PostUpdates) {
5091 Expr *ConvE = S.BuildCStyleCastExpr(
5092 E->getExprLoc(),
5093 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
5094 E->getExprLoc(), E)
5095 .get();
5096 PostUpdate = PostUpdate
5097 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
5098 PostUpdate, ConvE)
5099 .get()
5100 : ConvE;
5101 }
5102 }
5103 return PostUpdate;
5104 }
5105
5106 /// Called on a for stmt to check itself and nested loops (if any).
5107 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
5108 /// number of collapsed loops otherwise.
5109 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopDirective::HelperExprs & Built)5110 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
5111 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
5112 DSAStackTy &DSA,
5113 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
5114 OMPLoopDirective::HelperExprs &Built) {
5115 unsigned NestedLoopCount = 1;
5116 if (CollapseLoopCountExpr) {
5117 // Found 'collapse' clause - calculate collapse number.
5118 Expr::EvalResult Result;
5119 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
5120 NestedLoopCount = Result.Val.getInt().getLimitedValue();
5121 }
5122 unsigned OrderedLoopCount = 1;
5123 if (OrderedLoopCountExpr) {
5124 // Found 'ordered' clause - calculate collapse number.
5125 Expr::EvalResult EVResult;
5126 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) {
5127 llvm::APSInt Result = EVResult.Val.getInt();
5128 if (Result.getLimitedValue() < NestedLoopCount) {
5129 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5130 diag::err_omp_wrong_ordered_loop_count)
5131 << OrderedLoopCountExpr->getSourceRange();
5132 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5133 diag::note_collapse_loop_count)
5134 << CollapseLoopCountExpr->getSourceRange();
5135 }
5136 OrderedLoopCount = Result.getLimitedValue();
5137 }
5138 }
5139 // This is helper routine for loop directives (e.g., 'for', 'simd',
5140 // 'for simd', etc.).
5141 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
5142 SmallVector<LoopIterationSpace, 4> IterSpaces;
5143 IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
5144 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
5145 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5146 if (checkOpenMPIterationSpace(
5147 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5148 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5149 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5150 Captures))
5151 return 0;
5152 // Move on to the next nested for loop, or to the loop body.
5153 // OpenMP [2.8.1, simd construct, Restrictions]
5154 // All loops associated with the construct must be perfectly nested; that
5155 // is, there must be no intervening code nor any OpenMP directive between
5156 // any two loops.
5157 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5158 }
5159 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
5160 if (checkOpenMPIterationSpace(
5161 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5162 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5163 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5164 Captures))
5165 return 0;
5166 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
5167 // Handle initialization of captured loop iterator variables.
5168 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
5169 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
5170 Captures[DRE] = DRE;
5171 }
5172 }
5173 // Move on to the next nested for loop, or to the loop body.
5174 // OpenMP [2.8.1, simd construct, Restrictions]
5175 // All loops associated with the construct must be perfectly nested; that
5176 // is, there must be no intervening code nor any OpenMP directive between
5177 // any two loops.
5178 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5179 }
5180
5181 Built.clear(/* size */ NestedLoopCount);
5182
5183 if (SemaRef.CurContext->isDependentContext())
5184 return NestedLoopCount;
5185
5186 // An example of what is generated for the following code:
5187 //
5188 // #pragma omp simd collapse(2) ordered(2)
5189 // for (i = 0; i < NI; ++i)
5190 // for (k = 0; k < NK; ++k)
5191 // for (j = J0; j < NJ; j+=2) {
5192 // <loop body>
5193 // }
5194 //
5195 // We generate the code below.
5196 // Note: the loop body may be outlined in CodeGen.
5197 // Note: some counters may be C++ classes, operator- is used to find number of
5198 // iterations and operator+= to calculate counter value.
5199 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
5200 // or i64 is currently supported).
5201 //
5202 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
5203 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
5204 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
5205 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
5206 // // similar updates for vars in clauses (e.g. 'linear')
5207 // <loop body (using local i and j)>
5208 // }
5209 // i = NI; // assign final values of counters
5210 // j = NJ;
5211 //
5212
5213 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
5214 // the iteration counts of the collapsed for loops.
5215 // Precondition tests if there is at least one iteration (all conditions are
5216 // true).
5217 auto PreCond = ExprResult(IterSpaces[0].PreCond);
5218 Expr *N0 = IterSpaces[0].NumIterations;
5219 ExprResult LastIteration32 =
5220 widenIterationCount(/*Bits=*/32,
5221 SemaRef
5222 .PerformImplicitConversion(
5223 N0->IgnoreImpCasts(), N0->getType(),
5224 Sema::AA_Converting, /*AllowExplicit=*/true)
5225 .get(),
5226 SemaRef);
5227 ExprResult LastIteration64 = widenIterationCount(
5228 /*Bits=*/64,
5229 SemaRef
5230 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
5231 Sema::AA_Converting,
5232 /*AllowExplicit=*/true)
5233 .get(),
5234 SemaRef);
5235
5236 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
5237 return NestedLoopCount;
5238
5239 ASTContext &C = SemaRef.Context;
5240 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
5241
5242 Scope *CurScope = DSA.getCurScope();
5243 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5244 if (PreCond.isUsable()) {
5245 PreCond =
5246 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
5247 PreCond.get(), IterSpaces[Cnt].PreCond);
5248 }
5249 Expr *N = IterSpaces[Cnt].NumIterations;
5250 SourceLocation Loc = N->getExprLoc();
5251 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5252 if (LastIteration32.isUsable())
5253 LastIteration32 = SemaRef.BuildBinOp(
5254 CurScope, Loc, BO_Mul, LastIteration32.get(),
5255 SemaRef
5256 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5257 Sema::AA_Converting,
5258 /*AllowExplicit=*/true)
5259 .get());
5260 if (LastIteration64.isUsable())
5261 LastIteration64 = SemaRef.BuildBinOp(
5262 CurScope, Loc, BO_Mul, LastIteration64.get(),
5263 SemaRef
5264 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5265 Sema::AA_Converting,
5266 /*AllowExplicit=*/true)
5267 .get());
5268 }
5269
5270 // Choose either the 32-bit or 64-bit version.
5271 ExprResult LastIteration = LastIteration64;
5272 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
5273 (LastIteration32.isUsable() &&
5274 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
5275 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5276 fitsInto(
5277 /*Bits=*/32,
5278 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
5279 LastIteration64.get(), SemaRef))))
5280 LastIteration = LastIteration32;
5281 QualType VType = LastIteration.get()->getType();
5282 QualType RealVType = VType;
5283 QualType StrideVType = VType;
5284 if (isOpenMPTaskLoopDirective(DKind)) {
5285 VType =
5286 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
5287 StrideVType =
5288 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
5289 }
5290
5291 if (!LastIteration.isUsable())
5292 return 0;
5293
5294 // Save the number of iterations.
5295 ExprResult NumIterations = LastIteration;
5296 {
5297 LastIteration = SemaRef.BuildBinOp(
5298 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
5299 LastIteration.get(),
5300 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5301 if (!LastIteration.isUsable())
5302 return 0;
5303 }
5304
5305 // Calculate the last iteration number beforehand instead of doing this on
5306 // each iteration. Do not do this if the number of iterations may be kfold-ed.
5307 llvm::APSInt Result;
5308 bool IsConstant =
5309 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
5310 ExprResult CalcLastIteration;
5311 if (!IsConstant) {
5312 ExprResult SaveRef =
5313 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
5314 LastIteration = SaveRef;
5315
5316 // Prepare SaveRef + 1.
5317 NumIterations = SemaRef.BuildBinOp(
5318 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
5319 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5320 if (!NumIterations.isUsable())
5321 return 0;
5322 }
5323
5324 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5325
5326 // Build variables passed into runtime, necessary for worksharing directives.
5327 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5328 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5329 isOpenMPDistributeDirective(DKind)) {
5330 // Lower bound variable, initialized with zero.
5331 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5332 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5333 SemaRef.AddInitializerToDecl(LBDecl,
5334 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5335 /*DirectInit*/ false);
5336
5337 // Upper bound variable, initialized with last iteration number.
5338 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5339 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5340 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5341 /*DirectInit*/ false);
5342
5343 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5344 // This will be used to implement clause 'lastprivate'.
5345 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5346 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5347 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5348 SemaRef.AddInitializerToDecl(ILDecl,
5349 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5350 /*DirectInit*/ false);
5351
5352 // Stride variable returned by runtime (we initialize it to 1 by default).
5353 VarDecl *STDecl =
5354 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5355 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5356 SemaRef.AddInitializerToDecl(STDecl,
5357 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5358 /*DirectInit*/ false);
5359
5360 // Build expression: UB = min(UB, LastIteration)
5361 // It is necessary for CodeGen of directives with static scheduling.
5362 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5363 UB.get(), LastIteration.get());
5364 ExprResult CondOp = SemaRef.ActOnConditionalOp(
5365 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
5366 LastIteration.get(), UB.get());
5367 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5368 CondOp.get());
5369 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5370
5371 // If we have a combined directive that combines 'distribute', 'for' or
5372 // 'simd' we need to be able to access the bounds of the schedule of the
5373 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5374 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5375 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5376 // Lower bound variable, initialized with zero.
5377 VarDecl *CombLBDecl =
5378 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
5379 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
5380 SemaRef.AddInitializerToDecl(
5381 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5382 /*DirectInit*/ false);
5383
5384 // Upper bound variable, initialized with last iteration number.
5385 VarDecl *CombUBDecl =
5386 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
5387 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
5388 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
5389 /*DirectInit*/ false);
5390
5391 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5392 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
5393 ExprResult CombCondOp =
5394 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
5395 LastIteration.get(), CombUB.get());
5396 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
5397 CombCondOp.get());
5398 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
5399
5400 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5401 // We expect to have at least 2 more parameters than the 'parallel'
5402 // directive does - the lower and upper bounds of the previous schedule.
5403 assert(CD->getNumParams() >= 4 &&
5404 "Unexpected number of parameters in loop combined directive");
5405
5406 // Set the proper type for the bounds given what we learned from the
5407 // enclosed loops.
5408 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5409 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5410
5411 // Previous lower and upper bounds are obtained from the region
5412 // parameters.
5413 PrevLB =
5414 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5415 PrevUB =
5416 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5417 }
5418 }
5419
5420 // Build the iteration variable and its initialization before loop.
5421 ExprResult IV;
5422 ExprResult Init, CombInit;
5423 {
5424 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5425 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5426 Expr *RHS =
5427 (isOpenMPWorksharingDirective(DKind) ||
5428 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5429 ? LB.get()
5430 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5431 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5432 Init = SemaRef.ActOnFinishFullExpr(Init.get());
5433
5434 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5435 Expr *CombRHS =
5436 (isOpenMPWorksharingDirective(DKind) ||
5437 isOpenMPTaskLoopDirective(DKind) ||
5438 isOpenMPDistributeDirective(DKind))
5439 ? CombLB.get()
5440 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5441 CombInit =
5442 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5443 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
5444 }
5445 }
5446
5447 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5448 SourceLocation CondLoc = AStmt->getBeginLoc();
5449 ExprResult Cond =
5450 (isOpenMPWorksharingDirective(DKind) ||
5451 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5452 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5453 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5454 NumIterations.get());
5455 ExprResult CombDistCond;
5456 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5457 CombDistCond =
5458 SemaRef.BuildBinOp(
5459 CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get());
5460 }
5461
5462 ExprResult CombCond;
5463 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5464 CombCond =
5465 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5466 }
5467 // Loop increment (IV = IV + 1)
5468 SourceLocation IncLoc = AStmt->getBeginLoc();
5469 ExprResult Inc =
5470 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5471 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5472 if (!Inc.isUsable())
5473 return 0;
5474 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5475 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5476 if (!Inc.isUsable())
5477 return 0;
5478
5479 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5480 // Used for directives with static scheduling.
5481 // In combined construct, add combined version that use CombLB and CombUB
5482 // base variables for the update
5483 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5484 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5485 isOpenMPDistributeDirective(DKind)) {
5486 // LB + ST
5487 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5488 if (!NextLB.isUsable())
5489 return 0;
5490 // LB = LB + ST
5491 NextLB =
5492 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5493 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5494 if (!NextLB.isUsable())
5495 return 0;
5496 // UB + ST
5497 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5498 if (!NextUB.isUsable())
5499 return 0;
5500 // UB = UB + ST
5501 NextUB =
5502 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5503 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5504 if (!NextUB.isUsable())
5505 return 0;
5506 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5507 CombNextLB =
5508 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5509 if (!NextLB.isUsable())
5510 return 0;
5511 // LB = LB + ST
5512 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5513 CombNextLB.get());
5514 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
5515 if (!CombNextLB.isUsable())
5516 return 0;
5517 // UB + ST
5518 CombNextUB =
5519 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5520 if (!CombNextUB.isUsable())
5521 return 0;
5522 // UB = UB + ST
5523 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5524 CombNextUB.get());
5525 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
5526 if (!CombNextUB.isUsable())
5527 return 0;
5528 }
5529 }
5530
5531 // Create increment expression for distribute loop when combined in a same
5532 // directive with for as IV = IV + ST; ensure upper bound expression based
5533 // on PrevUB instead of NumIterations - used to implement 'for' when found
5534 // in combination with 'distribute', like in 'distribute parallel for'
5535 SourceLocation DistIncLoc = AStmt->getBeginLoc();
5536 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
5537 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5538 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5539 assert(DistCond.isUsable() && "distribute cond expr was not built");
5540
5541 DistInc =
5542 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5543 assert(DistInc.isUsable() && "distribute inc expr was not built");
5544 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5545 DistInc.get());
5546 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
5547 assert(DistInc.isUsable() && "distribute inc expr was not built");
5548
5549 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5550 // construct
5551 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
5552 ExprResult IsUBGreater =
5553 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5554 ExprResult CondOp = SemaRef.ActOnConditionalOp(
5555 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5556 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5557 CondOp.get());
5558 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
5559
5560 // Build IV <= PrevUB to be used in parallel for is in combination with
5561 // a distribute directive with schedule(static, 1)
5562 ParForInDistCond =
5563 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get());
5564 }
5565
5566 // Build updates and final values of the loop counters.
5567 bool HasErrors = false;
5568 Built.Counters.resize(NestedLoopCount);
5569 Built.Inits.resize(NestedLoopCount);
5570 Built.Updates.resize(NestedLoopCount);
5571 Built.Finals.resize(NestedLoopCount);
5572 {
5573 // We implement the following algorithm for obtaining the
5574 // original loop iteration variable values based on the
5575 // value of the collapsed loop iteration variable IV.
5576 //
5577 // Let n+1 be the number of collapsed loops in the nest.
5578 // Iteration variables (I0, I1, .... In)
5579 // Iteration counts (N0, N1, ... Nn)
5580 //
5581 // Acc = IV;
5582 //
5583 // To compute Ik for loop k, 0 <= k <= n, generate:
5584 // Prod = N(k+1) * N(k+2) * ... * Nn;
5585 // Ik = Acc / Prod;
5586 // Acc -= Ik * Prod;
5587 //
5588 ExprResult Acc = IV;
5589 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5590 LoopIterationSpace &IS = IterSpaces[Cnt];
5591 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5592 ExprResult Iter;
5593
5594 // Compute prod
5595 ExprResult Prod =
5596 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
5597 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5598 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
5599 IterSpaces[K].NumIterations);
5600
5601 // Iter = Acc / Prod
5602 // If there is at least one more inner loop to avoid
5603 // multiplication by 1.
5604 if (Cnt + 1 < NestedLoopCount)
5605 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
5606 Acc.get(), Prod.get());
5607 else
5608 Iter = Acc;
5609 if (!Iter.isUsable()) {
5610 HasErrors = true;
5611 break;
5612 }
5613
5614 // Update Acc:
5615 // Acc -= Iter * Prod
5616 // Check if there is at least one more inner loop to avoid
5617 // multiplication by 1.
5618 if (Cnt + 1 < NestedLoopCount)
5619 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
5620 Iter.get(), Prod.get());
5621 else
5622 Prod = Iter;
5623 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
5624 Acc.get(), Prod.get());
5625
5626 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5627 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5628 DeclRefExpr *CounterVar = buildDeclRefExpr(
5629 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5630 /*RefersToCapture=*/true);
5631 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5632 IS.CounterInit, Captures);
5633 if (!Init.isUsable()) {
5634 HasErrors = true;
5635 break;
5636 }
5637 ExprResult Update = buildCounterUpdate(
5638 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5639 IS.CounterStep, IS.Subtract, &Captures);
5640 if (!Update.isUsable()) {
5641 HasErrors = true;
5642 break;
5643 }
5644
5645 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5646 ExprResult Final = buildCounterUpdate(
5647 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5648 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5649 if (!Final.isUsable()) {
5650 HasErrors = true;
5651 break;
5652 }
5653
5654 if (!Update.isUsable() || !Final.isUsable()) {
5655 HasErrors = true;
5656 break;
5657 }
5658 // Save results
5659 Built.Counters[Cnt] = IS.CounterVar;
5660 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5661 Built.Inits[Cnt] = Init.get();
5662 Built.Updates[Cnt] = Update.get();
5663 Built.Finals[Cnt] = Final.get();
5664 }
5665 }
5666
5667 if (HasErrors)
5668 return 0;
5669
5670 // Save results
5671 Built.IterationVarRef = IV.get();
5672 Built.LastIteration = LastIteration.get();
5673 Built.NumIterations = NumIterations.get();
5674 Built.CalcLastIteration =
5675 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5676 Built.PreCond = PreCond.get();
5677 Built.PreInits = buildPreInits(C, Captures);
5678 Built.Cond = Cond.get();
5679 Built.Init = Init.get();
5680 Built.Inc = Inc.get();
5681 Built.LB = LB.get();
5682 Built.UB = UB.get();
5683 Built.IL = IL.get();
5684 Built.ST = ST.get();
5685 Built.EUB = EUB.get();
5686 Built.NLB = NextLB.get();
5687 Built.NUB = NextUB.get();
5688 Built.PrevLB = PrevLB.get();
5689 Built.PrevUB = PrevUB.get();
5690 Built.DistInc = DistInc.get();
5691 Built.PrevEUB = PrevEUB.get();
5692 Built.DistCombinedFields.LB = CombLB.get();
5693 Built.DistCombinedFields.UB = CombUB.get();
5694 Built.DistCombinedFields.EUB = CombEUB.get();
5695 Built.DistCombinedFields.Init = CombInit.get();
5696 Built.DistCombinedFields.Cond = CombCond.get();
5697 Built.DistCombinedFields.NLB = CombNextLB.get();
5698 Built.DistCombinedFields.NUB = CombNextUB.get();
5699 Built.DistCombinedFields.DistCond = CombDistCond.get();
5700 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
5701
5702 return NestedLoopCount;
5703 }
5704
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)5705 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5706 auto CollapseClauses =
5707 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5708 if (CollapseClauses.begin() != CollapseClauses.end())
5709 return (*CollapseClauses.begin())->getNumForLoops();
5710 return nullptr;
5711 }
5712
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)5713 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5714 auto OrderedClauses =
5715 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5716 if (OrderedClauses.begin() != OrderedClauses.end())
5717 return (*OrderedClauses.begin())->getNumForLoops();
5718 return nullptr;
5719 }
5720
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)5721 static bool checkSimdlenSafelenSpecified(Sema &S,
5722 const ArrayRef<OMPClause *> Clauses) {
5723 const OMPSafelenClause *Safelen = nullptr;
5724 const OMPSimdlenClause *Simdlen = nullptr;
5725
5726 for (const OMPClause *Clause : Clauses) {
5727 if (Clause->getClauseKind() == OMPC_safelen)
5728 Safelen = cast<OMPSafelenClause>(Clause);
5729 else if (Clause->getClauseKind() == OMPC_simdlen)
5730 Simdlen = cast<OMPSimdlenClause>(Clause);
5731 if (Safelen && Simdlen)
5732 break;
5733 }
5734
5735 if (Simdlen && Safelen) {
5736 const Expr *SimdlenLength = Simdlen->getSimdlen();
5737 const Expr *SafelenLength = Safelen->getSafelen();
5738 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5739 SimdlenLength->isInstantiationDependent() ||
5740 SimdlenLength->containsUnexpandedParameterPack())
5741 return false;
5742 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5743 SafelenLength->isInstantiationDependent() ||
5744 SafelenLength->containsUnexpandedParameterPack())
5745 return false;
5746 Expr::EvalResult SimdlenResult, SafelenResult;
5747 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
5748 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
5749 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
5750 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
5751 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5752 // If both simdlen and safelen clauses are specified, the value of the
5753 // simdlen parameter must be less than or equal to the value of the safelen
5754 // parameter.
5755 if (SimdlenRes > SafelenRes) {
5756 S.Diag(SimdlenLength->getExprLoc(),
5757 diag::err_omp_wrong_simdlen_safelen_values)
5758 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5759 return true;
5760 }
5761 }
5762 return false;
5763 }
5764
5765 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5766 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5767 SourceLocation StartLoc, SourceLocation EndLoc,
5768 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5769 if (!AStmt)
5770 return StmtError();
5771
5772 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5773 OMPLoopDirective::HelperExprs B;
5774 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5775 // define the nested loops number.
5776 unsigned NestedLoopCount = checkOpenMPLoop(
5777 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5778 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5779 if (NestedLoopCount == 0)
5780 return StmtError();
5781
5782 assert((CurContext->isDependentContext() || B.builtAll()) &&
5783 "omp simd loop exprs were not built");
5784
5785 if (!CurContext->isDependentContext()) {
5786 // Finalize the clauses that need pre-built expressions for CodeGen.
5787 for (OMPClause *C : Clauses) {
5788 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5789 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5790 B.NumIterations, *this, CurScope,
5791 DSAStack))
5792 return StmtError();
5793 }
5794 }
5795
5796 if (checkSimdlenSafelenSpecified(*this, Clauses))
5797 return StmtError();
5798
5799 setFunctionHasBranchProtectedScope();
5800 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5801 Clauses, AStmt, B);
5802 }
5803
5804 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5805 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5806 SourceLocation StartLoc, SourceLocation EndLoc,
5807 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5808 if (!AStmt)
5809 return StmtError();
5810
5811 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5812 OMPLoopDirective::HelperExprs B;
5813 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5814 // define the nested loops number.
5815 unsigned NestedLoopCount = checkOpenMPLoop(
5816 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5817 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5818 if (NestedLoopCount == 0)
5819 return StmtError();
5820
5821 assert((CurContext->isDependentContext() || B.builtAll()) &&
5822 "omp for loop exprs were not built");
5823
5824 if (!CurContext->isDependentContext()) {
5825 // Finalize the clauses that need pre-built expressions for CodeGen.
5826 for (OMPClause *C : Clauses) {
5827 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5828 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5829 B.NumIterations, *this, CurScope,
5830 DSAStack))
5831 return StmtError();
5832 }
5833 }
5834
5835 setFunctionHasBranchProtectedScope();
5836 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5837 Clauses, AStmt, B, DSAStack->isCancelRegion());
5838 }
5839
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5840 StmtResult Sema::ActOnOpenMPForSimdDirective(
5841 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5842 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5843 if (!AStmt)
5844 return StmtError();
5845
5846 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5847 OMPLoopDirective::HelperExprs B;
5848 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5849 // define the nested loops number.
5850 unsigned NestedLoopCount =
5851 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5852 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5853 VarsWithImplicitDSA, B);
5854 if (NestedLoopCount == 0)
5855 return StmtError();
5856
5857 assert((CurContext->isDependentContext() || B.builtAll()) &&
5858 "omp for simd loop exprs were not built");
5859
5860 if (!CurContext->isDependentContext()) {
5861 // Finalize the clauses that need pre-built expressions for CodeGen.
5862 for (OMPClause *C : Clauses) {
5863 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5864 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5865 B.NumIterations, *this, CurScope,
5866 DSAStack))
5867 return StmtError();
5868 }
5869 }
5870
5871 if (checkSimdlenSafelenSpecified(*this, Clauses))
5872 return StmtError();
5873
5874 setFunctionHasBranchProtectedScope();
5875 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5876 Clauses, AStmt, B);
5877 }
5878
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5879 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5880 Stmt *AStmt,
5881 SourceLocation StartLoc,
5882 SourceLocation EndLoc) {
5883 if (!AStmt)
5884 return StmtError();
5885
5886 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5887 auto BaseStmt = AStmt;
5888 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5889 BaseStmt = CS->getCapturedStmt();
5890 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5891 auto S = C->children();
5892 if (S.begin() == S.end())
5893 return StmtError();
5894 // All associated statements must be '#pragma omp section' except for
5895 // the first one.
5896 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5897 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5898 if (SectionStmt)
5899 Diag(SectionStmt->getBeginLoc(),
5900 diag::err_omp_sections_substmt_not_section);
5901 return StmtError();
5902 }
5903 cast<OMPSectionDirective>(SectionStmt)
5904 ->setHasCancel(DSAStack->isCancelRegion());
5905 }
5906 } else {
5907 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
5908 return StmtError();
5909 }
5910
5911 setFunctionHasBranchProtectedScope();
5912
5913 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5914 DSAStack->isCancelRegion());
5915 }
5916
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5917 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5918 SourceLocation StartLoc,
5919 SourceLocation EndLoc) {
5920 if (!AStmt)
5921 return StmtError();
5922
5923 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5924
5925 setFunctionHasBranchProtectedScope();
5926 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5927
5928 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5929 DSAStack->isCancelRegion());
5930 }
5931
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5932 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5933 Stmt *AStmt,
5934 SourceLocation StartLoc,
5935 SourceLocation EndLoc) {
5936 if (!AStmt)
5937 return StmtError();
5938
5939 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5940
5941 setFunctionHasBranchProtectedScope();
5942
5943 // OpenMP [2.7.3, single Construct, Restrictions]
5944 // The copyprivate clause must not be used with the nowait clause.
5945 const OMPClause *Nowait = nullptr;
5946 const OMPClause *Copyprivate = nullptr;
5947 for (const OMPClause *Clause : Clauses) {
5948 if (Clause->getClauseKind() == OMPC_nowait)
5949 Nowait = Clause;
5950 else if (Clause->getClauseKind() == OMPC_copyprivate)
5951 Copyprivate = Clause;
5952 if (Copyprivate && Nowait) {
5953 Diag(Copyprivate->getBeginLoc(),
5954 diag::err_omp_single_copyprivate_with_nowait);
5955 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
5956 return StmtError();
5957 }
5958 }
5959
5960 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5961 }
5962
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5963 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5964 SourceLocation StartLoc,
5965 SourceLocation EndLoc) {
5966 if (!AStmt)
5967 return StmtError();
5968
5969 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5970
5971 setFunctionHasBranchProtectedScope();
5972
5973 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5974 }
5975
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5976 StmtResult Sema::ActOnOpenMPCriticalDirective(
5977 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5978 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5979 if (!AStmt)
5980 return StmtError();
5981
5982 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5983
5984 bool ErrorFound = false;
5985 llvm::APSInt Hint;
5986 SourceLocation HintLoc;
5987 bool DependentHint = false;
5988 for (const OMPClause *C : Clauses) {
5989 if (C->getClauseKind() == OMPC_hint) {
5990 if (!DirName.getName()) {
5991 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
5992 ErrorFound = true;
5993 }
5994 Expr *E = cast<OMPHintClause>(C)->getHint();
5995 if (E->isTypeDependent() || E->isValueDependent() ||
5996 E->isInstantiationDependent()) {
5997 DependentHint = true;
5998 } else {
5999 Hint = E->EvaluateKnownConstInt(Context);
6000 HintLoc = C->getBeginLoc();
6001 }
6002 }
6003 }
6004 if (ErrorFound)
6005 return StmtError();
6006 const auto Pair = DSAStack->getCriticalWithHint(DirName);
6007 if (Pair.first && DirName.getName() && !DependentHint) {
6008 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6009 Diag(StartLoc, diag::err_omp_critical_with_hint);
6010 if (HintLoc.isValid())
6011 Diag(HintLoc, diag::note_omp_critical_hint_here)
6012 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
6013 else
6014 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6015 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
6016 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
6017 << 1
6018 << C->getHint()->EvaluateKnownConstInt(Context).toString(
6019 /*Radix=*/10, /*Signed=*/false);
6020 } else {
6021 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6022 }
6023 }
6024 }
6025
6026 setFunctionHasBranchProtectedScope();
6027
6028 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
6029 Clauses, AStmt);
6030 if (!Pair.first && DirName.getName() && !DependentHint)
6031 DSAStack->addCriticalWithHint(Dir, Hint);
6032 return Dir;
6033 }
6034
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)6035 StmtResult Sema::ActOnOpenMPParallelForDirective(
6036 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6037 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6038 if (!AStmt)
6039 return StmtError();
6040
6041 auto *CS = cast<CapturedStmt>(AStmt);
6042 // 1.2.2 OpenMP Language Terminology
6043 // Structured block - An executable statement with a single entry at the
6044 // top and a single exit at the bottom.
6045 // The point of exit cannot be a branch out of the structured block.
6046 // longjmp() and throw() must not violate the entry/exit criteria.
6047 CS->getCapturedDecl()->setNothrow();
6048
6049 OMPLoopDirective::HelperExprs B;
6050 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6051 // define the nested loops number.
6052 unsigned NestedLoopCount =
6053 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
6054 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6055 VarsWithImplicitDSA, B);
6056 if (NestedLoopCount == 0)
6057 return StmtError();
6058
6059 assert((CurContext->isDependentContext() || B.builtAll()) &&
6060 "omp parallel for loop exprs were not built");
6061
6062 if (!CurContext->isDependentContext()) {
6063 // Finalize the clauses that need pre-built expressions for CodeGen.
6064 for (OMPClause *C : Clauses) {
6065 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6066 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6067 B.NumIterations, *this, CurScope,
6068 DSAStack))
6069 return StmtError();
6070 }
6071 }
6072
6073 setFunctionHasBranchProtectedScope();
6074 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
6075 NestedLoopCount, Clauses, AStmt, B,
6076 DSAStack->isCancelRegion());
6077 }
6078
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)6079 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
6080 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6081 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6082 if (!AStmt)
6083 return StmtError();
6084
6085 auto *CS = cast<CapturedStmt>(AStmt);
6086 // 1.2.2 OpenMP Language Terminology
6087 // Structured block - An executable statement with a single entry at the
6088 // top and a single exit at the bottom.
6089 // The point of exit cannot be a branch out of the structured block.
6090 // longjmp() and throw() must not violate the entry/exit criteria.
6091 CS->getCapturedDecl()->setNothrow();
6092
6093 OMPLoopDirective::HelperExprs B;
6094 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6095 // define the nested loops number.
6096 unsigned NestedLoopCount =
6097 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
6098 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6099 VarsWithImplicitDSA, B);
6100 if (NestedLoopCount == 0)
6101 return StmtError();
6102
6103 if (!CurContext->isDependentContext()) {
6104 // Finalize the clauses that need pre-built expressions for CodeGen.
6105 for (OMPClause *C : Clauses) {
6106 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6107 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6108 B.NumIterations, *this, CurScope,
6109 DSAStack))
6110 return StmtError();
6111 }
6112 }
6113
6114 if (checkSimdlenSafelenSpecified(*this, Clauses))
6115 return StmtError();
6116
6117 setFunctionHasBranchProtectedScope();
6118 return OMPParallelForSimdDirective::Create(
6119 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6120 }
6121
6122 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6123 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
6124 Stmt *AStmt, SourceLocation StartLoc,
6125 SourceLocation EndLoc) {
6126 if (!AStmt)
6127 return StmtError();
6128
6129 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6130 auto BaseStmt = AStmt;
6131 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6132 BaseStmt = CS->getCapturedStmt();
6133 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6134 auto S = C->children();
6135 if (S.begin() == S.end())
6136 return StmtError();
6137 // All associated statements must be '#pragma omp section' except for
6138 // the first one.
6139 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6140 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6141 if (SectionStmt)
6142 Diag(SectionStmt->getBeginLoc(),
6143 diag::err_omp_parallel_sections_substmt_not_section);
6144 return StmtError();
6145 }
6146 cast<OMPSectionDirective>(SectionStmt)
6147 ->setHasCancel(DSAStack->isCancelRegion());
6148 }
6149 } else {
6150 Diag(AStmt->getBeginLoc(),
6151 diag::err_omp_parallel_sections_not_compound_stmt);
6152 return StmtError();
6153 }
6154
6155 setFunctionHasBranchProtectedScope();
6156
6157 return OMPParallelSectionsDirective::Create(
6158 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
6159 }
6160
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6161 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
6162 Stmt *AStmt, SourceLocation StartLoc,
6163 SourceLocation EndLoc) {
6164 if (!AStmt)
6165 return StmtError();
6166
6167 auto *CS = cast<CapturedStmt>(AStmt);
6168 // 1.2.2 OpenMP Language Terminology
6169 // Structured block - An executable statement with a single entry at the
6170 // top and a single exit at the bottom.
6171 // The point of exit cannot be a branch out of the structured block.
6172 // longjmp() and throw() must not violate the entry/exit criteria.
6173 CS->getCapturedDecl()->setNothrow();
6174
6175 setFunctionHasBranchProtectedScope();
6176
6177 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6178 DSAStack->isCancelRegion());
6179 }
6180
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)6181 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
6182 SourceLocation EndLoc) {
6183 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
6184 }
6185
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)6186 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
6187 SourceLocation EndLoc) {
6188 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
6189 }
6190
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)6191 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
6192 SourceLocation EndLoc) {
6193 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
6194 }
6195
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6196 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
6197 Stmt *AStmt,
6198 SourceLocation StartLoc,
6199 SourceLocation EndLoc) {
6200 if (!AStmt)
6201 return StmtError();
6202
6203 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6204
6205 setFunctionHasBranchProtectedScope();
6206
6207 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
6208 AStmt,
6209 DSAStack->getTaskgroupReductionRef());
6210 }
6211
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)6212 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
6213 SourceLocation StartLoc,
6214 SourceLocation EndLoc) {
6215 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
6216 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
6217 }
6218
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6219 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
6220 Stmt *AStmt,
6221 SourceLocation StartLoc,
6222 SourceLocation EndLoc) {
6223 const OMPClause *DependFound = nullptr;
6224 const OMPClause *DependSourceClause = nullptr;
6225 const OMPClause *DependSinkClause = nullptr;
6226 bool ErrorFound = false;
6227 const OMPThreadsClause *TC = nullptr;
6228 const OMPSIMDClause *SC = nullptr;
6229 for (const OMPClause *C : Clauses) {
6230 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
6231 DependFound = C;
6232 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6233 if (DependSourceClause) {
6234 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
6235 << getOpenMPDirectiveName(OMPD_ordered)
6236 << getOpenMPClauseName(OMPC_depend) << 2;
6237 ErrorFound = true;
6238 } else {
6239 DependSourceClause = C;
6240 }
6241 if (DependSinkClause) {
6242 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6243 << 0;
6244 ErrorFound = true;
6245 }
6246 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6247 if (DependSourceClause) {
6248 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6249 << 1;
6250 ErrorFound = true;
6251 }
6252 DependSinkClause = C;
6253 }
6254 } else if (C->getClauseKind() == OMPC_threads) {
6255 TC = cast<OMPThreadsClause>(C);
6256 } else if (C->getClauseKind() == OMPC_simd) {
6257 SC = cast<OMPSIMDClause>(C);
6258 }
6259 }
6260 if (!ErrorFound && !SC &&
6261 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
6262 // OpenMP [2.8.1,simd Construct, Restrictions]
6263 // An ordered construct with the simd clause is the only OpenMP construct
6264 // that can appear in the simd region.
6265 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6266 ErrorFound = true;
6267 } else if (DependFound && (TC || SC)) {
6268 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6269 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
6270 ErrorFound = true;
6271 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
6272 Diag(DependFound->getBeginLoc(),
6273 diag::err_omp_ordered_directive_without_param);
6274 ErrorFound = true;
6275 } else if (TC || Clauses.empty()) {
6276 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
6277 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
6278 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6279 << (TC != nullptr);
6280 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6281 ErrorFound = true;
6282 }
6283 }
6284 if ((!AStmt && !DependFound) || ErrorFound)
6285 return StmtError();
6286
6287 if (AStmt) {
6288 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6289
6290 setFunctionHasBranchProtectedScope();
6291 }
6292
6293 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6294 }
6295
6296 namespace {
6297 /// Helper class for checking expression in 'omp atomic [update]'
6298 /// construct.
6299 class OpenMPAtomicUpdateChecker {
6300 /// Error results for atomic update expressions.
6301 enum ExprAnalysisErrorCode {
6302 /// A statement is not an expression statement.
6303 NotAnExpression,
6304 /// Expression is not builtin binary or unary operation.
6305 NotABinaryOrUnaryExpression,
6306 /// Unary operation is not post-/pre- increment/decrement operation.
6307 NotAnUnaryIncDecExpression,
6308 /// An expression is not of scalar type.
6309 NotAScalarType,
6310 /// A binary operation is not an assignment operation.
6311 NotAnAssignmentOp,
6312 /// RHS part of the binary operation is not a binary expression.
6313 NotABinaryExpression,
6314 /// RHS part is not additive/multiplicative/shift/biwise binary
6315 /// expression.
6316 NotABinaryOperator,
6317 /// RHS binary operation does not have reference to the updated LHS
6318 /// part.
6319 NotAnUpdateExpression,
6320 /// No errors is found.
6321 NoError
6322 };
6323 /// Reference to Sema.
6324 Sema &SemaRef;
6325 /// A location for note diagnostics (when error is found).
6326 SourceLocation NoteLoc;
6327 /// 'x' lvalue part of the source atomic expression.
6328 Expr *X;
6329 /// 'expr' rvalue part of the source atomic expression.
6330 Expr *E;
6331 /// Helper expression of the form
6332 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6333 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6334 Expr *UpdateExpr;
6335 /// Is 'x' a LHS in a RHS part of full update expression. It is
6336 /// important for non-associative operations.
6337 bool IsXLHSInRHSPart;
6338 BinaryOperatorKind Op;
6339 SourceLocation OpLoc;
6340 /// true if the source expression is a postfix unary operation, false
6341 /// if it is a prefix unary operation.
6342 bool IsPostfixUpdate;
6343
6344 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)6345 OpenMPAtomicUpdateChecker(Sema &SemaRef)
6346 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6347 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6348 /// Check specified statement that it is suitable for 'atomic update'
6349 /// constructs and extract 'x', 'expr' and Operation from the original
6350 /// expression. If DiagId and NoteId == 0, then only check is performed
6351 /// without error notification.
6352 /// \param DiagId Diagnostic which should be emitted if error is found.
6353 /// \param NoteId Diagnostic note for the main error message.
6354 /// \return true if statement is not an update expression, false otherwise.
6355 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6356 /// Return the 'x' lvalue part of the source atomic expression.
getX() const6357 Expr *getX() const { return X; }
6358 /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const6359 Expr *getExpr() const { return E; }
6360 /// Return the update expression used in calculation of the updated
6361 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6362 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const6363 Expr *getUpdateExpr() const { return UpdateExpr; }
6364 /// Return true if 'x' is LHS in RHS part of full update expression,
6365 /// false otherwise.
isXLHSInRHSPart() const6366 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6367
6368 /// true if the source expression is a postfix unary operation, false
6369 /// if it is a prefix unary operation.
isPostfixUpdate() const6370 bool isPostfixUpdate() const { return IsPostfixUpdate; }
6371
6372 private:
6373 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6374 unsigned NoteId = 0);
6375 };
6376 } // namespace
6377
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)6378 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6379 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6380 ExprAnalysisErrorCode ErrorFound = NoError;
6381 SourceLocation ErrorLoc, NoteLoc;
6382 SourceRange ErrorRange, NoteRange;
6383 // Allowed constructs are:
6384 // x = x binop expr;
6385 // x = expr binop x;
6386 if (AtomicBinOp->getOpcode() == BO_Assign) {
6387 X = AtomicBinOp->getLHS();
6388 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6389 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6390 if (AtomicInnerBinOp->isMultiplicativeOp() ||
6391 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6392 AtomicInnerBinOp->isBitwiseOp()) {
6393 Op = AtomicInnerBinOp->getOpcode();
6394 OpLoc = AtomicInnerBinOp->getOperatorLoc();
6395 Expr *LHS = AtomicInnerBinOp->getLHS();
6396 Expr *RHS = AtomicInnerBinOp->getRHS();
6397 llvm::FoldingSetNodeID XId, LHSId, RHSId;
6398 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6399 /*Canonical=*/true);
6400 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6401 /*Canonical=*/true);
6402 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6403 /*Canonical=*/true);
6404 if (XId == LHSId) {
6405 E = RHS;
6406 IsXLHSInRHSPart = true;
6407 } else if (XId == RHSId) {
6408 E = LHS;
6409 IsXLHSInRHSPart = false;
6410 } else {
6411 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6412 ErrorRange = AtomicInnerBinOp->getSourceRange();
6413 NoteLoc = X->getExprLoc();
6414 NoteRange = X->getSourceRange();
6415 ErrorFound = NotAnUpdateExpression;
6416 }
6417 } else {
6418 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6419 ErrorRange = AtomicInnerBinOp->getSourceRange();
6420 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6421 NoteRange = SourceRange(NoteLoc, NoteLoc);
6422 ErrorFound = NotABinaryOperator;
6423 }
6424 } else {
6425 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6426 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6427 ErrorFound = NotABinaryExpression;
6428 }
6429 } else {
6430 ErrorLoc = AtomicBinOp->getExprLoc();
6431 ErrorRange = AtomicBinOp->getSourceRange();
6432 NoteLoc = AtomicBinOp->getOperatorLoc();
6433 NoteRange = SourceRange(NoteLoc, NoteLoc);
6434 ErrorFound = NotAnAssignmentOp;
6435 }
6436 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6437 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6438 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6439 return true;
6440 }
6441 if (SemaRef.CurContext->isDependentContext())
6442 E = X = UpdateExpr = nullptr;
6443 return ErrorFound != NoError;
6444 }
6445
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)6446 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6447 unsigned NoteId) {
6448 ExprAnalysisErrorCode ErrorFound = NoError;
6449 SourceLocation ErrorLoc, NoteLoc;
6450 SourceRange ErrorRange, NoteRange;
6451 // Allowed constructs are:
6452 // x++;
6453 // x--;
6454 // ++x;
6455 // --x;
6456 // x binop= expr;
6457 // x = x binop expr;
6458 // x = expr binop x;
6459 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6460 AtomicBody = AtomicBody->IgnoreParenImpCasts();
6461 if (AtomicBody->getType()->isScalarType() ||
6462 AtomicBody->isInstantiationDependent()) {
6463 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6464 AtomicBody->IgnoreParenImpCasts())) {
6465 // Check for Compound Assignment Operation
6466 Op = BinaryOperator::getOpForCompoundAssignment(
6467 AtomicCompAssignOp->getOpcode());
6468 OpLoc = AtomicCompAssignOp->getOperatorLoc();
6469 E = AtomicCompAssignOp->getRHS();
6470 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6471 IsXLHSInRHSPart = true;
6472 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6473 AtomicBody->IgnoreParenImpCasts())) {
6474 // Check for Binary Operation
6475 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6476 return true;
6477 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6478 AtomicBody->IgnoreParenImpCasts())) {
6479 // Check for Unary Operation
6480 if (AtomicUnaryOp->isIncrementDecrementOp()) {
6481 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6482 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6483 OpLoc = AtomicUnaryOp->getOperatorLoc();
6484 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6485 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6486 IsXLHSInRHSPart = true;
6487 } else {
6488 ErrorFound = NotAnUnaryIncDecExpression;
6489 ErrorLoc = AtomicUnaryOp->getExprLoc();
6490 ErrorRange = AtomicUnaryOp->getSourceRange();
6491 NoteLoc = AtomicUnaryOp->getOperatorLoc();
6492 NoteRange = SourceRange(NoteLoc, NoteLoc);
6493 }
6494 } else if (!AtomicBody->isInstantiationDependent()) {
6495 ErrorFound = NotABinaryOrUnaryExpression;
6496 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6497 NoteRange = ErrorRange = AtomicBody->getSourceRange();
6498 }
6499 } else {
6500 ErrorFound = NotAScalarType;
6501 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6502 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6503 }
6504 } else {
6505 ErrorFound = NotAnExpression;
6506 NoteLoc = ErrorLoc = S->getBeginLoc();
6507 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6508 }
6509 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6510 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6511 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6512 return true;
6513 }
6514 if (SemaRef.CurContext->isDependentContext())
6515 E = X = UpdateExpr = nullptr;
6516 if (ErrorFound == NoError && E && X) {
6517 // Build an update expression of form 'OpaqueValueExpr(x) binop
6518 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6519 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6520 auto *OVEX = new (SemaRef.getASTContext())
6521 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6522 auto *OVEExpr = new (SemaRef.getASTContext())
6523 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
6524 ExprResult Update =
6525 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6526 IsXLHSInRHSPart ? OVEExpr : OVEX);
6527 if (Update.isInvalid())
6528 return true;
6529 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6530 Sema::AA_Casting);
6531 if (Update.isInvalid())
6532 return true;
6533 UpdateExpr = Update.get();
6534 }
6535 return ErrorFound != NoError;
6536 }
6537
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6538 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
6539 Stmt *AStmt,
6540 SourceLocation StartLoc,
6541 SourceLocation EndLoc) {
6542 if (!AStmt)
6543 return StmtError();
6544
6545 auto *CS = cast<CapturedStmt>(AStmt);
6546 // 1.2.2 OpenMP Language Terminology
6547 // Structured block - An executable statement with a single entry at the
6548 // top and a single exit at the bottom.
6549 // The point of exit cannot be a branch out of the structured block.
6550 // longjmp() and throw() must not violate the entry/exit criteria.
6551 OpenMPClauseKind AtomicKind = OMPC_unknown;
6552 SourceLocation AtomicKindLoc;
6553 for (const OMPClause *C : Clauses) {
6554 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6555 C->getClauseKind() == OMPC_update ||
6556 C->getClauseKind() == OMPC_capture) {
6557 if (AtomicKind != OMPC_unknown) {
6558 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6559 << SourceRange(C->getBeginLoc(), C->getEndLoc());
6560 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6561 << getOpenMPClauseName(AtomicKind);
6562 } else {
6563 AtomicKind = C->getClauseKind();
6564 AtomicKindLoc = C->getBeginLoc();
6565 }
6566 }
6567 }
6568
6569 Stmt *Body = CS->getCapturedStmt();
6570 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6571 Body = EWC->getSubExpr();
6572
6573 Expr *X = nullptr;
6574 Expr *V = nullptr;
6575 Expr *E = nullptr;
6576 Expr *UE = nullptr;
6577 bool IsXLHSInRHSPart = false;
6578 bool IsPostfixUpdate = false;
6579 // OpenMP [2.12.6, atomic Construct]
6580 // In the next expressions:
6581 // * x and v (as applicable) are both l-value expressions with scalar type.
6582 // * During the execution of an atomic region, multiple syntactic
6583 // occurrences of x must designate the same storage location.
6584 // * Neither of v and expr (as applicable) may access the storage location
6585 // designated by x.
6586 // * Neither of x and expr (as applicable) may access the storage location
6587 // designated by v.
6588 // * expr is an expression with scalar type.
6589 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6590 // * binop, binop=, ++, and -- are not overloaded operators.
6591 // * The expression x binop expr must be numerically equivalent to x binop
6592 // (expr). This requirement is satisfied if the operators in expr have
6593 // precedence greater than binop, or by using parentheses around expr or
6594 // subexpressions of expr.
6595 // * The expression expr binop x must be numerically equivalent to (expr)
6596 // binop x. This requirement is satisfied if the operators in expr have
6597 // precedence equal to or greater than binop, or by using parentheses around
6598 // expr or subexpressions of expr.
6599 // * For forms that allow multiple occurrences of x, the number of times
6600 // that x is evaluated is unspecified.
6601 if (AtomicKind == OMPC_read) {
6602 enum {
6603 NotAnExpression,
6604 NotAnAssignmentOp,
6605 NotAScalarType,
6606 NotAnLValue,
6607 NoError
6608 } ErrorFound = NoError;
6609 SourceLocation ErrorLoc, NoteLoc;
6610 SourceRange ErrorRange, NoteRange;
6611 // If clause is read:
6612 // v = x;
6613 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6614 const auto *AtomicBinOp =
6615 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6616 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6617 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6618 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6619 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6620 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6621 if (!X->isLValue() || !V->isLValue()) {
6622 const Expr *NotLValueExpr = X->isLValue() ? V : X;
6623 ErrorFound = NotAnLValue;
6624 ErrorLoc = AtomicBinOp->getExprLoc();
6625 ErrorRange = AtomicBinOp->getSourceRange();
6626 NoteLoc = NotLValueExpr->getExprLoc();
6627 NoteRange = NotLValueExpr->getSourceRange();
6628 }
6629 } else if (!X->isInstantiationDependent() ||
6630 !V->isInstantiationDependent()) {
6631 const Expr *NotScalarExpr =
6632 (X->isInstantiationDependent() || X->getType()->isScalarType())
6633 ? V
6634 : X;
6635 ErrorFound = NotAScalarType;
6636 ErrorLoc = AtomicBinOp->getExprLoc();
6637 ErrorRange = AtomicBinOp->getSourceRange();
6638 NoteLoc = NotScalarExpr->getExprLoc();
6639 NoteRange = NotScalarExpr->getSourceRange();
6640 }
6641 } else if (!AtomicBody->isInstantiationDependent()) {
6642 ErrorFound = NotAnAssignmentOp;
6643 ErrorLoc = AtomicBody->getExprLoc();
6644 ErrorRange = AtomicBody->getSourceRange();
6645 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6646 : AtomicBody->getExprLoc();
6647 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6648 : AtomicBody->getSourceRange();
6649 }
6650 } else {
6651 ErrorFound = NotAnExpression;
6652 NoteLoc = ErrorLoc = Body->getBeginLoc();
6653 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6654 }
6655 if (ErrorFound != NoError) {
6656 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6657 << ErrorRange;
6658 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6659 << NoteRange;
6660 return StmtError();
6661 }
6662 if (CurContext->isDependentContext())
6663 V = X = nullptr;
6664 } else if (AtomicKind == OMPC_write) {
6665 enum {
6666 NotAnExpression,
6667 NotAnAssignmentOp,
6668 NotAScalarType,
6669 NotAnLValue,
6670 NoError
6671 } ErrorFound = NoError;
6672 SourceLocation ErrorLoc, NoteLoc;
6673 SourceRange ErrorRange, NoteRange;
6674 // If clause is write:
6675 // x = expr;
6676 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6677 const auto *AtomicBinOp =
6678 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6679 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6680 X = AtomicBinOp->getLHS();
6681 E = AtomicBinOp->getRHS();
6682 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6683 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6684 if (!X->isLValue()) {
6685 ErrorFound = NotAnLValue;
6686 ErrorLoc = AtomicBinOp->getExprLoc();
6687 ErrorRange = AtomicBinOp->getSourceRange();
6688 NoteLoc = X->getExprLoc();
6689 NoteRange = X->getSourceRange();
6690 }
6691 } else if (!X->isInstantiationDependent() ||
6692 !E->isInstantiationDependent()) {
6693 const Expr *NotScalarExpr =
6694 (X->isInstantiationDependent() || X->getType()->isScalarType())
6695 ? E
6696 : X;
6697 ErrorFound = NotAScalarType;
6698 ErrorLoc = AtomicBinOp->getExprLoc();
6699 ErrorRange = AtomicBinOp->getSourceRange();
6700 NoteLoc = NotScalarExpr->getExprLoc();
6701 NoteRange = NotScalarExpr->getSourceRange();
6702 }
6703 } else if (!AtomicBody->isInstantiationDependent()) {
6704 ErrorFound = NotAnAssignmentOp;
6705 ErrorLoc = AtomicBody->getExprLoc();
6706 ErrorRange = AtomicBody->getSourceRange();
6707 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6708 : AtomicBody->getExprLoc();
6709 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6710 : AtomicBody->getSourceRange();
6711 }
6712 } else {
6713 ErrorFound = NotAnExpression;
6714 NoteLoc = ErrorLoc = Body->getBeginLoc();
6715 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6716 }
6717 if (ErrorFound != NoError) {
6718 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6719 << ErrorRange;
6720 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6721 << NoteRange;
6722 return StmtError();
6723 }
6724 if (CurContext->isDependentContext())
6725 E = X = nullptr;
6726 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6727 // If clause is update:
6728 // x++;
6729 // x--;
6730 // ++x;
6731 // --x;
6732 // x binop= expr;
6733 // x = x binop expr;
6734 // x = expr binop x;
6735 OpenMPAtomicUpdateChecker Checker(*this);
6736 if (Checker.checkStatement(
6737 Body, (AtomicKind == OMPC_update)
6738 ? diag::err_omp_atomic_update_not_expression_statement
6739 : diag::err_omp_atomic_not_expression_statement,
6740 diag::note_omp_atomic_update))
6741 return StmtError();
6742 if (!CurContext->isDependentContext()) {
6743 E = Checker.getExpr();
6744 X = Checker.getX();
6745 UE = Checker.getUpdateExpr();
6746 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6747 }
6748 } else if (AtomicKind == OMPC_capture) {
6749 enum {
6750 NotAnAssignmentOp,
6751 NotACompoundStatement,
6752 NotTwoSubstatements,
6753 NotASpecificExpression,
6754 NoError
6755 } ErrorFound = NoError;
6756 SourceLocation ErrorLoc, NoteLoc;
6757 SourceRange ErrorRange, NoteRange;
6758 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6759 // If clause is a capture:
6760 // v = x++;
6761 // v = x--;
6762 // v = ++x;
6763 // v = --x;
6764 // v = x binop= expr;
6765 // v = x = x binop expr;
6766 // v = x = expr binop x;
6767 const auto *AtomicBinOp =
6768 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6769 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6770 V = AtomicBinOp->getLHS();
6771 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6772 OpenMPAtomicUpdateChecker Checker(*this);
6773 if (Checker.checkStatement(
6774 Body, diag::err_omp_atomic_capture_not_expression_statement,
6775 diag::note_omp_atomic_update))
6776 return StmtError();
6777 E = Checker.getExpr();
6778 X = Checker.getX();
6779 UE = Checker.getUpdateExpr();
6780 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6781 IsPostfixUpdate = Checker.isPostfixUpdate();
6782 } else if (!AtomicBody->isInstantiationDependent()) {
6783 ErrorLoc = AtomicBody->getExprLoc();
6784 ErrorRange = AtomicBody->getSourceRange();
6785 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6786 : AtomicBody->getExprLoc();
6787 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6788 : AtomicBody->getSourceRange();
6789 ErrorFound = NotAnAssignmentOp;
6790 }
6791 if (ErrorFound != NoError) {
6792 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6793 << ErrorRange;
6794 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6795 return StmtError();
6796 }
6797 if (CurContext->isDependentContext())
6798 UE = V = E = X = nullptr;
6799 } else {
6800 // If clause is a capture:
6801 // { v = x; x = expr; }
6802 // { v = x; x++; }
6803 // { v = x; x--; }
6804 // { v = x; ++x; }
6805 // { v = x; --x; }
6806 // { v = x; x binop= expr; }
6807 // { v = x; x = x binop expr; }
6808 // { v = x; x = expr binop x; }
6809 // { x++; v = x; }
6810 // { x--; v = x; }
6811 // { ++x; v = x; }
6812 // { --x; v = x; }
6813 // { x binop= expr; v = x; }
6814 // { x = x binop expr; v = x; }
6815 // { x = expr binop x; v = x; }
6816 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6817 // Check that this is { expr1; expr2; }
6818 if (CS->size() == 2) {
6819 Stmt *First = CS->body_front();
6820 Stmt *Second = CS->body_back();
6821 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6822 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6823 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6824 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6825 // Need to find what subexpression is 'v' and what is 'x'.
6826 OpenMPAtomicUpdateChecker Checker(*this);
6827 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6828 BinaryOperator *BinOp = nullptr;
6829 if (IsUpdateExprFound) {
6830 BinOp = dyn_cast<BinaryOperator>(First);
6831 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6832 }
6833 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6834 // { v = x; x++; }
6835 // { v = x; x--; }
6836 // { v = x; ++x; }
6837 // { v = x; --x; }
6838 // { v = x; x binop= expr; }
6839 // { v = x; x = x binop expr; }
6840 // { v = x; x = expr binop x; }
6841 // Check that the first expression has form v = x.
6842 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6843 llvm::FoldingSetNodeID XId, PossibleXId;
6844 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6845 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6846 IsUpdateExprFound = XId == PossibleXId;
6847 if (IsUpdateExprFound) {
6848 V = BinOp->getLHS();
6849 X = Checker.getX();
6850 E = Checker.getExpr();
6851 UE = Checker.getUpdateExpr();
6852 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6853 IsPostfixUpdate = true;
6854 }
6855 }
6856 if (!IsUpdateExprFound) {
6857 IsUpdateExprFound = !Checker.checkStatement(First);
6858 BinOp = nullptr;
6859 if (IsUpdateExprFound) {
6860 BinOp = dyn_cast<BinaryOperator>(Second);
6861 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6862 }
6863 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6864 // { x++; v = x; }
6865 // { x--; v = x; }
6866 // { ++x; v = x; }
6867 // { --x; v = x; }
6868 // { x binop= expr; v = x; }
6869 // { x = x binop expr; v = x; }
6870 // { x = expr binop x; v = x; }
6871 // Check that the second expression has form v = x.
6872 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6873 llvm::FoldingSetNodeID XId, PossibleXId;
6874 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6875 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6876 IsUpdateExprFound = XId == PossibleXId;
6877 if (IsUpdateExprFound) {
6878 V = BinOp->getLHS();
6879 X = Checker.getX();
6880 E = Checker.getExpr();
6881 UE = Checker.getUpdateExpr();
6882 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6883 IsPostfixUpdate = false;
6884 }
6885 }
6886 }
6887 if (!IsUpdateExprFound) {
6888 // { v = x; x = expr; }
6889 auto *FirstExpr = dyn_cast<Expr>(First);
6890 auto *SecondExpr = dyn_cast<Expr>(Second);
6891 if (!FirstExpr || !SecondExpr ||
6892 !(FirstExpr->isInstantiationDependent() ||
6893 SecondExpr->isInstantiationDependent())) {
6894 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6895 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6896 ErrorFound = NotAnAssignmentOp;
6897 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6898 : First->getBeginLoc();
6899 NoteRange = ErrorRange = FirstBinOp
6900 ? FirstBinOp->getSourceRange()
6901 : SourceRange(ErrorLoc, ErrorLoc);
6902 } else {
6903 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6904 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6905 ErrorFound = NotAnAssignmentOp;
6906 NoteLoc = ErrorLoc = SecondBinOp
6907 ? SecondBinOp->getOperatorLoc()
6908 : Second->getBeginLoc();
6909 NoteRange = ErrorRange =
6910 SecondBinOp ? SecondBinOp->getSourceRange()
6911 : SourceRange(ErrorLoc, ErrorLoc);
6912 } else {
6913 Expr *PossibleXRHSInFirst =
6914 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6915 Expr *PossibleXLHSInSecond =
6916 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6917 llvm::FoldingSetNodeID X1Id, X2Id;
6918 PossibleXRHSInFirst->Profile(X1Id, Context,
6919 /*Canonical=*/true);
6920 PossibleXLHSInSecond->Profile(X2Id, Context,
6921 /*Canonical=*/true);
6922 IsUpdateExprFound = X1Id == X2Id;
6923 if (IsUpdateExprFound) {
6924 V = FirstBinOp->getLHS();
6925 X = SecondBinOp->getLHS();
6926 E = SecondBinOp->getRHS();
6927 UE = nullptr;
6928 IsXLHSInRHSPart = false;
6929 IsPostfixUpdate = true;
6930 } else {
6931 ErrorFound = NotASpecificExpression;
6932 ErrorLoc = FirstBinOp->getExprLoc();
6933 ErrorRange = FirstBinOp->getSourceRange();
6934 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6935 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6936 }
6937 }
6938 }
6939 }
6940 }
6941 } else {
6942 NoteLoc = ErrorLoc = Body->getBeginLoc();
6943 NoteRange = ErrorRange =
6944 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6945 ErrorFound = NotTwoSubstatements;
6946 }
6947 } else {
6948 NoteLoc = ErrorLoc = Body->getBeginLoc();
6949 NoteRange = ErrorRange =
6950 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6951 ErrorFound = NotACompoundStatement;
6952 }
6953 if (ErrorFound != NoError) {
6954 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6955 << ErrorRange;
6956 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6957 return StmtError();
6958 }
6959 if (CurContext->isDependentContext())
6960 UE = V = E = X = nullptr;
6961 }
6962 }
6963
6964 setFunctionHasBranchProtectedScope();
6965
6966 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6967 X, V, E, UE, IsXLHSInRHSPart,
6968 IsPostfixUpdate);
6969 }
6970
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6971 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6972 Stmt *AStmt,
6973 SourceLocation StartLoc,
6974 SourceLocation EndLoc) {
6975 if (!AStmt)
6976 return StmtError();
6977
6978 auto *CS = cast<CapturedStmt>(AStmt);
6979 // 1.2.2 OpenMP Language Terminology
6980 // Structured block - An executable statement with a single entry at the
6981 // top and a single exit at the bottom.
6982 // The point of exit cannot be a branch out of the structured block.
6983 // longjmp() and throw() must not violate the entry/exit criteria.
6984 CS->getCapturedDecl()->setNothrow();
6985 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6986 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6987 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6988 // 1.2.2 OpenMP Language Terminology
6989 // Structured block - An executable statement with a single entry at the
6990 // top and a single exit at the bottom.
6991 // The point of exit cannot be a branch out of the structured block.
6992 // longjmp() and throw() must not violate the entry/exit criteria.
6993 CS->getCapturedDecl()->setNothrow();
6994 }
6995
6996 // OpenMP [2.16, Nesting of Regions]
6997 // If specified, a teams construct must be contained within a target
6998 // construct. That target construct must contain no statements or directives
6999 // outside of the teams construct.
7000 if (DSAStack->hasInnerTeamsRegion()) {
7001 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
7002 bool OMPTeamsFound = true;
7003 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
7004 auto I = CS->body_begin();
7005 while (I != CS->body_end()) {
7006 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
7007 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
7008 OMPTeamsFound = false;
7009 break;
7010 }
7011 ++I;
7012 }
7013 assert(I != CS->body_end() && "Not found statement");
7014 S = *I;
7015 } else {
7016 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
7017 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
7018 }
7019 if (!OMPTeamsFound) {
7020 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7021 Diag(DSAStack->getInnerTeamsRegionLoc(),
7022 diag::note_omp_nested_teams_construct_here);
7023 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
7024 << isa<OMPExecutableDirective>(S);
7025 return StmtError();
7026 }
7027 }
7028
7029 setFunctionHasBranchProtectedScope();
7030
7031 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7032 }
7033
7034 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7035 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
7036 Stmt *AStmt, SourceLocation StartLoc,
7037 SourceLocation EndLoc) {
7038 if (!AStmt)
7039 return StmtError();
7040
7041 auto *CS = cast<CapturedStmt>(AStmt);
7042 // 1.2.2 OpenMP Language Terminology
7043 // Structured block - An executable statement with a single entry at the
7044 // top and a single exit at the bottom.
7045 // The point of exit cannot be a branch out of the structured block.
7046 // longjmp() and throw() must not violate the entry/exit criteria.
7047 CS->getCapturedDecl()->setNothrow();
7048 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7049 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7050 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7051 // 1.2.2 OpenMP Language Terminology
7052 // Structured block - An executable statement with a single entry at the
7053 // top and a single exit at the bottom.
7054 // The point of exit cannot be a branch out of the structured block.
7055 // longjmp() and throw() must not violate the entry/exit criteria.
7056 CS->getCapturedDecl()->setNothrow();
7057 }
7058
7059 setFunctionHasBranchProtectedScope();
7060
7061 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7062 AStmt);
7063 }
7064
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7065 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
7066 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7067 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7068 if (!AStmt)
7069 return StmtError();
7070
7071 auto *CS = cast<CapturedStmt>(AStmt);
7072 // 1.2.2 OpenMP Language Terminology
7073 // Structured block - An executable statement with a single entry at the
7074 // top and a single exit at the bottom.
7075 // The point of exit cannot be a branch out of the structured block.
7076 // longjmp() and throw() must not violate the entry/exit criteria.
7077 CS->getCapturedDecl()->setNothrow();
7078 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7079 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7080 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7081 // 1.2.2 OpenMP Language Terminology
7082 // Structured block - An executable statement with a single entry at the
7083 // top and a single exit at the bottom.
7084 // The point of exit cannot be a branch out of the structured block.
7085 // longjmp() and throw() must not violate the entry/exit criteria.
7086 CS->getCapturedDecl()->setNothrow();
7087 }
7088
7089 OMPLoopDirective::HelperExprs B;
7090 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7091 // define the nested loops number.
7092 unsigned NestedLoopCount =
7093 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
7094 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7095 VarsWithImplicitDSA, B);
7096 if (NestedLoopCount == 0)
7097 return StmtError();
7098
7099 assert((CurContext->isDependentContext() || B.builtAll()) &&
7100 "omp target parallel for loop exprs were not built");
7101
7102 if (!CurContext->isDependentContext()) {
7103 // Finalize the clauses that need pre-built expressions for CodeGen.
7104 for (OMPClause *C : Clauses) {
7105 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7107 B.NumIterations, *this, CurScope,
7108 DSAStack))
7109 return StmtError();
7110 }
7111 }
7112
7113 setFunctionHasBranchProtectedScope();
7114 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
7115 NestedLoopCount, Clauses, AStmt,
7116 B, DSAStack->isCancelRegion());
7117 }
7118
7119 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)7120 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
7121 const OpenMPClauseKind K) {
7122 return llvm::any_of(
7123 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
7124 }
7125
7126 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)7127 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
7128 const Params... ClauseTypes) {
7129 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
7130 }
7131
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7132 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
7133 Stmt *AStmt,
7134 SourceLocation StartLoc,
7135 SourceLocation EndLoc) {
7136 if (!AStmt)
7137 return StmtError();
7138
7139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7140
7141 // OpenMP [2.10.1, Restrictions, p. 97]
7142 // At least one map clause must appear on the directive.
7143 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7144 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7145 << "'map' or 'use_device_ptr'"
7146 << getOpenMPDirectiveName(OMPD_target_data);
7147 return StmtError();
7148 }
7149
7150 setFunctionHasBranchProtectedScope();
7151
7152 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7153 AStmt);
7154 }
7155
7156 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)7157 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
7158 SourceLocation StartLoc,
7159 SourceLocation EndLoc, Stmt *AStmt) {
7160 if (!AStmt)
7161 return StmtError();
7162
7163 auto *CS = cast<CapturedStmt>(AStmt);
7164 // 1.2.2 OpenMP Language Terminology
7165 // Structured block - An executable statement with a single entry at the
7166 // top and a single exit at the bottom.
7167 // The point of exit cannot be a branch out of the structured block.
7168 // longjmp() and throw() must not violate the entry/exit criteria.
7169 CS->getCapturedDecl()->setNothrow();
7170 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7171 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7172 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7173 // 1.2.2 OpenMP Language Terminology
7174 // Structured block - An executable statement with a single entry at the
7175 // top and a single exit at the bottom.
7176 // The point of exit cannot be a branch out of the structured block.
7177 // longjmp() and throw() must not violate the entry/exit criteria.
7178 CS->getCapturedDecl()->setNothrow();
7179 }
7180
7181 // OpenMP [2.10.2, Restrictions, p. 99]
7182 // At least one map clause must appear on the directive.
7183 if (!hasClauses(Clauses, OMPC_map)) {
7184 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7185 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
7186 return StmtError();
7187 }
7188
7189 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7190 AStmt);
7191 }
7192
7193 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)7194 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
7195 SourceLocation StartLoc,
7196 SourceLocation EndLoc, Stmt *AStmt) {
7197 if (!AStmt)
7198 return StmtError();
7199
7200 auto *CS = cast<CapturedStmt>(AStmt);
7201 // 1.2.2 OpenMP Language Terminology
7202 // Structured block - An executable statement with a single entry at the
7203 // top and a single exit at the bottom.
7204 // The point of exit cannot be a branch out of the structured block.
7205 // longjmp() and throw() must not violate the entry/exit criteria.
7206 CS->getCapturedDecl()->setNothrow();
7207 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7208 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7209 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7210 // 1.2.2 OpenMP Language Terminology
7211 // Structured block - An executable statement with a single entry at the
7212 // top and a single exit at the bottom.
7213 // The point of exit cannot be a branch out of the structured block.
7214 // longjmp() and throw() must not violate the entry/exit criteria.
7215 CS->getCapturedDecl()->setNothrow();
7216 }
7217
7218 // OpenMP [2.10.3, Restrictions, p. 102]
7219 // At least one map clause must appear on the directive.
7220 if (!hasClauses(Clauses, OMPC_map)) {
7221 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7222 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
7223 return StmtError();
7224 }
7225
7226 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7227 AStmt);
7228 }
7229
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)7230 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
7231 SourceLocation StartLoc,
7232 SourceLocation EndLoc,
7233 Stmt *AStmt) {
7234 if (!AStmt)
7235 return StmtError();
7236
7237 auto *CS = cast<CapturedStmt>(AStmt);
7238 // 1.2.2 OpenMP Language Terminology
7239 // Structured block - An executable statement with a single entry at the
7240 // top and a single exit at the bottom.
7241 // The point of exit cannot be a branch out of the structured block.
7242 // longjmp() and throw() must not violate the entry/exit criteria.
7243 CS->getCapturedDecl()->setNothrow();
7244 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7245 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7246 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7247 // 1.2.2 OpenMP Language Terminology
7248 // Structured block - An executable statement with a single entry at the
7249 // top and a single exit at the bottom.
7250 // The point of exit cannot be a branch out of the structured block.
7251 // longjmp() and throw() must not violate the entry/exit criteria.
7252 CS->getCapturedDecl()->setNothrow();
7253 }
7254
7255 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
7256 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7257 return StmtError();
7258 }
7259 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
7260 AStmt);
7261 }
7262
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7263 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
7264 Stmt *AStmt, SourceLocation StartLoc,
7265 SourceLocation EndLoc) {
7266 if (!AStmt)
7267 return StmtError();
7268
7269 auto *CS = cast<CapturedStmt>(AStmt);
7270 // 1.2.2 OpenMP Language Terminology
7271 // Structured block - An executable statement with a single entry at the
7272 // top and a single exit at the bottom.
7273 // The point of exit cannot be a branch out of the structured block.
7274 // longjmp() and throw() must not violate the entry/exit criteria.
7275 CS->getCapturedDecl()->setNothrow();
7276
7277 setFunctionHasBranchProtectedScope();
7278
7279 DSAStack->setParentTeamsRegionLoc(StartLoc);
7280
7281 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7282 }
7283
7284 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)7285 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
7286 SourceLocation EndLoc,
7287 OpenMPDirectiveKind CancelRegion) {
7288 if (DSAStack->isParentNowaitRegion()) {
7289 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7290 return StmtError();
7291 }
7292 if (DSAStack->isParentOrderedRegion()) {
7293 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7294 return StmtError();
7295 }
7296 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
7297 CancelRegion);
7298 }
7299
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)7300 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
7301 SourceLocation StartLoc,
7302 SourceLocation EndLoc,
7303 OpenMPDirectiveKind CancelRegion) {
7304 if (DSAStack->isParentNowaitRegion()) {
7305 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7306 return StmtError();
7307 }
7308 if (DSAStack->isParentOrderedRegion()) {
7309 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7310 return StmtError();
7311 }
7312 DSAStack->setParentCancelRegion(/*Cancel=*/true);
7313 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7314 CancelRegion);
7315 }
7316
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)7317 static bool checkGrainsizeNumTasksClauses(Sema &S,
7318 ArrayRef<OMPClause *> Clauses) {
7319 const OMPClause *PrevClause = nullptr;
7320 bool ErrorFound = false;
7321 for (const OMPClause *C : Clauses) {
7322 if (C->getClauseKind() == OMPC_grainsize ||
7323 C->getClauseKind() == OMPC_num_tasks) {
7324 if (!PrevClause)
7325 PrevClause = C;
7326 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
7327 S.Diag(C->getBeginLoc(),
7328 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7329 << getOpenMPClauseName(C->getClauseKind())
7330 << getOpenMPClauseName(PrevClause->getClauseKind());
7331 S.Diag(PrevClause->getBeginLoc(),
7332 diag::note_omp_previous_grainsize_num_tasks)
7333 << getOpenMPClauseName(PrevClause->getClauseKind());
7334 ErrorFound = true;
7335 }
7336 }
7337 }
7338 return ErrorFound;
7339 }
7340
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)7341 static bool checkReductionClauseWithNogroup(Sema &S,
7342 ArrayRef<OMPClause *> Clauses) {
7343 const OMPClause *ReductionClause = nullptr;
7344 const OMPClause *NogroupClause = nullptr;
7345 for (const OMPClause *C : Clauses) {
7346 if (C->getClauseKind() == OMPC_reduction) {
7347 ReductionClause = C;
7348 if (NogroupClause)
7349 break;
7350 continue;
7351 }
7352 if (C->getClauseKind() == OMPC_nogroup) {
7353 NogroupClause = C;
7354 if (ReductionClause)
7355 break;
7356 continue;
7357 }
7358 }
7359 if (ReductionClause && NogroupClause) {
7360 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7361 << SourceRange(NogroupClause->getBeginLoc(),
7362 NogroupClause->getEndLoc());
7363 return true;
7364 }
7365 return false;
7366 }
7367
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7368 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
7369 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7370 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7371 if (!AStmt)
7372 return StmtError();
7373
7374 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7375 OMPLoopDirective::HelperExprs B;
7376 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7377 // define the nested loops number.
7378 unsigned NestedLoopCount =
7379 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7380 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7381 VarsWithImplicitDSA, B);
7382 if (NestedLoopCount == 0)
7383 return StmtError();
7384
7385 assert((CurContext->isDependentContext() || B.builtAll()) &&
7386 "omp for loop exprs were not built");
7387
7388 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7389 // The grainsize clause and num_tasks clause are mutually exclusive and may
7390 // not appear on the same taskloop directive.
7391 if (checkGrainsizeNumTasksClauses(*this, Clauses))
7392 return StmtError();
7393 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7394 // If a reduction clause is present on the taskloop directive, the nogroup
7395 // clause must not be specified.
7396 if (checkReductionClauseWithNogroup(*this, Clauses))
7397 return StmtError();
7398
7399 setFunctionHasBranchProtectedScope();
7400 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7401 NestedLoopCount, Clauses, AStmt, B);
7402 }
7403
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7404 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
7405 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7406 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7407 if (!AStmt)
7408 return StmtError();
7409
7410 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7411 OMPLoopDirective::HelperExprs B;
7412 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7413 // define the nested loops number.
7414 unsigned NestedLoopCount =
7415 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7416 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7417 VarsWithImplicitDSA, B);
7418 if (NestedLoopCount == 0)
7419 return StmtError();
7420
7421 assert((CurContext->isDependentContext() || B.builtAll()) &&
7422 "omp for loop exprs were not built");
7423
7424 if (!CurContext->isDependentContext()) {
7425 // Finalize the clauses that need pre-built expressions for CodeGen.
7426 for (OMPClause *C : Clauses) {
7427 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7428 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7429 B.NumIterations, *this, CurScope,
7430 DSAStack))
7431 return StmtError();
7432 }
7433 }
7434
7435 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7436 // The grainsize clause and num_tasks clause are mutually exclusive and may
7437 // not appear on the same taskloop directive.
7438 if (checkGrainsizeNumTasksClauses(*this, Clauses))
7439 return StmtError();
7440 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7441 // If a reduction clause is present on the taskloop directive, the nogroup
7442 // clause must not be specified.
7443 if (checkReductionClauseWithNogroup(*this, Clauses))
7444 return StmtError();
7445 if (checkSimdlenSafelenSpecified(*this, Clauses))
7446 return StmtError();
7447
7448 setFunctionHasBranchProtectedScope();
7449 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7450 NestedLoopCount, Clauses, AStmt, B);
7451 }
7452
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7453 StmtResult Sema::ActOnOpenMPDistributeDirective(
7454 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7455 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7456 if (!AStmt)
7457 return StmtError();
7458
7459 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7460 OMPLoopDirective::HelperExprs B;
7461 // In presence of clause 'collapse' with number of loops, it will
7462 // define the nested loops number.
7463 unsigned NestedLoopCount =
7464 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7465 nullptr /*ordered not a clause on distribute*/, AStmt,
7466 *this, *DSAStack, VarsWithImplicitDSA, B);
7467 if (NestedLoopCount == 0)
7468 return StmtError();
7469
7470 assert((CurContext->isDependentContext() || B.builtAll()) &&
7471 "omp for loop exprs were not built");
7472
7473 setFunctionHasBranchProtectedScope();
7474 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7475 NestedLoopCount, Clauses, AStmt, B);
7476 }
7477
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7478 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
7479 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7480 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7481 if (!AStmt)
7482 return StmtError();
7483
7484 auto *CS = cast<CapturedStmt>(AStmt);
7485 // 1.2.2 OpenMP Language Terminology
7486 // Structured block - An executable statement with a single entry at the
7487 // top and a single exit at the bottom.
7488 // The point of exit cannot be a branch out of the structured block.
7489 // longjmp() and throw() must not violate the entry/exit criteria.
7490 CS->getCapturedDecl()->setNothrow();
7491 for (int ThisCaptureLevel =
7492 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7493 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7494 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7495 // 1.2.2 OpenMP Language Terminology
7496 // Structured block - An executable statement with a single entry at the
7497 // top and a single exit at the bottom.
7498 // The point of exit cannot be a branch out of the structured block.
7499 // longjmp() and throw() must not violate the entry/exit criteria.
7500 CS->getCapturedDecl()->setNothrow();
7501 }
7502
7503 OMPLoopDirective::HelperExprs B;
7504 // In presence of clause 'collapse' with number of loops, it will
7505 // define the nested loops number.
7506 unsigned NestedLoopCount = checkOpenMPLoop(
7507 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7508 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7509 VarsWithImplicitDSA, B);
7510 if (NestedLoopCount == 0)
7511 return StmtError();
7512
7513 assert((CurContext->isDependentContext() || B.builtAll()) &&
7514 "omp for loop exprs were not built");
7515
7516 setFunctionHasBranchProtectedScope();
7517 return OMPDistributeParallelForDirective::Create(
7518 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7519 DSAStack->isCancelRegion());
7520 }
7521
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7522 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
7523 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7524 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7525 if (!AStmt)
7526 return StmtError();
7527
7528 auto *CS = cast<CapturedStmt>(AStmt);
7529 // 1.2.2 OpenMP Language Terminology
7530 // Structured block - An executable statement with a single entry at the
7531 // top and a single exit at the bottom.
7532 // The point of exit cannot be a branch out of the structured block.
7533 // longjmp() and throw() must not violate the entry/exit criteria.
7534 CS->getCapturedDecl()->setNothrow();
7535 for (int ThisCaptureLevel =
7536 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7537 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7538 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7539 // 1.2.2 OpenMP Language Terminology
7540 // Structured block - An executable statement with a single entry at the
7541 // top and a single exit at the bottom.
7542 // The point of exit cannot be a branch out of the structured block.
7543 // longjmp() and throw() must not violate the entry/exit criteria.
7544 CS->getCapturedDecl()->setNothrow();
7545 }
7546
7547 OMPLoopDirective::HelperExprs B;
7548 // In presence of clause 'collapse' with number of loops, it will
7549 // define the nested loops number.
7550 unsigned NestedLoopCount = checkOpenMPLoop(
7551 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7552 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7553 VarsWithImplicitDSA, B);
7554 if (NestedLoopCount == 0)
7555 return StmtError();
7556
7557 assert((CurContext->isDependentContext() || B.builtAll()) &&
7558 "omp for loop exprs were not built");
7559
7560 if (!CurContext->isDependentContext()) {
7561 // Finalize the clauses that need pre-built expressions for CodeGen.
7562 for (OMPClause *C : Clauses) {
7563 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7564 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7565 B.NumIterations, *this, CurScope,
7566 DSAStack))
7567 return StmtError();
7568 }
7569 }
7570
7571 if (checkSimdlenSafelenSpecified(*this, Clauses))
7572 return StmtError();
7573
7574 setFunctionHasBranchProtectedScope();
7575 return OMPDistributeParallelForSimdDirective::Create(
7576 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7577 }
7578
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7579 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
7580 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7581 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7582 if (!AStmt)
7583 return StmtError();
7584
7585 auto *CS = cast<CapturedStmt>(AStmt);
7586 // 1.2.2 OpenMP Language Terminology
7587 // Structured block - An executable statement with a single entry at the
7588 // top and a single exit at the bottom.
7589 // The point of exit cannot be a branch out of the structured block.
7590 // longjmp() and throw() must not violate the entry/exit criteria.
7591 CS->getCapturedDecl()->setNothrow();
7592 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7593 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7594 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7595 // 1.2.2 OpenMP Language Terminology
7596 // Structured block - An executable statement with a single entry at the
7597 // top and a single exit at the bottom.
7598 // The point of exit cannot be a branch out of the structured block.
7599 // longjmp() and throw() must not violate the entry/exit criteria.
7600 CS->getCapturedDecl()->setNothrow();
7601 }
7602
7603 OMPLoopDirective::HelperExprs B;
7604 // In presence of clause 'collapse' with number of loops, it will
7605 // define the nested loops number.
7606 unsigned NestedLoopCount =
7607 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7608 nullptr /*ordered not a clause on distribute*/, CS, *this,
7609 *DSAStack, VarsWithImplicitDSA, B);
7610 if (NestedLoopCount == 0)
7611 return StmtError();
7612
7613 assert((CurContext->isDependentContext() || B.builtAll()) &&
7614 "omp for loop exprs were not built");
7615
7616 if (!CurContext->isDependentContext()) {
7617 // Finalize the clauses that need pre-built expressions for CodeGen.
7618 for (OMPClause *C : Clauses) {
7619 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7620 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7621 B.NumIterations, *this, CurScope,
7622 DSAStack))
7623 return StmtError();
7624 }
7625 }
7626
7627 if (checkSimdlenSafelenSpecified(*this, Clauses))
7628 return StmtError();
7629
7630 setFunctionHasBranchProtectedScope();
7631 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7632 NestedLoopCount, Clauses, AStmt, B);
7633 }
7634
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7635 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
7636 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7637 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7638 if (!AStmt)
7639 return StmtError();
7640
7641 auto *CS = cast<CapturedStmt>(AStmt);
7642 // 1.2.2 OpenMP Language Terminology
7643 // Structured block - An executable statement with a single entry at the
7644 // top and a single exit at the bottom.
7645 // The point of exit cannot be a branch out of the structured block.
7646 // longjmp() and throw() must not violate the entry/exit criteria.
7647 CS->getCapturedDecl()->setNothrow();
7648 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7649 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7650 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7651 // 1.2.2 OpenMP Language Terminology
7652 // Structured block - An executable statement with a single entry at the
7653 // top and a single exit at the bottom.
7654 // The point of exit cannot be a branch out of the structured block.
7655 // longjmp() and throw() must not violate the entry/exit criteria.
7656 CS->getCapturedDecl()->setNothrow();
7657 }
7658
7659 OMPLoopDirective::HelperExprs B;
7660 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7661 // define the nested loops number.
7662 unsigned NestedLoopCount = checkOpenMPLoop(
7663 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7664 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7665 VarsWithImplicitDSA, B);
7666 if (NestedLoopCount == 0)
7667 return StmtError();
7668
7669 assert((CurContext->isDependentContext() || B.builtAll()) &&
7670 "omp target parallel for simd loop exprs were not built");
7671
7672 if (!CurContext->isDependentContext()) {
7673 // Finalize the clauses that need pre-built expressions for CodeGen.
7674 for (OMPClause *C : Clauses) {
7675 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7676 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7677 B.NumIterations, *this, CurScope,
7678 DSAStack))
7679 return StmtError();
7680 }
7681 }
7682 if (checkSimdlenSafelenSpecified(*this, Clauses))
7683 return StmtError();
7684
7685 setFunctionHasBranchProtectedScope();
7686 return OMPTargetParallelForSimdDirective::Create(
7687 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7688 }
7689
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7690 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7691 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7692 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7693 if (!AStmt)
7694 return StmtError();
7695
7696 auto *CS = cast<CapturedStmt>(AStmt);
7697 // 1.2.2 OpenMP Language Terminology
7698 // Structured block - An executable statement with a single entry at the
7699 // top and a single exit at the bottom.
7700 // The point of exit cannot be a branch out of the structured block.
7701 // longjmp() and throw() must not violate the entry/exit criteria.
7702 CS->getCapturedDecl()->setNothrow();
7703 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7704 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7705 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7706 // 1.2.2 OpenMP Language Terminology
7707 // Structured block - An executable statement with a single entry at the
7708 // top and a single exit at the bottom.
7709 // The point of exit cannot be a branch out of the structured block.
7710 // longjmp() and throw() must not violate the entry/exit criteria.
7711 CS->getCapturedDecl()->setNothrow();
7712 }
7713
7714 OMPLoopDirective::HelperExprs B;
7715 // In presence of clause 'collapse' with number of loops, it will define the
7716 // nested loops number.
7717 unsigned NestedLoopCount =
7718 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7719 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7720 VarsWithImplicitDSA, B);
7721 if (NestedLoopCount == 0)
7722 return StmtError();
7723
7724 assert((CurContext->isDependentContext() || B.builtAll()) &&
7725 "omp target simd loop exprs were not built");
7726
7727 if (!CurContext->isDependentContext()) {
7728 // Finalize the clauses that need pre-built expressions for CodeGen.
7729 for (OMPClause *C : Clauses) {
7730 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7731 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7732 B.NumIterations, *this, CurScope,
7733 DSAStack))
7734 return StmtError();
7735 }
7736 }
7737
7738 if (checkSimdlenSafelenSpecified(*this, Clauses))
7739 return StmtError();
7740
7741 setFunctionHasBranchProtectedScope();
7742 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7743 NestedLoopCount, Clauses, AStmt, B);
7744 }
7745
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7746 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7747 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7748 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7749 if (!AStmt)
7750 return StmtError();
7751
7752 auto *CS = cast<CapturedStmt>(AStmt);
7753 // 1.2.2 OpenMP Language Terminology
7754 // Structured block - An executable statement with a single entry at the
7755 // top and a single exit at the bottom.
7756 // The point of exit cannot be a branch out of the structured block.
7757 // longjmp() and throw() must not violate the entry/exit criteria.
7758 CS->getCapturedDecl()->setNothrow();
7759 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7760 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7761 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7762 // 1.2.2 OpenMP Language Terminology
7763 // Structured block - An executable statement with a single entry at the
7764 // top and a single exit at the bottom.
7765 // The point of exit cannot be a branch out of the structured block.
7766 // longjmp() and throw() must not violate the entry/exit criteria.
7767 CS->getCapturedDecl()->setNothrow();
7768 }
7769
7770 OMPLoopDirective::HelperExprs B;
7771 // In presence of clause 'collapse' with number of loops, it will
7772 // define the nested loops number.
7773 unsigned NestedLoopCount =
7774 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7775 nullptr /*ordered not a clause on distribute*/, CS, *this,
7776 *DSAStack, VarsWithImplicitDSA, B);
7777 if (NestedLoopCount == 0)
7778 return StmtError();
7779
7780 assert((CurContext->isDependentContext() || B.builtAll()) &&
7781 "omp teams distribute loop exprs were not built");
7782
7783 setFunctionHasBranchProtectedScope();
7784
7785 DSAStack->setParentTeamsRegionLoc(StartLoc);
7786
7787 return OMPTeamsDistributeDirective::Create(
7788 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7789 }
7790
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7791 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7792 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7793 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7794 if (!AStmt)
7795 return StmtError();
7796
7797 auto *CS = cast<CapturedStmt>(AStmt);
7798 // 1.2.2 OpenMP Language Terminology
7799 // Structured block - An executable statement with a single entry at the
7800 // top and a single exit at the bottom.
7801 // The point of exit cannot be a branch out of the structured block.
7802 // longjmp() and throw() must not violate the entry/exit criteria.
7803 CS->getCapturedDecl()->setNothrow();
7804 for (int ThisCaptureLevel =
7805 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7806 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7807 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7808 // 1.2.2 OpenMP Language Terminology
7809 // Structured block - An executable statement with a single entry at the
7810 // top and a single exit at the bottom.
7811 // The point of exit cannot be a branch out of the structured block.
7812 // longjmp() and throw() must not violate the entry/exit criteria.
7813 CS->getCapturedDecl()->setNothrow();
7814 }
7815
7816
7817 OMPLoopDirective::HelperExprs B;
7818 // In presence of clause 'collapse' with number of loops, it will
7819 // define the nested loops number.
7820 unsigned NestedLoopCount = checkOpenMPLoop(
7821 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7822 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7823 VarsWithImplicitDSA, B);
7824
7825 if (NestedLoopCount == 0)
7826 return StmtError();
7827
7828 assert((CurContext->isDependentContext() || B.builtAll()) &&
7829 "omp teams distribute simd loop exprs were not built");
7830
7831 if (!CurContext->isDependentContext()) {
7832 // Finalize the clauses that need pre-built expressions for CodeGen.
7833 for (OMPClause *C : Clauses) {
7834 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7835 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7836 B.NumIterations, *this, CurScope,
7837 DSAStack))
7838 return StmtError();
7839 }
7840 }
7841
7842 if (checkSimdlenSafelenSpecified(*this, Clauses))
7843 return StmtError();
7844
7845 setFunctionHasBranchProtectedScope();
7846
7847 DSAStack->setParentTeamsRegionLoc(StartLoc);
7848
7849 return OMPTeamsDistributeSimdDirective::Create(
7850 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7851 }
7852
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7853 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7854 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7855 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7856 if (!AStmt)
7857 return StmtError();
7858
7859 auto *CS = cast<CapturedStmt>(AStmt);
7860 // 1.2.2 OpenMP Language Terminology
7861 // Structured block - An executable statement with a single entry at the
7862 // top and a single exit at the bottom.
7863 // The point of exit cannot be a branch out of the structured block.
7864 // longjmp() and throw() must not violate the entry/exit criteria.
7865 CS->getCapturedDecl()->setNothrow();
7866
7867 for (int ThisCaptureLevel =
7868 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7869 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7870 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7871 // 1.2.2 OpenMP Language Terminology
7872 // Structured block - An executable statement with a single entry at the
7873 // top and a single exit at the bottom.
7874 // The point of exit cannot be a branch out of the structured block.
7875 // longjmp() and throw() must not violate the entry/exit criteria.
7876 CS->getCapturedDecl()->setNothrow();
7877 }
7878
7879 OMPLoopDirective::HelperExprs B;
7880 // In presence of clause 'collapse' with number of loops, it will
7881 // define the nested loops number.
7882 unsigned NestedLoopCount = checkOpenMPLoop(
7883 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7884 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7885 VarsWithImplicitDSA, B);
7886
7887 if (NestedLoopCount == 0)
7888 return StmtError();
7889
7890 assert((CurContext->isDependentContext() || B.builtAll()) &&
7891 "omp for loop exprs were not built");
7892
7893 if (!CurContext->isDependentContext()) {
7894 // Finalize the clauses that need pre-built expressions for CodeGen.
7895 for (OMPClause *C : Clauses) {
7896 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7897 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7898 B.NumIterations, *this, CurScope,
7899 DSAStack))
7900 return StmtError();
7901 }
7902 }
7903
7904 if (checkSimdlenSafelenSpecified(*this, Clauses))
7905 return StmtError();
7906
7907 setFunctionHasBranchProtectedScope();
7908
7909 DSAStack->setParentTeamsRegionLoc(StartLoc);
7910
7911 return OMPTeamsDistributeParallelForSimdDirective::Create(
7912 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7913 }
7914
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7915 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7916 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7917 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7918 if (!AStmt)
7919 return StmtError();
7920
7921 auto *CS = cast<CapturedStmt>(AStmt);
7922 // 1.2.2 OpenMP Language Terminology
7923 // Structured block - An executable statement with a single entry at the
7924 // top and a single exit at the bottom.
7925 // The point of exit cannot be a branch out of the structured block.
7926 // longjmp() and throw() must not violate the entry/exit criteria.
7927 CS->getCapturedDecl()->setNothrow();
7928
7929 for (int ThisCaptureLevel =
7930 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7931 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7932 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7933 // 1.2.2 OpenMP Language Terminology
7934 // Structured block - An executable statement with a single entry at the
7935 // top and a single exit at the bottom.
7936 // The point of exit cannot be a branch out of the structured block.
7937 // longjmp() and throw() must not violate the entry/exit criteria.
7938 CS->getCapturedDecl()->setNothrow();
7939 }
7940
7941 OMPLoopDirective::HelperExprs B;
7942 // In presence of clause 'collapse' with number of loops, it will
7943 // define the nested loops number.
7944 unsigned NestedLoopCount = checkOpenMPLoop(
7945 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7946 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7947 VarsWithImplicitDSA, B);
7948
7949 if (NestedLoopCount == 0)
7950 return StmtError();
7951
7952 assert((CurContext->isDependentContext() || B.builtAll()) &&
7953 "omp for loop exprs were not built");
7954
7955 setFunctionHasBranchProtectedScope();
7956
7957 DSAStack->setParentTeamsRegionLoc(StartLoc);
7958
7959 return OMPTeamsDistributeParallelForDirective::Create(
7960 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7961 DSAStack->isCancelRegion());
7962 }
7963
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7964 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7965 Stmt *AStmt,
7966 SourceLocation StartLoc,
7967 SourceLocation EndLoc) {
7968 if (!AStmt)
7969 return StmtError();
7970
7971 auto *CS = cast<CapturedStmt>(AStmt);
7972 // 1.2.2 OpenMP Language Terminology
7973 // Structured block - An executable statement with a single entry at the
7974 // top and a single exit at the bottom.
7975 // The point of exit cannot be a branch out of the structured block.
7976 // longjmp() and throw() must not violate the entry/exit criteria.
7977 CS->getCapturedDecl()->setNothrow();
7978
7979 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7980 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7981 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7982 // 1.2.2 OpenMP Language Terminology
7983 // Structured block - An executable statement with a single entry at the
7984 // top and a single exit at the bottom.
7985 // The point of exit cannot be a branch out of the structured block.
7986 // longjmp() and throw() must not violate the entry/exit criteria.
7987 CS->getCapturedDecl()->setNothrow();
7988 }
7989 setFunctionHasBranchProtectedScope();
7990
7991 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7992 AStmt);
7993 }
7994
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7995 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7996 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7997 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7998 if (!AStmt)
7999 return StmtError();
8000
8001 auto *CS = cast<CapturedStmt>(AStmt);
8002 // 1.2.2 OpenMP Language Terminology
8003 // Structured block - An executable statement with a single entry at the
8004 // top and a single exit at the bottom.
8005 // The point of exit cannot be a branch out of the structured block.
8006 // longjmp() and throw() must not violate the entry/exit criteria.
8007 CS->getCapturedDecl()->setNothrow();
8008 for (int ThisCaptureLevel =
8009 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8010 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8011 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8012 // 1.2.2 OpenMP Language Terminology
8013 // Structured block - An executable statement with a single entry at the
8014 // top and a single exit at the bottom.
8015 // The point of exit cannot be a branch out of the structured block.
8016 // longjmp() and throw() must not violate the entry/exit criteria.
8017 CS->getCapturedDecl()->setNothrow();
8018 }
8019
8020 OMPLoopDirective::HelperExprs B;
8021 // In presence of clause 'collapse' with number of loops, it will
8022 // define the nested loops number.
8023 unsigned NestedLoopCount = checkOpenMPLoop(
8024 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
8025 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8026 VarsWithImplicitDSA, B);
8027 if (NestedLoopCount == 0)
8028 return StmtError();
8029
8030 assert((CurContext->isDependentContext() || B.builtAll()) &&
8031 "omp target teams distribute loop exprs were not built");
8032
8033 setFunctionHasBranchProtectedScope();
8034 return OMPTargetTeamsDistributeDirective::Create(
8035 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8036 }
8037
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8038 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
8039 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8040 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8041 if (!AStmt)
8042 return StmtError();
8043
8044 auto *CS = cast<CapturedStmt>(AStmt);
8045 // 1.2.2 OpenMP Language Terminology
8046 // Structured block - An executable statement with a single entry at the
8047 // top and a single exit at the bottom.
8048 // The point of exit cannot be a branch out of the structured block.
8049 // longjmp() and throw() must not violate the entry/exit criteria.
8050 CS->getCapturedDecl()->setNothrow();
8051 for (int ThisCaptureLevel =
8052 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8053 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8054 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8055 // 1.2.2 OpenMP Language Terminology
8056 // Structured block - An executable statement with a single entry at the
8057 // top and a single exit at the bottom.
8058 // The point of exit cannot be a branch out of the structured block.
8059 // longjmp() and throw() must not violate the entry/exit criteria.
8060 CS->getCapturedDecl()->setNothrow();
8061 }
8062
8063 OMPLoopDirective::HelperExprs B;
8064 // In presence of clause 'collapse' with number of loops, it will
8065 // define the nested loops number.
8066 unsigned NestedLoopCount = checkOpenMPLoop(
8067 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8068 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8069 VarsWithImplicitDSA, B);
8070 if (NestedLoopCount == 0)
8071 return StmtError();
8072
8073 assert((CurContext->isDependentContext() || B.builtAll()) &&
8074 "omp target teams distribute parallel for loop exprs were not built");
8075
8076 if (!CurContext->isDependentContext()) {
8077 // Finalize the clauses that need pre-built expressions for CodeGen.
8078 for (OMPClause *C : Clauses) {
8079 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8080 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8081 B.NumIterations, *this, CurScope,
8082 DSAStack))
8083 return StmtError();
8084 }
8085 }
8086
8087 setFunctionHasBranchProtectedScope();
8088 return OMPTargetTeamsDistributeParallelForDirective::Create(
8089 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8090 DSAStack->isCancelRegion());
8091 }
8092
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8093 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
8094 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8095 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8096 if (!AStmt)
8097 return StmtError();
8098
8099 auto *CS = cast<CapturedStmt>(AStmt);
8100 // 1.2.2 OpenMP Language Terminology
8101 // Structured block - An executable statement with a single entry at the
8102 // top and a single exit at the bottom.
8103 // The point of exit cannot be a branch out of the structured block.
8104 // longjmp() and throw() must not violate the entry/exit criteria.
8105 CS->getCapturedDecl()->setNothrow();
8106 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
8107 OMPD_target_teams_distribute_parallel_for_simd);
8108 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8109 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8110 // 1.2.2 OpenMP Language Terminology
8111 // Structured block - An executable statement with a single entry at the
8112 // top and a single exit at the bottom.
8113 // The point of exit cannot be a branch out of the structured block.
8114 // longjmp() and throw() must not violate the entry/exit criteria.
8115 CS->getCapturedDecl()->setNothrow();
8116 }
8117
8118 OMPLoopDirective::HelperExprs B;
8119 // In presence of clause 'collapse' with number of loops, it will
8120 // define the nested loops number.
8121 unsigned NestedLoopCount =
8122 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
8123 getCollapseNumberExpr(Clauses),
8124 nullptr /*ordered not a clause on distribute*/, CS, *this,
8125 *DSAStack, VarsWithImplicitDSA, B);
8126 if (NestedLoopCount == 0)
8127 return StmtError();
8128
8129 assert((CurContext->isDependentContext() || B.builtAll()) &&
8130 "omp target teams distribute parallel for simd loop exprs were not "
8131 "built");
8132
8133 if (!CurContext->isDependentContext()) {
8134 // Finalize the clauses that need pre-built expressions for CodeGen.
8135 for (OMPClause *C : Clauses) {
8136 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8137 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8138 B.NumIterations, *this, CurScope,
8139 DSAStack))
8140 return StmtError();
8141 }
8142 }
8143
8144 if (checkSimdlenSafelenSpecified(*this, Clauses))
8145 return StmtError();
8146
8147 setFunctionHasBranchProtectedScope();
8148 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
8149 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8150 }
8151
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8152 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
8153 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8154 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8155 if (!AStmt)
8156 return StmtError();
8157
8158 auto *CS = cast<CapturedStmt>(AStmt);
8159 // 1.2.2 OpenMP Language Terminology
8160 // Structured block - An executable statement with a single entry at the
8161 // top and a single exit at the bottom.
8162 // The point of exit cannot be a branch out of the structured block.
8163 // longjmp() and throw() must not violate the entry/exit criteria.
8164 CS->getCapturedDecl()->setNothrow();
8165 for (int ThisCaptureLevel =
8166 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8167 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8168 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8169 // 1.2.2 OpenMP Language Terminology
8170 // Structured block - An executable statement with a single entry at the
8171 // top and a single exit at the bottom.
8172 // The point of exit cannot be a branch out of the structured block.
8173 // longjmp() and throw() must not violate the entry/exit criteria.
8174 CS->getCapturedDecl()->setNothrow();
8175 }
8176
8177 OMPLoopDirective::HelperExprs B;
8178 // In presence of clause 'collapse' with number of loops, it will
8179 // define the nested loops number.
8180 unsigned NestedLoopCount = checkOpenMPLoop(
8181 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
8182 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8183 VarsWithImplicitDSA, B);
8184 if (NestedLoopCount == 0)
8185 return StmtError();
8186
8187 assert((CurContext->isDependentContext() || B.builtAll()) &&
8188 "omp target teams distribute simd loop exprs were not built");
8189
8190 if (!CurContext->isDependentContext()) {
8191 // Finalize the clauses that need pre-built expressions for CodeGen.
8192 for (OMPClause *C : Clauses) {
8193 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8194 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8195 B.NumIterations, *this, CurScope,
8196 DSAStack))
8197 return StmtError();
8198 }
8199 }
8200
8201 if (checkSimdlenSafelenSpecified(*this, Clauses))
8202 return StmtError();
8203
8204 setFunctionHasBranchProtectedScope();
8205 return OMPTargetTeamsDistributeSimdDirective::Create(
8206 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8207 }
8208
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8209 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
8210 SourceLocation StartLoc,
8211 SourceLocation LParenLoc,
8212 SourceLocation EndLoc) {
8213 OMPClause *Res = nullptr;
8214 switch (Kind) {
8215 case OMPC_final:
8216 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
8217 break;
8218 case OMPC_num_threads:
8219 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
8220 break;
8221 case OMPC_safelen:
8222 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
8223 break;
8224 case OMPC_simdlen:
8225 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
8226 break;
8227 case OMPC_collapse:
8228 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
8229 break;
8230 case OMPC_ordered:
8231 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
8232 break;
8233 case OMPC_device:
8234 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
8235 break;
8236 case OMPC_num_teams:
8237 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
8238 break;
8239 case OMPC_thread_limit:
8240 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
8241 break;
8242 case OMPC_priority:
8243 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
8244 break;
8245 case OMPC_grainsize:
8246 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
8247 break;
8248 case OMPC_num_tasks:
8249 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
8250 break;
8251 case OMPC_hint:
8252 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
8253 break;
8254 case OMPC_if:
8255 case OMPC_default:
8256 case OMPC_proc_bind:
8257 case OMPC_schedule:
8258 case OMPC_private:
8259 case OMPC_firstprivate:
8260 case OMPC_lastprivate:
8261 case OMPC_shared:
8262 case OMPC_reduction:
8263 case OMPC_task_reduction:
8264 case OMPC_in_reduction:
8265 case OMPC_linear:
8266 case OMPC_aligned:
8267 case OMPC_copyin:
8268 case OMPC_copyprivate:
8269 case OMPC_nowait:
8270 case OMPC_untied:
8271 case OMPC_mergeable:
8272 case OMPC_threadprivate:
8273 case OMPC_flush:
8274 case OMPC_read:
8275 case OMPC_write:
8276 case OMPC_update:
8277 case OMPC_capture:
8278 case OMPC_seq_cst:
8279 case OMPC_depend:
8280 case OMPC_threads:
8281 case OMPC_simd:
8282 case OMPC_map:
8283 case OMPC_nogroup:
8284 case OMPC_dist_schedule:
8285 case OMPC_defaultmap:
8286 case OMPC_unknown:
8287 case OMPC_uniform:
8288 case OMPC_to:
8289 case OMPC_from:
8290 case OMPC_use_device_ptr:
8291 case OMPC_is_device_ptr:
8292 case OMPC_unified_address:
8293 case OMPC_unified_shared_memory:
8294 case OMPC_reverse_offload:
8295 case OMPC_dynamic_allocators:
8296 case OMPC_atomic_default_mem_order:
8297 llvm_unreachable("Clause is not allowed.");
8298 }
8299 return Res;
8300 }
8301
8302 // An OpenMP directive such as 'target parallel' has two captured regions:
8303 // for the 'target' and 'parallel' respectively. This function returns
8304 // the region in which to capture expressions associated with a clause.
8305 // A return value of OMPD_unknown signifies that the expression should not
8306 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,OpenMPDirectiveKind NameModifier=OMPD_unknown)8307 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
8308 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
8309 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
8310 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8311 switch (CKind) {
8312 case OMPC_if:
8313 switch (DKind) {
8314 case OMPD_target_parallel:
8315 case OMPD_target_parallel_for:
8316 case OMPD_target_parallel_for_simd:
8317 // If this clause applies to the nested 'parallel' region, capture within
8318 // the 'target' region, otherwise do not capture.
8319 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8320 CaptureRegion = OMPD_target;
8321 break;
8322 case OMPD_target_teams_distribute_parallel_for:
8323 case OMPD_target_teams_distribute_parallel_for_simd:
8324 // If this clause applies to the nested 'parallel' region, capture within
8325 // the 'teams' region, otherwise do not capture.
8326 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8327 CaptureRegion = OMPD_teams;
8328 break;
8329 case OMPD_teams_distribute_parallel_for:
8330 case OMPD_teams_distribute_parallel_for_simd:
8331 CaptureRegion = OMPD_teams;
8332 break;
8333 case OMPD_target_update:
8334 case OMPD_target_enter_data:
8335 case OMPD_target_exit_data:
8336 CaptureRegion = OMPD_task;
8337 break;
8338 case OMPD_cancel:
8339 case OMPD_parallel:
8340 case OMPD_parallel_sections:
8341 case OMPD_parallel_for:
8342 case OMPD_parallel_for_simd:
8343 case OMPD_target:
8344 case OMPD_target_simd:
8345 case OMPD_target_teams:
8346 case OMPD_target_teams_distribute:
8347 case OMPD_target_teams_distribute_simd:
8348 case OMPD_distribute_parallel_for:
8349 case OMPD_distribute_parallel_for_simd:
8350 case OMPD_task:
8351 case OMPD_taskloop:
8352 case OMPD_taskloop_simd:
8353 case OMPD_target_data:
8354 // Do not capture if-clause expressions.
8355 break;
8356 case OMPD_threadprivate:
8357 case OMPD_taskyield:
8358 case OMPD_barrier:
8359 case OMPD_taskwait:
8360 case OMPD_cancellation_point:
8361 case OMPD_flush:
8362 case OMPD_declare_reduction:
8363 case OMPD_declare_simd:
8364 case OMPD_declare_target:
8365 case OMPD_end_declare_target:
8366 case OMPD_teams:
8367 case OMPD_simd:
8368 case OMPD_for:
8369 case OMPD_for_simd:
8370 case OMPD_sections:
8371 case OMPD_section:
8372 case OMPD_single:
8373 case OMPD_master:
8374 case OMPD_critical:
8375 case OMPD_taskgroup:
8376 case OMPD_distribute:
8377 case OMPD_ordered:
8378 case OMPD_atomic:
8379 case OMPD_distribute_simd:
8380 case OMPD_teams_distribute:
8381 case OMPD_teams_distribute_simd:
8382 case OMPD_requires:
8383 llvm_unreachable("Unexpected OpenMP directive with if-clause");
8384 case OMPD_unknown:
8385 llvm_unreachable("Unknown OpenMP directive");
8386 }
8387 break;
8388 case OMPC_num_threads:
8389 switch (DKind) {
8390 case OMPD_target_parallel:
8391 case OMPD_target_parallel_for:
8392 case OMPD_target_parallel_for_simd:
8393 CaptureRegion = OMPD_target;
8394 break;
8395 case OMPD_teams_distribute_parallel_for:
8396 case OMPD_teams_distribute_parallel_for_simd:
8397 case OMPD_target_teams_distribute_parallel_for:
8398 case OMPD_target_teams_distribute_parallel_for_simd:
8399 CaptureRegion = OMPD_teams;
8400 break;
8401 case OMPD_parallel:
8402 case OMPD_parallel_sections:
8403 case OMPD_parallel_for:
8404 case OMPD_parallel_for_simd:
8405 case OMPD_distribute_parallel_for:
8406 case OMPD_distribute_parallel_for_simd:
8407 // Do not capture num_threads-clause expressions.
8408 break;
8409 case OMPD_target_data:
8410 case OMPD_target_enter_data:
8411 case OMPD_target_exit_data:
8412 case OMPD_target_update:
8413 case OMPD_target:
8414 case OMPD_target_simd:
8415 case OMPD_target_teams:
8416 case OMPD_target_teams_distribute:
8417 case OMPD_target_teams_distribute_simd:
8418 case OMPD_cancel:
8419 case OMPD_task:
8420 case OMPD_taskloop:
8421 case OMPD_taskloop_simd:
8422 case OMPD_threadprivate:
8423 case OMPD_taskyield:
8424 case OMPD_barrier:
8425 case OMPD_taskwait:
8426 case OMPD_cancellation_point:
8427 case OMPD_flush:
8428 case OMPD_declare_reduction:
8429 case OMPD_declare_simd:
8430 case OMPD_declare_target:
8431 case OMPD_end_declare_target:
8432 case OMPD_teams:
8433 case OMPD_simd:
8434 case OMPD_for:
8435 case OMPD_for_simd:
8436 case OMPD_sections:
8437 case OMPD_section:
8438 case OMPD_single:
8439 case OMPD_master:
8440 case OMPD_critical:
8441 case OMPD_taskgroup:
8442 case OMPD_distribute:
8443 case OMPD_ordered:
8444 case OMPD_atomic:
8445 case OMPD_distribute_simd:
8446 case OMPD_teams_distribute:
8447 case OMPD_teams_distribute_simd:
8448 case OMPD_requires:
8449 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8450 case OMPD_unknown:
8451 llvm_unreachable("Unknown OpenMP directive");
8452 }
8453 break;
8454 case OMPC_num_teams:
8455 switch (DKind) {
8456 case OMPD_target_teams:
8457 case OMPD_target_teams_distribute:
8458 case OMPD_target_teams_distribute_simd:
8459 case OMPD_target_teams_distribute_parallel_for:
8460 case OMPD_target_teams_distribute_parallel_for_simd:
8461 CaptureRegion = OMPD_target;
8462 break;
8463 case OMPD_teams_distribute_parallel_for:
8464 case OMPD_teams_distribute_parallel_for_simd:
8465 case OMPD_teams:
8466 case OMPD_teams_distribute:
8467 case OMPD_teams_distribute_simd:
8468 // Do not capture num_teams-clause expressions.
8469 break;
8470 case OMPD_distribute_parallel_for:
8471 case OMPD_distribute_parallel_for_simd:
8472 case OMPD_task:
8473 case OMPD_taskloop:
8474 case OMPD_taskloop_simd:
8475 case OMPD_target_data:
8476 case OMPD_target_enter_data:
8477 case OMPD_target_exit_data:
8478 case OMPD_target_update:
8479 case OMPD_cancel:
8480 case OMPD_parallel:
8481 case OMPD_parallel_sections:
8482 case OMPD_parallel_for:
8483 case OMPD_parallel_for_simd:
8484 case OMPD_target:
8485 case OMPD_target_simd:
8486 case OMPD_target_parallel:
8487 case OMPD_target_parallel_for:
8488 case OMPD_target_parallel_for_simd:
8489 case OMPD_threadprivate:
8490 case OMPD_taskyield:
8491 case OMPD_barrier:
8492 case OMPD_taskwait:
8493 case OMPD_cancellation_point:
8494 case OMPD_flush:
8495 case OMPD_declare_reduction:
8496 case OMPD_declare_simd:
8497 case OMPD_declare_target:
8498 case OMPD_end_declare_target:
8499 case OMPD_simd:
8500 case OMPD_for:
8501 case OMPD_for_simd:
8502 case OMPD_sections:
8503 case OMPD_section:
8504 case OMPD_single:
8505 case OMPD_master:
8506 case OMPD_critical:
8507 case OMPD_taskgroup:
8508 case OMPD_distribute:
8509 case OMPD_ordered:
8510 case OMPD_atomic:
8511 case OMPD_distribute_simd:
8512 case OMPD_requires:
8513 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8514 case OMPD_unknown:
8515 llvm_unreachable("Unknown OpenMP directive");
8516 }
8517 break;
8518 case OMPC_thread_limit:
8519 switch (DKind) {
8520 case OMPD_target_teams:
8521 case OMPD_target_teams_distribute:
8522 case OMPD_target_teams_distribute_simd:
8523 case OMPD_target_teams_distribute_parallel_for:
8524 case OMPD_target_teams_distribute_parallel_for_simd:
8525 CaptureRegion = OMPD_target;
8526 break;
8527 case OMPD_teams_distribute_parallel_for:
8528 case OMPD_teams_distribute_parallel_for_simd:
8529 case OMPD_teams:
8530 case OMPD_teams_distribute:
8531 case OMPD_teams_distribute_simd:
8532 // Do not capture thread_limit-clause expressions.
8533 break;
8534 case OMPD_distribute_parallel_for:
8535 case OMPD_distribute_parallel_for_simd:
8536 case OMPD_task:
8537 case OMPD_taskloop:
8538 case OMPD_taskloop_simd:
8539 case OMPD_target_data:
8540 case OMPD_target_enter_data:
8541 case OMPD_target_exit_data:
8542 case OMPD_target_update:
8543 case OMPD_cancel:
8544 case OMPD_parallel:
8545 case OMPD_parallel_sections:
8546 case OMPD_parallel_for:
8547 case OMPD_parallel_for_simd:
8548 case OMPD_target:
8549 case OMPD_target_simd:
8550 case OMPD_target_parallel:
8551 case OMPD_target_parallel_for:
8552 case OMPD_target_parallel_for_simd:
8553 case OMPD_threadprivate:
8554 case OMPD_taskyield:
8555 case OMPD_barrier:
8556 case OMPD_taskwait:
8557 case OMPD_cancellation_point:
8558 case OMPD_flush:
8559 case OMPD_declare_reduction:
8560 case OMPD_declare_simd:
8561 case OMPD_declare_target:
8562 case OMPD_end_declare_target:
8563 case OMPD_simd:
8564 case OMPD_for:
8565 case OMPD_for_simd:
8566 case OMPD_sections:
8567 case OMPD_section:
8568 case OMPD_single:
8569 case OMPD_master:
8570 case OMPD_critical:
8571 case OMPD_taskgroup:
8572 case OMPD_distribute:
8573 case OMPD_ordered:
8574 case OMPD_atomic:
8575 case OMPD_distribute_simd:
8576 case OMPD_requires:
8577 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8578 case OMPD_unknown:
8579 llvm_unreachable("Unknown OpenMP directive");
8580 }
8581 break;
8582 case OMPC_schedule:
8583 switch (DKind) {
8584 case OMPD_parallel_for:
8585 case OMPD_parallel_for_simd:
8586 case OMPD_distribute_parallel_for:
8587 case OMPD_distribute_parallel_for_simd:
8588 case OMPD_teams_distribute_parallel_for:
8589 case OMPD_teams_distribute_parallel_for_simd:
8590 case OMPD_target_parallel_for:
8591 case OMPD_target_parallel_for_simd:
8592 case OMPD_target_teams_distribute_parallel_for:
8593 case OMPD_target_teams_distribute_parallel_for_simd:
8594 CaptureRegion = OMPD_parallel;
8595 break;
8596 case OMPD_for:
8597 case OMPD_for_simd:
8598 // Do not capture schedule-clause expressions.
8599 break;
8600 case OMPD_task:
8601 case OMPD_taskloop:
8602 case OMPD_taskloop_simd:
8603 case OMPD_target_data:
8604 case OMPD_target_enter_data:
8605 case OMPD_target_exit_data:
8606 case OMPD_target_update:
8607 case OMPD_teams:
8608 case OMPD_teams_distribute:
8609 case OMPD_teams_distribute_simd:
8610 case OMPD_target_teams_distribute:
8611 case OMPD_target_teams_distribute_simd:
8612 case OMPD_target:
8613 case OMPD_target_simd:
8614 case OMPD_target_parallel:
8615 case OMPD_cancel:
8616 case OMPD_parallel:
8617 case OMPD_parallel_sections:
8618 case OMPD_threadprivate:
8619 case OMPD_taskyield:
8620 case OMPD_barrier:
8621 case OMPD_taskwait:
8622 case OMPD_cancellation_point:
8623 case OMPD_flush:
8624 case OMPD_declare_reduction:
8625 case OMPD_declare_simd:
8626 case OMPD_declare_target:
8627 case OMPD_end_declare_target:
8628 case OMPD_simd:
8629 case OMPD_sections:
8630 case OMPD_section:
8631 case OMPD_single:
8632 case OMPD_master:
8633 case OMPD_critical:
8634 case OMPD_taskgroup:
8635 case OMPD_distribute:
8636 case OMPD_ordered:
8637 case OMPD_atomic:
8638 case OMPD_distribute_simd:
8639 case OMPD_target_teams:
8640 case OMPD_requires:
8641 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8642 case OMPD_unknown:
8643 llvm_unreachable("Unknown OpenMP directive");
8644 }
8645 break;
8646 case OMPC_dist_schedule:
8647 switch (DKind) {
8648 case OMPD_teams_distribute_parallel_for:
8649 case OMPD_teams_distribute_parallel_for_simd:
8650 case OMPD_teams_distribute:
8651 case OMPD_teams_distribute_simd:
8652 case OMPD_target_teams_distribute_parallel_for:
8653 case OMPD_target_teams_distribute_parallel_for_simd:
8654 case OMPD_target_teams_distribute:
8655 case OMPD_target_teams_distribute_simd:
8656 CaptureRegion = OMPD_teams;
8657 break;
8658 case OMPD_distribute_parallel_for:
8659 case OMPD_distribute_parallel_for_simd:
8660 case OMPD_distribute:
8661 case OMPD_distribute_simd:
8662 // Do not capture thread_limit-clause expressions.
8663 break;
8664 case OMPD_parallel_for:
8665 case OMPD_parallel_for_simd:
8666 case OMPD_target_parallel_for_simd:
8667 case OMPD_target_parallel_for:
8668 case OMPD_task:
8669 case OMPD_taskloop:
8670 case OMPD_taskloop_simd:
8671 case OMPD_target_data:
8672 case OMPD_target_enter_data:
8673 case OMPD_target_exit_data:
8674 case OMPD_target_update:
8675 case OMPD_teams:
8676 case OMPD_target:
8677 case OMPD_target_simd:
8678 case OMPD_target_parallel:
8679 case OMPD_cancel:
8680 case OMPD_parallel:
8681 case OMPD_parallel_sections:
8682 case OMPD_threadprivate:
8683 case OMPD_taskyield:
8684 case OMPD_barrier:
8685 case OMPD_taskwait:
8686 case OMPD_cancellation_point:
8687 case OMPD_flush:
8688 case OMPD_declare_reduction:
8689 case OMPD_declare_simd:
8690 case OMPD_declare_target:
8691 case OMPD_end_declare_target:
8692 case OMPD_simd:
8693 case OMPD_for:
8694 case OMPD_for_simd:
8695 case OMPD_sections:
8696 case OMPD_section:
8697 case OMPD_single:
8698 case OMPD_master:
8699 case OMPD_critical:
8700 case OMPD_taskgroup:
8701 case OMPD_ordered:
8702 case OMPD_atomic:
8703 case OMPD_target_teams:
8704 case OMPD_requires:
8705 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8706 case OMPD_unknown:
8707 llvm_unreachable("Unknown OpenMP directive");
8708 }
8709 break;
8710 case OMPC_device:
8711 switch (DKind) {
8712 case OMPD_target_update:
8713 case OMPD_target_enter_data:
8714 case OMPD_target_exit_data:
8715 case OMPD_target:
8716 case OMPD_target_simd:
8717 case OMPD_target_teams:
8718 case OMPD_target_parallel:
8719 case OMPD_target_teams_distribute:
8720 case OMPD_target_teams_distribute_simd:
8721 case OMPD_target_parallel_for:
8722 case OMPD_target_parallel_for_simd:
8723 case OMPD_target_teams_distribute_parallel_for:
8724 case OMPD_target_teams_distribute_parallel_for_simd:
8725 CaptureRegion = OMPD_task;
8726 break;
8727 case OMPD_target_data:
8728 // Do not capture device-clause expressions.
8729 break;
8730 case OMPD_teams_distribute_parallel_for:
8731 case OMPD_teams_distribute_parallel_for_simd:
8732 case OMPD_teams:
8733 case OMPD_teams_distribute:
8734 case OMPD_teams_distribute_simd:
8735 case OMPD_distribute_parallel_for:
8736 case OMPD_distribute_parallel_for_simd:
8737 case OMPD_task:
8738 case OMPD_taskloop:
8739 case OMPD_taskloop_simd:
8740 case OMPD_cancel:
8741 case OMPD_parallel:
8742 case OMPD_parallel_sections:
8743 case OMPD_parallel_for:
8744 case OMPD_parallel_for_simd:
8745 case OMPD_threadprivate:
8746 case OMPD_taskyield:
8747 case OMPD_barrier:
8748 case OMPD_taskwait:
8749 case OMPD_cancellation_point:
8750 case OMPD_flush:
8751 case OMPD_declare_reduction:
8752 case OMPD_declare_simd:
8753 case OMPD_declare_target:
8754 case OMPD_end_declare_target:
8755 case OMPD_simd:
8756 case OMPD_for:
8757 case OMPD_for_simd:
8758 case OMPD_sections:
8759 case OMPD_section:
8760 case OMPD_single:
8761 case OMPD_master:
8762 case OMPD_critical:
8763 case OMPD_taskgroup:
8764 case OMPD_distribute:
8765 case OMPD_ordered:
8766 case OMPD_atomic:
8767 case OMPD_distribute_simd:
8768 case OMPD_requires:
8769 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8770 case OMPD_unknown:
8771 llvm_unreachable("Unknown OpenMP directive");
8772 }
8773 break;
8774 case OMPC_firstprivate:
8775 case OMPC_lastprivate:
8776 case OMPC_reduction:
8777 case OMPC_task_reduction:
8778 case OMPC_in_reduction:
8779 case OMPC_linear:
8780 case OMPC_default:
8781 case OMPC_proc_bind:
8782 case OMPC_final:
8783 case OMPC_safelen:
8784 case OMPC_simdlen:
8785 case OMPC_collapse:
8786 case OMPC_private:
8787 case OMPC_shared:
8788 case OMPC_aligned:
8789 case OMPC_copyin:
8790 case OMPC_copyprivate:
8791 case OMPC_ordered:
8792 case OMPC_nowait:
8793 case OMPC_untied:
8794 case OMPC_mergeable:
8795 case OMPC_threadprivate:
8796 case OMPC_flush:
8797 case OMPC_read:
8798 case OMPC_write:
8799 case OMPC_update:
8800 case OMPC_capture:
8801 case OMPC_seq_cst:
8802 case OMPC_depend:
8803 case OMPC_threads:
8804 case OMPC_simd:
8805 case OMPC_map:
8806 case OMPC_priority:
8807 case OMPC_grainsize:
8808 case OMPC_nogroup:
8809 case OMPC_num_tasks:
8810 case OMPC_hint:
8811 case OMPC_defaultmap:
8812 case OMPC_unknown:
8813 case OMPC_uniform:
8814 case OMPC_to:
8815 case OMPC_from:
8816 case OMPC_use_device_ptr:
8817 case OMPC_is_device_ptr:
8818 case OMPC_unified_address:
8819 case OMPC_unified_shared_memory:
8820 case OMPC_reverse_offload:
8821 case OMPC_dynamic_allocators:
8822 case OMPC_atomic_default_mem_order:
8823 llvm_unreachable("Unexpected OpenMP clause.");
8824 }
8825 return CaptureRegion;
8826 }
8827
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)8828 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
8829 Expr *Condition, SourceLocation StartLoc,
8830 SourceLocation LParenLoc,
8831 SourceLocation NameModifierLoc,
8832 SourceLocation ColonLoc,
8833 SourceLocation EndLoc) {
8834 Expr *ValExpr = Condition;
8835 Stmt *HelperValStmt = nullptr;
8836 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8837 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8838 !Condition->isInstantiationDependent() &&
8839 !Condition->containsUnexpandedParameterPack()) {
8840 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8841 if (Val.isInvalid())
8842 return nullptr;
8843
8844 ValExpr = Val.get();
8845
8846 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8847 CaptureRegion =
8848 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8849 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8850 ValExpr = MakeFullExpr(ValExpr).get();
8851 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8852 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8853 HelperValStmt = buildPreInits(Context, Captures);
8854 }
8855 }
8856
8857 return new (Context)
8858 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8859 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8860 }
8861
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8862 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
8863 SourceLocation StartLoc,
8864 SourceLocation LParenLoc,
8865 SourceLocation EndLoc) {
8866 Expr *ValExpr = Condition;
8867 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8868 !Condition->isInstantiationDependent() &&
8869 !Condition->containsUnexpandedParameterPack()) {
8870 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8871 if (Val.isInvalid())
8872 return nullptr;
8873
8874 ValExpr = MakeFullExpr(Val.get()).get();
8875 }
8876
8877 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8878 }
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)8879 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
8880 Expr *Op) {
8881 if (!Op)
8882 return ExprError();
8883
8884 class IntConvertDiagnoser : public ICEConvertDiagnoser {
8885 public:
8886 IntConvertDiagnoser()
8887 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8888 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8889 QualType T) override {
8890 return S.Diag(Loc, diag::err_omp_not_integral) << T;
8891 }
8892 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8893 QualType T) override {
8894 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8895 }
8896 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8897 QualType T,
8898 QualType ConvTy) override {
8899 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8900 }
8901 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8902 QualType ConvTy) override {
8903 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8904 << ConvTy->isEnumeralType() << ConvTy;
8905 }
8906 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8907 QualType T) override {
8908 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8909 }
8910 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8911 QualType ConvTy) override {
8912 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8913 << ConvTy->isEnumeralType() << ConvTy;
8914 }
8915 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8916 QualType) override {
8917 llvm_unreachable("conversion functions are permitted");
8918 }
8919 } ConvertDiagnoser;
8920 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8921 }
8922
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive)8923 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8924 OpenMPClauseKind CKind,
8925 bool StrictlyPositive) {
8926 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8927 !ValExpr->isInstantiationDependent()) {
8928 SourceLocation Loc = ValExpr->getExprLoc();
8929 ExprResult Value =
8930 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8931 if (Value.isInvalid())
8932 return false;
8933
8934 ValExpr = Value.get();
8935 // The expression must evaluate to a non-negative integer value.
8936 llvm::APSInt Result;
8937 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8938 Result.isSigned() &&
8939 !((!StrictlyPositive && Result.isNonNegative()) ||
8940 (StrictlyPositive && Result.isStrictlyPositive()))) {
8941 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8942 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8943 << ValExpr->getSourceRange();
8944 return false;
8945 }
8946 }
8947 return true;
8948 }
8949
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8950 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
8951 SourceLocation StartLoc,
8952 SourceLocation LParenLoc,
8953 SourceLocation EndLoc) {
8954 Expr *ValExpr = NumThreads;
8955 Stmt *HelperValStmt = nullptr;
8956
8957 // OpenMP [2.5, Restrictions]
8958 // The num_threads expression must evaluate to a positive integer value.
8959 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8960 /*StrictlyPositive=*/true))
8961 return nullptr;
8962
8963 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8964 OpenMPDirectiveKind CaptureRegion =
8965 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8966 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8967 ValExpr = MakeFullExpr(ValExpr).get();
8968 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8969 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8970 HelperValStmt = buildPreInits(Context, Captures);
8971 }
8972
8973 return new (Context) OMPNumThreadsClause(
8974 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8975 }
8976
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)8977 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8978 OpenMPClauseKind CKind,
8979 bool StrictlyPositive) {
8980 if (!E)
8981 return ExprError();
8982 if (E->isValueDependent() || E->isTypeDependent() ||
8983 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
8984 return E;
8985 llvm::APSInt Result;
8986 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8987 if (ICE.isInvalid())
8988 return ExprError();
8989 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8990 (!StrictlyPositive && !Result.isNonNegative())) {
8991 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8992 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8993 << E->getSourceRange();
8994 return ExprError();
8995 }
8996 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8997 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8998 << E->getSourceRange();
8999 return ExprError();
9000 }
9001 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
9002 DSAStack->setAssociatedLoops(Result.getExtValue());
9003 else if (CKind == OMPC_ordered)
9004 DSAStack->setAssociatedLoops(Result.getExtValue());
9005 return ICE;
9006 }
9007
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9008 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
9009 SourceLocation LParenLoc,
9010 SourceLocation EndLoc) {
9011 // OpenMP [2.8.1, simd construct, Description]
9012 // The parameter of the safelen clause must be a constant
9013 // positive integer expression.
9014 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9015 if (Safelen.isInvalid())
9016 return nullptr;
9017 return new (Context)
9018 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
9019 }
9020
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9021 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
9022 SourceLocation LParenLoc,
9023 SourceLocation EndLoc) {
9024 // OpenMP [2.8.1, simd construct, Description]
9025 // The parameter of the simdlen clause must be a constant
9026 // positive integer expression.
9027 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9028 if (Simdlen.isInvalid())
9029 return nullptr;
9030 return new (Context)
9031 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
9032 }
9033
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9034 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
9035 SourceLocation StartLoc,
9036 SourceLocation LParenLoc,
9037 SourceLocation EndLoc) {
9038 // OpenMP [2.7.1, loop construct, Description]
9039 // OpenMP [2.8.1, simd construct, Description]
9040 // OpenMP [2.9.6, distribute construct, Description]
9041 // The parameter of the collapse clause must be a constant
9042 // positive integer expression.
9043 ExprResult NumForLoopsResult =
9044 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9045 if (NumForLoopsResult.isInvalid())
9046 return nullptr;
9047 return new (Context)
9048 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
9049 }
9050
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)9051 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
9052 SourceLocation EndLoc,
9053 SourceLocation LParenLoc,
9054 Expr *NumForLoops) {
9055 // OpenMP [2.7.1, loop construct, Description]
9056 // OpenMP [2.8.1, simd construct, Description]
9057 // OpenMP [2.9.6, distribute construct, Description]
9058 // The parameter of the ordered clause must be a constant
9059 // positive integer expression if any.
9060 if (NumForLoops && LParenLoc.isValid()) {
9061 ExprResult NumForLoopsResult =
9062 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9063 if (NumForLoopsResult.isInvalid())
9064 return nullptr;
9065 NumForLoops = NumForLoopsResult.get();
9066 } else {
9067 NumForLoops = nullptr;
9068 }
9069 auto *Clause = OMPOrderedClause::Create(
9070 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
9071 StartLoc, LParenLoc, EndLoc);
9072 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
9073 return Clause;
9074 }
9075
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9076 OMPClause *Sema::ActOnOpenMPSimpleClause(
9077 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
9078 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9079 OMPClause *Res = nullptr;
9080 switch (Kind) {
9081 case OMPC_default:
9082 Res =
9083 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9084 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9085 break;
9086 case OMPC_proc_bind:
9087 Res = ActOnOpenMPProcBindClause(
9088 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
9089 LParenLoc, EndLoc);
9090 break;
9091 case OMPC_atomic_default_mem_order:
9092 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9093 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9094 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9095 break;
9096 case OMPC_if:
9097 case OMPC_final:
9098 case OMPC_num_threads:
9099 case OMPC_safelen:
9100 case OMPC_simdlen:
9101 case OMPC_collapse:
9102 case OMPC_schedule:
9103 case OMPC_private:
9104 case OMPC_firstprivate:
9105 case OMPC_lastprivate:
9106 case OMPC_shared:
9107 case OMPC_reduction:
9108 case OMPC_task_reduction:
9109 case OMPC_in_reduction:
9110 case OMPC_linear:
9111 case OMPC_aligned:
9112 case OMPC_copyin:
9113 case OMPC_copyprivate:
9114 case OMPC_ordered:
9115 case OMPC_nowait:
9116 case OMPC_untied:
9117 case OMPC_mergeable:
9118 case OMPC_threadprivate:
9119 case OMPC_flush:
9120 case OMPC_read:
9121 case OMPC_write:
9122 case OMPC_update:
9123 case OMPC_capture:
9124 case OMPC_seq_cst:
9125 case OMPC_depend:
9126 case OMPC_device:
9127 case OMPC_threads:
9128 case OMPC_simd:
9129 case OMPC_map:
9130 case OMPC_num_teams:
9131 case OMPC_thread_limit:
9132 case OMPC_priority:
9133 case OMPC_grainsize:
9134 case OMPC_nogroup:
9135 case OMPC_num_tasks:
9136 case OMPC_hint:
9137 case OMPC_dist_schedule:
9138 case OMPC_defaultmap:
9139 case OMPC_unknown:
9140 case OMPC_uniform:
9141 case OMPC_to:
9142 case OMPC_from:
9143 case OMPC_use_device_ptr:
9144 case OMPC_is_device_ptr:
9145 case OMPC_unified_address:
9146 case OMPC_unified_shared_memory:
9147 case OMPC_reverse_offload:
9148 case OMPC_dynamic_allocators:
9149 llvm_unreachable("Clause is not allowed.");
9150 }
9151 return Res;
9152 }
9153
9154 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)9155 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
9156 ArrayRef<unsigned> Exclude = llvm::None) {
9157 SmallString<256> Buffer;
9158 llvm::raw_svector_ostream Out(Buffer);
9159 unsigned Bound = Last >= 2 ? Last - 2 : 0;
9160 unsigned Skipped = Exclude.size();
9161 auto S = Exclude.begin(), E = Exclude.end();
9162 for (unsigned I = First; I < Last; ++I) {
9163 if (std::find(S, E, I) != E) {
9164 --Skipped;
9165 continue;
9166 }
9167 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
9168 if (I == Bound - Skipped)
9169 Out << " or ";
9170 else if (I != Bound + 1 - Skipped)
9171 Out << ", ";
9172 }
9173 return Out.str();
9174 }
9175
ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9176 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
9177 SourceLocation KindKwLoc,
9178 SourceLocation StartLoc,
9179 SourceLocation LParenLoc,
9180 SourceLocation EndLoc) {
9181 if (Kind == OMPC_DEFAULT_unknown) {
9182 static_assert(OMPC_DEFAULT_unknown > 0,
9183 "OMPC_DEFAULT_unknown not greater than 0");
9184 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9185 << getListOfPossibleValues(OMPC_default, /*First=*/0,
9186 /*Last=*/OMPC_DEFAULT_unknown)
9187 << getOpenMPClauseName(OMPC_default);
9188 return nullptr;
9189 }
9190 switch (Kind) {
9191 case OMPC_DEFAULT_none:
9192 DSAStack->setDefaultDSANone(KindKwLoc);
9193 break;
9194 case OMPC_DEFAULT_shared:
9195 DSAStack->setDefaultDSAShared(KindKwLoc);
9196 break;
9197 case OMPC_DEFAULT_unknown:
9198 llvm_unreachable("Clause kind is not allowed.");
9199 break;
9200 }
9201 return new (Context)
9202 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9203 }
9204
ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9205 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
9206 SourceLocation KindKwLoc,
9207 SourceLocation StartLoc,
9208 SourceLocation LParenLoc,
9209 SourceLocation EndLoc) {
9210 if (Kind == OMPC_PROC_BIND_unknown) {
9211 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9212 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
9213 /*Last=*/OMPC_PROC_BIND_unknown)
9214 << getOpenMPClauseName(OMPC_proc_bind);
9215 return nullptr;
9216 }
9217 return new (Context)
9218 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9219 }
9220
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9221 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
9222 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
9223 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9224 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
9225 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9226 << getListOfPossibleValues(
9227 OMPC_atomic_default_mem_order, /*First=*/0,
9228 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
9229 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
9230 return nullptr;
9231 }
9232 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
9233 LParenLoc, EndLoc);
9234 }
9235
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)9236 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
9237 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
9238 SourceLocation StartLoc, SourceLocation LParenLoc,
9239 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
9240 SourceLocation EndLoc) {
9241 OMPClause *Res = nullptr;
9242 switch (Kind) {
9243 case OMPC_schedule:
9244 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
9245 assert(Argument.size() == NumberOfElements &&
9246 ArgumentLoc.size() == NumberOfElements);
9247 Res = ActOnOpenMPScheduleClause(
9248 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9249 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9250 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9251 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9252 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9253 break;
9254 case OMPC_if:
9255 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9256 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9257 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9258 DelimLoc, EndLoc);
9259 break;
9260 case OMPC_dist_schedule:
9261 Res = ActOnOpenMPDistScheduleClause(
9262 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9263 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9264 break;
9265 case OMPC_defaultmap:
9266 enum { Modifier, DefaultmapKind };
9267 Res = ActOnOpenMPDefaultmapClause(
9268 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
9269 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9270 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9271 EndLoc);
9272 break;
9273 case OMPC_final:
9274 case OMPC_num_threads:
9275 case OMPC_safelen:
9276 case OMPC_simdlen:
9277 case OMPC_collapse:
9278 case OMPC_default:
9279 case OMPC_proc_bind:
9280 case OMPC_private:
9281 case OMPC_firstprivate:
9282 case OMPC_lastprivate:
9283 case OMPC_shared:
9284 case OMPC_reduction:
9285 case OMPC_task_reduction:
9286 case OMPC_in_reduction:
9287 case OMPC_linear:
9288 case OMPC_aligned:
9289 case OMPC_copyin:
9290 case OMPC_copyprivate:
9291 case OMPC_ordered:
9292 case OMPC_nowait:
9293 case OMPC_untied:
9294 case OMPC_mergeable:
9295 case OMPC_threadprivate:
9296 case OMPC_flush:
9297 case OMPC_read:
9298 case OMPC_write:
9299 case OMPC_update:
9300 case OMPC_capture:
9301 case OMPC_seq_cst:
9302 case OMPC_depend:
9303 case OMPC_device:
9304 case OMPC_threads:
9305 case OMPC_simd:
9306 case OMPC_map:
9307 case OMPC_num_teams:
9308 case OMPC_thread_limit:
9309 case OMPC_priority:
9310 case OMPC_grainsize:
9311 case OMPC_nogroup:
9312 case OMPC_num_tasks:
9313 case OMPC_hint:
9314 case OMPC_unknown:
9315 case OMPC_uniform:
9316 case OMPC_to:
9317 case OMPC_from:
9318 case OMPC_use_device_ptr:
9319 case OMPC_is_device_ptr:
9320 case OMPC_unified_address:
9321 case OMPC_unified_shared_memory:
9322 case OMPC_reverse_offload:
9323 case OMPC_dynamic_allocators:
9324 case OMPC_atomic_default_mem_order:
9325 llvm_unreachable("Clause is not allowed.");
9326 }
9327 return Res;
9328 }
9329
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)9330 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
9331 OpenMPScheduleClauseModifier M2,
9332 SourceLocation M1Loc, SourceLocation M2Loc) {
9333 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
9334 SmallVector<unsigned, 2> Excluded;
9335 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
9336 Excluded.push_back(M2);
9337 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9338 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9339 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9340 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9341 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9342 << getListOfPossibleValues(OMPC_schedule,
9343 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
9344 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9345 Excluded)
9346 << getOpenMPClauseName(OMPC_schedule);
9347 return true;
9348 }
9349 return false;
9350 }
9351
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)9352 OMPClause *Sema::ActOnOpenMPScheduleClause(
9353 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
9354 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
9355 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
9356 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
9357 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
9358 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
9359 return nullptr;
9360 // OpenMP, 2.7.1, Loop Construct, Restrictions
9361 // Either the monotonic modifier or the nonmonotonic modifier can be specified
9362 // but not both.
9363 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
9364 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9365 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9366 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9367 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9368 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9369 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
9370 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
9371 return nullptr;
9372 }
9373 if (Kind == OMPC_SCHEDULE_unknown) {
9374 std::string Values;
9375 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
9376 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
9377 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9378 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9379 Exclude);
9380 } else {
9381 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9382 /*Last=*/OMPC_SCHEDULE_unknown);
9383 }
9384 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9385 << Values << getOpenMPClauseName(OMPC_schedule);
9386 return nullptr;
9387 }
9388 // OpenMP, 2.7.1, Loop Construct, Restrictions
9389 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9390 // schedule(guided).
9391 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9392 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9393 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9394 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9395 diag::err_omp_schedule_nonmonotonic_static);
9396 return nullptr;
9397 }
9398 Expr *ValExpr = ChunkSize;
9399 Stmt *HelperValStmt = nullptr;
9400 if (ChunkSize) {
9401 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9402 !ChunkSize->isInstantiationDependent() &&
9403 !ChunkSize->containsUnexpandedParameterPack()) {
9404 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
9405 ExprResult Val =
9406 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9407 if (Val.isInvalid())
9408 return nullptr;
9409
9410 ValExpr = Val.get();
9411
9412 // OpenMP [2.7.1, Restrictions]
9413 // chunk_size must be a loop invariant integer expression with a positive
9414 // value.
9415 llvm::APSInt Result;
9416 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9417 if (Result.isSigned() && !Result.isStrictlyPositive()) {
9418 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9419 << "schedule" << 1 << ChunkSize->getSourceRange();
9420 return nullptr;
9421 }
9422 } else if (getOpenMPCaptureRegionForClause(
9423 DSAStack->getCurrentDirective(), OMPC_schedule) !=
9424 OMPD_unknown &&
9425 !CurContext->isDependentContext()) {
9426 ValExpr = MakeFullExpr(ValExpr).get();
9427 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9428 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9429 HelperValStmt = buildPreInits(Context, Captures);
9430 }
9431 }
9432 }
9433
9434 return new (Context)
9435 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9436 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9437 }
9438
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)9439 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
9440 SourceLocation StartLoc,
9441 SourceLocation EndLoc) {
9442 OMPClause *Res = nullptr;
9443 switch (Kind) {
9444 case OMPC_ordered:
9445 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9446 break;
9447 case OMPC_nowait:
9448 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9449 break;
9450 case OMPC_untied:
9451 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9452 break;
9453 case OMPC_mergeable:
9454 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9455 break;
9456 case OMPC_read:
9457 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9458 break;
9459 case OMPC_write:
9460 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9461 break;
9462 case OMPC_update:
9463 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9464 break;
9465 case OMPC_capture:
9466 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9467 break;
9468 case OMPC_seq_cst:
9469 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9470 break;
9471 case OMPC_threads:
9472 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9473 break;
9474 case OMPC_simd:
9475 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9476 break;
9477 case OMPC_nogroup:
9478 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9479 break;
9480 case OMPC_unified_address:
9481 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
9482 break;
9483 case OMPC_unified_shared_memory:
9484 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9485 break;
9486 case OMPC_reverse_offload:
9487 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
9488 break;
9489 case OMPC_dynamic_allocators:
9490 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
9491 break;
9492 case OMPC_if:
9493 case OMPC_final:
9494 case OMPC_num_threads:
9495 case OMPC_safelen:
9496 case OMPC_simdlen:
9497 case OMPC_collapse:
9498 case OMPC_schedule:
9499 case OMPC_private:
9500 case OMPC_firstprivate:
9501 case OMPC_lastprivate:
9502 case OMPC_shared:
9503 case OMPC_reduction:
9504 case OMPC_task_reduction:
9505 case OMPC_in_reduction:
9506 case OMPC_linear:
9507 case OMPC_aligned:
9508 case OMPC_copyin:
9509 case OMPC_copyprivate:
9510 case OMPC_default:
9511 case OMPC_proc_bind:
9512 case OMPC_threadprivate:
9513 case OMPC_flush:
9514 case OMPC_depend:
9515 case OMPC_device:
9516 case OMPC_map:
9517 case OMPC_num_teams:
9518 case OMPC_thread_limit:
9519 case OMPC_priority:
9520 case OMPC_grainsize:
9521 case OMPC_num_tasks:
9522 case OMPC_hint:
9523 case OMPC_dist_schedule:
9524 case OMPC_defaultmap:
9525 case OMPC_unknown:
9526 case OMPC_uniform:
9527 case OMPC_to:
9528 case OMPC_from:
9529 case OMPC_use_device_ptr:
9530 case OMPC_is_device_ptr:
9531 case OMPC_atomic_default_mem_order:
9532 llvm_unreachable("Clause is not allowed.");
9533 }
9534 return Res;
9535 }
9536
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)9537 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
9538 SourceLocation EndLoc) {
9539 DSAStack->setNowaitRegion();
9540 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
9541 }
9542
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)9543 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
9544 SourceLocation EndLoc) {
9545 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
9546 }
9547
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)9548 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
9549 SourceLocation EndLoc) {
9550 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
9551 }
9552
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)9553 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
9554 SourceLocation EndLoc) {
9555 return new (Context) OMPReadClause(StartLoc, EndLoc);
9556 }
9557
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)9558 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
9559 SourceLocation EndLoc) {
9560 return new (Context) OMPWriteClause(StartLoc, EndLoc);
9561 }
9562
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)9563 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
9564 SourceLocation EndLoc) {
9565 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
9566 }
9567
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)9568 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
9569 SourceLocation EndLoc) {
9570 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
9571 }
9572
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)9573 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
9574 SourceLocation EndLoc) {
9575 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
9576 }
9577
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)9578 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
9579 SourceLocation EndLoc) {
9580 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
9581 }
9582
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)9583 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
9584 SourceLocation EndLoc) {
9585 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
9586 }
9587
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)9588 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
9589 SourceLocation EndLoc) {
9590 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
9591 }
9592
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)9593 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
9594 SourceLocation EndLoc) {
9595 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
9596 }
9597
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)9598 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
9599 SourceLocation EndLoc) {
9600 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9601 }
9602
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)9603 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
9604 SourceLocation EndLoc) {
9605 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
9606 }
9607
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)9608 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
9609 SourceLocation EndLoc) {
9610 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
9611 }
9612
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,Expr * TailExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,OpenMPDependClauseKind DepKind,OpenMPLinearClauseKind LinKind,ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation DepLinMapLoc)9613 OMPClause *Sema::ActOnOpenMPVarListClause(
9614 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
9615 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
9616 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
9617 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
9618 OpenMPLinearClauseKind LinKind,
9619 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
9620 ArrayRef<SourceLocation> MapTypeModifiersLoc,
9621 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
9622 SourceLocation DepLinMapLoc) {
9623 OMPClause *Res = nullptr;
9624 switch (Kind) {
9625 case OMPC_private:
9626 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9627 break;
9628 case OMPC_firstprivate:
9629 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9630 break;
9631 case OMPC_lastprivate:
9632 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9633 break;
9634 case OMPC_shared:
9635 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9636 break;
9637 case OMPC_reduction:
9638 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9639 EndLoc, ReductionIdScopeSpec, ReductionId);
9640 break;
9641 case OMPC_task_reduction:
9642 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9643 EndLoc, ReductionIdScopeSpec,
9644 ReductionId);
9645 break;
9646 case OMPC_in_reduction:
9647 Res =
9648 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9649 EndLoc, ReductionIdScopeSpec, ReductionId);
9650 break;
9651 case OMPC_linear:
9652 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9653 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9654 break;
9655 case OMPC_aligned:
9656 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9657 ColonLoc, EndLoc);
9658 break;
9659 case OMPC_copyin:
9660 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9661 break;
9662 case OMPC_copyprivate:
9663 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9664 break;
9665 case OMPC_flush:
9666 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9667 break;
9668 case OMPC_depend:
9669 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9670 StartLoc, LParenLoc, EndLoc);
9671 break;
9672 case OMPC_map:
9673 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
9674 IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
9675 VarList, StartLoc, LParenLoc, EndLoc);
9676 break;
9677 case OMPC_to:
9678 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9679 break;
9680 case OMPC_from:
9681 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9682 break;
9683 case OMPC_use_device_ptr:
9684 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9685 break;
9686 case OMPC_is_device_ptr:
9687 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9688 break;
9689 case OMPC_if:
9690 case OMPC_final:
9691 case OMPC_num_threads:
9692 case OMPC_safelen:
9693 case OMPC_simdlen:
9694 case OMPC_collapse:
9695 case OMPC_default:
9696 case OMPC_proc_bind:
9697 case OMPC_schedule:
9698 case OMPC_ordered:
9699 case OMPC_nowait:
9700 case OMPC_untied:
9701 case OMPC_mergeable:
9702 case OMPC_threadprivate:
9703 case OMPC_read:
9704 case OMPC_write:
9705 case OMPC_update:
9706 case OMPC_capture:
9707 case OMPC_seq_cst:
9708 case OMPC_device:
9709 case OMPC_threads:
9710 case OMPC_simd:
9711 case OMPC_num_teams:
9712 case OMPC_thread_limit:
9713 case OMPC_priority:
9714 case OMPC_grainsize:
9715 case OMPC_nogroup:
9716 case OMPC_num_tasks:
9717 case OMPC_hint:
9718 case OMPC_dist_schedule:
9719 case OMPC_defaultmap:
9720 case OMPC_unknown:
9721 case OMPC_uniform:
9722 case OMPC_unified_address:
9723 case OMPC_unified_shared_memory:
9724 case OMPC_reverse_offload:
9725 case OMPC_dynamic_allocators:
9726 case OMPC_atomic_default_mem_order:
9727 llvm_unreachable("Clause is not allowed.");
9728 }
9729 return Res;
9730 }
9731
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)9732 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
9733 ExprObjectKind OK, SourceLocation Loc) {
9734 ExprResult Res = BuildDeclRefExpr(
9735 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9736 if (!Res.isUsable())
9737 return ExprError();
9738 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9739 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9740 if (!Res.isUsable())
9741 return ExprError();
9742 }
9743 if (VK != VK_LValue && Res.get()->isGLValue()) {
9744 Res = DefaultLvalueConversion(Res.get());
9745 if (!Res.isUsable())
9746 return ExprError();
9747 }
9748 return Res;
9749 }
9750
9751 static std::pair<ValueDecl *, bool>
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection=false)9752 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
9753 SourceRange &ERange, bool AllowArraySection = false) {
9754 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9755 RefExpr->containsUnexpandedParameterPack())
9756 return std::make_pair(nullptr, true);
9757
9758 // OpenMP [3.1, C/C++]
9759 // A list item is a variable name.
9760 // OpenMP [2.9.3.3, Restrictions, p.1]
9761 // A variable that is part of another variable (as an array or
9762 // structure element) cannot appear in a private clause.
9763 RefExpr = RefExpr->IgnoreParens();
9764 enum {
9765 NoArrayExpr = -1,
9766 ArraySubscript = 0,
9767 OMPArraySection = 1
9768 } IsArrayExpr = NoArrayExpr;
9769 if (AllowArraySection) {
9770 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9771 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
9772 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9773 Base = TempASE->getBase()->IgnoreParenImpCasts();
9774 RefExpr = Base;
9775 IsArrayExpr = ArraySubscript;
9776 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9777 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9778 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9779 Base = TempOASE->getBase()->IgnoreParenImpCasts();
9780 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9781 Base = TempASE->getBase()->IgnoreParenImpCasts();
9782 RefExpr = Base;
9783 IsArrayExpr = OMPArraySection;
9784 }
9785 }
9786 ELoc = RefExpr->getExprLoc();
9787 ERange = RefExpr->getSourceRange();
9788 RefExpr = RefExpr->IgnoreParenImpCasts();
9789 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9790 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9791 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9792 (S.getCurrentThisType().isNull() || !ME ||
9793 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9794 !isa<FieldDecl>(ME->getMemberDecl()))) {
9795 if (IsArrayExpr != NoArrayExpr) {
9796 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9797 << ERange;
9798 } else {
9799 S.Diag(ELoc,
9800 AllowArraySection
9801 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9802 : diag::err_omp_expected_var_name_member_expr)
9803 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9804 }
9805 return std::make_pair(nullptr, false);
9806 }
9807 return std::make_pair(
9808 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9809 }
9810
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9811 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
9812 SourceLocation StartLoc,
9813 SourceLocation LParenLoc,
9814 SourceLocation EndLoc) {
9815 SmallVector<Expr *, 8> Vars;
9816 SmallVector<Expr *, 8> PrivateCopies;
9817 for (Expr *RefExpr : VarList) {
9818 assert(RefExpr && "NULL expr in OpenMP private clause.");
9819 SourceLocation ELoc;
9820 SourceRange ERange;
9821 Expr *SimpleRefExpr = RefExpr;
9822 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9823 if (Res.second) {
9824 // It will be analyzed later.
9825 Vars.push_back(RefExpr);
9826 PrivateCopies.push_back(nullptr);
9827 }
9828 ValueDecl *D = Res.first;
9829 if (!D)
9830 continue;
9831
9832 QualType Type = D->getType();
9833 auto *VD = dyn_cast<VarDecl>(D);
9834
9835 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9836 // A variable that appears in a private clause must not have an incomplete
9837 // type or a reference type.
9838 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9839 continue;
9840 Type = Type.getNonReferenceType();
9841
9842 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
9843 // A variable that is privatized must not have a const-qualified type
9844 // unless it is of class type with a mutable member. This restriction does
9845 // not apply to the firstprivate clause.
9846 //
9847 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
9848 // A variable that appears in a private clause must not have a
9849 // const-qualified type unless it is of class type with a mutable member.
9850 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
9851 continue;
9852
9853 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9854 // in a Construct]
9855 // Variables with the predetermined data-sharing attributes may not be
9856 // listed in data-sharing attributes clauses, except for the cases
9857 // listed below. For these exceptions only, listing a predetermined
9858 // variable in a data-sharing attribute clause is allowed and overrides
9859 // the variable's predetermined data-sharing attributes.
9860 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9861 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9862 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9863 << getOpenMPClauseName(OMPC_private);
9864 reportOriginalDsa(*this, DSAStack, D, DVar);
9865 continue;
9866 }
9867
9868 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9869 // Variably modified types are not supported for tasks.
9870 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9871 isOpenMPTaskingDirective(CurrDir)) {
9872 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9873 << getOpenMPClauseName(OMPC_private) << Type
9874 << getOpenMPDirectiveName(CurrDir);
9875 bool IsDecl =
9876 !VD ||
9877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9878 Diag(D->getLocation(),
9879 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9880 << D;
9881 continue;
9882 }
9883
9884 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9885 // A list item cannot appear in both a map clause and a data-sharing
9886 // attribute clause on the same construct
9887 if (isOpenMPTargetExecutionDirective(CurrDir)) {
9888 OpenMPClauseKind ConflictKind;
9889 if (DSAStack->checkMappableExprComponentListsForDecl(
9890 VD, /*CurrentRegionOnly=*/true,
9891 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9892 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9893 ConflictKind = WhereFoundClauseKind;
9894 return true;
9895 })) {
9896 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9897 << getOpenMPClauseName(OMPC_private)
9898 << getOpenMPClauseName(ConflictKind)
9899 << getOpenMPDirectiveName(CurrDir);
9900 reportOriginalDsa(*this, DSAStack, D, DVar);
9901 continue;
9902 }
9903 }
9904
9905 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9906 // A variable of class type (or array thereof) that appears in a private
9907 // clause requires an accessible, unambiguous default constructor for the
9908 // class type.
9909 // Generate helper private variable and initialize it with the default
9910 // value. The address of the original variable is replaced by the address of
9911 // the new private variable in CodeGen. This new variable is not added to
9912 // IdResolver, so the code in the OpenMP region uses original variable for
9913 // proper diagnostics.
9914 Type = Type.getUnqualifiedType();
9915 VarDecl *VDPrivate =
9916 buildVarDecl(*this, ELoc, Type, D->getName(),
9917 D->hasAttrs() ? &D->getAttrs() : nullptr,
9918 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9919 ActOnUninitializedDecl(VDPrivate);
9920 if (VDPrivate->isInvalidDecl())
9921 continue;
9922 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9923 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9924
9925 DeclRefExpr *Ref = nullptr;
9926 if (!VD && !CurContext->isDependentContext())
9927 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9928 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9929 Vars.push_back((VD || CurContext->isDependentContext())
9930 ? RefExpr->IgnoreParens()
9931 : Ref);
9932 PrivateCopies.push_back(VDPrivateRefExpr);
9933 }
9934
9935 if (Vars.empty())
9936 return nullptr;
9937
9938 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9939 PrivateCopies);
9940 }
9941
9942 namespace {
9943 class DiagsUninitializedSeveretyRAII {
9944 private:
9945 DiagnosticsEngine &Diags;
9946 SourceLocation SavedLoc;
9947 bool IsIgnored = false;
9948
9949 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)9950 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9951 bool IsIgnored)
9952 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9953 if (!IsIgnored) {
9954 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9955 /*Map*/ diag::Severity::Ignored, Loc);
9956 }
9957 }
~DiagsUninitializedSeveretyRAII()9958 ~DiagsUninitializedSeveretyRAII() {
9959 if (!IsIgnored)
9960 Diags.popMappings(SavedLoc);
9961 }
9962 };
9963 }
9964
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9965 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
9966 SourceLocation StartLoc,
9967 SourceLocation LParenLoc,
9968 SourceLocation EndLoc) {
9969 SmallVector<Expr *, 8> Vars;
9970 SmallVector<Expr *, 8> PrivateCopies;
9971 SmallVector<Expr *, 8> Inits;
9972 SmallVector<Decl *, 4> ExprCaptures;
9973 bool IsImplicitClause =
9974 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9975 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
9976
9977 for (Expr *RefExpr : VarList) {
9978 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9979 SourceLocation ELoc;
9980 SourceRange ERange;
9981 Expr *SimpleRefExpr = RefExpr;
9982 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9983 if (Res.second) {
9984 // It will be analyzed later.
9985 Vars.push_back(RefExpr);
9986 PrivateCopies.push_back(nullptr);
9987 Inits.push_back(nullptr);
9988 }
9989 ValueDecl *D = Res.first;
9990 if (!D)
9991 continue;
9992
9993 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9994 QualType Type = D->getType();
9995 auto *VD = dyn_cast<VarDecl>(D);
9996
9997 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9998 // A variable that appears in a private clause must not have an incomplete
9999 // type or a reference type.
10000 if (RequireCompleteType(ELoc, Type,
10001 diag::err_omp_firstprivate_incomplete_type))
10002 continue;
10003 Type = Type.getNonReferenceType();
10004
10005 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
10006 // A variable of class type (or array thereof) that appears in a private
10007 // clause requires an accessible, unambiguous copy constructor for the
10008 // class type.
10009 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
10010
10011 // If an implicit firstprivate variable found it was checked already.
10012 DSAStackTy::DSAVarData TopDVar;
10013 if (!IsImplicitClause) {
10014 DSAStackTy::DSAVarData DVar =
10015 DSAStack->getTopDSA(D, /*FromParent=*/false);
10016 TopDVar = DVar;
10017 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10018 bool IsConstant = ElemType.isConstant(Context);
10019 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
10020 // A list item that specifies a given variable may not appear in more
10021 // than one clause on the same directive, except that a variable may be
10022 // specified in both firstprivate and lastprivate clauses.
10023 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10024 // A list item may appear in a firstprivate or lastprivate clause but not
10025 // both.
10026 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10027 (isOpenMPDistributeDirective(CurrDir) ||
10028 DVar.CKind != OMPC_lastprivate) &&
10029 DVar.RefExpr) {
10030 Diag(ELoc, diag::err_omp_wrong_dsa)
10031 << getOpenMPClauseName(DVar.CKind)
10032 << getOpenMPClauseName(OMPC_firstprivate);
10033 reportOriginalDsa(*this, DSAStack, D, DVar);
10034 continue;
10035 }
10036
10037 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10038 // in a Construct]
10039 // Variables with the predetermined data-sharing attributes may not be
10040 // listed in data-sharing attributes clauses, except for the cases
10041 // listed below. For these exceptions only, listing a predetermined
10042 // variable in a data-sharing attribute clause is allowed and overrides
10043 // the variable's predetermined data-sharing attributes.
10044 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10045 // in a Construct, C/C++, p.2]
10046 // Variables with const-qualified type having no mutable member may be
10047 // listed in a firstprivate clause, even if they are static data members.
10048 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10049 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
10050 Diag(ELoc, diag::err_omp_wrong_dsa)
10051 << getOpenMPClauseName(DVar.CKind)
10052 << getOpenMPClauseName(OMPC_firstprivate);
10053 reportOriginalDsa(*this, DSAStack, D, DVar);
10054 continue;
10055 }
10056
10057 // OpenMP [2.9.3.4, Restrictions, p.2]
10058 // A list item that is private within a parallel region must not appear
10059 // in a firstprivate clause on a worksharing construct if any of the
10060 // worksharing regions arising from the worksharing construct ever bind
10061 // to any of the parallel regions arising from the parallel construct.
10062 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10063 // A list item that is private within a teams region must not appear in a
10064 // firstprivate clause on a distribute construct if any of the distribute
10065 // regions arising from the distribute construct ever bind to any of the
10066 // teams regions arising from the teams construct.
10067 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10068 // A list item that appears in a reduction clause of a teams construct
10069 // must not appear in a firstprivate clause on a distribute construct if
10070 // any of the distribute regions arising from the distribute construct
10071 // ever bind to any of the teams regions arising from the teams construct.
10072 if ((isOpenMPWorksharingDirective(CurrDir) ||
10073 isOpenMPDistributeDirective(CurrDir)) &&
10074 !isOpenMPParallelDirective(CurrDir) &&
10075 !isOpenMPTeamsDirective(CurrDir)) {
10076 DVar = DSAStack->getImplicitDSA(D, true);
10077 if (DVar.CKind != OMPC_shared &&
10078 (isOpenMPParallelDirective(DVar.DKind) ||
10079 isOpenMPTeamsDirective(DVar.DKind) ||
10080 DVar.DKind == OMPD_unknown)) {
10081 Diag(ELoc, diag::err_omp_required_access)
10082 << getOpenMPClauseName(OMPC_firstprivate)
10083 << getOpenMPClauseName(OMPC_shared);
10084 reportOriginalDsa(*this, DSAStack, D, DVar);
10085 continue;
10086 }
10087 }
10088 // OpenMP [2.9.3.4, Restrictions, p.3]
10089 // A list item that appears in a reduction clause of a parallel construct
10090 // must not appear in a firstprivate clause on a worksharing or task
10091 // construct if any of the worksharing or task regions arising from the
10092 // worksharing or task construct ever bind to any of the parallel regions
10093 // arising from the parallel construct.
10094 // OpenMP [2.9.3.4, Restrictions, p.4]
10095 // A list item that appears in a reduction clause in worksharing
10096 // construct must not appear in a firstprivate clause in a task construct
10097 // encountered during execution of any of the worksharing regions arising
10098 // from the worksharing construct.
10099 if (isOpenMPTaskingDirective(CurrDir)) {
10100 DVar = DSAStack->hasInnermostDSA(
10101 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
10102 [](OpenMPDirectiveKind K) {
10103 return isOpenMPParallelDirective(K) ||
10104 isOpenMPWorksharingDirective(K) ||
10105 isOpenMPTeamsDirective(K);
10106 },
10107 /*FromParent=*/true);
10108 if (DVar.CKind == OMPC_reduction &&
10109 (isOpenMPParallelDirective(DVar.DKind) ||
10110 isOpenMPWorksharingDirective(DVar.DKind) ||
10111 isOpenMPTeamsDirective(DVar.DKind))) {
10112 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10113 << getOpenMPDirectiveName(DVar.DKind);
10114 reportOriginalDsa(*this, DSAStack, D, DVar);
10115 continue;
10116 }
10117 }
10118
10119 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10120 // A list item cannot appear in both a map clause and a data-sharing
10121 // attribute clause on the same construct
10122 if (isOpenMPTargetExecutionDirective(CurrDir)) {
10123 OpenMPClauseKind ConflictKind;
10124 if (DSAStack->checkMappableExprComponentListsForDecl(
10125 VD, /*CurrentRegionOnly=*/true,
10126 [&ConflictKind](
10127 OMPClauseMappableExprCommon::MappableExprComponentListRef,
10128 OpenMPClauseKind WhereFoundClauseKind) {
10129 ConflictKind = WhereFoundClauseKind;
10130 return true;
10131 })) {
10132 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10133 << getOpenMPClauseName(OMPC_firstprivate)
10134 << getOpenMPClauseName(ConflictKind)
10135 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10136 reportOriginalDsa(*this, DSAStack, D, DVar);
10137 continue;
10138 }
10139 }
10140 }
10141
10142 // Variably modified types are not supported for tasks.
10143 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
10144 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
10145 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10146 << getOpenMPClauseName(OMPC_firstprivate) << Type
10147 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10148 bool IsDecl =
10149 !VD ||
10150 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10151 Diag(D->getLocation(),
10152 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10153 << D;
10154 continue;
10155 }
10156
10157 Type = Type.getUnqualifiedType();
10158 VarDecl *VDPrivate =
10159 buildVarDecl(*this, ELoc, Type, D->getName(),
10160 D->hasAttrs() ? &D->getAttrs() : nullptr,
10161 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10162 // Generate helper private variable and initialize it with the value of the
10163 // original variable. The address of the original variable is replaced by
10164 // the address of the new private variable in the CodeGen. This new variable
10165 // is not added to IdResolver, so the code in the OpenMP region uses
10166 // original variable for proper diagnostics and variable capturing.
10167 Expr *VDInitRefExpr = nullptr;
10168 // For arrays generate initializer for single element and replace it by the
10169 // original array element in CodeGen.
10170 if (Type->isArrayType()) {
10171 VarDecl *VDInit =
10172 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
10173 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
10174 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10175 ElemType = ElemType.getUnqualifiedType();
10176 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
10177 ".firstprivate.temp");
10178 InitializedEntity Entity =
10179 InitializedEntity::InitializeVariable(VDInitTemp);
10180 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
10181
10182 InitializationSequence InitSeq(*this, Entity, Kind, Init);
10183 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
10184 if (Result.isInvalid())
10185 VDPrivate->setInvalidDecl();
10186 else
10187 VDPrivate->setInit(Result.getAs<Expr>());
10188 // Remove temp variable declaration.
10189 Context.Deallocate(VDInitTemp);
10190 } else {
10191 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
10192 ".firstprivate.temp");
10193 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
10194 RefExpr->getExprLoc());
10195 AddInitializerToDecl(VDPrivate,
10196 DefaultLvalueConversion(VDInitRefExpr).get(),
10197 /*DirectInit=*/false);
10198 }
10199 if (VDPrivate->isInvalidDecl()) {
10200 if (IsImplicitClause) {
10201 Diag(RefExpr->getExprLoc(),
10202 diag::note_omp_task_predetermined_firstprivate_here);
10203 }
10204 continue;
10205 }
10206 CurContext->addDecl(VDPrivate);
10207 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
10208 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
10209 RefExpr->getExprLoc());
10210 DeclRefExpr *Ref = nullptr;
10211 if (!VD && !CurContext->isDependentContext()) {
10212 if (TopDVar.CKind == OMPC_lastprivate) {
10213 Ref = TopDVar.PrivateCopy;
10214 } else {
10215 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10216 if (!isOpenMPCapturedDecl(D))
10217 ExprCaptures.push_back(Ref->getDecl());
10218 }
10219 }
10220 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10221 Vars.push_back((VD || CurContext->isDependentContext())
10222 ? RefExpr->IgnoreParens()
10223 : Ref);
10224 PrivateCopies.push_back(VDPrivateRefExpr);
10225 Inits.push_back(VDInitRefExpr);
10226 }
10227
10228 if (Vars.empty())
10229 return nullptr;
10230
10231 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10232 Vars, PrivateCopies, Inits,
10233 buildPreInits(Context, ExprCaptures));
10234 }
10235
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)10236 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
10237 SourceLocation StartLoc,
10238 SourceLocation LParenLoc,
10239 SourceLocation EndLoc) {
10240 SmallVector<Expr *, 8> Vars;
10241 SmallVector<Expr *, 8> SrcExprs;
10242 SmallVector<Expr *, 8> DstExprs;
10243 SmallVector<Expr *, 8> AssignmentOps;
10244 SmallVector<Decl *, 4> ExprCaptures;
10245 SmallVector<Expr *, 4> ExprPostUpdates;
10246 for (Expr *RefExpr : VarList) {
10247 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10248 SourceLocation ELoc;
10249 SourceRange ERange;
10250 Expr *SimpleRefExpr = RefExpr;
10251 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10252 if (Res.second) {
10253 // It will be analyzed later.
10254 Vars.push_back(RefExpr);
10255 SrcExprs.push_back(nullptr);
10256 DstExprs.push_back(nullptr);
10257 AssignmentOps.push_back(nullptr);
10258 }
10259 ValueDecl *D = Res.first;
10260 if (!D)
10261 continue;
10262
10263 QualType Type = D->getType();
10264 auto *VD = dyn_cast<VarDecl>(D);
10265
10266 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
10267 // A variable that appears in a lastprivate clause must not have an
10268 // incomplete type or a reference type.
10269 if (RequireCompleteType(ELoc, Type,
10270 diag::err_omp_lastprivate_incomplete_type))
10271 continue;
10272 Type = Type.getNonReferenceType();
10273
10274 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10275 // A variable that is privatized must not have a const-qualified type
10276 // unless it is of class type with a mutable member. This restriction does
10277 // not apply to the firstprivate clause.
10278 //
10279 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
10280 // A variable that appears in a lastprivate clause must not have a
10281 // const-qualified type unless it is of class type with a mutable member.
10282 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
10283 continue;
10284
10285 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10286 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10287 // in a Construct]
10288 // Variables with the predetermined data-sharing attributes may not be
10289 // listed in data-sharing attributes clauses, except for the cases
10290 // listed below.
10291 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10292 // A list item may appear in a firstprivate or lastprivate clause but not
10293 // both.
10294 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10295 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10296 (isOpenMPDistributeDirective(CurrDir) ||
10297 DVar.CKind != OMPC_firstprivate) &&
10298 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
10299 Diag(ELoc, diag::err_omp_wrong_dsa)
10300 << getOpenMPClauseName(DVar.CKind)
10301 << getOpenMPClauseName(OMPC_lastprivate);
10302 reportOriginalDsa(*this, DSAStack, D, DVar);
10303 continue;
10304 }
10305
10306 // OpenMP [2.14.3.5, Restrictions, p.2]
10307 // A list item that is private within a parallel region, or that appears in
10308 // the reduction clause of a parallel construct, must not appear in a
10309 // lastprivate clause on a worksharing construct if any of the corresponding
10310 // worksharing regions ever binds to any of the corresponding parallel
10311 // regions.
10312 DSAStackTy::DSAVarData TopDVar = DVar;
10313 if (isOpenMPWorksharingDirective(CurrDir) &&
10314 !isOpenMPParallelDirective(CurrDir) &&
10315 !isOpenMPTeamsDirective(CurrDir)) {
10316 DVar = DSAStack->getImplicitDSA(D, true);
10317 if (DVar.CKind != OMPC_shared) {
10318 Diag(ELoc, diag::err_omp_required_access)
10319 << getOpenMPClauseName(OMPC_lastprivate)
10320 << getOpenMPClauseName(OMPC_shared);
10321 reportOriginalDsa(*this, DSAStack, D, DVar);
10322 continue;
10323 }
10324 }
10325
10326 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
10327 // A variable of class type (or array thereof) that appears in a
10328 // lastprivate clause requires an accessible, unambiguous default
10329 // constructor for the class type, unless the list item is also specified
10330 // in a firstprivate clause.
10331 // A variable of class type (or array thereof) that appears in a
10332 // lastprivate clause requires an accessible, unambiguous copy assignment
10333 // operator for the class type.
10334 Type = Context.getBaseElementType(Type).getNonReferenceType();
10335 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
10336 Type.getUnqualifiedType(), ".lastprivate.src",
10337 D->hasAttrs() ? &D->getAttrs() : nullptr);
10338 DeclRefExpr *PseudoSrcExpr =
10339 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
10340 VarDecl *DstVD =
10341 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
10342 D->hasAttrs() ? &D->getAttrs() : nullptr);
10343 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
10344 // For arrays generate assignment operation for single element and replace
10345 // it by the original array element in CodeGen.
10346 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
10347 PseudoDstExpr, PseudoSrcExpr);
10348 if (AssignmentOp.isInvalid())
10349 continue;
10350 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
10351 /*DiscardedValue=*/true);
10352 if (AssignmentOp.isInvalid())
10353 continue;
10354
10355 DeclRefExpr *Ref = nullptr;
10356 if (!VD && !CurContext->isDependentContext()) {
10357 if (TopDVar.CKind == OMPC_firstprivate) {
10358 Ref = TopDVar.PrivateCopy;
10359 } else {
10360 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10361 if (!isOpenMPCapturedDecl(D))
10362 ExprCaptures.push_back(Ref->getDecl());
10363 }
10364 if (TopDVar.CKind == OMPC_firstprivate ||
10365 (!isOpenMPCapturedDecl(D) &&
10366 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
10367 ExprResult RefRes = DefaultLvalueConversion(Ref);
10368 if (!RefRes.isUsable())
10369 continue;
10370 ExprResult PostUpdateRes =
10371 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10372 RefRes.get());
10373 if (!PostUpdateRes.isUsable())
10374 continue;
10375 ExprPostUpdates.push_back(
10376 IgnoredValueConversions(PostUpdateRes.get()).get());
10377 }
10378 }
10379 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10380 Vars.push_back((VD || CurContext->isDependentContext())
10381 ? RefExpr->IgnoreParens()
10382 : Ref);
10383 SrcExprs.push_back(PseudoSrcExpr);
10384 DstExprs.push_back(PseudoDstExpr);
10385 AssignmentOps.push_back(AssignmentOp.get());
10386 }
10387
10388 if (Vars.empty())
10389 return nullptr;
10390
10391 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10392 Vars, SrcExprs, DstExprs, AssignmentOps,
10393 buildPreInits(Context, ExprCaptures),
10394 buildPostUpdate(*this, ExprPostUpdates));
10395 }
10396
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)10397 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
10398 SourceLocation StartLoc,
10399 SourceLocation LParenLoc,
10400 SourceLocation EndLoc) {
10401 SmallVector<Expr *, 8> Vars;
10402 for (Expr *RefExpr : VarList) {
10403 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10404 SourceLocation ELoc;
10405 SourceRange ERange;
10406 Expr *SimpleRefExpr = RefExpr;
10407 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10408 if (Res.second) {
10409 // It will be analyzed later.
10410 Vars.push_back(RefExpr);
10411 }
10412 ValueDecl *D = Res.first;
10413 if (!D)
10414 continue;
10415
10416 auto *VD = dyn_cast<VarDecl>(D);
10417 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10418 // in a Construct]
10419 // Variables with the predetermined data-sharing attributes may not be
10420 // listed in data-sharing attributes clauses, except for the cases
10421 // listed below. For these exceptions only, listing a predetermined
10422 // variable in a data-sharing attribute clause is allowed and overrides
10423 // the variable's predetermined data-sharing attributes.
10424 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10425 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
10426 DVar.RefExpr) {
10427 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10428 << getOpenMPClauseName(OMPC_shared);
10429 reportOriginalDsa(*this, DSAStack, D, DVar);
10430 continue;
10431 }
10432
10433 DeclRefExpr *Ref = nullptr;
10434 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10435 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10436 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10437 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10438 ? RefExpr->IgnoreParens()
10439 : Ref);
10440 }
10441
10442 if (Vars.empty())
10443 return nullptr;
10444
10445 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
10446 }
10447
10448 namespace {
10449 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
10450 DSAStackTy *Stack;
10451
10452 public:
VisitDeclRefExpr(DeclRefExpr * E)10453 bool VisitDeclRefExpr(DeclRefExpr *E) {
10454 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10455 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10456 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10457 return false;
10458 if (DVar.CKind != OMPC_unknown)
10459 return true;
10460 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10461 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10462 /*FromParent=*/true);
10463 return DVarPrivate.CKind != OMPC_unknown;
10464 }
10465 return false;
10466 }
VisitStmt(Stmt * S)10467 bool VisitStmt(Stmt *S) {
10468 for (Stmt *Child : S->children()) {
10469 if (Child && Visit(Child))
10470 return true;
10471 }
10472 return false;
10473 }
DSARefChecker(DSAStackTy * S)10474 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10475 };
10476 } // namespace
10477
10478 namespace {
10479 // Transform MemberExpression for specified FieldDecl of current class to
10480 // DeclRefExpr to specified OMPCapturedExprDecl.
10481 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10482 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
10483 ValueDecl *Field = nullptr;
10484 DeclRefExpr *CapturedExpr = nullptr;
10485
10486 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)10487 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
10488 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10489
TransformMemberExpr(MemberExpr * E)10490 ExprResult TransformMemberExpr(MemberExpr *E) {
10491 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10492 E->getMemberDecl() == Field) {
10493 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10494 return CapturedExpr;
10495 }
10496 return BaseTransform::TransformMemberExpr(E);
10497 }
getCapturedExpr()10498 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
10499 };
10500 } // namespace
10501
10502 template <typename T, typename U>
filterLookupForUDR(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)10503 static T filterLookupForUDR(SmallVectorImpl<U> &Lookups,
10504 const llvm::function_ref<T(ValueDecl *)> Gen) {
10505 for (U &Set : Lookups) {
10506 for (auto *D : Set) {
10507 if (T Res = Gen(cast<ValueDecl>(D)))
10508 return Res;
10509 }
10510 }
10511 return T();
10512 }
10513
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)10514 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
10515 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
10516
10517 for (auto RD : D->redecls()) {
10518 // Don't bother with extra checks if we already know this one isn't visible.
10519 if (RD == D)
10520 continue;
10521
10522 auto ND = cast<NamedDecl>(RD);
10523 if (LookupResult::isVisible(SemaRef, ND))
10524 return ND;
10525 }
10526
10527 return nullptr;
10528 }
10529
10530 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & ReductionId,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)10531 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId,
10532 SourceLocation Loc, QualType Ty,
10533 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
10534 // Find all of the associated namespaces and classes based on the
10535 // arguments we have.
10536 Sema::AssociatedNamespaceSet AssociatedNamespaces;
10537 Sema::AssociatedClassSet AssociatedClasses;
10538 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
10539 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
10540 AssociatedClasses);
10541
10542 // C++ [basic.lookup.argdep]p3:
10543 // Let X be the lookup set produced by unqualified lookup (3.4.1)
10544 // and let Y be the lookup set produced by argument dependent
10545 // lookup (defined as follows). If X contains [...] then Y is
10546 // empty. Otherwise Y is the set of declarations found in the
10547 // namespaces associated with the argument types as described
10548 // below. The set of declarations found by the lookup of the name
10549 // is the union of X and Y.
10550 //
10551 // Here, we compute Y and add its members to the overloaded
10552 // candidate set.
10553 for (auto *NS : AssociatedNamespaces) {
10554 // When considering an associated namespace, the lookup is the
10555 // same as the lookup performed when the associated namespace is
10556 // used as a qualifier (3.4.3.2) except that:
10557 //
10558 // -- Any using-directives in the associated namespace are
10559 // ignored.
10560 //
10561 // -- Any namespace-scope friend functions declared in
10562 // associated classes are visible within their respective
10563 // namespaces even if they are not visible during an ordinary
10564 // lookup (11.4).
10565 DeclContext::lookup_result R = NS->lookup(ReductionId.getName());
10566 for (auto *D : R) {
10567 auto *Underlying = D;
10568 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10569 Underlying = USD->getTargetDecl();
10570
10571 if (!isa<OMPDeclareReductionDecl>(Underlying))
10572 continue;
10573
10574 if (!SemaRef.isVisible(D)) {
10575 D = findAcceptableDecl(SemaRef, D);
10576 if (!D)
10577 continue;
10578 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10579 Underlying = USD->getTargetDecl();
10580 }
10581 Lookups.emplace_back();
10582 Lookups.back().addDecl(Underlying);
10583 }
10584 }
10585 }
10586
10587 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)10588 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
10589 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
10590 const DeclarationNameInfo &ReductionId, QualType Ty,
10591 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
10592 if (ReductionIdScopeSpec.isInvalid())
10593 return ExprError();
10594 SmallVector<UnresolvedSet<8>, 4> Lookups;
10595 if (S) {
10596 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10597 Lookup.suppressDiagnostics();
10598 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
10599 NamedDecl *D = Lookup.getRepresentativeDecl();
10600 do {
10601 S = S->getParent();
10602 } while (S && !S->isDeclScope(D));
10603 if (S)
10604 S = S->getParent();
10605 Lookups.emplace_back();
10606 Lookups.back().append(Lookup.begin(), Lookup.end());
10607 Lookup.clear();
10608 }
10609 } else if (auto *ULE =
10610 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10611 Lookups.push_back(UnresolvedSet<8>());
10612 Decl *PrevD = nullptr;
10613 for (NamedDecl *D : ULE->decls()) {
10614 if (D == PrevD)
10615 Lookups.push_back(UnresolvedSet<8>());
10616 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
10617 Lookups.back().addDecl(DRD);
10618 PrevD = D;
10619 }
10620 }
10621 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
10622 Ty->isInstantiationDependentType() ||
10623 Ty->containsUnexpandedParameterPack() ||
10624 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
10625 return !D->isInvalidDecl() &&
10626 (D->getType()->isDependentType() ||
10627 D->getType()->isInstantiationDependentType() ||
10628 D->getType()->containsUnexpandedParameterPack());
10629 })) {
10630 UnresolvedSet<8> ResSet;
10631 for (const UnresolvedSet<8> &Set : Lookups) {
10632 if (Set.empty())
10633 continue;
10634 ResSet.append(Set.begin(), Set.end());
10635 // The last item marks the end of all declarations at the specified scope.
10636 ResSet.addDecl(Set[Set.size() - 1]);
10637 }
10638 return UnresolvedLookupExpr::Create(
10639 SemaRef.Context, /*NamingClass=*/nullptr,
10640 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
10641 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
10642 }
10643 // Lookup inside the classes.
10644 // C++ [over.match.oper]p3:
10645 // For a unary operator @ with an operand of a type whose
10646 // cv-unqualified version is T1, and for a binary operator @ with
10647 // a left operand of a type whose cv-unqualified version is T1 and
10648 // a right operand of a type whose cv-unqualified version is T2,
10649 // three sets of candidate functions, designated member
10650 // candidates, non-member candidates and built-in candidates, are
10651 // constructed as follows:
10652 // -- If T1 is a complete class type or a class currently being
10653 // defined, the set of member candidates is the result of the
10654 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
10655 // the set of member candidates is empty.
10656 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10657 Lookup.suppressDiagnostics();
10658 if (const auto *TyRec = Ty->getAs<RecordType>()) {
10659 // Complete the type if it can be completed.
10660 // If the type is neither complete nor being defined, bail out now.
10661 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
10662 TyRec->getDecl()->getDefinition()) {
10663 Lookup.clear();
10664 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
10665 if (Lookup.empty()) {
10666 Lookups.emplace_back();
10667 Lookups.back().append(Lookup.begin(), Lookup.end());
10668 }
10669 }
10670 }
10671 // Perform ADL.
10672 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
10673 if (auto *VD = filterLookupForUDR<ValueDecl *>(
10674 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
10675 if (!D->isInvalidDecl() &&
10676 SemaRef.Context.hasSameType(D->getType(), Ty))
10677 return D;
10678 return nullptr;
10679 }))
10680 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10681 if (auto *VD = filterLookupForUDR<ValueDecl *>(
10682 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
10683 if (!D->isInvalidDecl() &&
10684 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
10685 !Ty.isMoreQualifiedThan(D->getType()))
10686 return D;
10687 return nullptr;
10688 })) {
10689 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
10690 /*DetectVirtual=*/false);
10691 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10692 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
10693 VD->getType().getUnqualifiedType()))) {
10694 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
10695 /*DiagID=*/0) !=
10696 Sema::AR_inaccessible) {
10697 SemaRef.BuildBasePathArray(Paths, BasePath);
10698 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10699 }
10700 }
10701 }
10702 }
10703 if (ReductionIdScopeSpec.isSet()) {
10704 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10705 return ExprError();
10706 }
10707 return ExprEmpty();
10708 }
10709
10710 namespace {
10711 /// Data for the reduction-based clauses.
10712 struct ReductionData {
10713 /// List of original reduction items.
10714 SmallVector<Expr *, 8> Vars;
10715 /// List of private copies of the reduction items.
10716 SmallVector<Expr *, 8> Privates;
10717 /// LHS expressions for the reduction_op expressions.
10718 SmallVector<Expr *, 8> LHSs;
10719 /// RHS expressions for the reduction_op expressions.
10720 SmallVector<Expr *, 8> RHSs;
10721 /// Reduction operation expression.
10722 SmallVector<Expr *, 8> ReductionOps;
10723 /// Taskgroup descriptors for the corresponding reduction items in
10724 /// in_reduction clauses.
10725 SmallVector<Expr *, 8> TaskgroupDescriptors;
10726 /// List of captures for clause.
10727 SmallVector<Decl *, 4> ExprCaptures;
10728 /// List of postupdate expressions.
10729 SmallVector<Expr *, 4> ExprPostUpdates;
10730 ReductionData() = delete;
10731 /// Reserves required memory for the reduction data.
ReductionData__anon523c83f23611::ReductionData10732 ReductionData(unsigned Size) {
10733 Vars.reserve(Size);
10734 Privates.reserve(Size);
10735 LHSs.reserve(Size);
10736 RHSs.reserve(Size);
10737 ReductionOps.reserve(Size);
10738 TaskgroupDescriptors.reserve(Size);
10739 ExprCaptures.reserve(Size);
10740 ExprPostUpdates.reserve(Size);
10741 }
10742 /// Stores reduction item and reduction operation only (required for dependent
10743 /// reduction item).
push__anon523c83f23611::ReductionData10744 void push(Expr *Item, Expr *ReductionOp) {
10745 Vars.emplace_back(Item);
10746 Privates.emplace_back(nullptr);
10747 LHSs.emplace_back(nullptr);
10748 RHSs.emplace_back(nullptr);
10749 ReductionOps.emplace_back(ReductionOp);
10750 TaskgroupDescriptors.emplace_back(nullptr);
10751 }
10752 /// Stores reduction data.
push__anon523c83f23611::ReductionData10753 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
10754 Expr *TaskgroupDescriptor) {
10755 Vars.emplace_back(Item);
10756 Privates.emplace_back(Private);
10757 LHSs.emplace_back(LHS);
10758 RHSs.emplace_back(RHS);
10759 ReductionOps.emplace_back(ReductionOp);
10760 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10761 }
10762 };
10763 } // namespace
10764
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)10765 static bool checkOMPArraySectionConstantForReduction(
10766 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10767 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10768 const Expr *Length = OASE->getLength();
10769 if (Length == nullptr) {
10770 // For array sections of the form [1:] or [:], we would need to analyze
10771 // the lower bound...
10772 if (OASE->getColonLoc().isValid())
10773 return false;
10774
10775 // This is an array subscript which has implicit length 1!
10776 SingleElement = true;
10777 ArraySizes.push_back(llvm::APSInt::get(1));
10778 } else {
10779 Expr::EvalResult Result;
10780 if (!Length->EvaluateAsInt(Result, Context))
10781 return false;
10782
10783 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10784 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10785 ArraySizes.push_back(ConstantLengthValue);
10786 }
10787
10788 // Get the base of this array section and walk up from there.
10789 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10790
10791 // We require length = 1 for all array sections except the right-most to
10792 // guarantee that the memory region is contiguous and has no holes in it.
10793 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10794 Length = TempOASE->getLength();
10795 if (Length == nullptr) {
10796 // For array sections of the form [1:] or [:], we would need to analyze
10797 // the lower bound...
10798 if (OASE->getColonLoc().isValid())
10799 return false;
10800
10801 // This is an array subscript which has implicit length 1!
10802 ArraySizes.push_back(llvm::APSInt::get(1));
10803 } else {
10804 Expr::EvalResult Result;
10805 if (!Length->EvaluateAsInt(Result, Context))
10806 return false;
10807
10808 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10809 if (ConstantLengthValue.getSExtValue() != 1)
10810 return false;
10811
10812 ArraySizes.push_back(ConstantLengthValue);
10813 }
10814 Base = TempOASE->getBase()->IgnoreParenImpCasts();
10815 }
10816
10817 // If we have a single element, we don't need to add the implicit lengths.
10818 if (!SingleElement) {
10819 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10820 // Has implicit length 1!
10821 ArraySizes.push_back(llvm::APSInt::get(1));
10822 Base = TempASE->getBase()->IgnoreParenImpCasts();
10823 }
10824 }
10825
10826 // This array section can be privatized as a single value or as a constant
10827 // sized array.
10828 return true;
10829 }
10830
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)10831 static bool actOnOMPReductionKindClause(
10832 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10833 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10834 SourceLocation ColonLoc, SourceLocation EndLoc,
10835 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10836 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10837 DeclarationName DN = ReductionId.getName();
10838 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
10839 BinaryOperatorKind BOK = BO_Comma;
10840
10841 ASTContext &Context = S.Context;
10842 // OpenMP [2.14.3.6, reduction clause]
10843 // C
10844 // reduction-identifier is either an identifier or one of the following
10845 // operators: +, -, *, &, |, ^, && and ||
10846 // C++
10847 // reduction-identifier is either an id-expression or one of the following
10848 // operators: +, -, *, &, |, ^, && and ||
10849 switch (OOK) {
10850 case OO_Plus:
10851 case OO_Minus:
10852 BOK = BO_Add;
10853 break;
10854 case OO_Star:
10855 BOK = BO_Mul;
10856 break;
10857 case OO_Amp:
10858 BOK = BO_And;
10859 break;
10860 case OO_Pipe:
10861 BOK = BO_Or;
10862 break;
10863 case OO_Caret:
10864 BOK = BO_Xor;
10865 break;
10866 case OO_AmpAmp:
10867 BOK = BO_LAnd;
10868 break;
10869 case OO_PipePipe:
10870 BOK = BO_LOr;
10871 break;
10872 case OO_New:
10873 case OO_Delete:
10874 case OO_Array_New:
10875 case OO_Array_Delete:
10876 case OO_Slash:
10877 case OO_Percent:
10878 case OO_Tilde:
10879 case OO_Exclaim:
10880 case OO_Equal:
10881 case OO_Less:
10882 case OO_Greater:
10883 case OO_LessEqual:
10884 case OO_GreaterEqual:
10885 case OO_PlusEqual:
10886 case OO_MinusEqual:
10887 case OO_StarEqual:
10888 case OO_SlashEqual:
10889 case OO_PercentEqual:
10890 case OO_CaretEqual:
10891 case OO_AmpEqual:
10892 case OO_PipeEqual:
10893 case OO_LessLess:
10894 case OO_GreaterGreater:
10895 case OO_LessLessEqual:
10896 case OO_GreaterGreaterEqual:
10897 case OO_EqualEqual:
10898 case OO_ExclaimEqual:
10899 case OO_Spaceship:
10900 case OO_PlusPlus:
10901 case OO_MinusMinus:
10902 case OO_Comma:
10903 case OO_ArrowStar:
10904 case OO_Arrow:
10905 case OO_Call:
10906 case OO_Subscript:
10907 case OO_Conditional:
10908 case OO_Coawait:
10909 case NUM_OVERLOADED_OPERATORS:
10910 llvm_unreachable("Unexpected reduction identifier");
10911 case OO_None:
10912 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
10913 if (II->isStr("max"))
10914 BOK = BO_GT;
10915 else if (II->isStr("min"))
10916 BOK = BO_LT;
10917 }
10918 break;
10919 }
10920 SourceRange ReductionIdRange;
10921 if (ReductionIdScopeSpec.isValid())
10922 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10923 else
10924 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10925 ReductionIdRange.setEnd(ReductionId.getEndLoc());
10926
10927 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10928 bool FirstIter = true;
10929 for (Expr *RefExpr : VarList) {
10930 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10931 // OpenMP [2.1, C/C++]
10932 // A list item is a variable or array section, subject to the restrictions
10933 // specified in Section 2.4 on page 42 and in each of the sections
10934 // describing clauses and directives for which a list appears.
10935 // OpenMP [2.14.3.3, Restrictions, p.1]
10936 // A variable that is part of another variable (as an array or
10937 // structure element) cannot appear in a private clause.
10938 if (!FirstIter && IR != ER)
10939 ++IR;
10940 FirstIter = false;
10941 SourceLocation ELoc;
10942 SourceRange ERange;
10943 Expr *SimpleRefExpr = RefExpr;
10944 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10945 /*AllowArraySection=*/true);
10946 if (Res.second) {
10947 // Try to find 'declare reduction' corresponding construct before using
10948 // builtin/overloaded operators.
10949 QualType Type = Context.DependentTy;
10950 CXXCastPath BasePath;
10951 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10952 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10953 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10954 Expr *ReductionOp = nullptr;
10955 if (S.CurContext->isDependentContext() &&
10956 (DeclareReductionRef.isUnset() ||
10957 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10958 ReductionOp = DeclareReductionRef.get();
10959 // It will be analyzed later.
10960 RD.push(RefExpr, ReductionOp);
10961 }
10962 ValueDecl *D = Res.first;
10963 if (!D)
10964 continue;
10965
10966 Expr *TaskgroupDescriptor = nullptr;
10967 QualType Type;
10968 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10969 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10970 if (ASE) {
10971 Type = ASE->getType().getNonReferenceType();
10972 } else if (OASE) {
10973 QualType BaseType =
10974 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10975 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
10976 Type = ATy->getElementType();
10977 else
10978 Type = BaseType->getPointeeType();
10979 Type = Type.getNonReferenceType();
10980 } else {
10981 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10982 }
10983 auto *VD = dyn_cast<VarDecl>(D);
10984
10985 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10986 // A variable that appears in a private clause must not have an incomplete
10987 // type or a reference type.
10988 if (S.RequireCompleteType(ELoc, D->getType(),
10989 diag::err_omp_reduction_incomplete_type))
10990 continue;
10991 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10992 // A list item that appears in a reduction clause must not be
10993 // const-qualified.
10994 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
10995 /*AcceptIfMutable*/ false, ASE || OASE))
10996 continue;
10997
10998 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10999 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
11000 // If a list-item is a reference type then it must bind to the same object
11001 // for all threads of the team.
11002 if (!ASE && !OASE) {
11003 if (VD) {
11004 VarDecl *VDDef = VD->getDefinition();
11005 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
11006 DSARefChecker Check(Stack);
11007 if (Check.Visit(VDDef->getInit())) {
11008 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11009 << getOpenMPClauseName(ClauseKind) << ERange;
11010 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
11011 continue;
11012 }
11013 }
11014 }
11015
11016 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11017 // in a Construct]
11018 // Variables with the predetermined data-sharing attributes may not be
11019 // listed in data-sharing attributes clauses, except for the cases
11020 // listed below. For these exceptions only, listing a predetermined
11021 // variable in a data-sharing attribute clause is allowed and overrides
11022 // the variable's predetermined data-sharing attributes.
11023 // OpenMP [2.14.3.6, Restrictions, p.3]
11024 // Any number of reduction clauses can be specified on the directive,
11025 // but a list item can appear only once in the reduction clauses for that
11026 // directive.
11027 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
11028 if (DVar.CKind == OMPC_reduction) {
11029 S.Diag(ELoc, diag::err_omp_once_referenced)
11030 << getOpenMPClauseName(ClauseKind);
11031 if (DVar.RefExpr)
11032 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11033 continue;
11034 }
11035 if (DVar.CKind != OMPC_unknown) {
11036 S.Diag(ELoc, diag::err_omp_wrong_dsa)
11037 << getOpenMPClauseName(DVar.CKind)
11038 << getOpenMPClauseName(OMPC_reduction);
11039 reportOriginalDsa(S, Stack, D, DVar);
11040 continue;
11041 }
11042
11043 // OpenMP [2.14.3.6, Restrictions, p.1]
11044 // A list item that appears in a reduction clause of a worksharing
11045 // construct must be shared in the parallel regions to which any of the
11046 // worksharing regions arising from the worksharing construct bind.
11047 if (isOpenMPWorksharingDirective(CurrDir) &&
11048 !isOpenMPParallelDirective(CurrDir) &&
11049 !isOpenMPTeamsDirective(CurrDir)) {
11050 DVar = Stack->getImplicitDSA(D, true);
11051 if (DVar.CKind != OMPC_shared) {
11052 S.Diag(ELoc, diag::err_omp_required_access)
11053 << getOpenMPClauseName(OMPC_reduction)
11054 << getOpenMPClauseName(OMPC_shared);
11055 reportOriginalDsa(S, Stack, D, DVar);
11056 continue;
11057 }
11058 }
11059 }
11060
11061 // Try to find 'declare reduction' corresponding construct before using
11062 // builtin/overloaded operators.
11063 CXXCastPath BasePath;
11064 ExprResult DeclareReductionRef = buildDeclareReductionRef(
11065 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11066 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11067 if (DeclareReductionRef.isInvalid())
11068 continue;
11069 if (S.CurContext->isDependentContext() &&
11070 (DeclareReductionRef.isUnset() ||
11071 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
11072 RD.push(RefExpr, DeclareReductionRef.get());
11073 continue;
11074 }
11075 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
11076 // Not allowed reduction identifier is found.
11077 S.Diag(ReductionId.getBeginLoc(),
11078 diag::err_omp_unknown_reduction_identifier)
11079 << Type << ReductionIdRange;
11080 continue;
11081 }
11082
11083 // OpenMP [2.14.3.6, reduction clause, Restrictions]
11084 // The type of a list item that appears in a reduction clause must be valid
11085 // for the reduction-identifier. For a max or min reduction in C, the type
11086 // of the list item must be an allowed arithmetic data type: char, int,
11087 // float, double, or _Bool, possibly modified with long, short, signed, or
11088 // unsigned. For a max or min reduction in C++, the type of the list item
11089 // must be an allowed arithmetic data type: char, wchar_t, int, float,
11090 // double, or bool, possibly modified with long, short, signed, or unsigned.
11091 if (DeclareReductionRef.isUnset()) {
11092 if ((BOK == BO_GT || BOK == BO_LT) &&
11093 !(Type->isScalarType() ||
11094 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11095 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11096 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
11097 if (!ASE && !OASE) {
11098 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11099 VarDecl::DeclarationOnly;
11100 S.Diag(D->getLocation(),
11101 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11102 << D;
11103 }
11104 continue;
11105 }
11106 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11107 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
11108 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11109 << getOpenMPClauseName(ClauseKind);
11110 if (!ASE && !OASE) {
11111 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11112 VarDecl::DeclarationOnly;
11113 S.Diag(D->getLocation(),
11114 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11115 << D;
11116 }
11117 continue;
11118 }
11119 }
11120
11121 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11122 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
11123 D->hasAttrs() ? &D->getAttrs() : nullptr);
11124 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
11125 D->hasAttrs() ? &D->getAttrs() : nullptr);
11126 QualType PrivateTy = Type;
11127
11128 // Try if we can determine constant lengths for all array sections and avoid
11129 // the VLA.
11130 bool ConstantLengthOASE = false;
11131 if (OASE) {
11132 bool SingleElement;
11133 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
11134 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
11135 Context, OASE, SingleElement, ArraySizes);
11136
11137 // If we don't have a single element, we must emit a constant array type.
11138 if (ConstantLengthOASE && !SingleElement) {
11139 for (llvm::APSInt &Size : ArraySizes)
11140 PrivateTy = Context.getConstantArrayType(
11141 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
11142 }
11143 }
11144
11145 if ((OASE && !ConstantLengthOASE) ||
11146 (!OASE && !ASE &&
11147 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
11148 if (!Context.getTargetInfo().isVLASupported() &&
11149 S.shouldDiagnoseTargetSupportFromOpenMP()) {
11150 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11151 S.Diag(ELoc, diag::note_vla_unsupported);
11152 continue;
11153 }
11154 // For arrays/array sections only:
11155 // Create pseudo array type for private copy. The size for this array will
11156 // be generated during codegen.
11157 // For array subscripts or single variables Private Ty is the same as Type
11158 // (type of the variable or single array element).
11159 PrivateTy = Context.getVariableArrayType(
11160 Type,
11161 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
11162 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
11163 } else if (!ASE && !OASE &&
11164 Context.getAsArrayType(D->getType().getNonReferenceType())) {
11165 PrivateTy = D->getType().getNonReferenceType();
11166 }
11167 // Private copy.
11168 VarDecl *PrivateVD =
11169 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
11170 D->hasAttrs() ? &D->getAttrs() : nullptr,
11171 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11172 // Add initializer for private variable.
11173 Expr *Init = nullptr;
11174 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
11175 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
11176 if (DeclareReductionRef.isUsable()) {
11177 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
11178 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11179 if (DRD->getInitializer()) {
11180 Init = DRDRef;
11181 RHSVD->setInit(DRDRef);
11182 RHSVD->setInitStyle(VarDecl::CallInit);
11183 }
11184 } else {
11185 switch (BOK) {
11186 case BO_Add:
11187 case BO_Xor:
11188 case BO_Or:
11189 case BO_LOr:
11190 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
11191 if (Type->isScalarType() || Type->isAnyComplexType())
11192 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
11193 break;
11194 case BO_Mul:
11195 case BO_LAnd:
11196 if (Type->isScalarType() || Type->isAnyComplexType()) {
11197 // '*' and '&&' reduction ops - initializer is '1'.
11198 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
11199 }
11200 break;
11201 case BO_And: {
11202 // '&' reduction op - initializer is '~0'.
11203 QualType OrigType = Type;
11204 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
11205 Type = ComplexTy->getElementType();
11206 if (Type->isRealFloatingType()) {
11207 llvm::APFloat InitValue =
11208 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
11209 /*isIEEE=*/true);
11210 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11211 Type, ELoc);
11212 } else if (Type->isScalarType()) {
11213 uint64_t Size = Context.getTypeSize(Type);
11214 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
11215 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11216 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11217 }
11218 if (Init && OrigType->isAnyComplexType()) {
11219 // Init = 0xFFFF + 0xFFFFi;
11220 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
11221 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
11222 }
11223 Type = OrigType;
11224 break;
11225 }
11226 case BO_LT:
11227 case BO_GT: {
11228 // 'min' reduction op - initializer is 'Largest representable number in
11229 // the reduction list item type'.
11230 // 'max' reduction op - initializer is 'Least representable number in
11231 // the reduction list item type'.
11232 if (Type->isIntegerType() || Type->isPointerType()) {
11233 bool IsSigned = Type->hasSignedIntegerRepresentation();
11234 uint64_t Size = Context.getTypeSize(Type);
11235 QualType IntTy =
11236 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
11237 llvm::APInt InitValue =
11238 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11239 : llvm::APInt::getMinValue(Size)
11240 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11241 : llvm::APInt::getMaxValue(Size);
11242 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11243 if (Type->isPointerType()) {
11244 // Cast to pointer type.
11245 ExprResult CastExpr = S.BuildCStyleCastExpr(
11246 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
11247 if (CastExpr.isInvalid())
11248 continue;
11249 Init = CastExpr.get();
11250 }
11251 } else if (Type->isRealFloatingType()) {
11252 llvm::APFloat InitValue = llvm::APFloat::getLargest(
11253 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
11254 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11255 Type, ELoc);
11256 }
11257 break;
11258 }
11259 case BO_PtrMemD:
11260 case BO_PtrMemI:
11261 case BO_MulAssign:
11262 case BO_Div:
11263 case BO_Rem:
11264 case BO_Sub:
11265 case BO_Shl:
11266 case BO_Shr:
11267 case BO_LE:
11268 case BO_GE:
11269 case BO_EQ:
11270 case BO_NE:
11271 case BO_Cmp:
11272 case BO_AndAssign:
11273 case BO_XorAssign:
11274 case BO_OrAssign:
11275 case BO_Assign:
11276 case BO_AddAssign:
11277 case BO_SubAssign:
11278 case BO_DivAssign:
11279 case BO_RemAssign:
11280 case BO_ShlAssign:
11281 case BO_ShrAssign:
11282 case BO_Comma:
11283 llvm_unreachable("Unexpected reduction operation");
11284 }
11285 }
11286 if (Init && DeclareReductionRef.isUnset())
11287 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
11288 else if (!Init)
11289 S.ActOnUninitializedDecl(RHSVD);
11290 if (RHSVD->isInvalidDecl())
11291 continue;
11292 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
11293 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11294 << Type << ReductionIdRange;
11295 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11296 VarDecl::DeclarationOnly;
11297 S.Diag(D->getLocation(),
11298 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11299 << D;
11300 continue;
11301 }
11302 // Store initializer for single element in private copy. Will be used during
11303 // codegen.
11304 PrivateVD->setInit(RHSVD->getInit());
11305 PrivateVD->setInitStyle(RHSVD->getInitStyle());
11306 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
11307 ExprResult ReductionOp;
11308 if (DeclareReductionRef.isUsable()) {
11309 QualType RedTy = DeclareReductionRef.get()->getType();
11310 QualType PtrRedTy = Context.getPointerType(RedTy);
11311 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
11312 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
11313 if (!BasePath.empty()) {
11314 LHS = S.DefaultLvalueConversion(LHS.get());
11315 RHS = S.DefaultLvalueConversion(RHS.get());
11316 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11317 CK_UncheckedDerivedToBase, LHS.get(),
11318 &BasePath, LHS.get()->getValueKind());
11319 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11320 CK_UncheckedDerivedToBase, RHS.get(),
11321 &BasePath, RHS.get()->getValueKind());
11322 }
11323 FunctionProtoType::ExtProtoInfo EPI;
11324 QualType Params[] = {PtrRedTy, PtrRedTy};
11325 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
11326 auto *OVE = new (Context) OpaqueValueExpr(
11327 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
11328 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
11329 Expr *Args[] = {LHS.get(), RHS.get()};
11330 ReductionOp =
11331 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
11332 } else {
11333 ReductionOp = S.BuildBinOp(
11334 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11335 if (ReductionOp.isUsable()) {
11336 if (BOK != BO_LT && BOK != BO_GT) {
11337 ReductionOp =
11338 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11339 BO_Assign, LHSDRE, ReductionOp.get());
11340 } else {
11341 auto *ConditionalOp = new (Context)
11342 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
11343 Type, VK_LValue, OK_Ordinary);
11344 ReductionOp =
11345 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11346 BO_Assign, LHSDRE, ConditionalOp);
11347 }
11348 if (ReductionOp.isUsable())
11349 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
11350 }
11351 if (!ReductionOp.isUsable())
11352 continue;
11353 }
11354
11355 // OpenMP [2.15.4.6, Restrictions, p.2]
11356 // A list item that appears in an in_reduction clause of a task construct
11357 // must appear in a task_reduction clause of a construct associated with a
11358 // taskgroup region that includes the participating task in its taskgroup
11359 // set. The construct associated with the innermost region that meets this
11360 // condition must specify the same reduction-identifier as the in_reduction
11361 // clause.
11362 if (ClauseKind == OMPC_in_reduction) {
11363 SourceRange ParentSR;
11364 BinaryOperatorKind ParentBOK;
11365 const Expr *ParentReductionOp;
11366 Expr *ParentBOKTD, *ParentReductionOpTD;
11367 DSAStackTy::DSAVarData ParentBOKDSA =
11368 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11369 ParentBOKTD);
11370 DSAStackTy::DSAVarData ParentReductionOpDSA =
11371 Stack->getTopMostTaskgroupReductionData(
11372 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11373 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
11374 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
11375 if (!IsParentBOK && !IsParentReductionOp) {
11376 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11377 continue;
11378 }
11379 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
11380 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
11381 IsParentReductionOp) {
11382 bool EmitError = true;
11383 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
11384 llvm::FoldingSetNodeID RedId, ParentRedId;
11385 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
11386 DeclareReductionRef.get()->Profile(RedId, Context,
11387 /*Canonical=*/true);
11388 EmitError = RedId != ParentRedId;
11389 }
11390 if (EmitError) {
11391 S.Diag(ReductionId.getBeginLoc(),
11392 diag::err_omp_reduction_identifier_mismatch)
11393 << ReductionIdRange << RefExpr->getSourceRange();
11394 S.Diag(ParentSR.getBegin(),
11395 diag::note_omp_previous_reduction_identifier)
11396 << ParentSR
11397 << (IsParentBOK ? ParentBOKDSA.RefExpr
11398 : ParentReductionOpDSA.RefExpr)
11399 ->getSourceRange();
11400 continue;
11401 }
11402 }
11403 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11404 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
11405 }
11406
11407 DeclRefExpr *Ref = nullptr;
11408 Expr *VarsExpr = RefExpr->IgnoreParens();
11409 if (!VD && !S.CurContext->isDependentContext()) {
11410 if (ASE || OASE) {
11411 TransformExprToCaptures RebuildToCapture(S, D);
11412 VarsExpr =
11413 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
11414 Ref = RebuildToCapture.getCapturedExpr();
11415 } else {
11416 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
11417 }
11418 if (!S.isOpenMPCapturedDecl(D)) {
11419 RD.ExprCaptures.emplace_back(Ref->getDecl());
11420 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11421 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
11422 if (!RefRes.isUsable())
11423 continue;
11424 ExprResult PostUpdateRes =
11425 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11426 RefRes.get());
11427 if (!PostUpdateRes.isUsable())
11428 continue;
11429 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
11430 Stack->getCurrentDirective() == OMPD_taskgroup) {
11431 S.Diag(RefExpr->getExprLoc(),
11432 diag::err_omp_reduction_non_addressable_expression)
11433 << RefExpr->getSourceRange();
11434 continue;
11435 }
11436 RD.ExprPostUpdates.emplace_back(
11437 S.IgnoredValueConversions(PostUpdateRes.get()).get());
11438 }
11439 }
11440 }
11441 // All reduction items are still marked as reduction (to do not increase
11442 // code base size).
11443 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11444 if (CurrDir == OMPD_taskgroup) {
11445 if (DeclareReductionRef.isUsable())
11446 Stack->addTaskgroupReductionData(D, ReductionIdRange,
11447 DeclareReductionRef.get());
11448 else
11449 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11450 }
11451 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
11452 TaskgroupDescriptor);
11453 }
11454 return RD.Vars.empty();
11455 }
11456
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)11457 OMPClause *Sema::ActOnOpenMPReductionClause(
11458 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11459 SourceLocation ColonLoc, SourceLocation EndLoc,
11460 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11461 ArrayRef<Expr *> UnresolvedReductions) {
11462 ReductionData RD(VarList.size());
11463 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
11464 StartLoc, LParenLoc, ColonLoc, EndLoc,
11465 ReductionIdScopeSpec, ReductionId,
11466 UnresolvedReductions, RD))
11467 return nullptr;
11468
11469 return OMPReductionClause::Create(
11470 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11471 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11472 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11473 buildPreInits(Context, RD.ExprCaptures),
11474 buildPostUpdate(*this, RD.ExprPostUpdates));
11475 }
11476
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)11477 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
11478 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11479 SourceLocation ColonLoc, SourceLocation EndLoc,
11480 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11481 ArrayRef<Expr *> UnresolvedReductions) {
11482 ReductionData RD(VarList.size());
11483 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
11484 StartLoc, LParenLoc, ColonLoc, EndLoc,
11485 ReductionIdScopeSpec, ReductionId,
11486 UnresolvedReductions, RD))
11487 return nullptr;
11488
11489 return OMPTaskReductionClause::Create(
11490 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11491 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11492 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11493 buildPreInits(Context, RD.ExprCaptures),
11494 buildPostUpdate(*this, RD.ExprPostUpdates));
11495 }
11496
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)11497 OMPClause *Sema::ActOnOpenMPInReductionClause(
11498 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11499 SourceLocation ColonLoc, SourceLocation EndLoc,
11500 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11501 ArrayRef<Expr *> UnresolvedReductions) {
11502 ReductionData RD(VarList.size());
11503 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
11504 StartLoc, LParenLoc, ColonLoc, EndLoc,
11505 ReductionIdScopeSpec, ReductionId,
11506 UnresolvedReductions, RD))
11507 return nullptr;
11508
11509 return OMPInReductionClause::Create(
11510 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11511 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11512 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
11513 buildPreInits(Context, RD.ExprCaptures),
11514 buildPostUpdate(*this, RD.ExprPostUpdates));
11515 }
11516
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)11517 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
11518 SourceLocation LinLoc) {
11519 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
11520 LinKind == OMPC_LINEAR_unknown) {
11521 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
11522 return true;
11523 }
11524 return false;
11525 }
11526
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type)11527 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
11528 OpenMPLinearClauseKind LinKind,
11529 QualType Type) {
11530 const auto *VD = dyn_cast_or_null<VarDecl>(D);
11531 // A variable must not have an incomplete type or a reference type.
11532 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
11533 return true;
11534 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
11535 !Type->isReferenceType()) {
11536 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
11537 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
11538 return true;
11539 }
11540 Type = Type.getNonReferenceType();
11541
11542 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
11543 // A variable that is privatized must not have a const-qualified type
11544 // unless it is of class type with a mutable member. This restriction does
11545 // not apply to the firstprivate clause.
11546 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
11547 return true;
11548
11549 // A list item must be of integral or pointer type.
11550 Type = Type.getUnqualifiedType().getCanonicalType();
11551 const auto *Ty = Type.getTypePtrOrNull();
11552 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11553 !Ty->isPointerType())) {
11554 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11555 if (D) {
11556 bool IsDecl =
11557 !VD ||
11558 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11559 Diag(D->getLocation(),
11560 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11561 << D;
11562 }
11563 return true;
11564 }
11565 return false;
11566 }
11567
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)11568 OMPClause *Sema::ActOnOpenMPLinearClause(
11569 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
11570 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
11571 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
11572 SmallVector<Expr *, 8> Vars;
11573 SmallVector<Expr *, 8> Privates;
11574 SmallVector<Expr *, 8> Inits;
11575 SmallVector<Decl *, 4> ExprCaptures;
11576 SmallVector<Expr *, 4> ExprPostUpdates;
11577 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11578 LinKind = OMPC_LINEAR_val;
11579 for (Expr *RefExpr : VarList) {
11580 assert(RefExpr && "NULL expr in OpenMP linear clause.");
11581 SourceLocation ELoc;
11582 SourceRange ERange;
11583 Expr *SimpleRefExpr = RefExpr;
11584 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11585 if (Res.second) {
11586 // It will be analyzed later.
11587 Vars.push_back(RefExpr);
11588 Privates.push_back(nullptr);
11589 Inits.push_back(nullptr);
11590 }
11591 ValueDecl *D = Res.first;
11592 if (!D)
11593 continue;
11594
11595 QualType Type = D->getType();
11596 auto *VD = dyn_cast<VarDecl>(D);
11597
11598 // OpenMP [2.14.3.7, linear clause]
11599 // A list-item cannot appear in more than one linear clause.
11600 // A list-item that appears in a linear clause cannot appear in any
11601 // other data-sharing attribute clause.
11602 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
11603 if (DVar.RefExpr) {
11604 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11605 << getOpenMPClauseName(OMPC_linear);
11606 reportOriginalDsa(*this, DSAStack, D, DVar);
11607 continue;
11608 }
11609
11610 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11611 continue;
11612 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
11613
11614 // Build private copy of original var.
11615 VarDecl *Private =
11616 buildVarDecl(*this, ELoc, Type, D->getName(),
11617 D->hasAttrs() ? &D->getAttrs() : nullptr,
11618 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11619 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
11620 // Build var to save initial value.
11621 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
11622 Expr *InitExpr;
11623 DeclRefExpr *Ref = nullptr;
11624 if (!VD && !CurContext->isDependentContext()) {
11625 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
11626 if (!isOpenMPCapturedDecl(D)) {
11627 ExprCaptures.push_back(Ref->getDecl());
11628 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11629 ExprResult RefRes = DefaultLvalueConversion(Ref);
11630 if (!RefRes.isUsable())
11631 continue;
11632 ExprResult PostUpdateRes =
11633 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11634 SimpleRefExpr, RefRes.get());
11635 if (!PostUpdateRes.isUsable())
11636 continue;
11637 ExprPostUpdates.push_back(
11638 IgnoredValueConversions(PostUpdateRes.get()).get());
11639 }
11640 }
11641 }
11642 if (LinKind == OMPC_LINEAR_uval)
11643 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11644 else
11645 InitExpr = VD ? SimpleRefExpr : Ref;
11646 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
11647 /*DirectInit=*/false);
11648 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
11649
11650 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11651 Vars.push_back((VD || CurContext->isDependentContext())
11652 ? RefExpr->IgnoreParens()
11653 : Ref);
11654 Privates.push_back(PrivateRef);
11655 Inits.push_back(InitRef);
11656 }
11657
11658 if (Vars.empty())
11659 return nullptr;
11660
11661 Expr *StepExpr = Step;
11662 Expr *CalcStepExpr = nullptr;
11663 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
11664 !Step->isInstantiationDependent() &&
11665 !Step->containsUnexpandedParameterPack()) {
11666 SourceLocation StepLoc = Step->getBeginLoc();
11667 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11668 if (Val.isInvalid())
11669 return nullptr;
11670 StepExpr = Val.get();
11671
11672 // Build var to save the step value.
11673 VarDecl *SaveVar =
11674 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
11675 ExprResult SaveRef =
11676 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
11677 ExprResult CalcStep =
11678 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11679 CalcStep = ActOnFinishFullExpr(CalcStep.get());
11680
11681 // Warn about zero linear step (it would be probably better specified as
11682 // making corresponding variables 'const').
11683 llvm::APSInt Result;
11684 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
11685 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11686 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11687 << (Vars.size() > 1);
11688 if (!IsConstant && CalcStep.isUsable()) {
11689 // Calculate the step beforehand instead of doing this on each iteration.
11690 // (This is not used if the number of iterations may be kfold-ed).
11691 CalcStepExpr = CalcStep.get();
11692 }
11693 }
11694
11695 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
11696 ColonLoc, EndLoc, Vars, Privates, Inits,
11697 StepExpr, CalcStepExpr,
11698 buildPreInits(Context, ExprCaptures),
11699 buildPostUpdate(*this, ExprPostUpdates));
11700 }
11701
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)11702 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
11703 Expr *NumIterations, Sema &SemaRef,
11704 Scope *S, DSAStackTy *Stack) {
11705 // Walk the vars and build update/final expressions for the CodeGen.
11706 SmallVector<Expr *, 8> Updates;
11707 SmallVector<Expr *, 8> Finals;
11708 Expr *Step = Clause.getStep();
11709 Expr *CalcStep = Clause.getCalcStep();
11710 // OpenMP [2.14.3.7, linear clause]
11711 // If linear-step is not specified it is assumed to be 1.
11712 if (!Step)
11713 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
11714 else if (CalcStep)
11715 Step = cast<BinaryOperator>(CalcStep)->getLHS();
11716 bool HasErrors = false;
11717 auto CurInit = Clause.inits().begin();
11718 auto CurPrivate = Clause.privates().begin();
11719 OpenMPLinearClauseKind LinKind = Clause.getModifier();
11720 for (Expr *RefExpr : Clause.varlists()) {
11721 SourceLocation ELoc;
11722 SourceRange ERange;
11723 Expr *SimpleRefExpr = RefExpr;
11724 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
11725 ValueDecl *D = Res.first;
11726 if (Res.second || !D) {
11727 Updates.push_back(nullptr);
11728 Finals.push_back(nullptr);
11729 HasErrors = true;
11730 continue;
11731 }
11732 auto &&Info = Stack->isLoopControlVariable(D);
11733 // OpenMP [2.15.11, distribute simd Construct]
11734 // A list item may not appear in a linear clause, unless it is the loop
11735 // iteration variable.
11736 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
11737 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
11738 SemaRef.Diag(ELoc,
11739 diag::err_omp_linear_distribute_var_non_loop_iteration);
11740 Updates.push_back(nullptr);
11741 Finals.push_back(nullptr);
11742 HasErrors = true;
11743 continue;
11744 }
11745 Expr *InitExpr = *CurInit;
11746
11747 // Build privatized reference to the current linear var.
11748 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11749 Expr *CapturedRef;
11750 if (LinKind == OMPC_LINEAR_uval)
11751 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11752 else
11753 CapturedRef =
11754 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11755 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11756 /*RefersToCapture=*/true);
11757
11758 // Build update: Var = InitExpr + IV * Step
11759 ExprResult Update;
11760 if (!Info.first)
11761 Update =
11762 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11763 InitExpr, IV, Step, /* Subtract */ false);
11764 else
11765 Update = *CurPrivate;
11766 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
11767 /*DiscardedValue=*/true);
11768
11769 // Build final: Var = InitExpr + NumIterations * Step
11770 ExprResult Final;
11771 if (!Info.first)
11772 Final =
11773 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11774 InitExpr, NumIterations, Step, /*Subtract=*/false);
11775 else
11776 Final = *CurPrivate;
11777 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
11778 /*DiscardedValue=*/true);
11779
11780 if (!Update.isUsable() || !Final.isUsable()) {
11781 Updates.push_back(nullptr);
11782 Finals.push_back(nullptr);
11783 HasErrors = true;
11784 } else {
11785 Updates.push_back(Update.get());
11786 Finals.push_back(Final.get());
11787 }
11788 ++CurInit;
11789 ++CurPrivate;
11790 }
11791 Clause.setUpdates(Updates);
11792 Clause.setFinals(Finals);
11793 return HasErrors;
11794 }
11795
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)11796 OMPClause *Sema::ActOnOpenMPAlignedClause(
11797 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11798 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
11799 SmallVector<Expr *, 8> Vars;
11800 for (Expr *RefExpr : VarList) {
11801 assert(RefExpr && "NULL expr in OpenMP linear clause.");
11802 SourceLocation ELoc;
11803 SourceRange ERange;
11804 Expr *SimpleRefExpr = RefExpr;
11805 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11806 if (Res.second) {
11807 // It will be analyzed later.
11808 Vars.push_back(RefExpr);
11809 }
11810 ValueDecl *D = Res.first;
11811 if (!D)
11812 continue;
11813
11814 QualType QType = D->getType();
11815 auto *VD = dyn_cast<VarDecl>(D);
11816
11817 // OpenMP [2.8.1, simd construct, Restrictions]
11818 // The type of list items appearing in the aligned clause must be
11819 // array, pointer, reference to array, or reference to pointer.
11820 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
11821 const Type *Ty = QType.getTypePtrOrNull();
11822 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11823 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11824 << QType << getLangOpts().CPlusPlus << ERange;
11825 bool IsDecl =
11826 !VD ||
11827 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11828 Diag(D->getLocation(),
11829 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11830 << D;
11831 continue;
11832 }
11833
11834 // OpenMP [2.8.1, simd construct, Restrictions]
11835 // A list-item cannot appear in more than one aligned clause.
11836 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11837 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11838 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11839 << getOpenMPClauseName(OMPC_aligned);
11840 continue;
11841 }
11842
11843 DeclRefExpr *Ref = nullptr;
11844 if (!VD && isOpenMPCapturedDecl(D))
11845 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11846 Vars.push_back(DefaultFunctionArrayConversion(
11847 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11848 .get());
11849 }
11850
11851 // OpenMP [2.8.1, simd construct, Description]
11852 // The parameter of the aligned clause, alignment, must be a constant
11853 // positive integer expression.
11854 // If no optional parameter is specified, implementation-defined default
11855 // alignments for SIMD instructions on the target platforms are assumed.
11856 if (Alignment != nullptr) {
11857 ExprResult AlignResult =
11858 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11859 if (AlignResult.isInvalid())
11860 return nullptr;
11861 Alignment = AlignResult.get();
11862 }
11863 if (Vars.empty())
11864 return nullptr;
11865
11866 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11867 EndLoc, Vars, Alignment);
11868 }
11869
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11870 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
11871 SourceLocation StartLoc,
11872 SourceLocation LParenLoc,
11873 SourceLocation EndLoc) {
11874 SmallVector<Expr *, 8> Vars;
11875 SmallVector<Expr *, 8> SrcExprs;
11876 SmallVector<Expr *, 8> DstExprs;
11877 SmallVector<Expr *, 8> AssignmentOps;
11878 for (Expr *RefExpr : VarList) {
11879 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
11880 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11881 // It will be analyzed later.
11882 Vars.push_back(RefExpr);
11883 SrcExprs.push_back(nullptr);
11884 DstExprs.push_back(nullptr);
11885 AssignmentOps.push_back(nullptr);
11886 continue;
11887 }
11888
11889 SourceLocation ELoc = RefExpr->getExprLoc();
11890 // OpenMP [2.1, C/C++]
11891 // A list item is a variable name.
11892 // OpenMP [2.14.4.1, Restrictions, p.1]
11893 // A list item that appears in a copyin clause must be threadprivate.
11894 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
11895 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11896 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11897 << 0 << RefExpr->getSourceRange();
11898 continue;
11899 }
11900
11901 Decl *D = DE->getDecl();
11902 auto *VD = cast<VarDecl>(D);
11903
11904 QualType Type = VD->getType();
11905 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11906 // It will be analyzed later.
11907 Vars.push_back(DE);
11908 SrcExprs.push_back(nullptr);
11909 DstExprs.push_back(nullptr);
11910 AssignmentOps.push_back(nullptr);
11911 continue;
11912 }
11913
11914 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11915 // A list item that appears in a copyin clause must be threadprivate.
11916 if (!DSAStack->isThreadPrivate(VD)) {
11917 Diag(ELoc, diag::err_omp_required_access)
11918 << getOpenMPClauseName(OMPC_copyin)
11919 << getOpenMPDirectiveName(OMPD_threadprivate);
11920 continue;
11921 }
11922
11923 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11924 // A variable of class type (or array thereof) that appears in a
11925 // copyin clause requires an accessible, unambiguous copy assignment
11926 // operator for the class type.
11927 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11928 VarDecl *SrcVD =
11929 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
11930 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11931 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
11932 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11933 VarDecl *DstVD =
11934 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
11935 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11936 DeclRefExpr *PseudoDstExpr =
11937 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11938 // For arrays generate assignment operation for single element and replace
11939 // it by the original array element in CodeGen.
11940 ExprResult AssignmentOp =
11941 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11942 PseudoSrcExpr);
11943 if (AssignmentOp.isInvalid())
11944 continue;
11945 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11946 /*DiscardedValue=*/true);
11947 if (AssignmentOp.isInvalid())
11948 continue;
11949
11950 DSAStack->addDSA(VD, DE, OMPC_copyin);
11951 Vars.push_back(DE);
11952 SrcExprs.push_back(PseudoSrcExpr);
11953 DstExprs.push_back(PseudoDstExpr);
11954 AssignmentOps.push_back(AssignmentOp.get());
11955 }
11956
11957 if (Vars.empty())
11958 return nullptr;
11959
11960 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11961 SrcExprs, DstExprs, AssignmentOps);
11962 }
11963
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11964 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
11965 SourceLocation StartLoc,
11966 SourceLocation LParenLoc,
11967 SourceLocation EndLoc) {
11968 SmallVector<Expr *, 8> Vars;
11969 SmallVector<Expr *, 8> SrcExprs;
11970 SmallVector<Expr *, 8> DstExprs;
11971 SmallVector<Expr *, 8> AssignmentOps;
11972 for (Expr *RefExpr : VarList) {
11973 assert(RefExpr && "NULL expr in OpenMP linear clause.");
11974 SourceLocation ELoc;
11975 SourceRange ERange;
11976 Expr *SimpleRefExpr = RefExpr;
11977 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11978 if (Res.second) {
11979 // It will be analyzed later.
11980 Vars.push_back(RefExpr);
11981 SrcExprs.push_back(nullptr);
11982 DstExprs.push_back(nullptr);
11983 AssignmentOps.push_back(nullptr);
11984 }
11985 ValueDecl *D = Res.first;
11986 if (!D)
11987 continue;
11988
11989 QualType Type = D->getType();
11990 auto *VD = dyn_cast<VarDecl>(D);
11991
11992 // OpenMP [2.14.4.2, Restrictions, p.2]
11993 // A list item that appears in a copyprivate clause may not appear in a
11994 // private or firstprivate clause on the single construct.
11995 if (!VD || !DSAStack->isThreadPrivate(VD)) {
11996 DSAStackTy::DSAVarData DVar =
11997 DSAStack->getTopDSA(D, /*FromParent=*/false);
11998 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11999 DVar.RefExpr) {
12000 Diag(ELoc, diag::err_omp_wrong_dsa)
12001 << getOpenMPClauseName(DVar.CKind)
12002 << getOpenMPClauseName(OMPC_copyprivate);
12003 reportOriginalDsa(*this, DSAStack, D, DVar);
12004 continue;
12005 }
12006
12007 // OpenMP [2.11.4.2, Restrictions, p.1]
12008 // All list items that appear in a copyprivate clause must be either
12009 // threadprivate or private in the enclosing context.
12010 if (DVar.CKind == OMPC_unknown) {
12011 DVar = DSAStack->getImplicitDSA(D, false);
12012 if (DVar.CKind == OMPC_shared) {
12013 Diag(ELoc, diag::err_omp_required_access)
12014 << getOpenMPClauseName(OMPC_copyprivate)
12015 << "threadprivate or private in the enclosing context";
12016 reportOriginalDsa(*this, DSAStack, D, DVar);
12017 continue;
12018 }
12019 }
12020 }
12021
12022 // Variably modified types are not supported.
12023 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
12024 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12025 << getOpenMPClauseName(OMPC_copyprivate) << Type
12026 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12027 bool IsDecl =
12028 !VD ||
12029 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12030 Diag(D->getLocation(),
12031 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12032 << D;
12033 continue;
12034 }
12035
12036 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12037 // A variable of class type (or array thereof) that appears in a
12038 // copyin clause requires an accessible, unambiguous copy assignment
12039 // operator for the class type.
12040 Type = Context.getBaseElementType(Type.getNonReferenceType())
12041 .getUnqualifiedType();
12042 VarDecl *SrcVD =
12043 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
12044 D->hasAttrs() ? &D->getAttrs() : nullptr);
12045 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
12046 VarDecl *DstVD =
12047 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
12048 D->hasAttrs() ? &D->getAttrs() : nullptr);
12049 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12050 ExprResult AssignmentOp = BuildBinOp(
12051 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12052 if (AssignmentOp.isInvalid())
12053 continue;
12054 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
12055 /*DiscardedValue=*/true);
12056 if (AssignmentOp.isInvalid())
12057 continue;
12058
12059 // No need to mark vars as copyprivate, they are already threadprivate or
12060 // implicitly private.
12061 assert(VD || isOpenMPCapturedDecl(D));
12062 Vars.push_back(
12063 VD ? RefExpr->IgnoreParens()
12064 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
12065 SrcExprs.push_back(PseudoSrcExpr);
12066 DstExprs.push_back(PseudoDstExpr);
12067 AssignmentOps.push_back(AssignmentOp.get());
12068 }
12069
12070 if (Vars.empty())
12071 return nullptr;
12072
12073 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12074 Vars, SrcExprs, DstExprs, AssignmentOps);
12075 }
12076
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12077 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
12078 SourceLocation StartLoc,
12079 SourceLocation LParenLoc,
12080 SourceLocation EndLoc) {
12081 if (VarList.empty())
12082 return nullptr;
12083
12084 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
12085 }
12086
12087 OMPClause *
ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12088 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
12089 SourceLocation DepLoc, SourceLocation ColonLoc,
12090 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12091 SourceLocation LParenLoc, SourceLocation EndLoc) {
12092 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
12093 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12094 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12095 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
12096 return nullptr;
12097 }
12098 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
12099 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
12100 DepKind == OMPC_DEPEND_sink)) {
12101 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
12102 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12103 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12104 /*Last=*/OMPC_DEPEND_unknown, Except)
12105 << getOpenMPClauseName(OMPC_depend);
12106 return nullptr;
12107 }
12108 SmallVector<Expr *, 8> Vars;
12109 DSAStackTy::OperatorOffsetTy OpsOffs;
12110 llvm::APSInt DepCounter(/*BitWidth=*/32);
12111 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
12112 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12113 if (const Expr *OrderedCountExpr =
12114 DSAStack->getParentOrderedRegionParam().first) {
12115 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12116 TotalDepCount.setIsUnsigned(/*Val=*/true);
12117 }
12118 }
12119 for (Expr *RefExpr : VarList) {
12120 assert(RefExpr && "NULL expr in OpenMP shared clause.");
12121 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12122 // It will be analyzed later.
12123 Vars.push_back(RefExpr);
12124 continue;
12125 }
12126
12127 SourceLocation ELoc = RefExpr->getExprLoc();
12128 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
12129 if (DepKind == OMPC_DEPEND_sink) {
12130 if (DSAStack->getParentOrderedRegionParam().first &&
12131 DepCounter >= TotalDepCount) {
12132 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12133 continue;
12134 }
12135 ++DepCounter;
12136 // OpenMP [2.13.9, Summary]
12137 // depend(dependence-type : vec), where dependence-type is:
12138 // 'sink' and where vec is the iteration vector, which has the form:
12139 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
12140 // where n is the value specified by the ordered clause in the loop
12141 // directive, xi denotes the loop iteration variable of the i-th nested
12142 // loop associated with the loop directive, and di is a constant
12143 // non-negative integer.
12144 if (CurContext->isDependentContext()) {
12145 // It will be analyzed later.
12146 Vars.push_back(RefExpr);
12147 continue;
12148 }
12149 SimpleExpr = SimpleExpr->IgnoreImplicit();
12150 OverloadedOperatorKind OOK = OO_None;
12151 SourceLocation OOLoc;
12152 Expr *LHS = SimpleExpr;
12153 Expr *RHS = nullptr;
12154 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12155 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
12156 OOLoc = BO->getOperatorLoc();
12157 LHS = BO->getLHS()->IgnoreParenImpCasts();
12158 RHS = BO->getRHS()->IgnoreParenImpCasts();
12159 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12160 OOK = OCE->getOperator();
12161 OOLoc = OCE->getOperatorLoc();
12162 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12163 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
12164 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12165 OOK = MCE->getMethodDecl()
12166 ->getNameInfo()
12167 .getName()
12168 .getCXXOverloadedOperator();
12169 OOLoc = MCE->getCallee()->getExprLoc();
12170 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
12171 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12172 }
12173 SourceLocation ELoc;
12174 SourceRange ERange;
12175 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
12176 if (Res.second) {
12177 // It will be analyzed later.
12178 Vars.push_back(RefExpr);
12179 }
12180 ValueDecl *D = Res.first;
12181 if (!D)
12182 continue;
12183
12184 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
12185 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12186 continue;
12187 }
12188 if (RHS) {
12189 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12190 RHS, OMPC_depend, /*StrictlyPositive=*/false);
12191 if (RHSRes.isInvalid())
12192 continue;
12193 }
12194 if (!CurContext->isDependentContext() &&
12195 DSAStack->getParentOrderedRegionParam().first &&
12196 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
12197 const ValueDecl *VD =
12198 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12199 if (VD)
12200 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12201 << 1 << VD;
12202 else
12203 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12204 continue;
12205 }
12206 OpsOffs.emplace_back(RHS, OOK);
12207 } else {
12208 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
12209 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12210 (ASE &&
12211 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12212 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12213 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12214 << RefExpr->getSourceRange();
12215 continue;
12216 }
12217 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12218 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
12219 ExprResult Res =
12220 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12221 getDiagnostics().setSuppressAllDiagnostics(Suppress);
12222 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12223 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12224 << RefExpr->getSourceRange();
12225 continue;
12226 }
12227 }
12228 Vars.push_back(RefExpr->IgnoreParenImpCasts());
12229 }
12230
12231 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12232 TotalDepCount > VarList.size() &&
12233 DSAStack->getParentOrderedRegionParam().first &&
12234 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12235 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12236 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12237 }
12238 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12239 Vars.empty())
12240 return nullptr;
12241
12242 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12243 DepKind, DepLoc, ColonLoc, Vars,
12244 TotalDepCount.getZExtValue());
12245 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12246 DSAStack->isParentOrderedRegion())
12247 DSAStack->addDoacrossDependClause(C, OpsOffs);
12248 return C;
12249 }
12250
ActOnOpenMPDeviceClause(Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12251 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
12252 SourceLocation LParenLoc,
12253 SourceLocation EndLoc) {
12254 Expr *ValExpr = Device;
12255 Stmt *HelperValStmt = nullptr;
12256
12257 // OpenMP [2.9.1, Restrictions]
12258 // The device expression must evaluate to a non-negative integer value.
12259 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
12260 /*StrictlyPositive=*/false))
12261 return nullptr;
12262
12263 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12264 OpenMPDirectiveKind CaptureRegion =
12265 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
12266 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12267 ValExpr = MakeFullExpr(ValExpr).get();
12268 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12269 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12270 HelperValStmt = buildPreInits(Context, Captures);
12271 }
12272
12273 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12274 StartLoc, LParenLoc, EndLoc);
12275 }
12276
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)12277 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
12278 DSAStackTy *Stack, QualType QTy,
12279 bool FullCheck = true) {
12280 NamedDecl *ND;
12281 if (QTy->isIncompleteType(&ND)) {
12282 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
12283 return false;
12284 }
12285 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
12286 !QTy.isTrivialType(SemaRef.Context))
12287 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12288 return true;
12289 }
12290
12291 /// Return true if it can be proven that the provided array expression
12292 /// (array section or array subscript) does NOT specify the whole size of the
12293 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)12294 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
12295 const Expr *E,
12296 QualType BaseQTy) {
12297 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12298
12299 // If this is an array subscript, it refers to the whole size if the size of
12300 // the dimension is constant and equals 1. Also, an array section assumes the
12301 // format of an array subscript if no colon is used.
12302 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12303 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12304 return ATy->getSize().getSExtValue() != 1;
12305 // Size can't be evaluated statically.
12306 return false;
12307 }
12308
12309 assert(OASE && "Expecting array section if not an array subscript.");
12310 const Expr *LowerBound = OASE->getLowerBound();
12311 const Expr *Length = OASE->getLength();
12312
12313 // If there is a lower bound that does not evaluates to zero, we are not
12314 // covering the whole dimension.
12315 if (LowerBound) {
12316 Expr::EvalResult Result;
12317 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
12318 return false; // Can't get the integer value as a constant.
12319
12320 llvm::APSInt ConstLowerBound = Result.Val.getInt();
12321 if (ConstLowerBound.getSExtValue())
12322 return true;
12323 }
12324
12325 // If we don't have a length we covering the whole dimension.
12326 if (!Length)
12327 return false;
12328
12329 // If the base is a pointer, we don't have a way to get the size of the
12330 // pointee.
12331 if (BaseQTy->isPointerType())
12332 return false;
12333
12334 // We can only check if the length is the same as the size of the dimension
12335 // if we have a constant array.
12336 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
12337 if (!CATy)
12338 return false;
12339
12340 Expr::EvalResult Result;
12341 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12342 return false; // Can't get the integer value as a constant.
12343
12344 llvm::APSInt ConstLength = Result.Val.getInt();
12345 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12346 }
12347
12348 // Return true if it can be proven that the provided array expression (array
12349 // section or array subscript) does NOT specify a single element of the array
12350 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)12351 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
12352 const Expr *E,
12353 QualType BaseQTy) {
12354 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12355
12356 // An array subscript always refer to a single element. Also, an array section
12357 // assumes the format of an array subscript if no colon is used.
12358 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12359 return false;
12360
12361 assert(OASE && "Expecting array section if not an array subscript.");
12362 const Expr *Length = OASE->getLength();
12363
12364 // If we don't have a length we have to check if the array has unitary size
12365 // for this dimension. Also, we should always expect a length if the base type
12366 // is pointer.
12367 if (!Length) {
12368 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12369 return ATy->getSize().getSExtValue() != 1;
12370 // We cannot assume anything.
12371 return false;
12372 }
12373
12374 // Check if the length evaluates to 1.
12375 Expr::EvalResult Result;
12376 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12377 return false; // Can't get the integer value as a constant.
12378
12379 llvm::APSInt ConstLength = Result.Val.getInt();
12380 return ConstLength.getSExtValue() != 1;
12381 }
12382
12383 // Return the expression of the base of the mappable expression or null if it
12384 // cannot be determined and do all the necessary checks to see if the expression
12385 // is valid as a standalone mappable expression. In the process, record all the
12386 // components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,bool NoDiagnose)12387 static const Expr *checkMapClauseExpressionBase(
12388 Sema &SemaRef, Expr *E,
12389 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
12390 OpenMPClauseKind CKind, bool NoDiagnose) {
12391 SourceLocation ELoc = E->getExprLoc();
12392 SourceRange ERange = E->getSourceRange();
12393
12394 // The base of elements of list in a map clause have to be either:
12395 // - a reference to variable or field.
12396 // - a member expression.
12397 // - an array expression.
12398 //
12399 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
12400 // reference to 'r'.
12401 //
12402 // If we have:
12403 //
12404 // struct SS {
12405 // Bla S;
12406 // foo() {
12407 // #pragma omp target map (S.Arr[:12]);
12408 // }
12409 // }
12410 //
12411 // We want to retrieve the member expression 'this->S';
12412
12413 const Expr *RelevantExpr = nullptr;
12414
12415 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
12416 // If a list item is an array section, it must specify contiguous storage.
12417 //
12418 // For this restriction it is sufficient that we make sure only references
12419 // to variables or fields and array expressions, and that no array sections
12420 // exist except in the rightmost expression (unless they cover the whole
12421 // dimension of the array). E.g. these would be invalid:
12422 //
12423 // r.ArrS[3:5].Arr[6:7]
12424 //
12425 // r.ArrS[3:5].x
12426 //
12427 // but these would be valid:
12428 // r.ArrS[3].Arr[6:7]
12429 //
12430 // r.ArrS[3].x
12431
12432 bool AllowUnitySizeArraySection = true;
12433 bool AllowWholeSizeArraySection = true;
12434
12435 while (!RelevantExpr) {
12436 E = E->IgnoreParenImpCasts();
12437
12438 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12439 if (!isa<VarDecl>(CurE->getDecl()))
12440 return nullptr;
12441
12442 RelevantExpr = CurE;
12443
12444 // If we got a reference to a declaration, we should not expect any array
12445 // section before that.
12446 AllowUnitySizeArraySection = false;
12447 AllowWholeSizeArraySection = false;
12448
12449 // Record the component.
12450 CurComponents.emplace_back(CurE, CurE->getDecl());
12451 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
12452 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
12453
12454 if (isa<CXXThisExpr>(BaseE))
12455 // We found a base expression: this->Val.
12456 RelevantExpr = CurE;
12457 else
12458 E = BaseE;
12459
12460 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12461 if (!NoDiagnose) {
12462 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12463 << CurE->getSourceRange();
12464 return nullptr;
12465 }
12466 if (RelevantExpr)
12467 return nullptr;
12468 continue;
12469 }
12470
12471 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12472
12473 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
12474 // A bit-field cannot appear in a map clause.
12475 //
12476 if (FD->isBitField()) {
12477 if (!NoDiagnose) {
12478 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12479 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
12480 return nullptr;
12481 }
12482 if (RelevantExpr)
12483 return nullptr;
12484 continue;
12485 }
12486
12487 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12488 // If the type of a list item is a reference to a type T then the type
12489 // will be considered to be T for all purposes of this clause.
12490 QualType CurType = BaseE->getType().getNonReferenceType();
12491
12492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
12493 // A list item cannot be a variable that is a member of a structure with
12494 // a union type.
12495 //
12496 if (CurType->isUnionType()) {
12497 if (!NoDiagnose) {
12498 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
12499 << CurE->getSourceRange();
12500 return nullptr;
12501 }
12502 continue;
12503 }
12504
12505 // If we got a member expression, we should not expect any array section
12506 // before that:
12507 //
12508 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
12509 // If a list item is an element of a structure, only the rightmost symbol
12510 // of the variable reference can be an array section.
12511 //
12512 AllowUnitySizeArraySection = false;
12513 AllowWholeSizeArraySection = false;
12514
12515 // Record the component.
12516 CurComponents.emplace_back(CurE, FD);
12517 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
12518 E = CurE->getBase()->IgnoreParenImpCasts();
12519
12520 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
12521 if (!NoDiagnose) {
12522 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12523 << 0 << CurE->getSourceRange();
12524 return nullptr;
12525 }
12526 continue;
12527 }
12528
12529 // If we got an array subscript that express the whole dimension we
12530 // can have any array expressions before. If it only expressing part of
12531 // the dimension, we can only have unitary-size array expressions.
12532 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
12533 E->getType()))
12534 AllowWholeSizeArraySection = false;
12535
12536 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12537 Expr::EvalResult Result;
12538 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
12539 if (!Result.Val.getInt().isNullValue()) {
12540 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12541 diag::err_omp_invalid_map_this_expr);
12542 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12543 diag::note_omp_invalid_subscript_on_this_ptr_map);
12544 }
12545 }
12546 RelevantExpr = TE;
12547 }
12548
12549 // Record the component - we don't have any declaration associated.
12550 CurComponents.emplace_back(CurE, nullptr);
12551 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
12552 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
12553 E = CurE->getBase()->IgnoreParenImpCasts();
12554
12555 QualType CurType =
12556 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
12557
12558 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12559 // If the type of a list item is a reference to a type T then the type
12560 // will be considered to be T for all purposes of this clause.
12561 if (CurType->isReferenceType())
12562 CurType = CurType->getPointeeType();
12563
12564 bool IsPointer = CurType->isAnyPointerType();
12565
12566 if (!IsPointer && !CurType->isArrayType()) {
12567 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12568 << 0 << CurE->getSourceRange();
12569 return nullptr;
12570 }
12571
12572 bool NotWhole =
12573 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
12574 bool NotUnity =
12575 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
12576
12577 if (AllowWholeSizeArraySection) {
12578 // Any array section is currently allowed. Allowing a whole size array
12579 // section implies allowing a unity array section as well.
12580 //
12581 // If this array section refers to the whole dimension we can still
12582 // accept other array sections before this one, except if the base is a
12583 // pointer. Otherwise, only unitary sections are accepted.
12584 if (NotWhole || IsPointer)
12585 AllowWholeSizeArraySection = false;
12586 } else if (AllowUnitySizeArraySection && NotUnity) {
12587 // A unity or whole array section is not allowed and that is not
12588 // compatible with the properties of the current array section.
12589 SemaRef.Diag(
12590 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12591 << CurE->getSourceRange();
12592 return nullptr;
12593 }
12594
12595 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12596 Expr::EvalResult ResultR;
12597 Expr::EvalResult ResultL;
12598 if (CurE->getLength()->EvaluateAsInt(ResultR,
12599 SemaRef.getASTContext())) {
12600 if (!ResultR.Val.getInt().isOneValue()) {
12601 SemaRef.Diag(CurE->getLength()->getExprLoc(),
12602 diag::err_omp_invalid_map_this_expr);
12603 SemaRef.Diag(CurE->getLength()->getExprLoc(),
12604 diag::note_omp_invalid_length_on_this_ptr_mapping);
12605 }
12606 }
12607 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
12608 ResultL, SemaRef.getASTContext())) {
12609 if (!ResultL.Val.getInt().isNullValue()) {
12610 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12611 diag::err_omp_invalid_map_this_expr);
12612 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12613 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
12614 }
12615 }
12616 RelevantExpr = TE;
12617 }
12618
12619 // Record the component - we don't have any declaration associated.
12620 CurComponents.emplace_back(CurE, nullptr);
12621 } else {
12622 if (!NoDiagnose) {
12623 // If nothing else worked, this is not a valid map clause expression.
12624 SemaRef.Diag(
12625 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12626 << ERange;
12627 }
12628 return nullptr;
12629 }
12630 }
12631
12632 return RelevantExpr;
12633 }
12634
12635 // Return true if expression E associated with value VD has conflicts with other
12636 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)12637 static bool checkMapConflicts(
12638 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
12639 bool CurrentRegionOnly,
12640 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
12641 OpenMPClauseKind CKind) {
12642 assert(VD && E);
12643 SourceLocation ELoc = E->getExprLoc();
12644 SourceRange ERange = E->getSourceRange();
12645
12646 // In order to easily check the conflicts we need to match each component of
12647 // the expression under test with the components of the expressions that are
12648 // already in the stack.
12649
12650 assert(!CurComponents.empty() && "Map clause expression with no components!");
12651 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12652 "Map clause expression with unexpected base!");
12653
12654 // Variables to help detecting enclosing problems in data environment nests.
12655 bool IsEnclosedByDataEnvironmentExpr = false;
12656 const Expr *EnclosingExpr = nullptr;
12657
12658 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12659 VD, CurrentRegionOnly,
12660 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12661 ERange, CKind, &EnclosingExpr,
12662 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
12663 StackComponents,
12664 OpenMPClauseKind) {
12665 assert(!StackComponents.empty() &&
12666 "Map clause expression with no components!");
12667 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12668 "Map clause expression with unexpected base!");
12669 (void)VD;
12670
12671 // The whole expression in the stack.
12672 const Expr *RE = StackComponents.front().getAssociatedExpression();
12673
12674 // Expressions must start from the same base. Here we detect at which
12675 // point both expressions diverge from each other and see if we can
12676 // detect if the memory referred to both expressions is contiguous and
12677 // do not overlap.
12678 auto CI = CurComponents.rbegin();
12679 auto CE = CurComponents.rend();
12680 auto SI = StackComponents.rbegin();
12681 auto SE = StackComponents.rend();
12682 for (; CI != CE && SI != SE; ++CI, ++SI) {
12683
12684 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
12685 // At most one list item can be an array item derived from a given
12686 // variable in map clauses of the same construct.
12687 if (CurrentRegionOnly &&
12688 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12689 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12690 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12691 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12692 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
12693 diag::err_omp_multiple_array_items_in_map_clause)
12694 << CI->getAssociatedExpression()->getSourceRange();
12695 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
12696 diag::note_used_here)
12697 << SI->getAssociatedExpression()->getSourceRange();
12698 return true;
12699 }
12700
12701 // Do both expressions have the same kind?
12702 if (CI->getAssociatedExpression()->getStmtClass() !=
12703 SI->getAssociatedExpression()->getStmtClass())
12704 break;
12705
12706 // Are we dealing with different variables/fields?
12707 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12708 break;
12709 }
12710 // Check if the extra components of the expressions in the enclosing
12711 // data environment are redundant for the current base declaration.
12712 // If they are, the maps completely overlap, which is legal.
12713 for (; SI != SE; ++SI) {
12714 QualType Type;
12715 if (const auto *ASE =
12716 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12717 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12718 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12719 SI->getAssociatedExpression())) {
12720 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
12721 Type =
12722 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
12723 }
12724 if (Type.isNull() || Type->isAnyPointerType() ||
12725 checkArrayExpressionDoesNotReferToWholeSize(
12726 SemaRef, SI->getAssociatedExpression(), Type))
12727 break;
12728 }
12729
12730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12731 // List items of map clauses in the same construct must not share
12732 // original storage.
12733 //
12734 // If the expressions are exactly the same or one is a subset of the
12735 // other, it means they are sharing storage.
12736 if (CI == CE && SI == SE) {
12737 if (CurrentRegionOnly) {
12738 if (CKind == OMPC_map) {
12739 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12740 } else {
12741 assert(CKind == OMPC_to || CKind == OMPC_from);
12742 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12743 << ERange;
12744 }
12745 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12746 << RE->getSourceRange();
12747 return true;
12748 }
12749 // If we find the same expression in the enclosing data environment,
12750 // that is legal.
12751 IsEnclosedByDataEnvironmentExpr = true;
12752 return false;
12753 }
12754
12755 QualType DerivedType =
12756 std::prev(CI)->getAssociatedDeclaration()->getType();
12757 SourceLocation DerivedLoc =
12758 std::prev(CI)->getAssociatedExpression()->getExprLoc();
12759
12760 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12761 // If the type of a list item is a reference to a type T then the type
12762 // will be considered to be T for all purposes of this clause.
12763 DerivedType = DerivedType.getNonReferenceType();
12764
12765 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
12766 // A variable for which the type is pointer and an array section
12767 // derived from that variable must not appear as list items of map
12768 // clauses of the same construct.
12769 //
12770 // Also, cover one of the cases in:
12771 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12772 // If any part of the original storage of a list item has corresponding
12773 // storage in the device data environment, all of the original storage
12774 // must have corresponding storage in the device data environment.
12775 //
12776 if (DerivedType->isAnyPointerType()) {
12777 if (CI == CE || SI == SE) {
12778 SemaRef.Diag(
12779 DerivedLoc,
12780 diag::err_omp_pointer_mapped_along_with_derived_section)
12781 << DerivedLoc;
12782 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12783 << RE->getSourceRange();
12784 return true;
12785 }
12786 if (CI->getAssociatedExpression()->getStmtClass() !=
12787 SI->getAssociatedExpression()->getStmtClass() ||
12788 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12789 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12790 assert(CI != CE && SI != SE);
12791 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12792 << DerivedLoc;
12793 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12794 << RE->getSourceRange();
12795 return true;
12796 }
12797 }
12798
12799 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12800 // List items of map clauses in the same construct must not share
12801 // original storage.
12802 //
12803 // An expression is a subset of the other.
12804 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12805 if (CKind == OMPC_map) {
12806 if (CI != CE || SI != SE) {
12807 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
12808 // a pointer.
12809 auto Begin =
12810 CI != CE ? CurComponents.begin() : StackComponents.begin();
12811 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
12812 auto It = Begin;
12813 while (It != End && !It->getAssociatedDeclaration())
12814 std::advance(It, 1);
12815 assert(It != End &&
12816 "Expected at least one component with the declaration.");
12817 if (It != Begin && It->getAssociatedDeclaration()
12818 ->getType()
12819 .getCanonicalType()
12820 ->isAnyPointerType()) {
12821 IsEnclosedByDataEnvironmentExpr = false;
12822 EnclosingExpr = nullptr;
12823 return false;
12824 }
12825 }
12826 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12827 } else {
12828 assert(CKind == OMPC_to || CKind == OMPC_from);
12829 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12830 << ERange;
12831 }
12832 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12833 << RE->getSourceRange();
12834 return true;
12835 }
12836
12837 // The current expression uses the same base as other expression in the
12838 // data environment but does not contain it completely.
12839 if (!CurrentRegionOnly && SI != SE)
12840 EnclosingExpr = RE;
12841
12842 // The current expression is a subset of the expression in the data
12843 // environment.
12844 IsEnclosedByDataEnvironmentExpr |=
12845 (!CurrentRegionOnly && CI != CE && SI == SE);
12846
12847 return false;
12848 });
12849
12850 if (CurrentRegionOnly)
12851 return FoundError;
12852
12853 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12854 // If any part of the original storage of a list item has corresponding
12855 // storage in the device data environment, all of the original storage must
12856 // have corresponding storage in the device data environment.
12857 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12858 // If a list item is an element of a structure, and a different element of
12859 // the structure has a corresponding list item in the device data environment
12860 // prior to a task encountering the construct associated with the map clause,
12861 // then the list item must also have a corresponding list item in the device
12862 // data environment prior to the task encountering the construct.
12863 //
12864 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12865 SemaRef.Diag(ELoc,
12866 diag::err_omp_original_storage_is_shared_and_does_not_contain)
12867 << ERange;
12868 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12869 << EnclosingExpr->getSourceRange();
12870 return true;
12871 }
12872
12873 return FoundError;
12874 }
12875
12876 namespace {
12877 // Utility struct that gathers all the related lists associated with a mappable
12878 // expression.
12879 struct MappableVarListInfo {
12880 // The list of expressions.
12881 ArrayRef<Expr *> VarList;
12882 // The list of processed expressions.
12883 SmallVector<Expr *, 16> ProcessedVarList;
12884 // The mappble components for each expression.
12885 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
12886 // The base declaration of the variable.
12887 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12888
MappableVarListInfo__anon523c83f23811::MappableVarListInfo12889 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12890 // We have a list of components and base declarations for each entry in the
12891 // variable list.
12892 VarComponents.reserve(VarList.size());
12893 VarBaseDeclarations.reserve(VarList.size());
12894 }
12895 };
12896 }
12897
12898 // Check the validity of the provided variable list for the provided clause kind
12899 // \a CKind. In the check process the valid expressions, and mappable expression
12900 // components and variables are extracted and used to fill \a Vars,
12901 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12902 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12903 static void
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,bool IsMapTypeImplicit=false)12904 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12905 OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12906 SourceLocation StartLoc,
12907 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
12908 bool IsMapTypeImplicit = false) {
12909 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12910 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12911 "Unexpected clause kind with mappable expressions!");
12912
12913 // Keep track of the mappable components and base declarations in this clause.
12914 // Each entry in the list is going to have a list of components associated. We
12915 // record each set of the components so that we can build the clause later on.
12916 // In the end we should have the same amount of declarations and component
12917 // lists.
12918
12919 for (Expr *RE : MVLI.VarList) {
12920 assert(RE && "Null expr in omp to/from/map clause");
12921 SourceLocation ELoc = RE->getExprLoc();
12922
12923 const Expr *VE = RE->IgnoreParenLValueCasts();
12924
12925 if (VE->isValueDependent() || VE->isTypeDependent() ||
12926 VE->isInstantiationDependent() ||
12927 VE->containsUnexpandedParameterPack()) {
12928 // We can only analyze this information once the missing information is
12929 // resolved.
12930 MVLI.ProcessedVarList.push_back(RE);
12931 continue;
12932 }
12933
12934 Expr *SimpleExpr = RE->IgnoreParenCasts();
12935
12936 if (!RE->IgnoreParenImpCasts()->isLValue()) {
12937 SemaRef.Diag(ELoc,
12938 diag::err_omp_expected_named_var_member_or_array_expression)
12939 << RE->getSourceRange();
12940 continue;
12941 }
12942
12943 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
12944 ValueDecl *CurDeclaration = nullptr;
12945
12946 // Obtain the array or member expression bases if required. Also, fill the
12947 // components array with all the components identified in the process.
12948 const Expr *BE = checkMapClauseExpressionBase(
12949 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
12950 if (!BE)
12951 continue;
12952
12953 assert(!CurComponents.empty() &&
12954 "Invalid mappable expression information.");
12955
12956 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
12957 // Add store "this" pointer to class in DSAStackTy for future checking
12958 DSAS->addMappedClassesQualTypes(TE->getType());
12959 // Skip restriction checking for variable or field declarations
12960 MVLI.ProcessedVarList.push_back(RE);
12961 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12962 MVLI.VarComponents.back().append(CurComponents.begin(),
12963 CurComponents.end());
12964 MVLI.VarBaseDeclarations.push_back(nullptr);
12965 continue;
12966 }
12967
12968 // For the following checks, we rely on the base declaration which is
12969 // expected to be associated with the last component. The declaration is
12970 // expected to be a variable or a field (if 'this' is being mapped).
12971 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12972 assert(CurDeclaration && "Null decl on map clause.");
12973 assert(
12974 CurDeclaration->isCanonicalDecl() &&
12975 "Expecting components to have associated only canonical declarations.");
12976
12977 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12978 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12979
12980 assert((VD || FD) && "Only variables or fields are expected here!");
12981 (void)FD;
12982
12983 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12984 // threadprivate variables cannot appear in a map clause.
12985 // OpenMP 4.5 [2.10.5, target update Construct]
12986 // threadprivate variables cannot appear in a from clause.
12987 if (VD && DSAS->isThreadPrivate(VD)) {
12988 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12989 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12990 << getOpenMPClauseName(CKind);
12991 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
12992 continue;
12993 }
12994
12995 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12996 // A list item cannot appear in both a map clause and a data-sharing
12997 // attribute clause on the same construct.
12998
12999 // Check conflicts with other map clause expressions. We check the conflicts
13000 // with the current construct separately from the enclosing data
13001 // environment, because the restrictions are different. We only have to
13002 // check conflicts across regions for the map clauses.
13003 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13004 /*CurrentRegionOnly=*/true, CurComponents, CKind))
13005 break;
13006 if (CKind == OMPC_map &&
13007 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13008 /*CurrentRegionOnly=*/false, CurComponents, CKind))
13009 break;
13010
13011 // OpenMP 4.5 [2.10.5, target update Construct]
13012 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13013 // If the type of a list item is a reference to a type T then the type will
13014 // be considered to be T for all purposes of this clause.
13015 auto I = llvm::find_if(
13016 CurComponents,
13017 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
13018 return MC.getAssociatedDeclaration();
13019 });
13020 assert(I != CurComponents.end() && "Null decl on map clause.");
13021 QualType Type =
13022 I->getAssociatedDeclaration()->getType().getNonReferenceType();
13023
13024 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
13025 // A list item in a to or from clause must have a mappable type.
13026 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13027 // A list item must have a mappable type.
13028 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
13029 DSAS, Type))
13030 continue;
13031
13032 if (CKind == OMPC_map) {
13033 // target enter data
13034 // OpenMP [2.10.2, Restrictions, p. 99]
13035 // A map-type must be specified in all map clauses and must be either
13036 // to or alloc.
13037 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
13038 if (DKind == OMPD_target_enter_data &&
13039 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13040 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13041 << (IsMapTypeImplicit ? 1 : 0)
13042 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13043 << getOpenMPDirectiveName(DKind);
13044 continue;
13045 }
13046
13047 // target exit_data
13048 // OpenMP [2.10.3, Restrictions, p. 102]
13049 // A map-type must be specified in all map clauses and must be either
13050 // from, release, or delete.
13051 if (DKind == OMPD_target_exit_data &&
13052 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13053 MapType == OMPC_MAP_delete)) {
13054 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13055 << (IsMapTypeImplicit ? 1 : 0)
13056 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13057 << getOpenMPDirectiveName(DKind);
13058 continue;
13059 }
13060
13061 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13062 // A list item cannot appear in both a map clause and a data-sharing
13063 // attribute clause on the same construct
13064 if (VD && isOpenMPTargetExecutionDirective(DKind)) {
13065 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13066 if (isOpenMPPrivate(DVar.CKind)) {
13067 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13068 << getOpenMPClauseName(DVar.CKind)
13069 << getOpenMPClauseName(OMPC_map)
13070 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
13071 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
13072 continue;
13073 }
13074 }
13075 }
13076
13077 // Save the current expression.
13078 MVLI.ProcessedVarList.push_back(RE);
13079
13080 // Store the components in the stack so that they can be used to check
13081 // against other clauses later on.
13082 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13083 /*WhereFoundClauseKind=*/OMPC_map);
13084
13085 // Save the components and declaration to create the clause. For purposes of
13086 // the clause creation, any component list that has has base 'this' uses
13087 // null as base declaration.
13088 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13089 MVLI.VarComponents.back().append(CurComponents.begin(),
13090 CurComponents.end());
13091 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
13092 : CurDeclaration);
13093 }
13094 }
13095
13096 OMPClause *
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13097 Sema::ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13098 ArrayRef<SourceLocation> MapTypeModifiersLoc,
13099 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
13100 SourceLocation MapLoc, SourceLocation ColonLoc,
13101 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
13102 SourceLocation LParenLoc, SourceLocation EndLoc) {
13103 MappableVarListInfo MVLI(VarList);
13104 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
13105 MapType, IsMapTypeImplicit);
13106
13107 OpenMPMapModifierKind Modifiers[] = { OMPC_MAP_MODIFIER_unknown,
13108 OMPC_MAP_MODIFIER_unknown };
13109 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
13110
13111 // Process map-type-modifiers, flag errors for duplicate modifiers.
13112 unsigned Count = 0;
13113 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
13114 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13115 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13116 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13117 continue;
13118 }
13119 assert(Count < OMPMapClause::NumberOfModifiers &&
13120 "Modifiers exceed the allowed number of map type modifiers");
13121 Modifiers[Count] = MapTypeModifiers[I];
13122 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13123 ++Count;
13124 }
13125
13126 // We need to produce a map clause even if we don't have variables so that
13127 // other diagnostics related with non-existing map clauses are accurate.
13128 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13129 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13130 MVLI.VarComponents, Modifiers, ModifiersLoc,
13131 MapType, IsMapTypeImplicit, MapLoc);
13132 }
13133
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)13134 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
13135 TypeResult ParsedType) {
13136 assert(ParsedType.isUsable());
13137
13138 QualType ReductionType = GetTypeFromParser(ParsedType.get());
13139 if (ReductionType.isNull())
13140 return QualType();
13141
13142 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
13143 // A type name in a declare reduction directive cannot be a function type, an
13144 // array type, a reference type, or a type qualified with const, volatile or
13145 // restrict.
13146 if (ReductionType.hasQualifiers()) {
13147 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13148 return QualType();
13149 }
13150
13151 if (ReductionType->isFunctionType()) {
13152 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13153 return QualType();
13154 }
13155 if (ReductionType->isReferenceType()) {
13156 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13157 return QualType();
13158 }
13159 if (ReductionType->isArrayType()) {
13160 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13161 return QualType();
13162 }
13163 return ReductionType;
13164 }
13165
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)13166 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
13167 Scope *S, DeclContext *DC, DeclarationName Name,
13168 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
13169 AccessSpecifier AS, Decl *PrevDeclInScope) {
13170 SmallVector<Decl *, 8> Decls;
13171 Decls.reserve(ReductionTypes.size());
13172
13173 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
13174 forRedeclarationInCurContext());
13175 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
13176 // A reduction-identifier may not be re-declared in the current scope for the
13177 // same type or for a type that is compatible according to the base language
13178 // rules.
13179 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13180 OMPDeclareReductionDecl *PrevDRD = nullptr;
13181 bool InCompoundScope = true;
13182 if (S != nullptr) {
13183 // Find previous declaration with the same name not referenced in other
13184 // declarations.
13185 FunctionScopeInfo *ParentFn = getEnclosingFunction();
13186 InCompoundScope =
13187 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
13188 LookupName(Lookup, S);
13189 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
13190 /*AllowInlineNamespace=*/false);
13191 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13192 LookupResult::Filter Filter = Lookup.makeFilter();
13193 while (Filter.hasNext()) {
13194 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
13195 if (InCompoundScope) {
13196 auto I = UsedAsPrevious.find(PrevDecl);
13197 if (I == UsedAsPrevious.end())
13198 UsedAsPrevious[PrevDecl] = false;
13199 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
13200 UsedAsPrevious[D] = true;
13201 }
13202 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13203 PrevDecl->getLocation();
13204 }
13205 Filter.done();
13206 if (InCompoundScope) {
13207 for (const auto &PrevData : UsedAsPrevious) {
13208 if (!PrevData.second) {
13209 PrevDRD = PrevData.first;
13210 break;
13211 }
13212 }
13213 }
13214 } else if (PrevDeclInScope != nullptr) {
13215 auto *PrevDRDInScope = PrevDRD =
13216 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13217 do {
13218 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13219 PrevDRDInScope->getLocation();
13220 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13221 } while (PrevDRDInScope != nullptr);
13222 }
13223 for (const auto &TyData : ReductionTypes) {
13224 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13225 bool Invalid = false;
13226 if (I != PreviousRedeclTypes.end()) {
13227 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13228 << TyData.first;
13229 Diag(I->second, diag::note_previous_definition);
13230 Invalid = true;
13231 }
13232 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13233 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
13234 Name, TyData.first, PrevDRD);
13235 DC->addDecl(DRD);
13236 DRD->setAccess(AS);
13237 Decls.push_back(DRD);
13238 if (Invalid)
13239 DRD->setInvalidDecl();
13240 else
13241 PrevDRD = DRD;
13242 }
13243
13244 return DeclGroupPtrTy::make(
13245 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
13246 }
13247
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)13248 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
13249 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13250
13251 // Enter new function scope.
13252 PushFunctionScope();
13253 setFunctionHasBranchProtectedScope();
13254 getCurFunction()->setHasOMPDeclareReductionCombiner();
13255
13256 if (S != nullptr)
13257 PushDeclContext(S, DRD);
13258 else
13259 CurContext = DRD;
13260
13261 PushExpressionEvaluationContext(
13262 ExpressionEvaluationContext::PotentiallyEvaluated);
13263
13264 QualType ReductionType = DRD->getType();
13265 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
13266 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
13267 // uses semantics of argument handles by value, but it should be passed by
13268 // reference. C lang does not support references, so pass all parameters as
13269 // pointers.
13270 // Create 'T omp_in;' variable.
13271 VarDecl *OmpInParm =
13272 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
13273 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
13274 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
13275 // uses semantics of argument handles by value, but it should be passed by
13276 // reference. C lang does not support references, so pass all parameters as
13277 // pointers.
13278 // Create 'T omp_out;' variable.
13279 VarDecl *OmpOutParm =
13280 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
13281 if (S != nullptr) {
13282 PushOnScopeChains(OmpInParm, S);
13283 PushOnScopeChains(OmpOutParm, S);
13284 } else {
13285 DRD->addDecl(OmpInParm);
13286 DRD->addDecl(OmpOutParm);
13287 }
13288 Expr *InE =
13289 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
13290 Expr *OutE =
13291 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
13292 DRD->setCombinerData(InE, OutE);
13293 }
13294
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)13295 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
13296 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13297 DiscardCleanupsInEvaluationContext();
13298 PopExpressionEvaluationContext();
13299
13300 PopDeclContext();
13301 PopFunctionScopeInfo();
13302
13303 if (Combiner != nullptr)
13304 DRD->setCombiner(Combiner);
13305 else
13306 DRD->setInvalidDecl();
13307 }
13308
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)13309 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
13310 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13311
13312 // Enter new function scope.
13313 PushFunctionScope();
13314 setFunctionHasBranchProtectedScope();
13315
13316 if (S != nullptr)
13317 PushDeclContext(S, DRD);
13318 else
13319 CurContext = DRD;
13320
13321 PushExpressionEvaluationContext(
13322 ExpressionEvaluationContext::PotentiallyEvaluated);
13323
13324 QualType ReductionType = DRD->getType();
13325 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
13326 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
13327 // uses semantics of argument handles by value, but it should be passed by
13328 // reference. C lang does not support references, so pass all parameters as
13329 // pointers.
13330 // Create 'T omp_priv;' variable.
13331 VarDecl *OmpPrivParm =
13332 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
13333 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
13334 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
13335 // uses semantics of argument handles by value, but it should be passed by
13336 // reference. C lang does not support references, so pass all parameters as
13337 // pointers.
13338 // Create 'T omp_orig;' variable.
13339 VarDecl *OmpOrigParm =
13340 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
13341 if (S != nullptr) {
13342 PushOnScopeChains(OmpPrivParm, S);
13343 PushOnScopeChains(OmpOrigParm, S);
13344 } else {
13345 DRD->addDecl(OmpPrivParm);
13346 DRD->addDecl(OmpOrigParm);
13347 }
13348 Expr *OrigE =
13349 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
13350 Expr *PrivE =
13351 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
13352 DRD->setInitializerData(OrigE, PrivE);
13353 return OmpPrivParm;
13354 }
13355
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)13356 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
13357 VarDecl *OmpPrivParm) {
13358 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13359 DiscardCleanupsInEvaluationContext();
13360 PopExpressionEvaluationContext();
13361
13362 PopDeclContext();
13363 PopFunctionScopeInfo();
13364
13365 if (Initializer != nullptr) {
13366 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
13367 } else if (OmpPrivParm->hasInit()) {
13368 DRD->setInitializer(OmpPrivParm->getInit(),
13369 OmpPrivParm->isDirectInit()
13370 ? OMPDeclareReductionDecl::DirectInit
13371 : OMPDeclareReductionDecl::CopyInit);
13372 } else {
13373 DRD->setInvalidDecl();
13374 }
13375 }
13376
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)13377 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
13378 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
13379 for (Decl *D : DeclReductions.get()) {
13380 if (IsValid) {
13381 if (S)
13382 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
13383 /*AddToContext=*/false);
13384 } else {
13385 D->setInvalidDecl();
13386 }
13387 }
13388 return DeclReductions;
13389 }
13390
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13391 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
13392 SourceLocation StartLoc,
13393 SourceLocation LParenLoc,
13394 SourceLocation EndLoc) {
13395 Expr *ValExpr = NumTeams;
13396 Stmt *HelperValStmt = nullptr;
13397
13398 // OpenMP [teams Constrcut, Restrictions]
13399 // The num_teams expression must evaluate to a positive integer value.
13400 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
13401 /*StrictlyPositive=*/true))
13402 return nullptr;
13403
13404 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13405 OpenMPDirectiveKind CaptureRegion =
13406 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
13407 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13408 ValExpr = MakeFullExpr(ValExpr).get();
13409 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13410 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13411 HelperValStmt = buildPreInits(Context, Captures);
13412 }
13413
13414 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
13415 StartLoc, LParenLoc, EndLoc);
13416 }
13417
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13418 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
13419 SourceLocation StartLoc,
13420 SourceLocation LParenLoc,
13421 SourceLocation EndLoc) {
13422 Expr *ValExpr = ThreadLimit;
13423 Stmt *HelperValStmt = nullptr;
13424
13425 // OpenMP [teams Constrcut, Restrictions]
13426 // The thread_limit expression must evaluate to a positive integer value.
13427 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
13428 /*StrictlyPositive=*/true))
13429 return nullptr;
13430
13431 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13432 OpenMPDirectiveKind CaptureRegion =
13433 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
13434 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13435 ValExpr = MakeFullExpr(ValExpr).get();
13436 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13437 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13438 HelperValStmt = buildPreInits(Context, Captures);
13439 }
13440
13441 return new (Context) OMPThreadLimitClause(
13442 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13443 }
13444
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13445 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
13446 SourceLocation StartLoc,
13447 SourceLocation LParenLoc,
13448 SourceLocation EndLoc) {
13449 Expr *ValExpr = Priority;
13450
13451 // OpenMP [2.9.1, task Constrcut]
13452 // The priority-value is a non-negative numerical scalar expression.
13453 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
13454 /*StrictlyPositive=*/false))
13455 return nullptr;
13456
13457 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13458 }
13459
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13460 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
13461 SourceLocation StartLoc,
13462 SourceLocation LParenLoc,
13463 SourceLocation EndLoc) {
13464 Expr *ValExpr = Grainsize;
13465
13466 // OpenMP [2.9.2, taskloop Constrcut]
13467 // The parameter of the grainsize clause must be a positive integer
13468 // expression.
13469 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
13470 /*StrictlyPositive=*/true))
13471 return nullptr;
13472
13473 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13474 }
13475
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13476 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
13477 SourceLocation StartLoc,
13478 SourceLocation LParenLoc,
13479 SourceLocation EndLoc) {
13480 Expr *ValExpr = NumTasks;
13481
13482 // OpenMP [2.9.2, taskloop Constrcut]
13483 // The parameter of the num_tasks clause must be a positive integer
13484 // expression.
13485 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
13486 /*StrictlyPositive=*/true))
13487 return nullptr;
13488
13489 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13490 }
13491
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13492 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
13493 SourceLocation LParenLoc,
13494 SourceLocation EndLoc) {
13495 // OpenMP [2.13.2, critical construct, Description]
13496 // ... where hint-expression is an integer constant expression that evaluates
13497 // to a valid lock hint.
13498 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
13499 if (HintExpr.isInvalid())
13500 return nullptr;
13501 return new (Context)
13502 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
13503 }
13504
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)13505 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
13506 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13507 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
13508 SourceLocation EndLoc) {
13509 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
13510 std::string Values;
13511 Values += "'";
13512 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
13513 Values += "'";
13514 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13515 << Values << getOpenMPClauseName(OMPC_dist_schedule);
13516 return nullptr;
13517 }
13518 Expr *ValExpr = ChunkSize;
13519 Stmt *HelperValStmt = nullptr;
13520 if (ChunkSize) {
13521 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13522 !ChunkSize->isInstantiationDependent() &&
13523 !ChunkSize->containsUnexpandedParameterPack()) {
13524 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13525 ExprResult Val =
13526 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13527 if (Val.isInvalid())
13528 return nullptr;
13529
13530 ValExpr = Val.get();
13531
13532 // OpenMP [2.7.1, Restrictions]
13533 // chunk_size must be a loop invariant integer expression with a positive
13534 // value.
13535 llvm::APSInt Result;
13536 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
13537 if (Result.isSigned() && !Result.isStrictlyPositive()) {
13538 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13539 << "dist_schedule" << ChunkSize->getSourceRange();
13540 return nullptr;
13541 }
13542 } else if (getOpenMPCaptureRegionForClause(
13543 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
13544 OMPD_unknown &&
13545 !CurContext->isDependentContext()) {
13546 ValExpr = MakeFullExpr(ValExpr).get();
13547 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13548 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13549 HelperValStmt = buildPreInits(Context, Captures);
13550 }
13551 }
13552 }
13553
13554 return new (Context)
13555 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
13556 Kind, ValExpr, HelperValStmt);
13557 }
13558
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)13559 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
13560 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
13561 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
13562 SourceLocation KindLoc, SourceLocation EndLoc) {
13563 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
13564 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
13565 std::string Value;
13566 SourceLocation Loc;
13567 Value += "'";
13568 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
13569 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13570 OMPC_DEFAULTMAP_MODIFIER_tofrom);
13571 Loc = MLoc;
13572 } else {
13573 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13574 OMPC_DEFAULTMAP_scalar);
13575 Loc = KindLoc;
13576 }
13577 Value += "'";
13578 Diag(Loc, diag::err_omp_unexpected_clause_value)
13579 << Value << getOpenMPClauseName(OMPC_defaultmap);
13580 return nullptr;
13581 }
13582 DSAStack->setDefaultDMAToFromScalar(StartLoc);
13583
13584 return new (Context)
13585 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
13586 }
13587
ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)13588 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
13589 DeclContext *CurLexicalContext = getCurLexicalContext();
13590 if (!CurLexicalContext->isFileContext() &&
13591 !CurLexicalContext->isExternCContext() &&
13592 !CurLexicalContext->isExternCXXContext() &&
13593 !isa<CXXRecordDecl>(CurLexicalContext) &&
13594 !isa<ClassTemplateDecl>(CurLexicalContext) &&
13595 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
13596 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
13597 Diag(Loc, diag::err_omp_region_not_file_context);
13598 return false;
13599 }
13600 ++DeclareTargetNestingLevel;
13601 return true;
13602 }
13603
ActOnFinishOpenMPDeclareTargetDirective()13604 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
13605 assert(DeclareTargetNestingLevel > 0 &&
13606 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
13607 --DeclareTargetNestingLevel;
13608 }
13609
ActOnOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OMPDeclareTargetDeclAttr::MapTypeTy MT,NamedDeclSetType & SameDirectiveDecls)13610 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
13611 CXXScopeSpec &ScopeSpec,
13612 const DeclarationNameInfo &Id,
13613 OMPDeclareTargetDeclAttr::MapTypeTy MT,
13614 NamedDeclSetType &SameDirectiveDecls) {
13615 LookupResult Lookup(*this, Id, LookupOrdinaryName);
13616 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
13617
13618 if (Lookup.isAmbiguous())
13619 return;
13620 Lookup.suppressDiagnostics();
13621
13622 if (!Lookup.isSingleResult()) {
13623 if (TypoCorrection Corrected =
13624 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
13625 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
13626 CTK_ErrorRecovery)) {
13627 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
13628 << Id.getName());
13629 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
13630 return;
13631 }
13632
13633 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
13634 return;
13635 }
13636
13637 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
13638 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
13639 isa<FunctionTemplateDecl>(ND)) {
13640 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
13641 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
13642 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
13643 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
13644 cast<ValueDecl>(ND));
13645 if (!Res) {
13646 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13647 ND->addAttr(A);
13648 if (ASTMutationListener *ML = Context.getASTMutationListener())
13649 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13650 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
13651 } else if (*Res != MT) {
13652 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
13653 << Id.getName();
13654 }
13655 } else {
13656 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
13657 }
13658 }
13659
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)13660 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
13661 Sema &SemaRef, Decl *D) {
13662 if (!D || !isa<VarDecl>(D))
13663 return;
13664 auto *VD = cast<VarDecl>(D);
13665 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
13666 return;
13667 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
13668 SemaRef.Diag(SL, diag::note_used_here) << SR;
13669 }
13670
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)13671 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
13672 Sema &SemaRef, DSAStackTy *Stack,
13673 ValueDecl *VD) {
13674 return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13675 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
13676 /*FullCheck=*/false);
13677 }
13678
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)13679 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
13680 SourceLocation IdLoc) {
13681 if (!D || D->isInvalidDecl())
13682 return;
13683 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
13684 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
13685 if (auto *VD = dyn_cast<VarDecl>(D)) {
13686 // Only global variables can be marked as declare target.
13687 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
13688 !VD->isStaticDataMember())
13689 return;
13690 // 2.10.6: threadprivate variable cannot appear in a declare target
13691 // directive.
13692 if (DSAStack->isThreadPrivate(VD)) {
13693 Diag(SL, diag::err_omp_threadprivate_in_target);
13694 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
13695 return;
13696 }
13697 }
13698 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13699 D = FTD->getTemplatedDecl();
13700 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
13701 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
13702 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
13703 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
13704 assert(IdLoc.isValid() && "Source location is expected");
13705 Diag(IdLoc, diag::err_omp_function_in_link_clause);
13706 Diag(FD->getLocation(), diag::note_defined_here) << FD;
13707 return;
13708 }
13709 }
13710 if (auto *VD = dyn_cast<ValueDecl>(D)) {
13711 // Problem if any with var declared with incomplete type will be reported
13712 // as normal, so no need to check it here.
13713 if ((E || !VD->getType()->isIncompleteType()) &&
13714 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
13715 return;
13716 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
13717 // Checking declaration inside declare target region.
13718 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13719 isa<FunctionTemplateDecl>(D)) {
13720 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13721 Context, OMPDeclareTargetDeclAttr::MT_To);
13722 D->addAttr(A);
13723 if (ASTMutationListener *ML = Context.getASTMutationListener())
13724 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13725 }
13726 return;
13727 }
13728 }
13729 if (!E)
13730 return;
13731 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
13732 }
13733
ActOnOpenMPToClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13734 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
13735 SourceLocation StartLoc,
13736 SourceLocation LParenLoc,
13737 SourceLocation EndLoc) {
13738 MappableVarListInfo MVLI(VarList);
13739 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
13740 if (MVLI.ProcessedVarList.empty())
13741 return nullptr;
13742
13743 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13744 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13745 MVLI.VarComponents);
13746 }
13747
ActOnOpenMPFromClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13748 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
13749 SourceLocation StartLoc,
13750 SourceLocation LParenLoc,
13751 SourceLocation EndLoc) {
13752 MappableVarListInfo MVLI(VarList);
13753 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
13754 if (MVLI.ProcessedVarList.empty())
13755 return nullptr;
13756
13757 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13758 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13759 MVLI.VarComponents);
13760 }
13761
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13762 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
13763 SourceLocation StartLoc,
13764 SourceLocation LParenLoc,
13765 SourceLocation EndLoc) {
13766 MappableVarListInfo MVLI(VarList);
13767 SmallVector<Expr *, 8> PrivateCopies;
13768 SmallVector<Expr *, 8> Inits;
13769
13770 for (Expr *RefExpr : VarList) {
13771 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
13772 SourceLocation ELoc;
13773 SourceRange ERange;
13774 Expr *SimpleRefExpr = RefExpr;
13775 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13776 if (Res.second) {
13777 // It will be analyzed later.
13778 MVLI.ProcessedVarList.push_back(RefExpr);
13779 PrivateCopies.push_back(nullptr);
13780 Inits.push_back(nullptr);
13781 }
13782 ValueDecl *D = Res.first;
13783 if (!D)
13784 continue;
13785
13786 QualType Type = D->getType();
13787 Type = Type.getNonReferenceType().getUnqualifiedType();
13788
13789 auto *VD = dyn_cast<VarDecl>(D);
13790
13791 // Item should be a pointer or reference to pointer.
13792 if (!Type->isPointerType()) {
13793 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13794 << 0 << RefExpr->getSourceRange();
13795 continue;
13796 }
13797
13798 // Build the private variable and the expression that refers to it.
13799 auto VDPrivate =
13800 buildVarDecl(*this, ELoc, Type, D->getName(),
13801 D->hasAttrs() ? &D->getAttrs() : nullptr,
13802 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13803 if (VDPrivate->isInvalidDecl())
13804 continue;
13805
13806 CurContext->addDecl(VDPrivate);
13807 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13808 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13809
13810 // Add temporary variable to initialize the private copy of the pointer.
13811 VarDecl *VDInit =
13812 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13813 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
13814 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13815 AddInitializerToDecl(VDPrivate,
13816 DefaultLvalueConversion(VDInitRefExpr).get(),
13817 /*DirectInit=*/false);
13818
13819 // If required, build a capture to implement the privatization initialized
13820 // with the current list item value.
13821 DeclRefExpr *Ref = nullptr;
13822 if (!VD)
13823 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13824 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13825 PrivateCopies.push_back(VDPrivateRefExpr);
13826 Inits.push_back(VDInitRefExpr);
13827
13828 // We need to add a data sharing attribute for this variable to make sure it
13829 // is correctly captured. A variable that shows up in a use_device_ptr has
13830 // similar properties of a first private variable.
13831 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13832
13833 // Create a mappable component for the list item. List items in this clause
13834 // only need a component.
13835 MVLI.VarBaseDeclarations.push_back(D);
13836 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13837 MVLI.VarComponents.back().push_back(
13838 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
13839 }
13840
13841 if (MVLI.ProcessedVarList.empty())
13842 return nullptr;
13843
13844 return OMPUseDevicePtrClause::Create(
13845 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13846 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13847 }
13848
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13849 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
13850 SourceLocation StartLoc,
13851 SourceLocation LParenLoc,
13852 SourceLocation EndLoc) {
13853 MappableVarListInfo MVLI(VarList);
13854 for (Expr *RefExpr : VarList) {
13855 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
13856 SourceLocation ELoc;
13857 SourceRange ERange;
13858 Expr *SimpleRefExpr = RefExpr;
13859 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13860 if (Res.second) {
13861 // It will be analyzed later.
13862 MVLI.ProcessedVarList.push_back(RefExpr);
13863 }
13864 ValueDecl *D = Res.first;
13865 if (!D)
13866 continue;
13867
13868 QualType Type = D->getType();
13869 // item should be a pointer or array or reference to pointer or array
13870 if (!Type.getNonReferenceType()->isPointerType() &&
13871 !Type.getNonReferenceType()->isArrayType()) {
13872 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13873 << 0 << RefExpr->getSourceRange();
13874 continue;
13875 }
13876
13877 // Check if the declaration in the clause does not show up in any data
13878 // sharing attribute.
13879 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13880 if (isOpenMPPrivate(DVar.CKind)) {
13881 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13882 << getOpenMPClauseName(DVar.CKind)
13883 << getOpenMPClauseName(OMPC_is_device_ptr)
13884 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
13885 reportOriginalDsa(*this, DSAStack, D, DVar);
13886 continue;
13887 }
13888
13889 const Expr *ConflictExpr;
13890 if (DSAStack->checkMappableExprComponentListsForDecl(
13891 D, /*CurrentRegionOnly=*/true,
13892 [&ConflictExpr](
13893 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
13894 OpenMPClauseKind) -> bool {
13895 ConflictExpr = R.front().getAssociatedExpression();
13896 return true;
13897 })) {
13898 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13899 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13900 << ConflictExpr->getSourceRange();
13901 continue;
13902 }
13903
13904 // Store the components in the stack so that they can be used to check
13905 // against other clauses later on.
13906 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
13907 DSAStack->addMappableExpressionComponents(
13908 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13909
13910 // Record the expression we've just processed.
13911 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13912
13913 // Create a mappable component for the list item. List items in this clause
13914 // only need a component. We use a null declaration to signal fields in
13915 // 'this'.
13916 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13917 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13918 "Unexpected device pointer expression!");
13919 MVLI.VarBaseDeclarations.push_back(
13920 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13921 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13922 MVLI.VarComponents.back().push_back(MC);
13923 }
13924
13925 if (MVLI.ProcessedVarList.empty())
13926 return nullptr;
13927
13928 return OMPIsDevicePtrClause::Create(
13929 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13930 MVLI.VarBaseDeclarations, MVLI.VarComponents);
13931 }
13932