blob: 19a7d784c563305a48eb9b95b4687e4252420f71 [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
Alexey Bataeva769e072013-03-22 06:34:35 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alexey Bataeva769e072013-03-22 06:34:35 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00009/// This file implements semantic analysis for OpenMP directives and
Alexey Bataev6f6f3b42013-05-13 04:18:18 +000010/// clauses.
Alexey Bataeva769e072013-03-22 06:34:35 +000011///
12//===----------------------------------------------------------------------===//
13
Alexey Bataevb08f89f2015-08-14 12:25:37 +000014#include "TreeTransform.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000015#include "clang/AST/ASTContext.h"
Alexey Bataev97720002014-11-11 04:05:39 +000016#include "clang/AST/ASTMutationListener.h"
Alexey Bataeva839ddd2016-03-17 10:19:46 +000017#include "clang/AST/CXXInheritance.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000018#include "clang/AST/Decl.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000019#include "clang/AST/DeclCXX.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000020#include "clang/AST/DeclOpenMP.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000021#include "clang/AST/StmtCXX.h"
22#include "clang/AST/StmtOpenMP.h"
23#include "clang/AST/StmtVisitor.h"
Patrick Lystere13b1e32019-01-02 19:28:48 +000024#include "clang/AST/TypeOrdering.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000025#include "clang/Basic/OpenMPKinds.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000026#include "clang/Sema/Initialization.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000027#include "clang/Sema/Lookup.h"
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000028#include "clang/Sema/Scope.h"
29#include "clang/Sema/ScopeInfo.h"
Chandler Carruth5553d0d2014-01-07 11:51:46 +000030#include "clang/Sema/SemaInternal.h"
Alexey Bataevfa312f32017-07-21 18:48:21 +000031#include "llvm/ADT/PointerEmbeddedInt.h"
Alexey Bataeva769e072013-03-22 06:34:35 +000032using namespace clang;
33
Alexey Bataev758e55e2013-09-06 18:03:48 +000034//===----------------------------------------------------------------------===//
35// Stack of data-sharing attributes for variables
36//===----------------------------------------------------------------------===//
37
Alexey Bataeve3727102018-04-18 15:57:46 +000038static const Expr *checkMapClauseExpressionBase(
Alexey Bataevf47c4b42017-09-26 13:47:31 +000039 Sema &SemaRef, Expr *E,
40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
Alexey Bataevb7a9b742017-12-05 19:20:09 +000041 OpenMPClauseKind CKind, bool NoDiagnose);
Alexey Bataevf47c4b42017-09-26 13:47:31 +000042
Alexey Bataev758e55e2013-09-06 18:03:48 +000043namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000044/// Default data sharing attributes, which can be applied to directive.
Alexey Bataev758e55e2013-09-06 18:03:48 +000045enum DefaultDataSharingAttributes {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000046 DSA_unspecified = 0, /// Data sharing attribute not specified.
47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
Alexey Bataev2fd0cb22017-10-05 17:51:39 +000049};
50
51/// Attributes of the defaultmap clause.
52enum DefaultMapAttributes {
53 DMA_unspecified, /// Default mapping is not specified.
54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
Alexey Bataev758e55e2013-09-06 18:03:48 +000055};
Alexey Bataev7ff55242014-06-19 09:13:45 +000056
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000057/// Stack for tracking declarations used in OpenMP directives and
Alexey Bataev758e55e2013-09-06 18:03:48 +000058/// clauses and their data-sharing attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +000059class DSAStackTy {
Alexey Bataev758e55e2013-09-06 18:03:48 +000060public:
Alexey Bataeve3727102018-04-18 15:57:46 +000061 struct DSAVarData {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000062 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
Alexey Bataeve3727102018-04-18 15:57:46 +000064 const Expr *RefExpr = nullptr;
Alexey Bataev7ace49d2016-05-17 08:55:33 +000065 DeclRefExpr *PrivateCopy = nullptr;
Alexey Bataevbae9a792014-06-27 10:37:06 +000066 SourceLocation ImplicitDSALoc;
Alexey Bataev4d4624c2017-07-20 16:47:47 +000067 DSAVarData() = default;
Alexey Bataeve3727102018-04-18 15:57:46 +000068 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70 SourceLocation ImplicitDSALoc)
Alexey Bataevf189cb72017-07-24 14:52:13 +000071 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
Alexey Bataev758e55e2013-09-06 18:03:48 +000073 };
Alexey Bataeve3727102018-04-18 15:57:46 +000074 using OperatorOffsetTy =
75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
Alexey Bataevf138fda2018-08-13 19:04:24 +000076 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
Alexey Bataeved09d242014-05-28 05:53:51 +000078
Alexey Bataev758e55e2013-09-06 18:03:48 +000079private:
Alexey Bataeve3727102018-04-18 15:57:46 +000080 struct DSAInfo {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000081 OpenMPClauseKind Attributes = OMPC_unknown;
82 /// Pointer to a reference expression and a flag which shows that the
83 /// variable is marked as lastprivate(true) or not (false).
Alexey Bataeve3727102018-04-18 15:57:46 +000084 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
Alexey Bataev7ace49d2016-05-17 08:55:33 +000085 DeclRefExpr *PrivateCopy = nullptr;
Alexey Bataev758e55e2013-09-06 18:03:48 +000086 };
Alexey Bataeve3727102018-04-18 15:57:46 +000087 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
Samuel Antao6890b092016-07-28 14:25:09 +000092 /// Struct that associates a component with the clause kind where they are
93 /// found.
94 struct MappedExprComponentTy {
95 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96 OpenMPClauseKind Kind = OMPC_unknown;
97 };
Alexey Bataeve3727102018-04-18 15:57:46 +000098 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000102 struct ReductionData {
Alexey Bataeve3727102018-04-18 15:57:46 +0000103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000104 SourceRange ReductionRange;
Alexey Bataevf87fa882017-07-21 19:26:22 +0000105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000106 ReductionData() = default;
107 void set(BinaryOperatorKind BO, SourceRange RR) {
108 ReductionRange = RR;
109 ReductionOp = BO;
110 }
111 void set(const Expr *RefExpr, SourceRange RR) {
112 ReductionRange = RR;
113 ReductionOp = RefExpr;
114 }
115 };
Alexey Bataeve3727102018-04-18 15:57:46 +0000116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000118
Alexey Bataeve3727102018-04-18 15:57:46 +0000119 struct SharingMapTy {
Alexey Bataev758e55e2013-09-06 18:03:48 +0000120 DeclSAMapTy SharingMap;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000121 DeclReductionMapTy ReductionMap;
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000122 AlignedMapTy AlignedMap;
Samuel Antao90927002016-04-26 14:54:23 +0000123 MappedExprComponentsTy MappedExprComponents;
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000124 LoopControlVariablesMapTy LCVMap;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000126 SourceLocation DefaultAttrLoc;
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128 SourceLocation DefaultMapAttrLoc;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000129 OpenMPDirectiveKind Directive = OMPD_unknown;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000130 DeclarationNameInfo DirectiveName;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000131 Scope *CurScope = nullptr;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000132 SourceLocation ConstructLoc;
Alexey Bataev8b427062016-05-25 12:36:08 +0000133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134 /// get the data (loop counters etc.) about enclosing loop-based construct.
135 /// This data is required during codegen.
136 DoacrossDependMapTy DoacrossDepends;
Patrick Lyster16471942019-02-06 18:18:02 +0000137 /// First argument (Expr *) contains optional argument of the
Alexey Bataev346265e2015-09-25 10:37:12 +0000138 /// 'ordered' clause, the second one is true if the regions has 'ordered'
139 /// clause, false otherwise.
Alexey Bataevf138fda2018-08-13 19:04:24 +0000140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000141 unsigned AssociatedLoops = 1;
142 const Decl *PossiblyLoopCounter = nullptr;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000143 bool NowaitRegion = false;
144 bool CancelRegion = false;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000145 bool LoopStart = false;
Alexey Bataev13314bf2014-10-09 04:18:56 +0000146 SourceLocation InnerTeamsRegionLoc;
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000147 /// Reference to the taskgroup task_reduction reference expression.
148 Expr *TaskgroupReductionRef = nullptr;
Patrick Lystere13b1e32019-01-02 19:28:48 +0000149 llvm::DenseSet<QualType> MappedClassesQualTypes;
Alexey Bataeva495c642019-03-11 19:51:42 +0000150 /// List of globals marked as declare target link in this target region
151 /// (isOpenMPTargetExecutionDirective(Directive) == true).
152 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
Alexey Bataeved09d242014-05-28 05:53:51 +0000153 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Alexey Bataevbae9a792014-06-27 10:37:06 +0000154 Scope *CurScope, SourceLocation Loc)
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000155 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
156 ConstructLoc(Loc) {}
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000157 SharingMapTy() = default;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000158 };
159
Alexey Bataeve3727102018-04-18 15:57:46 +0000160 using StackTy = SmallVector<SharingMapTy, 4>;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000161
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000162 /// Stack of used declaration and their data-sharing attributes.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000163 DeclSAMapTy Threadprivates;
Alexey Bataev4b465392017-04-26 15:06:24 +0000164 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
165 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000166 /// true, if check for DSA must be from parent directive, false, if
Alexey Bataev39f915b82015-05-08 10:41:21 +0000167 /// from current directive.
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000168 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
Alexey Bataev7ff55242014-06-19 09:13:45 +0000169 Sema &SemaRef;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000170 bool ForceCapturing = false;
Alexey Bataev60705422018-10-30 15:50:12 +0000171 /// true if all the vaiables in the target executable directives must be
172 /// captured by reference.
173 bool ForceCaptureByReferenceInTargetExecutable = false;
Alexey Bataev28c75412015-12-15 08:19:24 +0000174 CriticalsWithHintsTy Criticals;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000175
Alexey Bataeve3727102018-04-18 15:57:46 +0000176 using iterator = StackTy::const_reverse_iterator;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000177
Alexey Bataeve3727102018-04-18 15:57:46 +0000178 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
Alexey Bataevec3da872014-01-31 05:15:34 +0000179
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000180 /// Checks if the variable is a local for OpenMP region.
Alexey Bataeve3727102018-04-18 15:57:46 +0000181 bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
Alexey Bataeved09d242014-05-28 05:53:51 +0000182
Alexey Bataev4b465392017-04-26 15:06:24 +0000183 bool isStackEmpty() const {
184 return Stack.empty() ||
185 Stack.back().second != CurrentNonCapturingFunctionScope ||
186 Stack.back().first.empty();
187 }
188
Kelvin Li1408f912018-09-26 04:28:39 +0000189 /// Vector of previously declared requires directives
190 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
Alexey Bataev27ef9512019-03-20 20:14:22 +0000191 /// omp_allocator_handle_t type.
192 QualType OMPAllocatorHandleT;
193 /// Expression for the predefined allocators.
194 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
195 nullptr};
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +0000196 /// Vector of previously encountered target directives
197 SmallVector<SourceLocation, 2> TargetLocations;
Kelvin Li1408f912018-09-26 04:28:39 +0000198
Alexey Bataev758e55e2013-09-06 18:03:48 +0000199public:
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000200 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
Alexey Bataev39f915b82015-05-08 10:41:21 +0000201
Alexey Bataev27ef9512019-03-20 20:14:22 +0000202 /// Sets omp_allocator_handle_t type.
203 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
204 /// Gets omp_allocator_handle_t type.
205 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
206 /// Sets the given default allocator.
207 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
208 Expr *Allocator) {
209 OMPPredefinedAllocators[AllocatorKind] = Allocator;
210 }
211 /// Returns the specified default allocator.
212 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
213 return OMPPredefinedAllocators[AllocatorKind];
214 }
215
Alexey Bataevaac108a2015-06-23 04:51:00 +0000216 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
Alexey Bataev3f82cfc2017-12-13 15:28:44 +0000217 OpenMPClauseKind getClauseParsingMode() const {
218 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
219 return ClauseKindMode;
220 }
Alexey Bataevaac108a2015-06-23 04:51:00 +0000221 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000222
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000223 bool isForceVarCapturing() const { return ForceCapturing; }
224 void setForceVarCapturing(bool V) { ForceCapturing = V; }
225
Alexey Bataev60705422018-10-30 15:50:12 +0000226 void setForceCaptureByReferenceInTargetExecutable(bool V) {
227 ForceCaptureByReferenceInTargetExecutable = V;
228 }
229 bool isForceCaptureByReferenceInTargetExecutable() const {
230 return ForceCaptureByReferenceInTargetExecutable;
231 }
232
Alexey Bataev758e55e2013-09-06 18:03:48 +0000233 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
Alexey Bataevbae9a792014-06-27 10:37:06 +0000234 Scope *CurScope, SourceLocation Loc) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000235 if (Stack.empty() ||
236 Stack.back().second != CurrentNonCapturingFunctionScope)
237 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
238 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
239 Stack.back().first.back().DefaultAttrLoc = Loc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000240 }
241
242 void pop() {
Alexey Bataev4b465392017-04-26 15:06:24 +0000243 assert(!Stack.back().first.empty() &&
244 "Data-sharing attributes stack is empty!");
245 Stack.back().first.pop_back();
246 }
247
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000248 /// Marks that we're started loop parsing.
249 void loopInit() {
250 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
251 "Expected loop-based directive.");
252 Stack.back().first.back().LoopStart = true;
253 }
254 /// Start capturing of the variables in the loop context.
255 void loopStart() {
256 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
257 "Expected loop-based directive.");
258 Stack.back().first.back().LoopStart = false;
259 }
260 /// true, if variables are captured, false otherwise.
261 bool isLoopStarted() const {
262 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
263 "Expected loop-based directive.");
264 return !Stack.back().first.back().LoopStart;
265 }
266 /// Marks (or clears) declaration as possibly loop counter.
267 void resetPossibleLoopCounter(const Decl *D = nullptr) {
268 Stack.back().first.back().PossiblyLoopCounter =
269 D ? D->getCanonicalDecl() : D;
270 }
271 /// Gets the possible loop counter decl.
272 const Decl *getPossiblyLoopCunter() const {
273 return Stack.back().first.back().PossiblyLoopCounter;
274 }
Alexey Bataev4b465392017-04-26 15:06:24 +0000275 /// Start new OpenMP region stack in new non-capturing function.
276 void pushFunction() {
277 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
278 assert(!isa<CapturingScopeInfo>(CurFnScope));
279 CurrentNonCapturingFunctionScope = CurFnScope;
280 }
281 /// Pop region stack for non-capturing function.
282 void popFunction(const FunctionScopeInfo *OldFSI) {
283 if (!Stack.empty() && Stack.back().second == OldFSI) {
284 assert(Stack.back().first.empty());
285 Stack.pop_back();
286 }
287 CurrentNonCapturingFunctionScope = nullptr;
288 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
289 if (!isa<CapturingScopeInfo>(FSI)) {
290 CurrentNonCapturingFunctionScope = FSI;
291 break;
292 }
293 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000294 }
295
Alexey Bataeve3727102018-04-18 15:57:46 +0000296 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
Alexey Bataev43a919f2018-04-13 17:48:43 +0000297 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
Alexey Bataev28c75412015-12-15 08:19:24 +0000298 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000299 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
Alexey Bataev28c75412015-12-15 08:19:24 +0000300 getCriticalWithHint(const DeclarationNameInfo &Name) const {
301 auto I = Criticals.find(Name.getAsString());
302 if (I != Criticals.end())
303 return I->second;
304 return std::make_pair(nullptr, llvm::APSInt());
305 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000306 /// If 'aligned' declaration for given variable \a D was not seen yet,
Alp Toker15e62a32014-06-06 12:02:07 +0000307 /// add it and return NULL; otherwise return previous occurrence's expression
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000308 /// for diagnostics.
Alexey Bataeve3727102018-04-18 15:57:46 +0000309 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000310
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000311 /// Register specified variable as loop control variable.
Alexey Bataeve3727102018-04-18 15:57:46 +0000312 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000313 /// Check if the specified variable is a loop control variable for
Alexey Bataev9c821032015-04-30 04:23:23 +0000314 /// current region.
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000315 /// \return The index of the loop control variable in the list of associated
316 /// for-loops (from outer to inner).
Alexey Bataeve3727102018-04-18 15:57:46 +0000317 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000318 /// Check if the specified variable is a loop control variable for
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000319 /// parent region.
320 /// \return The index of the loop control variable in the list of associated
321 /// for-loops (from outer to inner).
Alexey Bataeve3727102018-04-18 15:57:46 +0000322 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000323 /// Get the loop control variable for the I-th loop (or nullptr) in
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000324 /// parent directive.
Alexey Bataeve3727102018-04-18 15:57:46 +0000325 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
Alexey Bataev9c821032015-04-30 04:23:23 +0000326
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000327 /// Adds explicit data sharing attribute to the specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000328 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
Alexey Bataev90c228f2016-02-08 09:29:13 +0000329 DeclRefExpr *PrivateCopy = nullptr);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000330
Alexey Bataevfa312f32017-07-21 18:48:21 +0000331 /// Adds additional information for the reduction items with the reduction id
332 /// represented as an operator.
Alexey Bataeve3727102018-04-18 15:57:46 +0000333 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000334 BinaryOperatorKind BOK);
Alexey Bataevfa312f32017-07-21 18:48:21 +0000335 /// Adds additional information for the reduction items with the reduction id
336 /// represented as reduction identifier.
Alexey Bataeve3727102018-04-18 15:57:46 +0000337 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000338 const Expr *ReductionRef);
Alexey Bataevfa312f32017-07-21 18:48:21 +0000339 /// Returns the location and reduction operation from the innermost parent
340 /// region for the given \p D.
Alexey Bataeve3727102018-04-18 15:57:46 +0000341 const DSAVarData
342 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
343 BinaryOperatorKind &BOK,
344 Expr *&TaskgroupDescriptor) const;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000345 /// Returns the location and reduction operation from the innermost parent
346 /// region for the given \p D.
Alexey Bataeve3727102018-04-18 15:57:46 +0000347 const DSAVarData
348 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
349 const Expr *&ReductionRef,
350 Expr *&TaskgroupDescriptor) const;
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000351 /// Return reduction reference expression for the current taskgroup.
352 Expr *getTaskgroupReductionRef() const {
353 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
354 "taskgroup reference expression requested for non taskgroup "
355 "directive.");
356 return Stack.back().first.back().TaskgroupReductionRef;
357 }
Alexey Bataev88202be2017-07-27 13:20:36 +0000358 /// Checks if the given \p VD declaration is actually a taskgroup reduction
359 /// descriptor variable at the \p Level of OpenMP regions.
Alexey Bataeve3727102018-04-18 15:57:46 +0000360 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
Alexey Bataev88202be2017-07-27 13:20:36 +0000361 return Stack.back().first[Level].TaskgroupReductionRef &&
362 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
363 ->getDecl() == VD;
364 }
Alexey Bataevfa312f32017-07-21 18:48:21 +0000365
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000366 /// Returns data sharing attributes from top of the stack for the
Alexey Bataev758e55e2013-09-06 18:03:48 +0000367 /// specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000368 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000369 /// Returns data-sharing attributes for the specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000370 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000371 /// Checks if the specified variables has data-sharing attributes which
Alexey Bataevf29276e2014-06-18 04:14:57 +0000372 /// match specified \a CPred predicate in any directive which matches \a DPred
373 /// predicate.
Alexey Bataeve3727102018-04-18 15:57:46 +0000374 const DSAVarData
375 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
376 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
377 bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000378 /// Checks if the specified variables has data-sharing attributes which
Alexey Bataevf29276e2014-06-18 04:14:57 +0000379 /// match specified \a CPred predicate in any innermost directive which
380 /// matches \a DPred predicate.
Alexey Bataeve3727102018-04-18 15:57:46 +0000381 const DSAVarData
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000382 hasInnermostDSA(ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000383 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
384 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000385 bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000386 /// Checks if the specified variables has explicit data-sharing
Alexey Bataevaac108a2015-06-23 04:51:00 +0000387 /// attributes which match specified \a CPred predicate at the specified
388 /// OpenMP region.
Alexey Bataeve3727102018-04-18 15:57:46 +0000389 bool hasExplicitDSA(const ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000390 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000391 unsigned Level, bool NotLastprivate = false) const;
Samuel Antao4be30e92015-10-02 17:14:03 +0000392
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000393 /// Returns true if the directive at level \Level matches in the
Samuel Antao4be30e92015-10-02 17:14:03 +0000394 /// specified \a DPred predicate.
395 bool hasExplicitDirective(
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000396 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000397 unsigned Level) const;
Samuel Antao4be30e92015-10-02 17:14:03 +0000398
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000399 /// Finds a directive which matches specified \a DPred predicate.
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000400 bool hasDirective(
401 const llvm::function_ref<bool(
402 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
403 DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000404 bool FromParent) const;
Alexey Bataevd5af8e42013-10-01 05:32:34 +0000405
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000406 /// Returns currently analyzed directive.
Alexey Bataev758e55e2013-09-06 18:03:48 +0000407 OpenMPDirectiveKind getCurrentDirective() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000408 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000409 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000410 /// Returns directive kind at specified level.
Alexey Bataevdfa430f2017-12-08 15:03:50 +0000411 OpenMPDirectiveKind getDirective(unsigned Level) const {
412 assert(!isStackEmpty() && "No directive at specified level.");
413 return Stack.back().first[Level].Directive;
414 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000415 /// Returns parent directive.
Alexey Bataev549210e2014-06-24 04:39:47 +0000416 OpenMPDirectiveKind getParentDirective() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000417 if (isStackEmpty() || Stack.back().first.size() == 1)
418 return OMPD_unknown;
419 return std::next(Stack.back().first.rbegin())->Directive;
Alexey Bataev549210e2014-06-24 04:39:47 +0000420 }
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000421
Kelvin Li1408f912018-09-26 04:28:39 +0000422 /// Add requires decl to internal vector
423 void addRequiresDecl(OMPRequiresDecl *RD) {
424 RequiresDecls.push_back(RD);
425 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000426
Alexey Bataev318f431b2019-03-22 15:25:12 +0000427 /// Checks if the defined 'requires' directive has specified type of clause.
428 template <typename ClauseType>
429 bool hasRequiresDeclWithClause() {
430 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
431 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
432 return isa<ClauseType>(C);
433 });
434 });
435 }
436
Kelvin Li1408f912018-09-26 04:28:39 +0000437 /// Checks for a duplicate clause amongst previously declared requires
438 /// directives
439 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
440 bool IsDuplicate = false;
441 for (OMPClause *CNew : ClauseList) {
442 for (const OMPRequiresDecl *D : RequiresDecls) {
443 for (const OMPClause *CPrev : D->clauselists()) {
444 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
445 SemaRef.Diag(CNew->getBeginLoc(),
446 diag::err_omp_requires_clause_redeclaration)
447 << getOpenMPClauseName(CNew->getClauseKind());
448 SemaRef.Diag(CPrev->getBeginLoc(),
449 diag::note_omp_requires_previous_clause)
450 << getOpenMPClauseName(CPrev->getClauseKind());
451 IsDuplicate = true;
452 }
453 }
454 }
455 }
456 return IsDuplicate;
457 }
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +0000458
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +0000459 /// Add location of previously encountered target to internal vector
460 void addTargetDirLocation(SourceLocation LocStart) {
461 TargetLocations.push_back(LocStart);
462 }
463
464 // Return previously encountered target region locations.
465 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
466 return TargetLocations;
467 }
468
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000469 /// Set default data sharing attribute to none.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000470 void setDefaultDSANone(SourceLocation Loc) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000471 assert(!isStackEmpty());
472 Stack.back().first.back().DefaultAttr = DSA_none;
473 Stack.back().first.back().DefaultAttrLoc = Loc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000474 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000475 /// Set default data sharing attribute to shared.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000476 void setDefaultDSAShared(SourceLocation Loc) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000477 assert(!isStackEmpty());
478 Stack.back().first.back().DefaultAttr = DSA_shared;
479 Stack.back().first.back().DefaultAttrLoc = Loc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000480 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000481 /// Set default data mapping attribute to 'tofrom:scalar'.
482 void setDefaultDMAToFromScalar(SourceLocation Loc) {
483 assert(!isStackEmpty());
484 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
485 Stack.back().first.back().DefaultMapAttrLoc = Loc;
486 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000487
488 DefaultDataSharingAttributes getDefaultDSA() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000489 return isStackEmpty() ? DSA_unspecified
490 : Stack.back().first.back().DefaultAttr;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000491 }
Alexey Bataevbae9a792014-06-27 10:37:06 +0000492 SourceLocation getDefaultDSALocation() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000493 return isStackEmpty() ? SourceLocation()
494 : Stack.back().first.back().DefaultAttrLoc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000495 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000496 DefaultMapAttributes getDefaultDMA() const {
497 return isStackEmpty() ? DMA_unspecified
498 : Stack.back().first.back().DefaultMapAttr;
499 }
500 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
501 return Stack.back().first[Level].DefaultMapAttr;
502 }
503 SourceLocation getDefaultDMALocation() const {
504 return isStackEmpty() ? SourceLocation()
505 : Stack.back().first.back().DefaultMapAttrLoc;
506 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000507
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000508 /// Checks if the specified variable is a threadprivate.
Alexey Bataevd48bcd82014-03-31 03:36:38 +0000509 bool isThreadPrivate(VarDecl *D) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000510 const DSAVarData DVar = getTopDSA(D, false);
Alexey Bataevf29276e2014-06-18 04:14:57 +0000511 return isOpenMPThreadPrivate(DVar.CKind);
Alexey Bataevd48bcd82014-03-31 03:36:38 +0000512 }
513
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000514 /// Marks current region as ordered (it has an 'ordered' clause).
Alexey Bataevf138fda2018-08-13 19:04:24 +0000515 void setOrderedRegion(bool IsOrdered, const Expr *Param,
516 OMPOrderedClause *Clause) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000517 assert(!isStackEmpty());
Alexey Bataevf138fda2018-08-13 19:04:24 +0000518 if (IsOrdered)
519 Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
520 else
521 Stack.back().first.back().OrderedRegion.reset();
522 }
523 /// Returns true, if region is ordered (has associated 'ordered' clause),
524 /// false - otherwise.
525 bool isOrderedRegion() const {
526 if (isStackEmpty())
527 return false;
528 return Stack.back().first.rbegin()->OrderedRegion.hasValue();
529 }
530 /// Returns optional parameter for the ordered region.
531 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
532 if (isStackEmpty() ||
533 !Stack.back().first.rbegin()->OrderedRegion.hasValue())
534 return std::make_pair(nullptr, nullptr);
535 return Stack.back().first.rbegin()->OrderedRegion.getValue();
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000536 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000537 /// Returns true, if parent region is ordered (has associated
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000538 /// 'ordered' clause), false - otherwise.
539 bool isParentOrderedRegion() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000540 if (isStackEmpty() || Stack.back().first.size() == 1)
541 return false;
Alexey Bataevf138fda2018-08-13 19:04:24 +0000542 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000543 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000544 /// Returns optional parameter for the ordered region.
Alexey Bataevf138fda2018-08-13 19:04:24 +0000545 std::pair<const Expr *, OMPOrderedClause *>
546 getParentOrderedRegionParam() const {
547 if (isStackEmpty() || Stack.back().first.size() == 1 ||
548 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
549 return std::make_pair(nullptr, nullptr);
550 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
Alexey Bataev346265e2015-09-25 10:37:12 +0000551 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000552 /// Marks current region as nowait (it has a 'nowait' clause).
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000553 void setNowaitRegion(bool IsNowait = true) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000554 assert(!isStackEmpty());
555 Stack.back().first.back().NowaitRegion = IsNowait;
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000556 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000557 /// Returns true, if parent region is nowait (has associated
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000558 /// 'nowait' clause), false - otherwise.
559 bool isParentNowaitRegion() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000560 if (isStackEmpty() || Stack.back().first.size() == 1)
561 return false;
562 return std::next(Stack.back().first.rbegin())->NowaitRegion;
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000563 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000564 /// Marks parent region as cancel region.
Alexey Bataev25e5b442015-09-15 12:52:43 +0000565 void setParentCancelRegion(bool Cancel = true) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000566 if (!isStackEmpty() && Stack.back().first.size() > 1) {
567 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
568 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
569 }
Alexey Bataev25e5b442015-09-15 12:52:43 +0000570 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000571 /// Return true if current region has inner cancel construct.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000572 bool isCancelRegion() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000573 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000574 }
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000575
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000576 /// Set collapse value for the region.
Alexey Bataev4b465392017-04-26 15:06:24 +0000577 void setAssociatedLoops(unsigned Val) {
578 assert(!isStackEmpty());
579 Stack.back().first.back().AssociatedLoops = Val;
580 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000581 /// Return collapse value for region.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000582 unsigned getAssociatedLoops() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000583 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000584 }
Alexey Bataev9c821032015-04-30 04:23:23 +0000585
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000586 /// Marks current target region as one with closely nested teams
Alexey Bataev13314bf2014-10-09 04:18:56 +0000587 /// region.
588 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000589 if (!isStackEmpty() && Stack.back().first.size() > 1) {
590 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
591 TeamsRegionLoc;
592 }
Alexey Bataev13314bf2014-10-09 04:18:56 +0000593 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000594 /// Returns true, if current region has closely nested teams region.
Alexey Bataev13314bf2014-10-09 04:18:56 +0000595 bool hasInnerTeamsRegion() const {
596 return getInnerTeamsRegionLoc().isValid();
597 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000598 /// Returns location of the nested teams region (if any).
Alexey Bataev13314bf2014-10-09 04:18:56 +0000599 SourceLocation getInnerTeamsRegionLoc() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000600 return isStackEmpty() ? SourceLocation()
601 : Stack.back().first.back().InnerTeamsRegionLoc;
Alexey Bataev13314bf2014-10-09 04:18:56 +0000602 }
603
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000604 Scope *getCurScope() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000605 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000606 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000607 SourceLocation getConstructLoc() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000608 return isStackEmpty() ? SourceLocation()
609 : Stack.back().first.back().ConstructLoc;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000610 }
Kelvin Li0bff7af2015-11-23 05:32:03 +0000611
Samuel Antao4c8035b2016-12-12 18:00:20 +0000612 /// Do the check specified in \a Check to all component lists and return true
613 /// if any issue is found.
Samuel Antao90927002016-04-26 14:54:23 +0000614 bool checkMappableExprComponentListsForDecl(
Alexey Bataeve3727102018-04-18 15:57:46 +0000615 const ValueDecl *VD, bool CurrentRegionOnly,
Samuel Antao6890b092016-07-28 14:25:09 +0000616 const llvm::function_ref<
617 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000618 OpenMPClauseKind)>
Alexey Bataeve3727102018-04-18 15:57:46 +0000619 Check) const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000620 if (isStackEmpty())
621 return false;
622 auto SI = Stack.back().first.rbegin();
623 auto SE = Stack.back().first.rend();
Samuel Antao5de996e2016-01-22 20:21:36 +0000624
625 if (SI == SE)
626 return false;
627
Alexey Bataeve3727102018-04-18 15:57:46 +0000628 if (CurrentRegionOnly)
Samuel Antao5de996e2016-01-22 20:21:36 +0000629 SE = std::next(SI);
Alexey Bataeve3727102018-04-18 15:57:46 +0000630 else
631 std::advance(SI, 1);
Samuel Antao5de996e2016-01-22 20:21:36 +0000632
633 for (; SI != SE; ++SI) {
Samuel Antao90927002016-04-26 14:54:23 +0000634 auto MI = SI->MappedExprComponents.find(VD);
635 if (MI != SI->MappedExprComponents.end())
Alexey Bataeve3727102018-04-18 15:57:46 +0000636 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
637 MI->second.Components)
Samuel Antao6890b092016-07-28 14:25:09 +0000638 if (Check(L, MI->second.Kind))
Samuel Antao5de996e2016-01-22 20:21:36 +0000639 return true;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000640 }
Samuel Antao5de996e2016-01-22 20:21:36 +0000641 return false;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000642 }
643
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000644 /// Do the check specified in \a Check to all component lists at a given level
645 /// and return true if any issue is found.
646 bool checkMappableExprComponentListsForDeclAtLevel(
Alexey Bataeve3727102018-04-18 15:57:46 +0000647 const ValueDecl *VD, unsigned Level,
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000648 const llvm::function_ref<
649 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000650 OpenMPClauseKind)>
Alexey Bataeve3727102018-04-18 15:57:46 +0000651 Check) const {
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000652 if (isStackEmpty())
653 return false;
654
655 auto StartI = Stack.back().first.begin();
656 auto EndI = Stack.back().first.end();
657 if (std::distance(StartI, EndI) <= (int)Level)
658 return false;
659 std::advance(StartI, Level);
660
661 auto MI = StartI->MappedExprComponents.find(VD);
662 if (MI != StartI->MappedExprComponents.end())
Alexey Bataeve3727102018-04-18 15:57:46 +0000663 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
664 MI->second.Components)
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000665 if (Check(L, MI->second.Kind))
666 return true;
667 return false;
668 }
669
Samuel Antao4c8035b2016-12-12 18:00:20 +0000670 /// Create a new mappable expression component list associated with a given
671 /// declaration and initialize it with the provided list of components.
Samuel Antao90927002016-04-26 14:54:23 +0000672 void addMappableExpressionComponents(
Alexey Bataeve3727102018-04-18 15:57:46 +0000673 const ValueDecl *VD,
Samuel Antao6890b092016-07-28 14:25:09 +0000674 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
675 OpenMPClauseKind WhereFoundClauseKind) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000676 assert(!isStackEmpty() &&
Samuel Antao90927002016-04-26 14:54:23 +0000677 "Not expecting to retrieve components from a empty stack!");
Alexey Bataeve3727102018-04-18 15:57:46 +0000678 MappedExprComponentTy &MEC =
679 Stack.back().first.back().MappedExprComponents[VD];
Samuel Antao90927002016-04-26 14:54:23 +0000680 // Create new entry and append the new components there.
Samuel Antao6890b092016-07-28 14:25:09 +0000681 MEC.Components.resize(MEC.Components.size() + 1);
682 MEC.Components.back().append(Components.begin(), Components.end());
683 MEC.Kind = WhereFoundClauseKind;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000684 }
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000685
686 unsigned getNestingLevel() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000687 assert(!isStackEmpty());
688 return Stack.back().first.size() - 1;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000689 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000690 void addDoacrossDependClause(OMPDependClause *C,
691 const OperatorOffsetTy &OpsOffs) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000692 assert(!isStackEmpty() && Stack.back().first.size() > 1);
Alexey Bataeve3727102018-04-18 15:57:46 +0000693 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
Alexey Bataev4b465392017-04-26 15:06:24 +0000694 assert(isOpenMPWorksharingDirective(StackElem.Directive));
Alexey Bataeve3727102018-04-18 15:57:46 +0000695 StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
Alexey Bataev8b427062016-05-25 12:36:08 +0000696 }
697 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
698 getDoacrossDependClauses() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000699 assert(!isStackEmpty());
Alexey Bataeve3727102018-04-18 15:57:46 +0000700 const SharingMapTy &StackElem = Stack.back().first.back();
Alexey Bataev4b465392017-04-26 15:06:24 +0000701 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000702 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
Alexey Bataev8b427062016-05-25 12:36:08 +0000703 return llvm::make_range(Ref.begin(), Ref.end());
704 }
Alexey Bataev4b465392017-04-26 15:06:24 +0000705 return llvm::make_range(StackElem.DoacrossDepends.end(),
706 StackElem.DoacrossDepends.end());
Alexey Bataev8b427062016-05-25 12:36:08 +0000707 }
Patrick Lystere13b1e32019-01-02 19:28:48 +0000708
709 // Store types of classes which have been explicitly mapped
710 void addMappedClassesQualTypes(QualType QT) {
711 SharingMapTy &StackElem = Stack.back().first.back();
712 StackElem.MappedClassesQualTypes.insert(QT);
713 }
714
715 // Return set of mapped classes types
716 bool isClassPreviouslyMapped(QualType QT) const {
717 const SharingMapTy &StackElem = Stack.back().first.back();
718 return StackElem.MappedClassesQualTypes.count(QT) != 0;
719 }
720
Alexey Bataeva495c642019-03-11 19:51:42 +0000721 /// Adds global declare target to the parent target region.
722 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
723 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
724 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
725 "Expected declare target link global.");
726 if (isStackEmpty())
727 return;
728 auto It = Stack.back().first.rbegin();
729 while (It != Stack.back().first.rend() &&
730 !isOpenMPTargetExecutionDirective(It->Directive))
731 ++It;
732 if (It != Stack.back().first.rend()) {
733 assert(isOpenMPTargetExecutionDirective(It->Directive) &&
734 "Expected target executable directive.");
735 It->DeclareTargetLinkVarDecls.push_back(E);
736 }
737 }
738
739 /// Returns the list of globals with declare target link if current directive
740 /// is target.
741 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
742 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
743 "Expected target executable directive.");
744 return Stack.back().first.back().DeclareTargetLinkVarDecls;
745 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000746};
Alexey Bataev7e6803e2019-01-09 15:58:05 +0000747
748bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
749 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
750}
751
752bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
Alexey Bataev412254a2019-05-09 18:44:53 +0000753 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
754 DKind == OMPD_unknown;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000755}
Alexey Bataeve3727102018-04-18 15:57:46 +0000756
Alexey Bataeved09d242014-05-28 05:53:51 +0000757} // namespace
Alexey Bataev758e55e2013-09-06 18:03:48 +0000758
Alexey Bataeve3727102018-04-18 15:57:46 +0000759static const Expr *getExprAsWritten(const Expr *E) {
Bill Wendling7c44da22018-10-31 03:48:47 +0000760 if (const auto *FE = dyn_cast<FullExpr>(E))
761 E = FE->getSubExpr();
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000762
Alexey Bataeve3727102018-04-18 15:57:46 +0000763 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000764 E = MTE->GetTemporaryExpr();
765
Alexey Bataeve3727102018-04-18 15:57:46 +0000766 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000767 E = Binder->getSubExpr();
768
Alexey Bataeve3727102018-04-18 15:57:46 +0000769 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000770 E = ICE->getSubExprAsWritten();
771 return E->IgnoreParens();
772}
773
Alexey Bataeve3727102018-04-18 15:57:46 +0000774static Expr *getExprAsWritten(Expr *E) {
775 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
776}
777
778static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
779 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
780 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000781 D = ME->getMemberDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +0000782 const auto *VD = dyn_cast<VarDecl>(D);
783 const auto *FD = dyn_cast<FieldDecl>(D);
David Majnemer9d168222016-08-05 17:44:54 +0000784 if (VD != nullptr) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000785 VD = VD->getCanonicalDecl();
786 D = VD;
787 } else {
788 assert(FD);
789 FD = FD->getCanonicalDecl();
790 D = FD;
791 }
792 return D;
793}
794
Alexey Bataeve3727102018-04-18 15:57:46 +0000795static ValueDecl *getCanonicalDecl(ValueDecl *D) {
796 return const_cast<ValueDecl *>(
797 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
798}
799
800DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
801 ValueDecl *D) const {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000802 D = getCanonicalDecl(D);
803 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000804 const auto *FD = dyn_cast<FieldDecl>(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000805 DSAVarData DVar;
Alexey Bataev4b465392017-04-26 15:06:24 +0000806 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
Alexey Bataev750a58b2014-03-18 12:19:12 +0000807 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
808 // in a region but not in construct]
809 // File-scope or namespace-scope variables referenced in called routines
810 // in the region are shared unless they appear in a threadprivate
811 // directive.
Alexey Bataeve3727102018-04-18 15:57:46 +0000812 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
Alexey Bataev750a58b2014-03-18 12:19:12 +0000813 DVar.CKind = OMPC_shared;
814
815 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
816 // in a region but not in construct]
817 // Variables with static storage duration that are declared in called
818 // routines in the region are shared.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000819 if (VD && VD->hasGlobalStorage())
820 DVar.CKind = OMPC_shared;
821
822 // Non-static data members are shared by default.
823 if (FD)
Alexey Bataev750a58b2014-03-18 12:19:12 +0000824 DVar.CKind = OMPC_shared;
825
Alexey Bataev758e55e2013-09-06 18:03:48 +0000826 return DVar;
827 }
Alexey Bataevec3da872014-01-31 05:15:34 +0000828
Alexey Bataevec3da872014-01-31 05:15:34 +0000829 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
830 // in a Construct, C/C++, predetermined, p.1]
831 // Variables with automatic storage duration that are declared in a scope
832 // inside the construct are private.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000833 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
834 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
Alexey Bataevf29276e2014-06-18 04:14:57 +0000835 DVar.CKind = OMPC_private;
836 return DVar;
Alexey Bataevec3da872014-01-31 05:15:34 +0000837 }
838
Alexey Bataeveffbdf12017-07-21 17:24:30 +0000839 DVar.DKind = Iter->Directive;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000840 // Explicitly specified attributes and local variables with predetermined
841 // attributes.
842 if (Iter->SharingMap.count(D)) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000843 const DSAInfo &Data = Iter->SharingMap.lookup(D);
844 DVar.RefExpr = Data.RefExpr.getPointer();
845 DVar.PrivateCopy = Data.PrivateCopy;
846 DVar.CKind = Data.Attributes;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000847 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000848 return DVar;
849 }
850
851 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
852 // in a Construct, C/C++, implicitly determined, p.1]
853 // In a parallel or task construct, the data-sharing attributes of these
854 // variables are determined by the default clause, if present.
855 switch (Iter->DefaultAttr) {
856 case DSA_shared:
857 DVar.CKind = OMPC_shared;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000858 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000859 return DVar;
860 case DSA_none:
861 return DVar;
862 case DSA_unspecified:
863 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
864 // in a Construct, implicitly determined, p.2]
865 // In a parallel construct, if no default clause is present, these
866 // variables are shared.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000867 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev13314bf2014-10-09 04:18:56 +0000868 if (isOpenMPParallelDirective(DVar.DKind) ||
869 isOpenMPTeamsDirective(DVar.DKind)) {
Alexey Bataev758e55e2013-09-06 18:03:48 +0000870 DVar.CKind = OMPC_shared;
871 return DVar;
872 }
873
874 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
875 // in a Construct, implicitly determined, p.4]
876 // In a task construct, if no default clause is present, a variable that in
877 // the enclosing context is determined to be shared by all implicit tasks
878 // bound to the current team is shared.
Alexey Bataev35aaee62016-04-13 13:36:48 +0000879 if (isOpenMPTaskingDirective(DVar.DKind)) {
Alexey Bataev758e55e2013-09-06 18:03:48 +0000880 DSAVarData DVarTemp;
Alexey Bataeve3727102018-04-18 15:57:46 +0000881 iterator I = Iter, E = Stack.back().first.rend();
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000882 do {
883 ++I;
Alexey Bataeved09d242014-05-28 05:53:51 +0000884 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
Alexey Bataev35aaee62016-04-13 13:36:48 +0000885 // Referenced in a Construct, implicitly determined, p.6]
Alexey Bataev758e55e2013-09-06 18:03:48 +0000886 // In a task construct, if no default clause is present, a variable
887 // whose data-sharing attribute is not determined by the rules above is
888 // firstprivate.
889 DVarTemp = getDSA(I, D);
890 if (DVarTemp.CKind != OMPC_shared) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +0000891 DVar.RefExpr = nullptr;
Alexey Bataevd5af8e42013-10-01 05:32:34 +0000892 DVar.CKind = OMPC_firstprivate;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000893 return DVar;
894 }
Alexey Bataev7e6803e2019-01-09 15:58:05 +0000895 } while (I != E && !isImplicitTaskingRegion(I->Directive));
Alexey Bataev758e55e2013-09-06 18:03:48 +0000896 DVar.CKind =
Alexey Bataeved09d242014-05-28 05:53:51 +0000897 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000898 return DVar;
899 }
900 }
901 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
902 // in a Construct, implicitly determined, p.3]
903 // For constructs other than task, if no default clause is present, these
904 // variables inherit their data-sharing attributes from the enclosing
905 // context.
Dmitry Polukhindc78bc822016-04-01 09:52:30 +0000906 return getDSA(++Iter, D);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000907}
908
Alexey Bataeve3727102018-04-18 15:57:46 +0000909const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
910 const Expr *NewDE) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000911 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000912 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000913 SharingMapTy &StackElem = Stack.back().first.back();
Alexey Bataev4b465392017-04-26 15:06:24 +0000914 auto It = StackElem.AlignedMap.find(D);
915 if (It == StackElem.AlignedMap.end()) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000916 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
Alexey Bataev4b465392017-04-26 15:06:24 +0000917 StackElem.AlignedMap[D] = NewDE;
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000918 return nullptr;
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000919 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000920 assert(It->second && "Unexpected nullptr expr in the aligned map");
921 return It->second;
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000922}
923
Alexey Bataeve3727102018-04-18 15:57:46 +0000924void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
Alexey Bataev4b465392017-04-26 15:06:24 +0000925 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000926 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000927 SharingMapTy &StackElem = Stack.back().first.back();
928 StackElem.LCVMap.try_emplace(
929 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
Alexey Bataev9c821032015-04-30 04:23:23 +0000930}
931
Alexey Bataeve3727102018-04-18 15:57:46 +0000932const DSAStackTy::LCDeclInfo
933DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000934 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000935 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000936 const SharingMapTy &StackElem = Stack.back().first.back();
Alexey Bataev4b465392017-04-26 15:06:24 +0000937 auto It = StackElem.LCVMap.find(D);
938 if (It != StackElem.LCVMap.end())
939 return It->second;
940 return {0, nullptr};
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000941}
942
Alexey Bataeve3727102018-04-18 15:57:46 +0000943const DSAStackTy::LCDeclInfo
944DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000945 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
946 "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000947 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000948 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
Alexey Bataev4b465392017-04-26 15:06:24 +0000949 auto It = StackElem.LCVMap.find(D);
950 if (It != StackElem.LCVMap.end())
951 return It->second;
952 return {0, nullptr};
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000953}
954
Alexey Bataeve3727102018-04-18 15:57:46 +0000955const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000956 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
957 "Data-sharing attributes stack is empty");
Alexey Bataeve3727102018-04-18 15:57:46 +0000958 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
Alexey Bataev4b465392017-04-26 15:06:24 +0000959 if (StackElem.LCVMap.size() < I)
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000960 return nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +0000961 for (const auto &Pair : StackElem.LCVMap)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +0000962 if (Pair.second.first == I)
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000963 return Pair.first;
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000964 return nullptr;
Alexey Bataev9c821032015-04-30 04:23:23 +0000965}
966
Alexey Bataeve3727102018-04-18 15:57:46 +0000967void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
Alexey Bataev90c228f2016-02-08 09:29:13 +0000968 DeclRefExpr *PrivateCopy) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000969 D = getCanonicalDecl(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000970 if (A == OMPC_threadprivate) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000971 DSAInfo &Data = Threadprivates[D];
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000972 Data.Attributes = A;
973 Data.RefExpr.setPointer(E);
974 Data.PrivateCopy = nullptr;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000975 } else {
Alexey Bataev4b465392017-04-26 15:06:24 +0000976 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataeve3727102018-04-18 15:57:46 +0000977 DSAInfo &Data = Stack.back().first.back().SharingMap[D];
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000978 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
979 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
980 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
981 (isLoopControlVariable(D).first && A == OMPC_private));
982 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
983 Data.RefExpr.setInt(/*IntVal=*/true);
984 return;
985 }
986 const bool IsLastprivate =
987 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
988 Data.Attributes = A;
989 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
990 Data.PrivateCopy = PrivateCopy;
991 if (PrivateCopy) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000992 DSAInfo &Data =
993 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000994 Data.Attributes = A;
995 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
996 Data.PrivateCopy = nullptr;
997 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000998 }
999}
1000
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001001/// Build a variable declaration for OpenMP loop iteration variable.
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001002static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001003 StringRef Name, const AttrVec *Attrs = nullptr,
1004 DeclRefExpr *OrigRef = nullptr) {
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001005 DeclContext *DC = SemaRef.CurContext;
1006 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1007 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
Alexey Bataeve3727102018-04-18 15:57:46 +00001008 auto *Decl =
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001009 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1010 if (Attrs) {
1011 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1012 I != E; ++I)
1013 Decl->addAttr(*I);
1014 }
1015 Decl->setImplicit();
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001016 if (OrigRef) {
1017 Decl->addAttr(
1018 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1019 }
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001020 return Decl;
1021}
1022
1023static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1024 SourceLocation Loc,
1025 bool RefersToCapture = false) {
1026 D->setReferenced();
1027 D->markUsed(S.Context);
1028 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1029 SourceLocation(), D, RefersToCapture, Loc, Ty,
1030 VK_LValue);
1031}
1032
Alexey Bataeve3727102018-04-18 15:57:46 +00001033void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001034 BinaryOperatorKind BOK) {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001035 D = getCanonicalDecl(D);
1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataevfa312f32017-07-21 18:48:21 +00001037 assert(
Richard Trieu09f14112017-07-21 21:29:35 +00001038 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001039 "Additional reduction info may be specified only for reduction items.");
Alexey Bataeve3727102018-04-18 15:57:46 +00001040 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
Alexey Bataevfa312f32017-07-21 18:48:21 +00001041 assert(ReductionData.ReductionRange.isInvalid() &&
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001042 Stack.back().first.back().Directive == OMPD_taskgroup &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001043 "Additional reduction info may be specified only once for reduction "
1044 "items.");
1045 ReductionData.set(BOK, SR);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001046 Expr *&TaskgroupReductionRef =
1047 Stack.back().first.back().TaskgroupReductionRef;
1048 if (!TaskgroupReductionRef) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001049 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1050 SemaRef.Context.VoidPtrTy, ".task_red.");
Alexey Bataevd070a582017-10-25 15:54:04 +00001051 TaskgroupReductionRef =
1052 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001053 }
Alexey Bataevfa312f32017-07-21 18:48:21 +00001054}
1055
Alexey Bataeve3727102018-04-18 15:57:46 +00001056void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001057 const Expr *ReductionRef) {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001058 D = getCanonicalDecl(D);
1059 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataevfa312f32017-07-21 18:48:21 +00001060 assert(
Richard Trieu09f14112017-07-21 21:29:35 +00001061 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001062 "Additional reduction info may be specified only for reduction items.");
Alexey Bataeve3727102018-04-18 15:57:46 +00001063 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
Alexey Bataevfa312f32017-07-21 18:48:21 +00001064 assert(ReductionData.ReductionRange.isInvalid() &&
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001065 Stack.back().first.back().Directive == OMPD_taskgroup &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001066 "Additional reduction info may be specified only once for reduction "
1067 "items.");
1068 ReductionData.set(ReductionRef, SR);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001069 Expr *&TaskgroupReductionRef =
1070 Stack.back().first.back().TaskgroupReductionRef;
1071 if (!TaskgroupReductionRef) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001072 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1073 SemaRef.Context.VoidPtrTy, ".task_red.");
Alexey Bataevd070a582017-10-25 15:54:04 +00001074 TaskgroupReductionRef =
1075 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001076 }
Alexey Bataevfa312f32017-07-21 18:48:21 +00001077}
1078
Alexey Bataeve3727102018-04-18 15:57:46 +00001079const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1080 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1081 Expr *&TaskgroupDescriptor) const {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001082 D = getCanonicalDecl(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001083 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1084 if (Stack.back().first.empty())
1085 return DSAVarData();
Alexey Bataeve3727102018-04-18 15:57:46 +00001086 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1087 E = Stack.back().first.rend();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001088 I != E; std::advance(I, 1)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001089 const DSAInfo &Data = I->SharingMap.lookup(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001090 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
Alexey Bataevfa312f32017-07-21 18:48:21 +00001091 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +00001092 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001093 if (!ReductionData.ReductionOp ||
1094 ReductionData.ReductionOp.is<const Expr *>())
Alexey Bataevf189cb72017-07-24 14:52:13 +00001095 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001096 SR = ReductionData.ReductionRange;
Alexey Bataevf87fa882017-07-21 19:26:22 +00001097 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
Alexey Bataev88202be2017-07-27 13:20:36 +00001098 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1099 "expression for the descriptor is not "
1100 "set.");
1101 TaskgroupDescriptor = I->TaskgroupReductionRef;
Alexey Bataevf189cb72017-07-24 14:52:13 +00001102 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1103 Data.PrivateCopy, I->DefaultAttrLoc);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001104 }
Alexey Bataevf189cb72017-07-24 14:52:13 +00001105 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001106}
1107
Alexey Bataeve3727102018-04-18 15:57:46 +00001108const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1109 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1110 Expr *&TaskgroupDescriptor) const {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001111 D = getCanonicalDecl(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001112 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1113 if (Stack.back().first.empty())
1114 return DSAVarData();
Alexey Bataeve3727102018-04-18 15:57:46 +00001115 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1116 E = Stack.back().first.rend();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001117 I != E; std::advance(I, 1)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001118 const DSAInfo &Data = I->SharingMap.lookup(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001119 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
Alexey Bataevfa312f32017-07-21 18:48:21 +00001120 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +00001121 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001122 if (!ReductionData.ReductionOp ||
1123 !ReductionData.ReductionOp.is<const Expr *>())
Alexey Bataevf189cb72017-07-24 14:52:13 +00001124 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001125 SR = ReductionData.ReductionRange;
1126 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
Alexey Bataev88202be2017-07-27 13:20:36 +00001127 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1128 "expression for the descriptor is not "
1129 "set.");
1130 TaskgroupDescriptor = I->TaskgroupReductionRef;
Alexey Bataevf189cb72017-07-24 14:52:13 +00001131 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1132 Data.PrivateCopy, I->DefaultAttrLoc);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001133 }
Alexey Bataevf189cb72017-07-24 14:52:13 +00001134 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001135}
1136
Alexey Bataeve3727102018-04-18 15:57:46 +00001137bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
Alexey Bataev6ddfe1a2015-04-16 13:49:42 +00001138 D = D->getCanonicalDecl();
Alexey Bataev852525d2018-03-02 17:17:12 +00001139 if (!isStackEmpty()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001140 iterator I = Iter, E = Stack.back().first.rend();
Alexander Musmancb7f9c42014-05-15 13:04:49 +00001141 Scope *TopScope = nullptr;
Alexey Bataev7e6803e2019-01-09 15:58:05 +00001142 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
Alexey Bataev852525d2018-03-02 17:17:12 +00001143 !isOpenMPTargetExecutionDirective(I->Directive))
Alexey Bataevec3da872014-01-31 05:15:34 +00001144 ++I;
Alexey Bataeved09d242014-05-28 05:53:51 +00001145 if (I == E)
1146 return false;
Alexander Musmancb7f9c42014-05-15 13:04:49 +00001147 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
Alexey Bataevec3da872014-01-31 05:15:34 +00001148 Scope *CurScope = getCurScope();
Alexey Bataeve66bf632019-04-29 15:51:36 +00001149 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
Alexey Bataev758e55e2013-09-06 18:03:48 +00001150 CurScope = CurScope->getParent();
Alexey Bataevec3da872014-01-31 05:15:34 +00001151 return CurScope != TopScope;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001152 }
Alexey Bataevec3da872014-01-31 05:15:34 +00001153 return false;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001154}
1155
Joel E. Dennyd2649292019-01-04 22:11:56 +00001156static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1157 bool AcceptIfMutable = true,
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001158 bool *IsClassType = nullptr) {
1159 ASTContext &Context = SemaRef.getASTContext();
Joel E. Dennyd2649292019-01-04 22:11:56 +00001160 Type = Type.getNonReferenceType().getCanonicalType();
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001161 bool IsConstant = Type.isConstant(Context);
1162 Type = Context.getBaseElementType(Type);
Joel E. Dennyd2649292019-01-04 22:11:56 +00001163 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1164 ? Type->getAsCXXRecordDecl()
1165 : nullptr;
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001166 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1167 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1168 RD = CTD->getTemplatedDecl();
1169 if (IsClassType)
1170 *IsClassType = RD;
1171 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1172 RD->hasDefinition() && RD->hasMutableFields());
1173}
1174
Joel E. Dennyd2649292019-01-04 22:11:56 +00001175static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1176 QualType Type, OpenMPClauseKind CKind,
1177 SourceLocation ELoc,
1178 bool AcceptIfMutable = true,
1179 bool ListItemNotVar = false) {
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001180 ASTContext &Context = SemaRef.getASTContext();
1181 bool IsClassType;
Joel E. Dennyd2649292019-01-04 22:11:56 +00001182 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1183 unsigned Diag = ListItemNotVar
1184 ? diag::err_omp_const_list_item
1185 : IsClassType ? diag::err_omp_const_not_mutable_variable
1186 : diag::err_omp_const_variable;
1187 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1188 if (!ListItemNotVar && D) {
1189 const VarDecl *VD = dyn_cast<VarDecl>(D);
1190 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1191 VarDecl::DeclarationOnly;
1192 SemaRef.Diag(D->getLocation(),
1193 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1194 << D;
1195 }
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001196 return true;
1197 }
1198 return false;
1199}
1200
Alexey Bataeve3727102018-04-18 15:57:46 +00001201const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1202 bool FromParent) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001203 D = getCanonicalDecl(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001204 DSAVarData DVar;
1205
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001206 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001207 auto TI = Threadprivates.find(D);
1208 if (TI != Threadprivates.end()) {
1209 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
Alexey Bataev758e55e2013-09-06 18:03:48 +00001210 DVar.CKind = OMPC_threadprivate;
1211 return DVar;
Alexey Bataeve3727102018-04-18 15:57:46 +00001212 }
1213 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
Alexey Bataev817d7f32017-11-14 21:01:01 +00001214 DVar.RefExpr = buildDeclRefExpr(
1215 SemaRef, VD, D->getType().getNonReferenceType(),
1216 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1217 DVar.CKind = OMPC_threadprivate;
1218 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
Alexey Bataev852525d2018-03-02 17:17:12 +00001219 return DVar;
1220 }
1221 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1222 // in a Construct, C/C++, predetermined, p.1]
1223 // Variables appearing in threadprivate directives are threadprivate.
1224 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1225 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1226 SemaRef.getLangOpts().OpenMPUseTLS &&
1227 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1228 (VD && VD->getStorageClass() == SC_Register &&
1229 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1230 DVar.RefExpr = buildDeclRefExpr(
1231 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1232 DVar.CKind = OMPC_threadprivate;
1233 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1234 return DVar;
1235 }
1236 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1237 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1238 !isLoopControlVariable(D).first) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001239 iterator IterTarget =
Alexey Bataev852525d2018-03-02 17:17:12 +00001240 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1241 [](const SharingMapTy &Data) {
1242 return isOpenMPTargetExecutionDirective(Data.Directive);
1243 });
1244 if (IterTarget != Stack.back().first.rend()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001245 iterator ParentIterTarget = std::next(IterTarget, 1);
1246 for (iterator Iter = Stack.back().first.rbegin();
1247 Iter != ParentIterTarget; std::advance(Iter, 1)) {
Alexey Bataev852525d2018-03-02 17:17:12 +00001248 if (isOpenMPLocal(VD, Iter)) {
1249 DVar.RefExpr =
1250 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1251 D->getLocation());
1252 DVar.CKind = OMPC_threadprivate;
1253 return DVar;
1254 }
Alexey Bataev852525d2018-03-02 17:17:12 +00001255 }
1256 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1257 auto DSAIter = IterTarget->SharingMap.find(D);
1258 if (DSAIter != IterTarget->SharingMap.end() &&
1259 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1260 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1261 DVar.CKind = OMPC_threadprivate;
1262 return DVar;
Alexey Bataeve3727102018-04-18 15:57:46 +00001263 }
1264 iterator End = Stack.back().first.rend();
1265 if (!SemaRef.isOpenMPCapturedByRef(
1266 D, std::distance(ParentIterTarget, End))) {
Alexey Bataev852525d2018-03-02 17:17:12 +00001267 DVar.RefExpr =
1268 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1269 IterTarget->ConstructLoc);
1270 DVar.CKind = OMPC_threadprivate;
1271 return DVar;
1272 }
1273 }
1274 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001275 }
1276
Alexey Bataev4b465392017-04-26 15:06:24 +00001277 if (isStackEmpty())
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001278 // Not in OpenMP execution region and top scope was already checked.
1279 return DVar;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001280
Alexey Bataev758e55e2013-09-06 18:03:48 +00001281 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
Alexey Bataevdffa93a2015-12-10 08:20:58 +00001282 // in a Construct, C/C++, predetermined, p.4]
1283 // Static data members are shared.
1284 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1285 // in a Construct, C/C++, predetermined, p.7]
1286 // Variables with static storage duration that are declared in a scope
1287 // inside the construct are shared.
Alexey Bataeve3727102018-04-18 15:57:46 +00001288 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001289 if (VD && VD->isStaticDataMember()) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001290 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
Alexey Bataevdffa93a2015-12-10 08:20:58 +00001291 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
Alexey Bataevec3da872014-01-31 05:15:34 +00001292 return DVar;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001293
Alexey Bataevdffa93a2015-12-10 08:20:58 +00001294 DVar.CKind = OMPC_shared;
1295 return DVar;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001296 }
1297
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001298 // The predetermined shared attribute for const-qualified types having no
1299 // mutable members was removed after OpenMP 3.1.
1300 if (SemaRef.LangOpts.OpenMP <= 31) {
1301 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1302 // in a Construct, C/C++, predetermined, p.6]
1303 // Variables with const qualified type having no mutable member are
1304 // shared.
Joel E. Dennyd2649292019-01-04 22:11:56 +00001305 if (isConstNotMutableType(SemaRef, D->getType())) {
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001306 // Variables with const-qualified type having no mutable member may be
1307 // listed in a firstprivate clause, even if they are static data members.
1308 DSAVarData DVarTemp = hasInnermostDSA(
1309 D,
1310 [](OpenMPClauseKind C) {
1311 return C == OMPC_firstprivate || C == OMPC_shared;
1312 },
1313 MatchesAlways, FromParent);
1314 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1315 return DVarTemp;
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001316
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001317 DVar.CKind = OMPC_shared;
1318 return DVar;
1319 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001320 }
1321
Alexey Bataev758e55e2013-09-06 18:03:48 +00001322 // Explicitly specified attributes and local variables with predetermined
1323 // attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +00001324 iterator I = Stack.back().first.rbegin();
1325 iterator EndI = Stack.back().first.rend();
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001326 if (FromParent && I != EndI)
1327 std::advance(I, 1);
Alexey Bataeve3727102018-04-18 15:57:46 +00001328 auto It = I->SharingMap.find(D);
1329 if (It != I->SharingMap.end()) {
1330 const DSAInfo &Data = It->getSecond();
1331 DVar.RefExpr = Data.RefExpr.getPointer();
1332 DVar.PrivateCopy = Data.PrivateCopy;
1333 DVar.CKind = Data.Attributes;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001334 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
Alexey Bataev4d4624c2017-07-20 16:47:47 +00001335 DVar.DKind = I->Directive;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001336 }
1337
1338 return DVar;
1339}
1340
Alexey Bataeve3727102018-04-18 15:57:46 +00001341const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1342 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001343 if (isStackEmpty()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001344 iterator I;
Alexey Bataev4b465392017-04-26 15:06:24 +00001345 return getDSA(I, D);
1346 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001347 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +00001348 iterator StartI = Stack.back().first.rbegin();
1349 iterator EndI = Stack.back().first.rend();
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001350 if (FromParent && StartI != EndI)
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001351 std::advance(StartI, 1);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001352 return getDSA(StartI, D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001353}
1354
Alexey Bataeve3727102018-04-18 15:57:46 +00001355const DSAStackTy::DSAVarData
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001356DSAStackTy::hasDSA(ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001357 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1358 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001359 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001360 if (isStackEmpty())
1361 return {};
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001362 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +00001363 iterator I = Stack.back().first.rbegin();
1364 iterator EndI = Stack.back().first.rend();
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001365 if (FromParent && I != EndI)
Alexey Bataev0e6fc1c2017-04-27 14:46:26 +00001366 std::advance(I, 1);
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001367 for (; I != EndI; std::advance(I, 1)) {
Alexey Bataev7e6803e2019-01-09 15:58:05 +00001368 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
Alexey Bataeved09d242014-05-28 05:53:51 +00001369 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +00001370 iterator NewI = I;
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001371 DSAVarData DVar = getDSA(NewI, D);
1372 if (I == NewI && CPred(DVar.CKind))
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001373 return DVar;
Alexey Bataev60859c02017-04-27 15:10:33 +00001374 }
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001375 return {};
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001376}
1377
Alexey Bataeve3727102018-04-18 15:57:46 +00001378const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001379 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1380 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001381 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001382 if (isStackEmpty())
1383 return {};
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001384 D = getCanonicalDecl(D);
Alexey Bataeve3727102018-04-18 15:57:46 +00001385 iterator StartI = Stack.back().first.rbegin();
1386 iterator EndI = Stack.back().first.rend();
Alexey Bataeve3978122016-07-19 05:06:39 +00001387 if (FromParent && StartI != EndI)
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001388 std::advance(StartI, 1);
Alexey Bataeve3978122016-07-19 05:06:39 +00001389 if (StartI == EndI || !DPred(StartI->Directive))
Alexey Bataev4b465392017-04-26 15:06:24 +00001390 return {};
Alexey Bataeve3727102018-04-18 15:57:46 +00001391 iterator NewI = StartI;
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001392 DSAVarData DVar = getDSA(NewI, D);
1393 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
Alexey Bataevc5e02582014-06-16 07:08:35 +00001394}
1395
Alexey Bataevaac108a2015-06-23 04:51:00 +00001396bool DSAStackTy::hasExplicitDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00001397 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1398 unsigned Level, bool NotLastprivate) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001399 if (isStackEmpty())
1400 return false;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001401 D = getCanonicalDecl(D);
Alexey Bataev4b465392017-04-26 15:06:24 +00001402 auto StartI = Stack.back().first.begin();
1403 auto EndI = Stack.back().first.end();
NAKAMURA Takumi0332eda2015-06-23 10:01:20 +00001404 if (std::distance(StartI, EndI) <= (int)Level)
Alexey Bataevaac108a2015-06-23 04:51:00 +00001405 return false;
1406 std::advance(StartI, Level);
Alexey Bataeve3727102018-04-18 15:57:46 +00001407 auto I = StartI->SharingMap.find(D);
Alexey Bataev92b33652018-11-21 19:41:10 +00001408 if ((I != StartI->SharingMap.end()) &&
Alexey Bataeve3727102018-04-18 15:57:46 +00001409 I->getSecond().RefExpr.getPointer() &&
1410 CPred(I->getSecond().Attributes) &&
Alexey Bataev92b33652018-11-21 19:41:10 +00001411 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1412 return true;
1413 // Check predetermined rules for the loop control variables.
1414 auto LI = StartI->LCVMap.find(D);
1415 if (LI != StartI->LCVMap.end())
1416 return CPred(OMPC_private);
1417 return false;
Alexey Bataevaac108a2015-06-23 04:51:00 +00001418}
1419
Samuel Antao4be30e92015-10-02 17:14:03 +00001420bool DSAStackTy::hasExplicitDirective(
Alexey Bataeve3727102018-04-18 15:57:46 +00001421 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1422 unsigned Level) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001423 if (isStackEmpty())
1424 return false;
1425 auto StartI = Stack.back().first.begin();
1426 auto EndI = Stack.back().first.end();
Samuel Antao4be30e92015-10-02 17:14:03 +00001427 if (std::distance(StartI, EndI) <= (int)Level)
1428 return false;
1429 std::advance(StartI, Level);
1430 return DPred(StartI->Directive);
1431}
1432
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001433bool DSAStackTy::hasDirective(
1434 const llvm::function_ref<bool(OpenMPDirectiveKind,
1435 const DeclarationNameInfo &, SourceLocation)>
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001436 DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001437 bool FromParent) const {
Samuel Antaof0d79752016-05-27 15:21:27 +00001438 // We look only in the enclosing region.
Alexey Bataev4b465392017-04-26 15:06:24 +00001439 if (isStackEmpty())
Samuel Antaof0d79752016-05-27 15:21:27 +00001440 return false;
Alexey Bataev4b465392017-04-26 15:06:24 +00001441 auto StartI = std::next(Stack.back().first.rbegin());
1442 auto EndI = Stack.back().first.rend();
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001443 if (FromParent && StartI != EndI)
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001444 StartI = std::next(StartI);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001445 for (auto I = StartI, EE = EndI; I != EE; ++I) {
1446 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1447 return true;
1448 }
1449 return false;
1450}
1451
Alexey Bataev758e55e2013-09-06 18:03:48 +00001452void Sema::InitDataSharingAttributesStack() {
1453 VarDataSharingAttributesStack = new DSAStackTy(*this);
1454}
1455
1456#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1457
Alexey Bataev4b465392017-04-26 15:06:24 +00001458void Sema::pushOpenMPFunctionRegion() {
1459 DSAStack->pushFunction();
1460}
1461
1462void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1463 DSAStack->popFunction(OldFSI);
1464}
1465
Alexey Bataevc416e642019-02-08 18:02:25 +00001466static bool isOpenMPDeviceDelayedContext(Sema &S) {
1467 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1468 "Expected OpenMP device compilation.");
1469 return !S.isInOpenMPTargetExecutionDirective() &&
1470 !S.isInOpenMPDeclareTargetContext();
1471}
1472
1473/// Do we know that we will eventually codegen the given function?
1474static bool isKnownEmitted(Sema &S, FunctionDecl *FD) {
1475 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1476 "Expected OpenMP device compilation.");
1477 // Templates are emitted when they're instantiated.
1478 if (FD->isDependentContext())
1479 return false;
1480
1481 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1482 FD->getCanonicalDecl()))
1483 return true;
1484
1485 // Otherwise, the function is known-emitted if it's in our set of
1486 // known-emitted functions.
1487 return S.DeviceKnownEmittedFns.count(FD) > 0;
1488}
1489
1490Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1491 unsigned DiagID) {
1492 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1493 "Expected OpenMP device compilation.");
1494 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) &&
1495 !isKnownEmitted(*this, getCurFunctionDecl()))
1496 ? DeviceDiagBuilder::K_Deferred
1497 : DeviceDiagBuilder::K_Immediate,
1498 Loc, DiagID, getCurFunctionDecl(), *this);
1499}
1500
1501void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) {
1502 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1503 "Expected OpenMP device compilation.");
1504 assert(Callee && "Callee may not be null.");
1505 FunctionDecl *Caller = getCurFunctionDecl();
1506
1507 // If the caller is known-emitted, mark the callee as known-emitted.
1508 // Otherwise, mark the call in our call graph so we can traverse it later.
1509 if (!isOpenMPDeviceDelayedContext(*this) ||
1510 (Caller && isKnownEmitted(*this, Caller)))
1511 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted);
1512 else if (Caller)
1513 DeviceCallGraph[Caller].insert({Callee, Loc});
1514}
1515
Alexey Bataev123ad192019-02-27 20:29:45 +00001516void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1517 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1518 "OpenMP device compilation mode is expected.");
1519 QualType Ty = E->getType();
1520 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1521 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) ||
1522 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1523 !Context.getTargetInfo().hasInt128Type()))
1524 targetDiag(E->getExprLoc(), diag::err_type_unsupported)
1525 << Ty << E->getSourceRange();
1526}
1527
Alexey Bataeve3727102018-04-18 15:57:46 +00001528bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001529 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1530
Alexey Bataeve3727102018-04-18 15:57:46 +00001531 ASTContext &Ctx = getASTContext();
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001532 bool IsByRef = true;
1533
1534 // Find the directive that is associated with the provided scope.
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00001535 D = cast<ValueDecl>(D->getCanonicalDecl());
Alexey Bataeve3727102018-04-18 15:57:46 +00001536 QualType Ty = D->getType();
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001537
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001538 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001539 // This table summarizes how a given variable should be passed to the device
1540 // given its type and the clauses where it appears. This table is based on
1541 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1542 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1543 //
1544 // =========================================================================
1545 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1546 // | |(tofrom:scalar)| | pvt | | | |
1547 // =========================================================================
1548 // | scl | | | | - | | bycopy|
1549 // | scl | | - | x | - | - | bycopy|
1550 // | scl | | x | - | - | - | null |
1551 // | scl | x | | | - | | byref |
1552 // | scl | x | - | x | - | - | bycopy|
1553 // | scl | x | x | - | - | - | null |
1554 // | scl | | - | - | - | x | byref |
1555 // | scl | x | - | - | - | x | byref |
1556 //
1557 // | agg | n.a. | | | - | | byref |
1558 // | agg | n.a. | - | x | - | - | byref |
1559 // | agg | n.a. | x | - | - | - | null |
1560 // | agg | n.a. | - | - | - | x | byref |
1561 // | agg | n.a. | - | - | - | x[] | byref |
1562 //
1563 // | ptr | n.a. | | | - | | bycopy|
1564 // | ptr | n.a. | - | x | - | - | bycopy|
1565 // | ptr | n.a. | x | - | - | - | null |
1566 // | ptr | n.a. | - | - | - | x | byref |
1567 // | ptr | n.a. | - | - | - | x[] | bycopy|
1568 // | ptr | n.a. | - | - | x | | bycopy|
1569 // | ptr | n.a. | - | - | x | x | bycopy|
1570 // | ptr | n.a. | - | - | x | x[] | bycopy|
1571 // =========================================================================
1572 // Legend:
1573 // scl - scalar
1574 // ptr - pointer
1575 // agg - aggregate
1576 // x - applies
1577 // - - invalid in this combination
1578 // [] - mapped with an array section
1579 // byref - should be mapped by reference
1580 // byval - should be mapped by value
1581 // null - initialize a local variable to null on the device
1582 //
1583 // Observations:
1584 // - All scalar declarations that show up in a map clause have to be passed
1585 // by reference, because they may have been mapped in the enclosing data
1586 // environment.
1587 // - If the scalar value does not fit the size of uintptr, it has to be
1588 // passed by reference, regardless the result in the table above.
1589 // - For pointers mapped by value that have either an implicit map or an
1590 // array section, the runtime library may pass the NULL value to the
1591 // device instead of the value passed to it by the compiler.
1592
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001593 if (Ty->isReferenceType())
1594 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
Samuel Antao86ace552016-04-27 22:40:57 +00001595
1596 // Locate map clauses and see if the variable being captured is referred to
1597 // in any of those clauses. Here we only care about variables, not fields,
1598 // because fields are part of aggregates.
1599 bool IsVariableUsedInMapClause = false;
1600 bool IsVariableAssociatedWithSection = false;
1601
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +00001602 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
Alexey Bataeve3727102018-04-18 15:57:46 +00001603 D, Level,
1604 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1605 OMPClauseMappableExprCommon::MappableExprComponentListRef
Samuel Antao6890b092016-07-28 14:25:09 +00001606 MapExprComponents,
1607 OpenMPClauseKind WhereFoundClauseKind) {
1608 // Only the map clause information influences how a variable is
1609 // captured. E.g. is_device_ptr does not require changing the default
Samuel Antao4c8035b2016-12-12 18:00:20 +00001610 // behavior.
Samuel Antao6890b092016-07-28 14:25:09 +00001611 if (WhereFoundClauseKind != OMPC_map)
1612 return false;
Samuel Antao86ace552016-04-27 22:40:57 +00001613
1614 auto EI = MapExprComponents.rbegin();
1615 auto EE = MapExprComponents.rend();
1616
1617 assert(EI != EE && "Invalid map expression!");
1618
1619 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1620 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1621
1622 ++EI;
1623 if (EI == EE)
1624 return false;
1625
1626 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1627 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1628 isa<MemberExpr>(EI->getAssociatedExpression())) {
1629 IsVariableAssociatedWithSection = true;
1630 // There is nothing more we need to know about this variable.
1631 return true;
1632 }
1633
1634 // Keep looking for more map info.
1635 return false;
1636 });
1637
1638 if (IsVariableUsedInMapClause) {
1639 // If variable is identified in a map clause it is always captured by
1640 // reference except if it is a pointer that is dereferenced somehow.
1641 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1642 } else {
Alexey Bataev3f96fe62017-12-13 17:31:39 +00001643 // By default, all the data that has a scalar type is mapped by copy
1644 // (except for reduction variables).
1645 IsByRef =
Alexey Bataev60705422018-10-30 15:50:12 +00001646 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1647 !Ty->isAnyPointerType()) ||
Alexey Bataev3f96fe62017-12-13 17:31:39 +00001648 !Ty->isScalarType() ||
1649 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1650 DSAStack->hasExplicitDSA(
1651 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
Samuel Antao86ace552016-04-27 22:40:57 +00001652 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001653 }
1654
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001655 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00001656 IsByRef =
Alexey Bataev60705422018-10-30 15:50:12 +00001657 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1658 !Ty->isAnyPointerType()) ||
1659 !DSAStack->hasExplicitDSA(
1660 D,
1661 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1662 Level, /*NotLastprivate=*/true)) &&
Alexey Bataev8e769ee2017-12-22 21:01:52 +00001663 // If the variable is artificial and must be captured by value - try to
1664 // capture by value.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00001665 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1666 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001667 }
1668
Samuel Antao86ace552016-04-27 22:40:57 +00001669 // When passing data by copy, we need to make sure it fits the uintptr size
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001670 // and alignment, because the runtime library only deals with uintptr types.
1671 // If it does not fit the uintptr size, we need to pass the data by reference
1672 // instead.
1673 if (!IsByRef &&
1674 (Ctx.getTypeSizeInChars(Ty) >
1675 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001676 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001677 IsByRef = true;
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001678 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001679
1680 return IsByRef;
1681}
1682
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001683unsigned Sema::getOpenMPNestingLevel() const {
1684 assert(getLangOpts().OpenMP);
1685 return DSAStack->getNestingLevel();
1686}
1687
Jonas Hahnfeld87d44262017-11-18 21:00:46 +00001688bool Sema::isInOpenMPTargetExecutionDirective() const {
1689 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1690 !DSAStack->isClauseParsingMode()) ||
1691 DSAStack->hasDirective(
1692 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1693 SourceLocation) -> bool {
1694 return isOpenMPTargetExecutionDirective(K);
1695 },
1696 false);
1697}
1698
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001699VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
1700 unsigned StopAt) {
Alexey Bataevf841bd92014-12-16 07:00:22 +00001701 assert(LangOpts.OpenMP && "OpenMP is not allowed");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001702 D = getCanonicalDecl(D);
Samuel Antao4be30e92015-10-02 17:14:03 +00001703
1704 // If we are attempting to capture a global variable in a directive with
1705 // 'target' we return true so that this global is also mapped to the device.
1706 //
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001707 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001708 if (VD && !VD->hasLocalStorage()) {
1709 if (isInOpenMPDeclareTargetContext() &&
1710 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1711 // Try to mark variable as declare target if it is used in capturing
1712 // regions.
Alexey Bataev97b72212018-08-14 18:31:20 +00001713 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001714 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
Alexey Bataev92327c52018-03-26 16:40:55 +00001715 return nullptr;
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001716 } else if (isInOpenMPTargetExecutionDirective()) {
1717 // If the declaration is enclosed in a 'declare target' directive,
1718 // then it should not be captured.
1719 //
Alexey Bataev97b72212018-08-14 18:31:20 +00001720 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001721 return nullptr;
1722 return VD;
1723 }
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001724 }
Alexey Bataev60705422018-10-30 15:50:12 +00001725 // Capture variables captured by reference in lambdas for target-based
1726 // directives.
1727 if (VD && !DSAStack->isClauseParsingMode()) {
1728 if (const auto *RD = VD->getType()
1729 .getCanonicalType()
1730 .getNonReferenceType()
1731 ->getAsCXXRecordDecl()) {
1732 bool SavedForceCaptureByReferenceInTargetExecutable =
1733 DSAStack->isForceCaptureByReferenceInTargetExecutable();
1734 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true);
Alexey Bataevd1840e52018-11-16 21:13:33 +00001735 if (RD->isLambda()) {
1736 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
1737 FieldDecl *ThisCapture;
1738 RD->getCaptureFields(Captures, ThisCapture);
Alexey Bataev60705422018-10-30 15:50:12 +00001739 for (const LambdaCapture &LC : RD->captures()) {
1740 if (LC.getCaptureKind() == LCK_ByRef) {
1741 VarDecl *VD = LC.getCapturedVar();
1742 DeclContext *VDC = VD->getDeclContext();
1743 if (!VDC->Encloses(CurContext))
1744 continue;
1745 DSAStackTy::DSAVarData DVarPrivate =
1746 DSAStack->getTopDSA(VD, /*FromParent=*/false);
1747 // Do not capture already captured variables.
1748 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
1749 DVarPrivate.CKind == OMPC_unknown &&
1750 !DSAStack->checkMappableExprComponentListsForDecl(
1751 D, /*CurrentRegionOnly=*/true,
1752 [](OMPClauseMappableExprCommon::
1753 MappableExprComponentListRef,
1754 OpenMPClauseKind) { return true; }))
1755 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar());
1756 } else if (LC.getCaptureKind() == LCK_This) {
Alexey Bataevd1840e52018-11-16 21:13:33 +00001757 QualType ThisTy = getCurrentThisType();
1758 if (!ThisTy.isNull() &&
1759 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
1760 CheckCXXThisCapture(LC.getLocation());
Alexey Bataev60705422018-10-30 15:50:12 +00001761 }
1762 }
Alexey Bataevd1840e52018-11-16 21:13:33 +00001763 }
Alexey Bataev60705422018-10-30 15:50:12 +00001764 DSAStack->setForceCaptureByReferenceInTargetExecutable(
1765 SavedForceCaptureByReferenceInTargetExecutable);
1766 }
1767 }
Samuel Antao4be30e92015-10-02 17:14:03 +00001768
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001769 if (CheckScopeInfo) {
1770 bool OpenMPFound = false;
1771 for (unsigned I = StopAt + 1; I > 0; --I) {
1772 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
1773 if(!isa<CapturingScopeInfo>(FSI))
1774 return nullptr;
1775 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
1776 if (RSI->CapRegionKind == CR_OpenMP) {
1777 OpenMPFound = true;
1778 break;
1779 }
1780 }
1781 if (!OpenMPFound)
1782 return nullptr;
1783 }
1784
Alexey Bataev48977c32015-08-04 08:10:48 +00001785 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1786 (!DSAStack->isClauseParsingMode() ||
1787 DSAStack->getParentDirective() != OMPD_unknown)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00001788 auto &&Info = DSAStack->isLoopControlVariable(D);
1789 if (Info.first ||
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001790 (VD && VD->hasLocalStorage() &&
Alexey Bataev7e6803e2019-01-09 15:58:05 +00001791 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001792 (VD && DSAStack->isForceVarCapturing()))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00001793 return VD ? VD : Info.second;
Alexey Bataeve3727102018-04-18 15:57:46 +00001794 DSAStackTy::DSAVarData DVarPrivate =
1795 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
Alexey Bataevf841bd92014-12-16 07:00:22 +00001796 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
Alexey Bataev90c228f2016-02-08 09:29:13 +00001797 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
Alexey Bataeve3727102018-04-18 15:57:46 +00001798 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1799 [](OpenMPDirectiveKind) { return true; },
1800 DSAStack->isClauseParsingMode());
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001801 // The variable is not private or it is the variable in the directive with
1802 // default(none) clause and not used in any clause.
1803 if (DVarPrivate.CKind != OMPC_unknown ||
1804 (VD && DSAStack->getDefaultDSA() == DSA_none))
Alexey Bataev90c228f2016-02-08 09:29:13 +00001805 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
Alexey Bataevf841bd92014-12-16 07:00:22 +00001806 }
Alexey Bataev90c228f2016-02-08 09:29:13 +00001807 return nullptr;
Alexey Bataevf841bd92014-12-16 07:00:22 +00001808}
1809
Alexey Bataevdfa430f2017-12-08 15:03:50 +00001810void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1811 unsigned Level) const {
1812 SmallVector<OpenMPDirectiveKind, 4> Regions;
1813 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1814 FunctionScopesIndex -= Regions.size();
1815}
1816
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00001817void Sema::startOpenMPLoop() {
1818 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1819 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1820 DSAStack->loopInit();
1821}
1822
Alexey Bataeve3727102018-04-18 15:57:46 +00001823bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
Alexey Bataevaac108a2015-06-23 04:51:00 +00001824 assert(LangOpts.OpenMP && "OpenMP is not allowed");
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00001825 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1826 if (DSAStack->getAssociatedLoops() > 0 &&
1827 !DSAStack->isLoopStarted()) {
1828 DSAStack->resetPossibleLoopCounter(D);
1829 DSAStack->loopStart();
1830 return true;
1831 }
1832 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
1833 DSAStack->isLoopControlVariable(D).first) &&
1834 !DSAStack->hasExplicitDSA(
1835 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
1836 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
1837 return true;
1838 }
Alexey Bataevaac108a2015-06-23 04:51:00 +00001839 return DSAStack->hasExplicitDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00001840 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
Alexey Bataev3f82cfc2017-12-13 15:28:44 +00001841 (DSAStack->isClauseParsingMode() &&
1842 DSAStack->getClauseParsingMode() == OMPC_private) ||
Alexey Bataev88202be2017-07-27 13:20:36 +00001843 // Consider taskgroup reduction descriptor variable a private to avoid
1844 // possible capture in the region.
1845 (DSAStack->hasExplicitDirective(
1846 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1847 Level) &&
1848 DSAStack->isTaskgroupReductionRef(D, Level));
Alexey Bataevaac108a2015-06-23 04:51:00 +00001849}
1850
Alexey Bataeve3727102018-04-18 15:57:46 +00001851void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
1852 unsigned Level) {
Alexey Bataev3b8d5582017-08-08 18:04:06 +00001853 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1854 D = getCanonicalDecl(D);
1855 OpenMPClauseKind OMPC = OMPC_unknown;
1856 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1857 const unsigned NewLevel = I - 1;
1858 if (DSAStack->hasExplicitDSA(D,
1859 [&OMPC](const OpenMPClauseKind K) {
1860 if (isOpenMPPrivate(K)) {
1861 OMPC = K;
1862 return true;
1863 }
1864 return false;
1865 },
1866 NewLevel))
1867 break;
1868 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1869 D, NewLevel,
1870 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1871 OpenMPClauseKind) { return true; })) {
1872 OMPC = OMPC_map;
1873 break;
1874 }
1875 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1876 NewLevel)) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001877 OMPC = OMPC_map;
1878 if (D->getType()->isScalarType() &&
1879 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1880 DefaultMapAttributes::DMA_tofrom_scalar)
1881 OMPC = OMPC_firstprivate;
Alexey Bataev3b8d5582017-08-08 18:04:06 +00001882 break;
1883 }
1884 }
1885 if (OMPC != OMPC_unknown)
1886 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1887}
1888
Alexey Bataeve3727102018-04-18 15:57:46 +00001889bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
1890 unsigned Level) const {
Samuel Antao4be30e92015-10-02 17:14:03 +00001891 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1892 // Return true if the current level is no longer enclosed in a target region.
1893
Alexey Bataeve3727102018-04-18 15:57:46 +00001894 const auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001895 return VD && !VD->hasLocalStorage() &&
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00001896 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1897 Level);
Samuel Antao4be30e92015-10-02 17:14:03 +00001898}
1899
Alexey Bataeved09d242014-05-28 05:53:51 +00001900void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001901
1902void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1903 const DeclarationNameInfo &DirName,
Alexey Bataevbae9a792014-06-27 10:37:06 +00001904 Scope *CurScope, SourceLocation Loc) {
1905 DSAStack->push(DKind, DirName, CurScope, Loc);
Faisal Valid143a0c2017-04-01 21:30:49 +00001906 PushExpressionEvaluationContext(
1907 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001908}
1909
Alexey Bataevaac108a2015-06-23 04:51:00 +00001910void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1911 DSAStack->setClauseParsingMode(K);
Alexey Bataev39f915b82015-05-08 10:41:21 +00001912}
1913
Alexey Bataevaac108a2015-06-23 04:51:00 +00001914void Sema::EndOpenMPClause() {
1915 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
Alexey Bataev39f915b82015-05-08 10:41:21 +00001916}
1917
Alexey Bataeve106f252019-04-01 14:25:31 +00001918static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
1919 ArrayRef<OMPClause *> Clauses);
1920
Alexey Bataev758e55e2013-09-06 18:03:48 +00001921void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
Alexey Bataevf29276e2014-06-18 04:14:57 +00001922 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1923 // A variable of class type (or array thereof) that appears in a lastprivate
1924 // clause requires an accessible, unambiguous default constructor for the
1925 // class type, unless the list item is also specified in a firstprivate
1926 // clause.
Alexey Bataeve3727102018-04-18 15:57:46 +00001927 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1928 for (OMPClause *C : D->clauses()) {
Alexey Bataev38e89532015-04-16 04:54:05 +00001929 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1930 SmallVector<Expr *, 8> PrivateCopies;
Alexey Bataeve3727102018-04-18 15:57:46 +00001931 for (Expr *DE : Clause->varlists()) {
Alexey Bataev38e89532015-04-16 04:54:05 +00001932 if (DE->isValueDependent() || DE->isTypeDependent()) {
1933 PrivateCopies.push_back(nullptr);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001934 continue;
Alexey Bataev38e89532015-04-16 04:54:05 +00001935 }
Alexey Bataev74caaf22016-02-20 04:09:36 +00001936 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
Alexey Bataeve3727102018-04-18 15:57:46 +00001937 auto *VD = cast<VarDecl>(DRE->getDecl());
Alexey Bataev005248a2016-02-25 05:25:57 +00001938 QualType Type = VD->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +00001939 const DSAStackTy::DSAVarData DVar =
1940 DSAStack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001941 if (DVar.CKind == OMPC_lastprivate) {
Alexey Bataev38e89532015-04-16 04:54:05 +00001942 // Generate helper private variable and initialize it with the
1943 // default value. The address of the original variable is replaced
1944 // by the address of the new private variable in CodeGen. This new
1945 // variable is not added to IdResolver, so the code in the OpenMP
1946 // region uses original variable for proper diagnostics.
Alexey Bataeve3727102018-04-18 15:57:46 +00001947 VarDecl *VDPrivate = buildVarDecl(
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +00001948 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001949 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
Richard Smith3beb7c62017-01-12 02:27:38 +00001950 ActOnUninitializedDecl(VDPrivate);
Alexey Bataeve106f252019-04-01 14:25:31 +00001951 if (VDPrivate->isInvalidDecl()) {
1952 PrivateCopies.push_back(nullptr);
Alexey Bataev38e89532015-04-16 04:54:05 +00001953 continue;
Alexey Bataeve106f252019-04-01 14:25:31 +00001954 }
Alexey Bataev39f915b82015-05-08 10:41:21 +00001955 PrivateCopies.push_back(buildDeclRefExpr(
1956 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
Alexey Bataev38e89532015-04-16 04:54:05 +00001957 } else {
1958 // The variable is also a firstprivate, so initialization sequence
1959 // for private copy is generated already.
1960 PrivateCopies.push_back(nullptr);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001961 }
1962 }
Alexey Bataeve106f252019-04-01 14:25:31 +00001963 Clause->setPrivateCopies(PrivateCopies);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001964 }
1965 }
Alexey Bataeve106f252019-04-01 14:25:31 +00001966 // Check allocate clauses.
1967 if (!CurContext->isDependentContext())
1968 checkAllocateClauses(*this, DSAStack, D->clauses());
Alexey Bataevf29276e2014-06-18 04:14:57 +00001969 }
1970
Alexey Bataev758e55e2013-09-06 18:03:48 +00001971 DSAStack->pop();
1972 DiscardCleanupsInEvaluationContext();
1973 PopExpressionEvaluationContext();
1974}
1975
Alexey Bataev5dff95c2016-04-22 03:56:56 +00001976static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1977 Expr *NumIterations, Sema &SemaRef,
1978 Scope *S, DSAStackTy *Stack);
Alexander Musman3276a272015-03-21 10:12:56 +00001979
Alexey Bataeva769e072013-03-22 06:34:35 +00001980namespace {
1981
Alexey Bataeve3727102018-04-18 15:57:46 +00001982class VarDeclFilterCCC final : public CorrectionCandidateCallback {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001983private:
Alexey Bataev7ff55242014-06-19 09:13:45 +00001984 Sema &SemaRef;
Alexey Bataeved09d242014-05-28 05:53:51 +00001985
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001986public:
Alexey Bataev7ff55242014-06-19 09:13:45 +00001987 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
Craig Toppere14c0f82014-03-12 04:55:44 +00001988 bool ValidateCandidate(const TypoCorrection &Candidate) override {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001989 NamedDecl *ND = Candidate.getCorrectionDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +00001990 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001991 return VD->hasGlobalStorage() &&
Alexey Bataev7ff55242014-06-19 09:13:45 +00001992 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1993 SemaRef.getCurScope());
Alexey Bataeva769e072013-03-22 06:34:35 +00001994 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00001995 return false;
Alexey Bataeva769e072013-03-22 06:34:35 +00001996 }
Bruno Ricci70ad3962019-03-25 17:08:51 +00001997
1998 std::unique_ptr<CorrectionCandidateCallback> clone() override {
1999 return llvm::make_unique<VarDeclFilterCCC>(*this);
2000 }
2001
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002002};
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002003
Alexey Bataeve3727102018-04-18 15:57:46 +00002004class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002005private:
2006 Sema &SemaRef;
2007
2008public:
2009 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2010 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2011 NamedDecl *ND = Candidate.getCorrectionDecl();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002012 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2013 isa<FunctionDecl>(ND))) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002014 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2015 SemaRef.getCurScope());
2016 }
2017 return false;
2018 }
Bruno Ricci70ad3962019-03-25 17:08:51 +00002019
2020 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2021 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this);
2022 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002023};
2024
Alexey Bataeved09d242014-05-28 05:53:51 +00002025} // namespace
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002026
2027ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2028 CXXScopeSpec &ScopeSpec,
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002029 const DeclarationNameInfo &Id,
2030 OpenMPDirectiveKind Kind) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002031 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2032 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2033
2034 if (Lookup.isAmbiguous())
2035 return ExprError();
2036
2037 VarDecl *VD;
2038 if (!Lookup.isSingleResult()) {
Bruno Ricci70ad3962019-03-25 17:08:51 +00002039 VarDeclFilterCCC CCC(*this);
2040 if (TypoCorrection Corrected =
2041 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2042 CTK_ErrorRecovery)) {
Richard Smithf9b15102013-08-17 00:46:16 +00002043 diagnoseTypo(Corrected,
Alexander Musmancb7f9c42014-05-15 13:04:49 +00002044 PDiag(Lookup.empty()
2045 ? diag::err_undeclared_var_use_suggest
2046 : diag::err_omp_expected_var_arg_suggest)
2047 << Id.getName());
Richard Smithf9b15102013-08-17 00:46:16 +00002048 VD = Corrected.getCorrectionDeclAs<VarDecl>();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002049 } else {
Richard Smithf9b15102013-08-17 00:46:16 +00002050 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2051 : diag::err_omp_expected_var_arg)
2052 << Id.getName();
2053 return ExprError();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002054 }
Alexey Bataeve3727102018-04-18 15:57:46 +00002055 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2056 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2057 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2058 return ExprError();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002059 }
2060 Lookup.suppressDiagnostics();
2061
2062 // OpenMP [2.9.2, Syntax, C/C++]
2063 // Variables must be file-scope, namespace-scope, or static block-scope.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002064 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002065 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002066 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
Alexey Bataeved09d242014-05-28 05:53:51 +00002067 bool IsDecl =
2068 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002069 Diag(VD->getLocation(),
Alexey Bataeved09d242014-05-28 05:53:51 +00002070 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2071 << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002072 return ExprError();
2073 }
2074
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002075 VarDecl *CanonicalVD = VD->getCanonicalDecl();
George Burgess IV00f70bd2018-03-01 05:43:23 +00002076 NamedDecl *ND = CanonicalVD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002077 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2078 // A threadprivate directive for file-scope variables must appear outside
2079 // any definition or declaration.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002080 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2081 !getCurLexicalContext()->isTranslationUnit()) {
2082 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002083 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002084 bool IsDecl =
2085 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2086 Diag(VD->getLocation(),
2087 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2088 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002089 return ExprError();
2090 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002091 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2092 // A threadprivate directive for static class member variables must appear
2093 // in the class definition, in the same scope in which the member
2094 // variables are declared.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002095 if (CanonicalVD->isStaticDataMember() &&
2096 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2097 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002098 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002099 bool IsDecl =
2100 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2101 Diag(VD->getLocation(),
2102 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2103 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002104 return ExprError();
2105 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002106 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2107 // A threadprivate directive for namespace-scope variables must appear
2108 // outside any definition or declaration other than the namespace
2109 // definition itself.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002110 if (CanonicalVD->getDeclContext()->isNamespace() &&
2111 (!getCurLexicalContext()->isFileContext() ||
2112 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2113 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002114 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002115 bool IsDecl =
2116 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2117 Diag(VD->getLocation(),
2118 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2119 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002120 return ExprError();
2121 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002122 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2123 // A threadprivate directive for static block-scope variables must appear
2124 // in the scope of the variable and not in a nested scope.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002125 if (CanonicalVD->isLocalVarDecl() && CurScope &&
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002126 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002127 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002128 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002129 bool IsDecl =
2130 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2131 Diag(VD->getLocation(),
2132 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2133 << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002134 return ExprError();
2135 }
2136
2137 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2138 // A threadprivate directive must lexically precede all references to any
2139 // of the variables in its list.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002140 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2141 !DSAStack->isThreadPrivate(VD)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002142 Diag(Id.getLoc(), diag::err_omp_var_used)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002143 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002144 return ExprError();
2145 }
2146
2147 QualType ExprType = VD->getType().getNonReferenceType();
Alexey Bataev376b4a42016-02-09 09:41:09 +00002148 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2149 SourceLocation(), VD,
2150 /*RefersToEnclosingVariableOrCapture=*/false,
2151 Id.getLoc(), ExprType, VK_LValue);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002152}
2153
Alexey Bataeved09d242014-05-28 05:53:51 +00002154Sema::DeclGroupPtrTy
2155Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2156 ArrayRef<Expr *> VarList) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002157 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002158 CurContext->addDecl(D);
2159 return DeclGroupPtrTy::make(DeclGroupRef(D));
2160 }
David Blaikie0403cb12016-01-15 23:43:25 +00002161 return nullptr;
Alexey Bataeva769e072013-03-22 06:34:35 +00002162}
2163
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002164namespace {
Alexey Bataeve3727102018-04-18 15:57:46 +00002165class LocalVarRefChecker final
2166 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002167 Sema &SemaRef;
2168
2169public:
2170 bool VisitDeclRefExpr(const DeclRefExpr *E) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002171 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002172 if (VD->hasLocalStorage()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002173 SemaRef.Diag(E->getBeginLoc(),
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002174 diag::err_omp_local_var_in_threadprivate_init)
2175 << E->getSourceRange();
2176 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2177 << VD << VD->getSourceRange();
2178 return true;
2179 }
2180 }
2181 return false;
2182 }
2183 bool VisitStmt(const Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002184 for (const Stmt *Child : S->children()) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002185 if (Child && Visit(Child))
2186 return true;
2187 }
2188 return false;
2189 }
Alexey Bataev23b69422014-06-18 07:08:49 +00002190 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002191};
2192} // namespace
2193
Alexey Bataeved09d242014-05-28 05:53:51 +00002194OMPThreadPrivateDecl *
2195Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002196 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +00002197 for (Expr *RefExpr : VarList) {
2198 auto *DE = cast<DeclRefExpr>(RefExpr);
2199 auto *VD = cast<VarDecl>(DE->getDecl());
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002200 SourceLocation ILoc = DE->getExprLoc();
Alexey Bataeva769e072013-03-22 06:34:35 +00002201
Alexey Bataev376b4a42016-02-09 09:41:09 +00002202 // Mark variable as used.
2203 VD->setReferenced();
2204 VD->markUsed(Context);
2205
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002206 QualType QType = VD->getType();
2207 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2208 // It will be analyzed later.
2209 Vars.push_back(DE);
2210 continue;
2211 }
2212
Alexey Bataeva769e072013-03-22 06:34:35 +00002213 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2214 // A threadprivate variable must not have an incomplete type.
2215 if (RequireCompleteType(ILoc, VD->getType(),
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002216 diag::err_omp_threadprivate_incomplete_type)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002217 continue;
2218 }
2219
2220 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2221 // A threadprivate variable must not have a reference type.
2222 if (VD->getType()->isReferenceType()) {
2223 Diag(ILoc, diag::err_omp_ref_type_arg)
Alexey Bataeved09d242014-05-28 05:53:51 +00002224 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2225 bool IsDecl =
2226 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2227 Diag(VD->getLocation(),
2228 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2229 << VD;
Alexey Bataeva769e072013-03-22 06:34:35 +00002230 continue;
2231 }
2232
Samuel Antaof8b50122015-07-13 22:54:53 +00002233 // Check if this is a TLS variable. If TLS is not being supported, produce
2234 // the corresponding diagnostic.
2235 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2236 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2237 getLangOpts().OpenMPUseTLS &&
2238 getASTContext().getTargetInfo().isTLSSupported())) ||
Alexey Bataev1a8b3f12015-05-06 06:34:55 +00002239 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2240 !VD->isLocalVarDecl())) {
Alexey Bataev26a39242015-01-13 03:35:30 +00002241 Diag(ILoc, diag::err_omp_var_thread_local)
2242 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
Alexey Bataeved09d242014-05-28 05:53:51 +00002243 bool IsDecl =
2244 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2245 Diag(VD->getLocation(),
2246 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2247 << VD;
Alexey Bataeva769e072013-03-22 06:34:35 +00002248 continue;
2249 }
2250
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002251 // Check if initial value of threadprivate variable reference variable with
2252 // local storage (it is not supported by runtime).
Alexey Bataeve3727102018-04-18 15:57:46 +00002253 if (const Expr *Init = VD->getAnyInitializer()) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002254 LocalVarRefChecker Checker(*this);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002255 if (Checker.Visit(Init))
2256 continue;
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002257 }
2258
Alexey Bataeved09d242014-05-28 05:53:51 +00002259 Vars.push_back(RefExpr);
Alexey Bataevd178ad42014-03-07 08:03:37 +00002260 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
Alexey Bataev97720002014-11-11 04:05:39 +00002261 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2262 Context, SourceRange(Loc, Loc)));
Alexey Bataeve3727102018-04-18 15:57:46 +00002263 if (ASTMutationListener *ML = Context.getASTMutationListener())
Alexey Bataev97720002014-11-11 04:05:39 +00002264 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
Alexey Bataeva769e072013-03-22 06:34:35 +00002265 }
Alexander Musmancb7f9c42014-05-15 13:04:49 +00002266 OMPThreadPrivateDecl *D = nullptr;
Alexey Bataevec3da872014-01-31 05:15:34 +00002267 if (!Vars.empty()) {
2268 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2269 Vars);
2270 D->setAccess(AS_public);
2271 }
2272 return D;
Alexey Bataeva769e072013-03-22 06:34:35 +00002273}
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002274
Alexey Bataev27ef9512019-03-20 20:14:22 +00002275static OMPAllocateDeclAttr::AllocatorTypeTy
2276getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2277 if (!Allocator)
2278 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2279 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2280 Allocator->isInstantiationDependent() ||
Alexey Bataev441510e2019-03-21 19:05:07 +00002281 Allocator->containsUnexpandedParameterPack())
Alexey Bataev27ef9512019-03-20 20:14:22 +00002282 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
Alexey Bataev27ef9512019-03-20 20:14:22 +00002283 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
Alexey Bataeve106f252019-04-01 14:25:31 +00002284 const Expr *AE = Allocator->IgnoreParenImpCasts();
Alexey Bataev27ef9512019-03-20 20:14:22 +00002285 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2286 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2287 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
Alexey Bataeve106f252019-04-01 14:25:31 +00002288 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
Alexey Bataev441510e2019-03-21 19:05:07 +00002289 llvm::FoldingSetNodeID AEId, DAEId;
2290 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2291 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2292 if (AEId == DAEId) {
Alexey Bataev27ef9512019-03-20 20:14:22 +00002293 AllocatorKindRes = AllocatorKind;
2294 break;
2295 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002296 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002297 return AllocatorKindRes;
2298}
2299
Alexey Bataeve106f252019-04-01 14:25:31 +00002300static bool checkPreviousOMPAllocateAttribute(
2301 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2302 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2303 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2304 return false;
2305 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2306 Expr *PrevAllocator = A->getAllocator();
2307 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2308 getAllocatorKind(S, Stack, PrevAllocator);
2309 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2310 if (AllocatorsMatch &&
2311 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2312 Allocator && PrevAllocator) {
2313 const Expr *AE = Allocator->IgnoreParenImpCasts();
2314 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2315 llvm::FoldingSetNodeID AEId, PAEId;
2316 AE->Profile(AEId, S.Context, /*Canonical=*/true);
2317 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2318 AllocatorsMatch = AEId == PAEId;
2319 }
2320 if (!AllocatorsMatch) {
2321 SmallString<256> AllocatorBuffer;
2322 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2323 if (Allocator)
2324 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2325 SmallString<256> PrevAllocatorBuffer;
2326 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2327 if (PrevAllocator)
2328 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2329 S.getPrintingPolicy());
2330
2331 SourceLocation AllocatorLoc =
2332 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2333 SourceRange AllocatorRange =
2334 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2335 SourceLocation PrevAllocatorLoc =
2336 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2337 SourceRange PrevAllocatorRange =
2338 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2339 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2340 << (Allocator ? 1 : 0) << AllocatorStream.str()
2341 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2342 << AllocatorRange;
2343 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2344 << PrevAllocatorRange;
2345 return true;
2346 }
2347 return false;
2348}
2349
2350static void
2351applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
2352 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2353 Expr *Allocator, SourceRange SR) {
2354 if (VD->hasAttr<OMPAllocateDeclAttr>())
2355 return;
2356 if (Allocator &&
2357 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2358 Allocator->isInstantiationDependent() ||
2359 Allocator->containsUnexpandedParameterPack()))
2360 return;
2361 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2362 Allocator, SR);
2363 VD->addAttr(A);
2364 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
2365 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2366}
2367
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002368Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2369 SourceLocation Loc, ArrayRef<Expr *> VarList,
2370 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2371 assert(Clauses.size() <= 1 && "Expected at most one clause.");
2372 Expr *Allocator = nullptr;
Alexey Bataev2213dd62019-03-22 14:41:39 +00002373 if (Clauses.empty()) {
Alexey Bataevf4936072019-03-22 15:32:02 +00002374 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2375 // allocate directives that appear in a target region must specify an
2376 // allocator clause unless a requires directive with the dynamic_allocators
2377 // clause is present in the same compilation unit.
Alexey Bataev318f431b2019-03-22 15:25:12 +00002378 if (LangOpts.OpenMPIsDevice &&
2379 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
Alexey Bataev2213dd62019-03-22 14:41:39 +00002380 targetDiag(Loc, diag::err_expected_allocator_clause);
2381 } else {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002382 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
Alexey Bataev2213dd62019-03-22 14:41:39 +00002383 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002384 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2385 getAllocatorKind(*this, DSAStack, Allocator);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002386 SmallVector<Expr *, 8> Vars;
2387 for (Expr *RefExpr : VarList) {
2388 auto *DE = cast<DeclRefExpr>(RefExpr);
2389 auto *VD = cast<VarDecl>(DE->getDecl());
2390
2391 // Check if this is a TLS variable or global register.
2392 if (VD->getTLSKind() != VarDecl::TLS_None ||
2393 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2394 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2395 !VD->isLocalVarDecl()))
2396 continue;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002397
Alexey Bataev282555a2019-03-19 20:33:44 +00002398 // If the used several times in the allocate directive, the same allocator
2399 // must be used.
Alexey Bataeve106f252019-04-01 14:25:31 +00002400 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
2401 AllocatorKind, Allocator))
2402 continue;
Alexey Bataev282555a2019-03-19 20:33:44 +00002403
Alexey Bataevd2fc9652019-03-19 18:39:11 +00002404 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2405 // If a list item has a static storage type, the allocator expression in the
2406 // allocator clause must be a constant expression that evaluates to one of
2407 // the predefined memory allocator values.
2408 if (Allocator && VD->hasGlobalStorage()) {
Alexey Bataev441510e2019-03-21 19:05:07 +00002409 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
Alexey Bataevd2fc9652019-03-19 18:39:11 +00002410 Diag(Allocator->getExprLoc(),
2411 diag::err_omp_expected_predefined_allocator)
2412 << Allocator->getSourceRange();
2413 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2414 VarDecl::DeclarationOnly;
2415 Diag(VD->getLocation(),
2416 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2417 << VD;
2418 continue;
2419 }
2420 }
2421
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002422 Vars.push_back(RefExpr);
Alexey Bataeve106f252019-04-01 14:25:31 +00002423 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2424 DE->getSourceRange());
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002425 }
2426 if (Vars.empty())
2427 return nullptr;
2428 if (!Owner)
2429 Owner = getCurLexicalContext();
Alexey Bataeve106f252019-04-01 14:25:31 +00002430 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002431 D->setAccess(AS_public);
2432 Owner->addDecl(D);
2433 return DeclGroupPtrTy::make(DeclGroupRef(D));
2434}
2435
2436Sema::DeclGroupPtrTy
Kelvin Li1408f912018-09-26 04:28:39 +00002437Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2438 ArrayRef<OMPClause *> ClauseList) {
2439 OMPRequiresDecl *D = nullptr;
2440 if (!CurContext->isFileContext()) {
2441 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2442 } else {
2443 D = CheckOMPRequiresDecl(Loc, ClauseList);
2444 if (D) {
2445 CurContext->addDecl(D);
2446 DSAStack->addRequiresDecl(D);
2447 }
2448 }
2449 return DeclGroupPtrTy::make(DeclGroupRef(D));
2450}
2451
2452OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2453 ArrayRef<OMPClause *> ClauseList) {
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +00002454 /// For target specific clauses, the requires directive cannot be
2455 /// specified after the handling of any of the target regions in the
2456 /// current compilation unit.
2457 ArrayRef<SourceLocation> TargetLocations =
2458 DSAStack->getEncounteredTargetLocs();
2459 if (!TargetLocations.empty()) {
2460 for (const OMPClause *CNew : ClauseList) {
2461 // Check if any of the requires clauses affect target regions.
2462 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2463 isa<OMPUnifiedAddressClause>(CNew) ||
2464 isa<OMPReverseOffloadClause>(CNew) ||
2465 isa<OMPDynamicAllocatorsClause>(CNew)) {
2466 Diag(Loc, diag::err_omp_target_before_requires)
2467 << getOpenMPClauseName(CNew->getClauseKind());
2468 for (SourceLocation TargetLoc : TargetLocations) {
2469 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2470 }
2471 }
2472 }
2473 }
2474
Kelvin Li1408f912018-09-26 04:28:39 +00002475 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2476 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2477 ClauseList);
2478 return nullptr;
2479}
2480
Alexey Bataeve3727102018-04-18 15:57:46 +00002481static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2482 const ValueDecl *D,
2483 const DSAStackTy::DSAVarData &DVar,
Alexey Bataev7ff55242014-06-19 09:13:45 +00002484 bool IsLoopIterVar = false) {
2485 if (DVar.RefExpr) {
2486 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2487 << getOpenMPClauseName(DVar.CKind);
2488 return;
2489 }
2490 enum {
2491 PDSA_StaticMemberShared,
2492 PDSA_StaticLocalVarShared,
2493 PDSA_LoopIterVarPrivate,
2494 PDSA_LoopIterVarLinear,
2495 PDSA_LoopIterVarLastprivate,
2496 PDSA_ConstVarShared,
2497 PDSA_GlobalVarShared,
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002498 PDSA_TaskVarFirstprivate,
Alexey Bataevbae9a792014-06-27 10:37:06 +00002499 PDSA_LocalVarPrivate,
2500 PDSA_Implicit
2501 } Reason = PDSA_Implicit;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002502 bool ReportHint = false;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002503 auto ReportLoc = D->getLocation();
2504 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev7ff55242014-06-19 09:13:45 +00002505 if (IsLoopIterVar) {
2506 if (DVar.CKind == OMPC_private)
2507 Reason = PDSA_LoopIterVarPrivate;
2508 else if (DVar.CKind == OMPC_lastprivate)
2509 Reason = PDSA_LoopIterVarLastprivate;
2510 else
2511 Reason = PDSA_LoopIterVarLinear;
Alexey Bataev35aaee62016-04-13 13:36:48 +00002512 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2513 DVar.CKind == OMPC_firstprivate) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002514 Reason = PDSA_TaskVarFirstprivate;
2515 ReportLoc = DVar.ImplicitDSALoc;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002516 } else if (VD && VD->isStaticLocal())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002517 Reason = PDSA_StaticLocalVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002518 else if (VD && VD->isStaticDataMember())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002519 Reason = PDSA_StaticMemberShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002520 else if (VD && VD->isFileVarDecl())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002521 Reason = PDSA_GlobalVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002522 else if (D->getType().isConstant(SemaRef.getASTContext()))
Alexey Bataev7ff55242014-06-19 09:13:45 +00002523 Reason = PDSA_ConstVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002524 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
Alexey Bataev7ff55242014-06-19 09:13:45 +00002525 ReportHint = true;
2526 Reason = PDSA_LocalVarPrivate;
2527 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002528 if (Reason != PDSA_Implicit) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002529 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
Alexey Bataevbae9a792014-06-27 10:37:06 +00002530 << Reason << ReportHint
2531 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2532 } else if (DVar.ImplicitDSALoc.isValid()) {
2533 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2534 << getOpenMPClauseName(DVar.CKind);
2535 }
Alexey Bataev7ff55242014-06-19 09:13:45 +00002536}
2537
Alexey Bataev758e55e2013-09-06 18:03:48 +00002538namespace {
Alexey Bataeve3727102018-04-18 15:57:46 +00002539class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
Alexey Bataev758e55e2013-09-06 18:03:48 +00002540 DSAStackTy *Stack;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002541 Sema &SemaRef;
Alexey Bataeve3727102018-04-18 15:57:46 +00002542 bool ErrorFound = false;
2543 CapturedStmt *CS = nullptr;
2544 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2545 llvm::SmallVector<Expr *, 4> ImplicitMap;
2546 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2547 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
Alexey Bataeved09d242014-05-28 05:53:51 +00002548
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00002549 void VisitSubCaptures(OMPExecutableDirective *S) {
2550 // Check implicitly captured variables.
2551 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2552 return;
2553 for (const CapturedStmt::Capture &Cap :
2554 S->getInnermostCapturedStmt()->captures()) {
2555 if (!Cap.capturesVariable())
2556 continue;
2557 VarDecl *VD = Cap.getCapturedVar();
2558 // Do not try to map the variable if it or its sub-component was mapped
2559 // already.
2560 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2561 Stack->checkMappableExprComponentListsForDecl(
2562 VD, /*CurrentRegionOnly=*/true,
2563 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2564 OpenMPClauseKind) { return true; }))
2565 continue;
2566 DeclRefExpr *DRE = buildDeclRefExpr(
2567 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
2568 Cap.getLocation(), /*RefersToCapture=*/true);
2569 Visit(DRE);
2570 }
2571 }
2572
Alexey Bataev758e55e2013-09-06 18:03:48 +00002573public:
2574 void VisitDeclRefExpr(DeclRefExpr *E) {
Alexey Bataev07b79c22016-04-29 09:56:11 +00002575 if (E->isTypeDependent() || E->isValueDependent() ||
2576 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2577 return;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002578 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
Alexey Bataev412254a2019-05-09 18:44:53 +00002579 // Check the datasharing rules for the expressions in the clauses.
2580 if (!CS) {
2581 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2582 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2583 Visit(CED->getInit());
2584 return;
2585 }
2586 }
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00002587 VD = VD->getCanonicalDecl();
Alexey Bataev758e55e2013-09-06 18:03:48 +00002588 // Skip internally declared variables.
Alexey Bataev412254a2019-05-09 18:44:53 +00002589 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
Alexey Bataeved09d242014-05-28 05:53:51 +00002590 return;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002591
Alexey Bataeve3727102018-04-18 15:57:46 +00002592 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002593 // Check if the variable has explicit DSA set and stop analysis if it so.
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00002594 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
David Majnemer9d168222016-08-05 17:44:54 +00002595 return;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002596
Alexey Bataevafe50572017-10-06 17:00:28 +00002597 // Skip internally declared static variables.
Alexey Bataev92327c52018-03-26 16:40:55 +00002598 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002599 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataev412254a2019-05-09 18:44:53 +00002600 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
Alexey Bataev92327c52018-03-26 16:40:55 +00002601 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
Alexey Bataevafe50572017-10-06 17:00:28 +00002602 return;
2603
Alexey Bataeve3727102018-04-18 15:57:46 +00002604 SourceLocation ELoc = E->getExprLoc();
2605 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
Alexey Bataev758e55e2013-09-06 18:03:48 +00002606 // The default(none) clause requires that each variable that is referenced
2607 // in the construct, and does not have a predetermined data-sharing
2608 // attribute, must have its data-sharing attribute explicitly determined
2609 // by being listed in a data-sharing attribute clause.
2610 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
Alexey Bataev7e6803e2019-01-09 15:58:05 +00002611 isImplicitOrExplicitTaskingRegion(DKind) &&
Alexey Bataev4acb8592014-07-07 13:01:15 +00002612 VarsWithInheritedDSA.count(VD) == 0) {
2613 VarsWithInheritedDSA[VD] = E;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002614 return;
2615 }
2616
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002617 if (isOpenMPTargetExecutionDirective(DKind) &&
2618 !Stack->isLoopControlVariable(VD).first) {
2619 if (!Stack->checkMappableExprComponentListsForDecl(
2620 VD, /*CurrentRegionOnly=*/true,
2621 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2622 StackComponents,
2623 OpenMPClauseKind) {
2624 // Variable is used if it has been marked as an array, array
2625 // section or the variable iself.
2626 return StackComponents.size() == 1 ||
2627 std::all_of(
2628 std::next(StackComponents.rbegin()),
2629 StackComponents.rend(),
2630 [](const OMPClauseMappableExprCommon::
2631 MappableComponent &MC) {
2632 return MC.getAssociatedDeclaration() ==
2633 nullptr &&
2634 (isa<OMPArraySectionExpr>(
2635 MC.getAssociatedExpression()) ||
2636 isa<ArraySubscriptExpr>(
2637 MC.getAssociatedExpression()));
2638 });
2639 })) {
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002640 bool IsFirstprivate = false;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002641 // By default lambdas are captured as firstprivates.
2642 if (const auto *RD =
2643 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002644 IsFirstprivate = RD->isLambda();
2645 IsFirstprivate =
2646 IsFirstprivate ||
2647 (VD->getType().getNonReferenceType()->isScalarType() &&
Alexey Bataev92327c52018-03-26 16:40:55 +00002648 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002649 if (IsFirstprivate)
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002650 ImplicitFirstprivate.emplace_back(E);
2651 else
2652 ImplicitMap.emplace_back(E);
2653 return;
2654 }
2655 }
2656
Alexey Bataev758e55e2013-09-06 18:03:48 +00002657 // OpenMP [2.9.3.6, Restrictions, p.2]
2658 // A list item that appears in a reduction clause of the innermost
2659 // enclosing worksharing or parallel construct may not be accessed in an
2660 // explicit task.
Alexey Bataev7ace49d2016-05-17 08:55:33 +00002661 DVar = Stack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00002662 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2663 [](OpenMPDirectiveKind K) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +00002664 return isOpenMPParallelDirective(K) ||
2665 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2666 },
Alexey Bataeveffbdf12017-07-21 17:24:30 +00002667 /*FromParent=*/true);
Alexey Bataev35aaee62016-04-13 13:36:48 +00002668 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
Alexey Bataevc5e02582014-06-16 07:08:35 +00002669 ErrorFound = true;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002670 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
Alexey Bataeve3727102018-04-18 15:57:46 +00002671 reportOriginalDsa(SemaRef, Stack, VD, DVar);
Alexey Bataevc5e02582014-06-16 07:08:35 +00002672 return;
2673 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002674
2675 // Define implicit data-sharing attributes for task.
Alexey Bataeve3727102018-04-18 15:57:46 +00002676 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
Alexey Bataev35aaee62016-04-13 13:36:48 +00002677 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
Alexey Bataeva495c642019-03-11 19:51:42 +00002678 !Stack->isLoopControlVariable(VD).first) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002679 ImplicitFirstprivate.push_back(E);
Alexey Bataeva495c642019-03-11 19:51:42 +00002680 return;
2681 }
2682
2683 // Store implicitly used globals with declare target link for parent
2684 // target.
2685 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
2686 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2687 Stack->addToParentTargetRegionLinkGlobals(E);
2688 return;
2689 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002690 }
2691 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002692 void VisitMemberExpr(MemberExpr *E) {
Alexey Bataev07b79c22016-04-29 09:56:11 +00002693 if (E->isTypeDependent() || E->isValueDependent() ||
2694 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2695 return;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002696 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002697 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
Patrick Lystere13b1e32019-01-02 19:28:48 +00002698 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002699 if (!FD)
2700 return;
Alexey Bataeve3727102018-04-18 15:57:46 +00002701 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002702 // Check if the variable has explicit DSA set and stop analysis if it
2703 // so.
2704 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2705 return;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002706
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002707 if (isOpenMPTargetExecutionDirective(DKind) &&
2708 !Stack->isLoopControlVariable(FD).first &&
2709 !Stack->checkMappableExprComponentListsForDecl(
2710 FD, /*CurrentRegionOnly=*/true,
2711 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2712 StackComponents,
2713 OpenMPClauseKind) {
2714 return isa<CXXThisExpr>(
2715 cast<MemberExpr>(
2716 StackComponents.back().getAssociatedExpression())
2717 ->getBase()
2718 ->IgnoreParens());
2719 })) {
2720 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2721 // A bit-field cannot appear in a map clause.
2722 //
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002723 if (FD->isBitField())
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002724 return;
Patrick Lystere13b1e32019-01-02 19:28:48 +00002725
2726 // Check to see if the member expression is referencing a class that
2727 // has already been explicitly mapped
2728 if (Stack->isClassPreviouslyMapped(TE->getType()))
2729 return;
2730
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002731 ImplicitMap.emplace_back(E);
2732 return;
2733 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002734
Alexey Bataeve3727102018-04-18 15:57:46 +00002735 SourceLocation ELoc = E->getExprLoc();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002736 // OpenMP [2.9.3.6, Restrictions, p.2]
2737 // A list item that appears in a reduction clause of the innermost
2738 // enclosing worksharing or parallel construct may not be accessed in
2739 // an explicit task.
2740 DVar = Stack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00002741 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2742 [](OpenMPDirectiveKind K) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002743 return isOpenMPParallelDirective(K) ||
2744 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2745 },
2746 /*FromParent=*/true);
2747 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2748 ErrorFound = true;
2749 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
Alexey Bataeve3727102018-04-18 15:57:46 +00002750 reportOriginalDsa(SemaRef, Stack, FD, DVar);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002751 return;
2752 }
2753
2754 // Define implicit data-sharing attributes for task.
Alexey Bataeve3727102018-04-18 15:57:46 +00002755 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002756 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
Alexey Bataevb40e05202018-10-24 18:53:12 +00002757 !Stack->isLoopControlVariable(FD).first) {
2758 // Check if there is a captured expression for the current field in the
2759 // region. Do not mark it as firstprivate unless there is no captured
2760 // expression.
2761 // TODO: try to make it firstprivate.
2762 if (DVar.CKind != OMPC_unknown)
2763 ImplicitFirstprivate.push_back(E);
2764 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002765 return;
2766 }
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002767 if (isOpenMPTargetExecutionDirective(DKind)) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002768 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
Alexey Bataeve3727102018-04-18 15:57:46 +00002769 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002770 /*NoDiagnose=*/true))
Alexey Bataev27041fa2017-12-05 15:22:49 +00002771 return;
Alexey Bataeve3727102018-04-18 15:57:46 +00002772 const auto *VD = cast<ValueDecl>(
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002773 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2774 if (!Stack->checkMappableExprComponentListsForDecl(
2775 VD, /*CurrentRegionOnly=*/true,
2776 [&CurComponents](
2777 OMPClauseMappableExprCommon::MappableExprComponentListRef
2778 StackComponents,
2779 OpenMPClauseKind) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002780 auto CCI = CurComponents.rbegin();
Alexey Bataev5ec38932017-09-26 16:19:04 +00002781 auto CCE = CurComponents.rend();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002782 for (const auto &SC : llvm::reverse(StackComponents)) {
2783 // Do both expressions have the same kind?
2784 if (CCI->getAssociatedExpression()->getStmtClass() !=
2785 SC.getAssociatedExpression()->getStmtClass())
2786 if (!(isa<OMPArraySectionExpr>(
2787 SC.getAssociatedExpression()) &&
2788 isa<ArraySubscriptExpr>(
2789 CCI->getAssociatedExpression())))
2790 return false;
2791
Alexey Bataeve3727102018-04-18 15:57:46 +00002792 const Decl *CCD = CCI->getAssociatedDeclaration();
2793 const Decl *SCD = SC.getAssociatedDeclaration();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002794 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2795 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2796 if (SCD != CCD)
2797 return false;
2798 std::advance(CCI, 1);
Alexey Bataev5ec38932017-09-26 16:19:04 +00002799 if (CCI == CCE)
2800 break;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002801 }
2802 return true;
2803 })) {
2804 Visit(E->getBase());
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002805 }
Alexey Bataeve3727102018-04-18 15:57:46 +00002806 } else {
Alexey Bataev7fcacd82016-11-28 15:55:15 +00002807 Visit(E->getBase());
Alexey Bataeve3727102018-04-18 15:57:46 +00002808 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002809 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002810 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002811 for (OMPClause *C : S->clauses()) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002812 // Skip analysis of arguments of implicitly defined firstprivate clause
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002813 // for task|target directives.
2814 // Skip analysis of arguments of implicitly defined map clause for target
2815 // directives.
2816 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2817 C->isImplicit())) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002818 for (Stmt *CC : C->children()) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002819 if (CC)
2820 Visit(CC);
2821 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002822 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002823 }
Alexey Bataevf07946e2018-10-29 20:17:42 +00002824 // Check implicitly captured variables.
2825 VisitSubCaptures(S);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002826 }
2827 void VisitStmt(Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002828 for (Stmt *C : S->children()) {
Alexey Bataev8fc7b5f2018-10-25 15:35:27 +00002829 if (C) {
Joel E. Denny0fdf5a92018-12-19 15:59:47 +00002830 // Check implicitly captured variables in the task-based directives to
2831 // check if they must be firstprivatized.
2832 Visit(C);
Alexey Bataev8fc7b5f2018-10-25 15:35:27 +00002833 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002834 }
Alexey Bataeved09d242014-05-28 05:53:51 +00002835 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002836
Alexey Bataeve3727102018-04-18 15:57:46 +00002837 bool isErrorFound() const { return ErrorFound; }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002838 ArrayRef<Expr *> getImplicitFirstprivate() const {
2839 return ImplicitFirstprivate;
2840 }
2841 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
Alexey Bataeve3727102018-04-18 15:57:46 +00002842 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
Alexey Bataev4acb8592014-07-07 13:01:15 +00002843 return VarsWithInheritedDSA;
2844 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002845
Alexey Bataev7ff55242014-06-19 09:13:45 +00002846 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
Alexey Bataeva495c642019-03-11 19:51:42 +00002847 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
2848 // Process declare target link variables for the target directives.
2849 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
2850 for (DeclRefExpr *E : Stack->getLinkGlobals())
2851 Visit(E);
2852 }
2853 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002854};
Alexey Bataeved09d242014-05-28 05:53:51 +00002855} // namespace
Alexey Bataev758e55e2013-09-06 18:03:48 +00002856
Alexey Bataevbae9a792014-06-27 10:37:06 +00002857void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
Alexey Bataev9959db52014-05-06 10:08:46 +00002858 switch (DKind) {
Kelvin Li70a12c52016-07-13 21:51:49 +00002859 case OMPD_parallel:
2860 case OMPD_parallel_for:
2861 case OMPD_parallel_for_simd:
2862 case OMPD_parallel_sections:
Carlo Bertolliba1487b2017-10-04 14:12:09 +00002863 case OMPD_teams:
Alexey Bataev999277a2017-12-06 14:31:09 +00002864 case OMPD_teams_distribute:
2865 case OMPD_teams_distribute_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002866 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Alexey Bataev2377fe92015-09-10 08:12:02 +00002867 QualType KmpInt32PtrTy =
2868 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
Alexey Bataevdf9b1592014-06-25 04:09:13 +00002869 Sema::CapturedParamNameType Params[] = {
Alexey Bataevf29276e2014-06-18 04:14:57 +00002870 std::make_pair(".global_tid.", KmpInt32PtrTy),
2871 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2872 std::make_pair(StringRef(), QualType()) // __context with shared vars
Alexey Bataev9959db52014-05-06 10:08:46 +00002873 };
Alexey Bataevbae9a792014-06-27 10:37:06 +00002874 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2875 Params);
Alexey Bataev9959db52014-05-06 10:08:46 +00002876 break;
2877 }
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00002878 case OMPD_target_teams:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00002879 case OMPD_target_parallel:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00002880 case OMPD_target_parallel_for:
Alexey Bataevdfa430f2017-12-08 15:03:50 +00002881 case OMPD_target_parallel_for_simd:
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00002882 case OMPD_target_teams_distribute:
2883 case OMPD_target_teams_distribute_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002884 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2885 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2886 QualType KmpInt32PtrTy =
2887 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2888 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00002889 FunctionProtoType::ExtProtoInfo EPI;
2890 EPI.Variadic = true;
2891 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2892 Sema::CapturedParamNameType Params[] = {
2893 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002894 std::make_pair(".part_id.", KmpInt32PtrTy),
2895 std::make_pair(".privates.", VoidPtrTy),
2896 std::make_pair(
2897 ".copy_fn.",
2898 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00002899 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2900 std::make_pair(StringRef(), QualType()) // __context with shared vars
2901 };
2902 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2903 Params);
Alexey Bataev0c869ef2018-01-16 15:57:07 +00002904 // Mark this captured region as inlined, because we don't use outlined
2905 // function directly.
2906 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2907 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002908 Context, AlwaysInlineAttr::Keyword_forceinline));
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00002909 Sema::CapturedParamNameType ParamsTarget[] = {
2910 std::make_pair(StringRef(), QualType()) // __context with shared vars
2911 };
2912 // Start a captured region for 'target' with no implicit parameters.
2913 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2914 ParamsTarget);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00002915 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00002916 std::make_pair(".global_tid.", KmpInt32PtrTy),
2917 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2918 std::make_pair(StringRef(), QualType()) // __context with shared vars
2919 };
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00002920 // Start a captured region for 'teams' or 'parallel'. Both regions have
2921 // the same implicit parameters.
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00002922 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00002923 ParamsTeamsOrParallel);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00002924 break;
2925 }
Alexey Bataev8451efa2018-01-15 19:06:12 +00002926 case OMPD_target:
2927 case OMPD_target_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002928 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2929 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2930 QualType KmpInt32PtrTy =
2931 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2932 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00002933 FunctionProtoType::ExtProtoInfo EPI;
2934 EPI.Variadic = true;
2935 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2936 Sema::CapturedParamNameType Params[] = {
2937 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002938 std::make_pair(".part_id.", KmpInt32PtrTy),
2939 std::make_pair(".privates.", VoidPtrTy),
2940 std::make_pair(
2941 ".copy_fn.",
2942 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00002943 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2944 std::make_pair(StringRef(), QualType()) // __context with shared vars
2945 };
2946 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2947 Params);
2948 // Mark this captured region as inlined, because we don't use outlined
2949 // function directly.
2950 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2951 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002952 Context, AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev8451efa2018-01-15 19:06:12 +00002953 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2954 std::make_pair(StringRef(), QualType()));
2955 break;
2956 }
Kelvin Li70a12c52016-07-13 21:51:49 +00002957 case OMPD_simd:
2958 case OMPD_for:
2959 case OMPD_for_simd:
2960 case OMPD_sections:
2961 case OMPD_section:
2962 case OMPD_single:
2963 case OMPD_master:
2964 case OMPD_critical:
Kelvin Lia579b912016-07-14 02:54:56 +00002965 case OMPD_taskgroup:
2966 case OMPD_distribute:
Alexey Bataev46506272017-12-05 17:41:34 +00002967 case OMPD_distribute_simd:
Kelvin Li70a12c52016-07-13 21:51:49 +00002968 case OMPD_ordered:
2969 case OMPD_atomic:
Alexey Bataev8451efa2018-01-15 19:06:12 +00002970 case OMPD_target_data: {
Alexey Bataevdf9b1592014-06-25 04:09:13 +00002971 Sema::CapturedParamNameType Params[] = {
Alexey Bataevf29276e2014-06-18 04:14:57 +00002972 std::make_pair(StringRef(), QualType()) // __context with shared vars
2973 };
Alexey Bataevbae9a792014-06-27 10:37:06 +00002974 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2975 Params);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002976 break;
2977 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002978 case OMPD_task: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002979 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2980 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2981 QualType KmpInt32PtrTy =
2982 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2983 QualType Args[] = {VoidPtrTy};
Alexey Bataev3ae88e22015-05-22 08:56:35 +00002984 FunctionProtoType::ExtProtoInfo EPI;
2985 EPI.Variadic = true;
2986 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002987 Sema::CapturedParamNameType Params[] = {
Alexey Bataev62b63b12015-03-10 07:28:44 +00002988 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00002989 std::make_pair(".part_id.", KmpInt32PtrTy),
2990 std::make_pair(".privates.", VoidPtrTy),
2991 std::make_pair(
2992 ".copy_fn.",
2993 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev48591dd2016-04-20 04:01:36 +00002994 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002995 std::make_pair(StringRef(), QualType()) // __context with shared vars
2996 };
2997 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2998 Params);
Alexey Bataev62b63b12015-03-10 07:28:44 +00002999 // Mark this captured region as inlined, because we don't use outlined
3000 // function directly.
3001 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3002 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003003 Context, AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003004 break;
3005 }
Alexey Bataev1e73ef32016-04-28 12:14:51 +00003006 case OMPD_taskloop:
3007 case OMPD_taskloop_simd: {
Alexey Bataev7292c292016-04-25 12:22:29 +00003008 QualType KmpInt32Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003009 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3010 .withConst();
Alexey Bataev7292c292016-04-25 12:22:29 +00003011 QualType KmpUInt64Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003012 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3013 .withConst();
Alexey Bataev7292c292016-04-25 12:22:29 +00003014 QualType KmpInt64Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003015 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3016 .withConst();
3017 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3018 QualType KmpInt32PtrTy =
3019 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3020 QualType Args[] = {VoidPtrTy};
Alexey Bataev7292c292016-04-25 12:22:29 +00003021 FunctionProtoType::ExtProtoInfo EPI;
3022 EPI.Variadic = true;
3023 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
Alexey Bataev49f6e782015-12-01 04:18:41 +00003024 Sema::CapturedParamNameType Params[] = {
Alexey Bataev7292c292016-04-25 12:22:29 +00003025 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003026 std::make_pair(".part_id.", KmpInt32PtrTy),
3027 std::make_pair(".privates.", VoidPtrTy),
Alexey Bataev7292c292016-04-25 12:22:29 +00003028 std::make_pair(
3029 ".copy_fn.",
3030 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3031 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3032 std::make_pair(".lb.", KmpUInt64Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003033 std::make_pair(".ub.", KmpUInt64Ty),
3034 std::make_pair(".st.", KmpInt64Ty),
Alexey Bataev7292c292016-04-25 12:22:29 +00003035 std::make_pair(".liter.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003036 std::make_pair(".reductions.", VoidPtrTy),
Alexey Bataev49f6e782015-12-01 04:18:41 +00003037 std::make_pair(StringRef(), QualType()) // __context with shared vars
3038 };
3039 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3040 Params);
Alexey Bataev7292c292016-04-25 12:22:29 +00003041 // Mark this captured region as inlined, because we don't use outlined
3042 // function directly.
3043 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3044 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003045 Context, AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev49f6e782015-12-01 04:18:41 +00003046 break;
3047 }
Kelvin Li4a39add2016-07-05 05:00:15 +00003048 case OMPD_distribute_parallel_for_simd:
Alexey Bataev647dd842018-01-15 20:59:40 +00003049 case OMPD_distribute_parallel_for: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003050 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli9925f152016-06-27 14:55:37 +00003051 QualType KmpInt32PtrTy =
3052 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3053 Sema::CapturedParamNameType Params[] = {
3054 std::make_pair(".global_tid.", KmpInt32PtrTy),
3055 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003056 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3057 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli9925f152016-06-27 14:55:37 +00003058 std::make_pair(StringRef(), QualType()) // __context with shared vars
3059 };
3060 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3061 Params);
3062 break;
3063 }
Alexey Bataev647dd842018-01-15 20:59:40 +00003064 case OMPD_target_teams_distribute_parallel_for:
3065 case OMPD_target_teams_distribute_parallel_for_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003066 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli52978c32018-01-03 21:12:44 +00003067 QualType KmpInt32PtrTy =
3068 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003069 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
Carlo Bertolli52978c32018-01-03 21:12:44 +00003070
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003071 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00003072 FunctionProtoType::ExtProtoInfo EPI;
3073 EPI.Variadic = true;
3074 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3075 Sema::CapturedParamNameType Params[] = {
3076 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003077 std::make_pair(".part_id.", KmpInt32PtrTy),
3078 std::make_pair(".privates.", VoidPtrTy),
3079 std::make_pair(
3080 ".copy_fn.",
3081 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00003082 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3083 std::make_pair(StringRef(), QualType()) // __context with shared vars
3084 };
3085 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3086 Params);
Alexey Bataev9f9fb0b2018-01-16 19:02:33 +00003087 // Mark this captured region as inlined, because we don't use outlined
3088 // function directly.
3089 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3090 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003091 Context, AlwaysInlineAttr::Keyword_forceinline));
Carlo Bertolli52978c32018-01-03 21:12:44 +00003092 Sema::CapturedParamNameType ParamsTarget[] = {
3093 std::make_pair(StringRef(), QualType()) // __context with shared vars
3094 };
3095 // Start a captured region for 'target' with no implicit parameters.
3096 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3097 ParamsTarget);
3098
3099 Sema::CapturedParamNameType ParamsTeams[] = {
3100 std::make_pair(".global_tid.", KmpInt32PtrTy),
3101 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3102 std::make_pair(StringRef(), QualType()) // __context with shared vars
3103 };
3104 // Start a captured region for 'target' with no implicit parameters.
3105 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3106 ParamsTeams);
3107
3108 Sema::CapturedParamNameType ParamsParallel[] = {
3109 std::make_pair(".global_tid.", KmpInt32PtrTy),
3110 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003111 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3112 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli52978c32018-01-03 21:12:44 +00003113 std::make_pair(StringRef(), QualType()) // __context with shared vars
3114 };
3115 // Start a captured region for 'teams' or 'parallel'. Both regions have
3116 // the same implicit parameters.
3117 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3118 ParamsParallel);
3119 break;
3120 }
3121
Alexey Bataev46506272017-12-05 17:41:34 +00003122 case OMPD_teams_distribute_parallel_for:
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00003123 case OMPD_teams_distribute_parallel_for_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli62fae152017-11-20 20:46:39 +00003125 QualType KmpInt32PtrTy =
3126 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3127
3128 Sema::CapturedParamNameType ParamsTeams[] = {
3129 std::make_pair(".global_tid.", KmpInt32PtrTy),
3130 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3131 std::make_pair(StringRef(), QualType()) // __context with shared vars
3132 };
3133 // Start a captured region for 'target' with no implicit parameters.
3134 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3135 ParamsTeams);
3136
3137 Sema::CapturedParamNameType ParamsParallel[] = {
3138 std::make_pair(".global_tid.", KmpInt32PtrTy),
3139 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003140 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3141 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli62fae152017-11-20 20:46:39 +00003142 std::make_pair(StringRef(), QualType()) // __context with shared vars
3143 };
3144 // Start a captured region for 'teams' or 'parallel'. Both regions have
3145 // the same implicit parameters.
3146 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3147 ParamsParallel);
3148 break;
3149 }
Alexey Bataev7828b252017-11-21 17:08:48 +00003150 case OMPD_target_update:
3151 case OMPD_target_enter_data:
3152 case OMPD_target_exit_data: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003153 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3154 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3155 QualType KmpInt32PtrTy =
3156 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3157 QualType Args[] = {VoidPtrTy};
Alexey Bataev7828b252017-11-21 17:08:48 +00003158 FunctionProtoType::ExtProtoInfo EPI;
3159 EPI.Variadic = true;
3160 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3161 Sema::CapturedParamNameType Params[] = {
3162 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003163 std::make_pair(".part_id.", KmpInt32PtrTy),
3164 std::make_pair(".privates.", VoidPtrTy),
3165 std::make_pair(
3166 ".copy_fn.",
3167 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev7828b252017-11-21 17:08:48 +00003168 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3169 std::make_pair(StringRef(), QualType()) // __context with shared vars
3170 };
3171 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3172 Params);
3173 // Mark this captured region as inlined, because we don't use outlined
3174 // function directly.
3175 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3176 AlwaysInlineAttr::CreateImplicit(
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003177 Context, AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev7828b252017-11-21 17:08:48 +00003178 break;
3179 }
Alexey Bataev9959db52014-05-06 10:08:46 +00003180 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00003181 case OMPD_allocate:
Alexey Bataevee9af452014-11-21 11:33:46 +00003182 case OMPD_taskyield:
3183 case OMPD_barrier:
3184 case OMPD_taskwait:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003185 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00003186 case OMPD_cancel:
Alexey Bataevee9af452014-11-21 11:33:46 +00003187 case OMPD_flush:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00003188 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00003189 case OMPD_declare_mapper:
Alexey Bataev587e1de2016-03-30 10:43:55 +00003190 case OMPD_declare_simd:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00003191 case OMPD_declare_target:
3192 case OMPD_end_declare_target:
Kelvin Li1408f912018-09-26 04:28:39 +00003193 case OMPD_requires:
Alexey Bataev9959db52014-05-06 10:08:46 +00003194 llvm_unreachable("OpenMP Directive is not allowed");
3195 case OMPD_unknown:
Alexey Bataev9959db52014-05-06 10:08:46 +00003196 llvm_unreachable("Unknown OpenMP directive");
3197 }
3198}
3199
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003200int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3201 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3202 getOpenMPCaptureRegions(CaptureRegions, DKind);
3203 return CaptureRegions.size();
3204}
3205
Alexey Bataev3392d762016-02-16 11:18:12 +00003206static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
Alexey Bataev5a3af132016-03-29 08:58:54 +00003207 Expr *CaptureExpr, bool WithInit,
3208 bool AsExpression) {
Alexey Bataev2bbf7212016-03-03 03:52:24 +00003209 assert(CaptureExpr);
Alexey Bataev4244be22016-02-11 05:35:55 +00003210 ASTContext &C = S.getASTContext();
Alexey Bataev5a3af132016-03-29 08:58:54 +00003211 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
Alexey Bataev4244be22016-02-11 05:35:55 +00003212 QualType Ty = Init->getType();
3213 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003214 if (S.getLangOpts().CPlusPlus) {
Alexey Bataev4244be22016-02-11 05:35:55 +00003215 Ty = C.getLValueReferenceType(Ty);
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003216 } else {
Alexey Bataev4244be22016-02-11 05:35:55 +00003217 Ty = C.getPointerType(Ty);
3218 ExprResult Res =
3219 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3220 if (!Res.isUsable())
3221 return nullptr;
3222 Init = Res.get();
3223 }
Alexey Bataev61205072016-03-02 04:57:40 +00003224 WithInit = true;
Alexey Bataev4244be22016-02-11 05:35:55 +00003225 }
Alexey Bataeva7206b92016-12-20 16:51:02 +00003226 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003227 CaptureExpr->getBeginLoc());
Alexey Bataev2bbf7212016-03-03 03:52:24 +00003228 if (!WithInit)
Alexey Bataeve3727102018-04-18 15:57:46 +00003229 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
Alexey Bataev4244be22016-02-11 05:35:55 +00003230 S.CurContext->addHiddenDecl(CED);
Richard Smith3beb7c62017-01-12 02:27:38 +00003231 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
Alexey Bataev3392d762016-02-16 11:18:12 +00003232 return CED;
3233}
3234
Alexey Bataev61205072016-03-02 04:57:40 +00003235static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3236 bool WithInit) {
Alexey Bataevb7a34b62016-02-25 03:59:29 +00003237 OMPCapturedExprDecl *CD;
Alexey Bataeve3727102018-04-18 15:57:46 +00003238 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
Alexey Bataevb7a34b62016-02-25 03:59:29 +00003239 CD = cast<OMPCapturedExprDecl>(VD);
Alexey Bataeve3727102018-04-18 15:57:46 +00003240 else
Alexey Bataev5a3af132016-03-29 08:58:54 +00003241 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3242 /*AsExpression=*/false);
Alexey Bataev3392d762016-02-16 11:18:12 +00003243 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
Alexey Bataev1efd1662016-03-29 10:59:56 +00003244 CaptureExpr->getExprLoc());
Alexey Bataev3392d762016-02-16 11:18:12 +00003245}
3246
Alexey Bataev5a3af132016-03-29 08:58:54 +00003247static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003248 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
Alexey Bataev5a3af132016-03-29 08:58:54 +00003249 if (!Ref) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003250 OMPCapturedExprDecl *CD = buildCaptureDecl(
3251 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3252 /*WithInit=*/true, /*AsExpression=*/true);
Alexey Bataev5a3af132016-03-29 08:58:54 +00003253 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3254 CaptureExpr->getExprLoc());
3255 }
3256 ExprResult Res = Ref;
3257 if (!S.getLangOpts().CPlusPlus &&
3258 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003259 Ref->getType()->isPointerType()) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00003260 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003261 if (!Res.isUsable())
3262 return ExprError();
3263 }
3264 return S.DefaultLvalueConversion(Res.get());
Alexey Bataev4244be22016-02-11 05:35:55 +00003265}
3266
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003267namespace {
3268// OpenMP directives parsed in this section are represented as a
3269// CapturedStatement with an associated statement. If a syntax error
3270// is detected during the parsing of the associated statement, the
3271// compiler must abort processing and close the CapturedStatement.
3272//
3273// Combined directives such as 'target parallel' have more than one
3274// nested CapturedStatements. This RAII ensures that we unwind out
3275// of all the nested CapturedStatements when an error is found.
3276class CaptureRegionUnwinderRAII {
3277private:
3278 Sema &S;
3279 bool &ErrorFound;
Alexey Bataeve3727102018-04-18 15:57:46 +00003280 OpenMPDirectiveKind DKind = OMPD_unknown;
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003281
3282public:
3283 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3284 OpenMPDirectiveKind DKind)
3285 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3286 ~CaptureRegionUnwinderRAII() {
3287 if (ErrorFound) {
3288 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3289 while (--ThisCaptureLevel >= 0)
3290 S.ActOnCapturedRegionError();
3291 }
3292 }
3293};
3294} // namespace
3295
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003296StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3297 ArrayRef<OMPClause *> Clauses) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003298 bool ErrorFound = false;
3299 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3300 *this, ErrorFound, DSAStack->getCurrentDirective());
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003301 if (!S.isUsable()) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003302 ErrorFound = true;
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003303 return StmtError();
3304 }
Alexey Bataev993d2802015-12-28 06:23:08 +00003305
Alexey Bataev2ba67042017-11-28 21:11:44 +00003306 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3307 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
Alexey Bataev993d2802015-12-28 06:23:08 +00003308 OMPOrderedClause *OC = nullptr;
Alexey Bataev6402bca2015-12-28 07:25:51 +00003309 OMPScheduleClause *SC = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +00003310 SmallVector<const OMPLinearClause *, 4> LCs;
3311 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
Alexey Bataev040d5402015-05-12 08:35:28 +00003312 // This is required for proper codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00003313 for (OMPClause *Clause : Clauses) {
Alexey Bataev88202be2017-07-27 13:20:36 +00003314 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
3315 Clause->getClauseKind() == OMPC_in_reduction) {
3316 // Capture taskgroup task_reduction descriptors inside the tasking regions
3317 // with the corresponding in_reduction items.
3318 auto *IRC = cast<OMPInReductionClause>(Clause);
Alexey Bataeve3727102018-04-18 15:57:46 +00003319 for (Expr *E : IRC->taskgroup_descriptors())
Alexey Bataev88202be2017-07-27 13:20:36 +00003320 if (E)
3321 MarkDeclarationsReferencedInExpr(E);
3322 }
Alexey Bataev16dc7b62015-05-20 03:46:04 +00003323 if (isOpenMPPrivate(Clause->getClauseKind()) ||
Samuel Antao9c75cfe2015-07-27 16:38:06 +00003324 Clause->getClauseKind() == OMPC_copyprivate ||
3325 (getLangOpts().OpenMPUseTLS &&
3326 getASTContext().getTargetInfo().isTLSSupported() &&
3327 Clause->getClauseKind() == OMPC_copyin)) {
3328 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
Alexey Bataev040d5402015-05-12 08:35:28 +00003329 // Mark all variables in private list clauses as used in inner region.
Alexey Bataeve3727102018-04-18 15:57:46 +00003330 for (Stmt *VarRef : Clause->children()) {
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003331 if (auto *E = cast_or_null<Expr>(VarRef)) {
Alexey Bataev8bf6b3e2015-04-02 13:07:08 +00003332 MarkDeclarationsReferencedInExpr(E);
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003333 }
3334 }
Samuel Antao9c75cfe2015-07-27 16:38:06 +00003335 DSAStack->setForceVarCapturing(/*V=*/false);
Alexey Bataev2ba67042017-11-28 21:11:44 +00003336 } else if (CaptureRegions.size() > 1 ||
3337 CaptureRegions.back() != OMPD_unknown) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003338 if (auto *C = OMPClauseWithPreInit::get(Clause))
3339 PICs.push_back(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00003340 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003341 if (Expr *E = C->getPostUpdateExpr())
Alexey Bataev005248a2016-02-25 05:25:57 +00003342 MarkDeclarationsReferencedInExpr(E);
3343 }
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003344 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003345 if (Clause->getClauseKind() == OMPC_schedule)
3346 SC = cast<OMPScheduleClause>(Clause);
3347 else if (Clause->getClauseKind() == OMPC_ordered)
Alexey Bataev993d2802015-12-28 06:23:08 +00003348 OC = cast<OMPOrderedClause>(Clause);
3349 else if (Clause->getClauseKind() == OMPC_linear)
3350 LCs.push_back(cast<OMPLinearClause>(Clause));
3351 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003352 // OpenMP, 2.7.1 Loop Construct, Restrictions
3353 // The nonmonotonic modifier cannot be specified if an ordered clause is
3354 // specified.
3355 if (SC &&
3356 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3357 SC->getSecondScheduleModifier() ==
3358 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3359 OC) {
3360 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3361 ? SC->getFirstScheduleModifierLoc()
3362 : SC->getSecondScheduleModifierLoc(),
3363 diag::err_omp_schedule_nonmonotonic_ordered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00003364 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
Alexey Bataev6402bca2015-12-28 07:25:51 +00003365 ErrorFound = true;
3366 }
Alexey Bataev993d2802015-12-28 06:23:08 +00003367 if (!LCs.empty() && OC && OC->getNumForLoops()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003368 for (const OMPLinearClause *C : LCs) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003369 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00003370 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
Alexey Bataev993d2802015-12-28 06:23:08 +00003371 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003372 ErrorFound = true;
3373 }
Alexey Bataev113438c2015-12-30 12:06:23 +00003374 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
3375 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
3376 OC->getNumForLoops()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003377 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
Alexey Bataev113438c2015-12-30 12:06:23 +00003378 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3379 ErrorFound = true;
3380 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003381 if (ErrorFound) {
Alexey Bataev993d2802015-12-28 06:23:08 +00003382 return StmtError();
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003383 }
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003384 StmtResult SR = S;
Alexey Bataev2ba67042017-11-28 21:11:44 +00003385 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003386 // Mark all variables in private list clauses as used in inner region.
3387 // Required for proper codegen of combined directives.
3388 // TODO: add processing for other clauses.
Alexey Bataev2ba67042017-11-28 21:11:44 +00003389 if (ThisCaptureRegion != OMPD_unknown) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003390 for (const clang::OMPClauseWithPreInit *C : PICs) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003391 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3392 // Find the particular capture region for the clause if the
3393 // directive is a combined one with multiple capture regions.
3394 // If the directive is not a combined one, the capture region
3395 // associated with the clause is OMPD_unknown and is generated
3396 // only once.
3397 if (CaptureRegion == ThisCaptureRegion ||
3398 CaptureRegion == OMPD_unknown) {
3399 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003400 for (Decl *D : DS->decls())
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003401 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3402 }
3403 }
3404 }
3405 }
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003406 SR = ActOnCapturedRegionEnd(SR.get());
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003407 }
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003408 return SR;
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003409}
3410
Jonas Hahnfeld64a9e3c2017-02-22 06:49:10 +00003411static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3412 OpenMPDirectiveKind CancelRegion,
3413 SourceLocation StartLoc) {
3414 // CancelRegion is only needed for cancel and cancellation_point.
3415 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3416 return false;
3417
3418 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3419 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3420 return false;
3421
3422 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3423 << getOpenMPDirectiveName(CancelRegion);
3424 return true;
3425}
3426
Alexey Bataeve3727102018-04-18 15:57:46 +00003427static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003428 OpenMPDirectiveKind CurrentRegion,
3429 const DeclarationNameInfo &CurrentName,
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003430 OpenMPDirectiveKind CancelRegion,
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003431 SourceLocation StartLoc) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003432 if (Stack->getCurScope()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003433 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3434 OpenMPDirectiveKind OffendingRegion = ParentRegion;
Alexey Bataev549210e2014-06-24 04:39:47 +00003435 bool NestingProhibited = false;
3436 bool CloseNesting = true;
David Majnemer9d168222016-08-05 17:44:54 +00003437 bool OrphanSeen = false;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003438 enum {
3439 NoRecommend,
3440 ShouldBeInParallelRegion,
Alexey Bataev13314bf2014-10-09 04:18:56 +00003441 ShouldBeInOrderedRegion,
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003442 ShouldBeInTargetRegion,
3443 ShouldBeInTeamsRegion
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003444 } Recommend = NoRecommend;
Kelvin Lifd8b5742016-07-01 14:30:25 +00003445 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003446 // OpenMP [2.16, Nesting of Regions]
3447 // OpenMP constructs may not be nested inside a simd region.
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003448 // OpenMP [2.8.1,simd Construct, Restrictions]
Kelvin Lifd8b5742016-07-01 14:30:25 +00003449 // An ordered construct with the simd clause is the only OpenMP
3450 // construct that can appear in the simd region.
David Majnemer9d168222016-08-05 17:44:54 +00003451 // Allowing a SIMD construct nested in another SIMD construct is an
Kelvin Lifd8b5742016-07-01 14:30:25 +00003452 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3453 // message.
3454 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3455 ? diag::err_omp_prohibited_region_simd
3456 : diag::warn_omp_nesting_simd);
3457 return CurrentRegion != OMPD_simd;
Alexey Bataev549210e2014-06-24 04:39:47 +00003458 }
Alexey Bataev0162e452014-07-22 10:10:35 +00003459 if (ParentRegion == OMPD_atomic) {
3460 // OpenMP [2.16, Nesting of Regions]
3461 // OpenMP constructs may not be nested inside an atomic region.
3462 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3463 return true;
3464 }
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003465 if (CurrentRegion == OMPD_section) {
3466 // OpenMP [2.7.2, sections Construct, Restrictions]
3467 // Orphaned section directives are prohibited. That is, the section
3468 // directives must appear within the sections construct and must not be
3469 // encountered elsewhere in the sections region.
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00003470 if (ParentRegion != OMPD_sections &&
3471 ParentRegion != OMPD_parallel_sections) {
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003472 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3473 << (ParentRegion != OMPD_unknown)
3474 << getOpenMPDirectiveName(ParentRegion);
3475 return true;
3476 }
3477 return false;
3478 }
Alexey Bataev185e88d2019-01-08 15:53:42 +00003479 // Allow some constructs (except teams and cancellation constructs) to be
3480 // orphaned (they could be used in functions, called from OpenMP regions
3481 // with the required preconditions).
Kelvin Libf594a52016-12-17 05:48:59 +00003482 if (ParentRegion == OMPD_unknown &&
Alexey Bataev185e88d2019-01-08 15:53:42 +00003483 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3484 CurrentRegion != OMPD_cancellation_point &&
3485 CurrentRegion != OMPD_cancel)
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003486 return false;
Alexey Bataev80909872015-07-02 11:25:17 +00003487 if (CurrentRegion == OMPD_cancellation_point ||
3488 CurrentRegion == OMPD_cancel) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003489 // OpenMP [2.16, Nesting of Regions]
3490 // A cancellation point construct for which construct-type-clause is
3491 // taskgroup must be nested inside a task construct. A cancellation
3492 // point construct for which construct-type-clause is not taskgroup must
3493 // be closely nested inside an OpenMP construct that matches the type
3494 // specified in construct-type-clause.
Alexey Bataev80909872015-07-02 11:25:17 +00003495 // A cancel construct for which construct-type-clause is taskgroup must be
3496 // nested inside a task construct. A cancel construct for which
3497 // construct-type-clause is not taskgroup must be closely nested inside an
3498 // OpenMP construct that matches the type specified in
3499 // construct-type-clause.
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003500 NestingProhibited =
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00003501 !((CancelRegion == OMPD_parallel &&
3502 (ParentRegion == OMPD_parallel ||
3503 ParentRegion == OMPD_target_parallel)) ||
Alexey Bataev25e5b442015-09-15 12:52:43 +00003504 (CancelRegion == OMPD_for &&
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00003505 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00003506 ParentRegion == OMPD_target_parallel_for ||
3507 ParentRegion == OMPD_distribute_parallel_for ||
Alexey Bataev16e79882017-11-22 21:12:03 +00003508 ParentRegion == OMPD_teams_distribute_parallel_for ||
3509 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003510 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3511 (CancelRegion == OMPD_sections &&
Alexey Bataev25e5b442015-09-15 12:52:43 +00003512 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3513 ParentRegion == OMPD_parallel_sections)));
Alexey Bataev185e88d2019-01-08 15:53:42 +00003514 OrphanSeen = ParentRegion == OMPD_unknown;
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003515 } else if (CurrentRegion == OMPD_master) {
Alexander Musman80c22892014-07-17 08:54:58 +00003516 // OpenMP [2.16, Nesting of Regions]
3517 // A master region may not be closely nested inside a worksharing,
Alexey Bataev0162e452014-07-22 10:10:35 +00003518 // atomic, or explicit task region.
Alexander Musman80c22892014-07-17 08:54:58 +00003519 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
Alexey Bataev35aaee62016-04-13 13:36:48 +00003520 isOpenMPTaskingDirective(ParentRegion);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003521 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3522 // OpenMP [2.16, Nesting of Regions]
3523 // A critical region may not be nested (closely or otherwise) inside a
3524 // critical region with the same name. Note that this restriction is not
3525 // sufficient to prevent deadlock.
3526 SourceLocation PreviousCriticalLoc;
David Majnemer9d168222016-08-05 17:44:54 +00003527 bool DeadLock = Stack->hasDirective(
3528 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3529 const DeclarationNameInfo &DNI,
Alexey Bataeve3727102018-04-18 15:57:46 +00003530 SourceLocation Loc) {
David Majnemer9d168222016-08-05 17:44:54 +00003531 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3532 PreviousCriticalLoc = Loc;
3533 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003534 }
3535 return false;
David Majnemer9d168222016-08-05 17:44:54 +00003536 },
3537 false /* skip top directive */);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003538 if (DeadLock) {
3539 SemaRef.Diag(StartLoc,
3540 diag::err_omp_prohibited_region_critical_same_name)
3541 << CurrentName.getName();
3542 if (PreviousCriticalLoc.isValid())
3543 SemaRef.Diag(PreviousCriticalLoc,
3544 diag::note_omp_previous_critical_region);
3545 return true;
3546 }
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00003547 } else if (CurrentRegion == OMPD_barrier) {
3548 // OpenMP [2.16, Nesting of Regions]
3549 // A barrier region may not be closely nested inside a worksharing,
Alexey Bataev0162e452014-07-22 10:10:35 +00003550 // explicit task, critical, ordered, atomic, or master region.
Alexey Bataev35aaee62016-04-13 13:36:48 +00003551 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3552 isOpenMPTaskingDirective(ParentRegion) ||
3553 ParentRegion == OMPD_master ||
3554 ParentRegion == OMPD_critical ||
3555 ParentRegion == OMPD_ordered;
Alexander Musman80c22892014-07-17 08:54:58 +00003556 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
Kelvin Li579e41c2016-11-30 23:51:03 +00003557 !isOpenMPParallelDirective(CurrentRegion) &&
3558 !isOpenMPTeamsDirective(CurrentRegion)) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003559 // OpenMP [2.16, Nesting of Regions]
3560 // A worksharing region may not be closely nested inside a worksharing,
3561 // explicit task, critical, ordered, atomic, or master region.
Alexey Bataev35aaee62016-04-13 13:36:48 +00003562 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3563 isOpenMPTaskingDirective(ParentRegion) ||
3564 ParentRegion == OMPD_master ||
3565 ParentRegion == OMPD_critical ||
3566 ParentRegion == OMPD_ordered;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003567 Recommend = ShouldBeInParallelRegion;
3568 } else if (CurrentRegion == OMPD_ordered) {
3569 // OpenMP [2.16, Nesting of Regions]
3570 // An ordered region may not be closely nested inside a critical,
Alexey Bataev0162e452014-07-22 10:10:35 +00003571 // atomic, or explicit task region.
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003572 // An ordered region must be closely nested inside a loop region (or
3573 // parallel loop region) with an ordered clause.
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003574 // OpenMP [2.8.1,simd Construct, Restrictions]
3575 // An ordered construct with the simd clause is the only OpenMP construct
3576 // that can appear in the simd region.
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003577 NestingProhibited = ParentRegion == OMPD_critical ||
Alexey Bataev35aaee62016-04-13 13:36:48 +00003578 isOpenMPTaskingDirective(ParentRegion) ||
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003579 !(isOpenMPSimdDirective(ParentRegion) ||
3580 Stack->isParentOrderedRegion());
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003581 Recommend = ShouldBeInOrderedRegion;
Kelvin Libf594a52016-12-17 05:48:59 +00003582 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00003583 // OpenMP [2.16, Nesting of Regions]
3584 // If specified, a teams construct must be contained within a target
3585 // construct.
3586 NestingProhibited = ParentRegion != OMPD_target;
Kelvin Li2b51f722016-07-26 04:32:50 +00003587 OrphanSeen = ParentRegion == OMPD_unknown;
Alexey Bataev13314bf2014-10-09 04:18:56 +00003588 Recommend = ShouldBeInTargetRegion;
Alexey Bataev13314bf2014-10-09 04:18:56 +00003589 }
Kelvin Libf594a52016-12-17 05:48:59 +00003590 if (!NestingProhibited &&
3591 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3592 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3593 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00003594 // OpenMP [2.16, Nesting of Regions]
3595 // distribute, parallel, parallel sections, parallel workshare, and the
3596 // parallel loop and parallel loop SIMD constructs are the only OpenMP
3597 // constructs that can be closely nested in the teams region.
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003598 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3599 !isOpenMPDistributeDirective(CurrentRegion);
Alexey Bataev13314bf2014-10-09 04:18:56 +00003600 Recommend = ShouldBeInParallelRegion;
Alexey Bataev549210e2014-06-24 04:39:47 +00003601 }
David Majnemer9d168222016-08-05 17:44:54 +00003602 if (!NestingProhibited &&
Kelvin Li02532872016-08-05 14:37:37 +00003603 isOpenMPNestingDistributeDirective(CurrentRegion)) {
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003604 // OpenMP 4.5 [2.17 Nesting of Regions]
3605 // The region associated with the distribute construct must be strictly
3606 // nested inside a teams region
Kelvin Libf594a52016-12-17 05:48:59 +00003607 NestingProhibited =
3608 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003609 Recommend = ShouldBeInTeamsRegion;
3610 }
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003611 if (!NestingProhibited &&
3612 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3613 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3614 // OpenMP 4.5 [2.17 Nesting of Regions]
3615 // If a target, target update, target data, target enter data, or
3616 // target exit data construct is encountered during execution of a
3617 // target region, the behavior is unspecified.
3618 NestingProhibited = Stack->hasDirective(
Alexey Bataev7ace49d2016-05-17 08:55:33 +00003619 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
Alexey Bataeve3727102018-04-18 15:57:46 +00003620 SourceLocation) {
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003621 if (isOpenMPTargetExecutionDirective(K)) {
3622 OffendingRegion = K;
3623 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003624 }
3625 return false;
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003626 },
3627 false /* don't skip top directive */);
3628 CloseNesting = false;
3629 }
Alexey Bataev549210e2014-06-24 04:39:47 +00003630 if (NestingProhibited) {
Kelvin Li2b51f722016-07-26 04:32:50 +00003631 if (OrphanSeen) {
3632 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3633 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3634 } else {
3635 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3636 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3637 << Recommend << getOpenMPDirectiveName(CurrentRegion);
3638 }
Alexey Bataev549210e2014-06-24 04:39:47 +00003639 return true;
3640 }
3641 }
3642 return false;
3643}
3644
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003645static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
3646 ArrayRef<OMPClause *> Clauses,
3647 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3648 bool ErrorFound = false;
3649 unsigned NamedModifiersNumber = 0;
3650 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
3651 OMPD_unknown + 1);
Alexey Bataevecb156a2015-09-15 17:23:56 +00003652 SmallVector<SourceLocation, 4> NameModifierLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +00003653 for (const OMPClause *C : Clauses) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003654 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3655 // At most one if clause without a directive-name-modifier can appear on
3656 // the directive.
3657 OpenMPDirectiveKind CurNM = IC->getNameModifier();
3658 if (FoundNameModifiers[CurNM]) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003659 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003660 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3661 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3662 ErrorFound = true;
Alexey Bataevecb156a2015-09-15 17:23:56 +00003663 } else if (CurNM != OMPD_unknown) {
3664 NameModifierLoc.push_back(IC->getNameModifierLoc());
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003665 ++NamedModifiersNumber;
Alexey Bataevecb156a2015-09-15 17:23:56 +00003666 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003667 FoundNameModifiers[CurNM] = IC;
3668 if (CurNM == OMPD_unknown)
3669 continue;
3670 // Check if the specified name modifier is allowed for the current
3671 // directive.
3672 // At most one if clause with the particular directive-name-modifier can
3673 // appear on the directive.
3674 bool MatchFound = false;
3675 for (auto NM : AllowedNameModifiers) {
3676 if (CurNM == NM) {
3677 MatchFound = true;
3678 break;
3679 }
3680 }
3681 if (!MatchFound) {
3682 S.Diag(IC->getNameModifierLoc(),
3683 diag::err_omp_wrong_if_directive_name_modifier)
3684 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
3685 ErrorFound = true;
3686 }
3687 }
3688 }
3689 // If any if clause on the directive includes a directive-name-modifier then
3690 // all if clauses on the directive must include a directive-name-modifier.
3691 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3692 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003693 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003694 diag::err_omp_no_more_if_clause);
3695 } else {
3696 std::string Values;
3697 std::string Sep(", ");
3698 unsigned AllowedCnt = 0;
3699 unsigned TotalAllowedNum =
3700 AllowedNameModifiers.size() - NamedModifiersNumber;
3701 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3702 ++Cnt) {
3703 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3704 if (!FoundNameModifiers[NM]) {
3705 Values += "'";
3706 Values += getOpenMPDirectiveName(NM);
3707 Values += "'";
3708 if (AllowedCnt + 2 == TotalAllowedNum)
3709 Values += " or ";
3710 else if (AllowedCnt + 1 != TotalAllowedNum)
3711 Values += Sep;
3712 ++AllowedCnt;
3713 }
3714 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003715 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003716 diag::err_omp_unnamed_if_clause)
3717 << (TotalAllowedNum > 1) << Values;
3718 }
Alexey Bataeve3727102018-04-18 15:57:46 +00003719 for (SourceLocation Loc : NameModifierLoc) {
Alexey Bataevecb156a2015-09-15 17:23:56 +00003720 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3721 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003722 ErrorFound = true;
3723 }
3724 return ErrorFound;
3725}
3726
Alexey Bataeve106f252019-04-01 14:25:31 +00003727static std::pair<ValueDecl *, bool>
3728getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
3729 SourceRange &ERange, bool AllowArraySection = false) {
3730 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
3731 RefExpr->containsUnexpandedParameterPack())
3732 return std::make_pair(nullptr, true);
3733
3734 // OpenMP [3.1, C/C++]
3735 // A list item is a variable name.
3736 // OpenMP [2.9.3.3, Restrictions, p.1]
3737 // A variable that is part of another variable (as an array or
3738 // structure element) cannot appear in a private clause.
3739 RefExpr = RefExpr->IgnoreParens();
3740 enum {
3741 NoArrayExpr = -1,
3742 ArraySubscript = 0,
3743 OMPArraySection = 1
3744 } IsArrayExpr = NoArrayExpr;
3745 if (AllowArraySection) {
3746 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
3747 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
3748 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
3749 Base = TempASE->getBase()->IgnoreParenImpCasts();
3750 RefExpr = Base;
3751 IsArrayExpr = ArraySubscript;
3752 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
3753 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
3754 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
3755 Base = TempOASE->getBase()->IgnoreParenImpCasts();
3756 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
3757 Base = TempASE->getBase()->IgnoreParenImpCasts();
3758 RefExpr = Base;
3759 IsArrayExpr = OMPArraySection;
3760 }
3761 }
3762 ELoc = RefExpr->getExprLoc();
3763 ERange = RefExpr->getSourceRange();
3764 RefExpr = RefExpr->IgnoreParenImpCasts();
3765 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
3766 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
3767 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
3768 (S.getCurrentThisType().isNull() || !ME ||
3769 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
3770 !isa<FieldDecl>(ME->getMemberDecl()))) {
3771 if (IsArrayExpr != NoArrayExpr) {
3772 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
3773 << ERange;
3774 } else {
3775 S.Diag(ELoc,
3776 AllowArraySection
3777 ? diag::err_omp_expected_var_name_member_expr_or_array_item
3778 : diag::err_omp_expected_var_name_member_expr)
3779 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
3780 }
3781 return std::make_pair(nullptr, false);
3782 }
3783 return std::make_pair(
3784 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
3785}
3786
3787static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
Alexey Bataev471171c2019-03-28 19:15:36 +00003788 ArrayRef<OMPClause *> Clauses) {
3789 assert(!S.CurContext->isDependentContext() &&
3790 "Expected non-dependent context.");
Alexey Bataev471171c2019-03-28 19:15:36 +00003791 auto AllocateRange =
3792 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
Alexey Bataeve106f252019-04-01 14:25:31 +00003793 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
3794 DeclToCopy;
3795 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
3796 return isOpenMPPrivate(C->getClauseKind());
3797 });
3798 for (OMPClause *Cl : PrivateRange) {
3799 MutableArrayRef<Expr *>::iterator I, It, Et;
3800 if (Cl->getClauseKind() == OMPC_private) {
3801 auto *PC = cast<OMPPrivateClause>(Cl);
3802 I = PC->private_copies().begin();
3803 It = PC->varlist_begin();
3804 Et = PC->varlist_end();
3805 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
3806 auto *PC = cast<OMPFirstprivateClause>(Cl);
3807 I = PC->private_copies().begin();
3808 It = PC->varlist_begin();
3809 Et = PC->varlist_end();
3810 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
3811 auto *PC = cast<OMPLastprivateClause>(Cl);
3812 I = PC->private_copies().begin();
3813 It = PC->varlist_begin();
3814 Et = PC->varlist_end();
3815 } else if (Cl->getClauseKind() == OMPC_linear) {
3816 auto *PC = cast<OMPLinearClause>(Cl);
3817 I = PC->privates().begin();
3818 It = PC->varlist_begin();
3819 Et = PC->varlist_end();
3820 } else if (Cl->getClauseKind() == OMPC_reduction) {
3821 auto *PC = cast<OMPReductionClause>(Cl);
3822 I = PC->privates().begin();
3823 It = PC->varlist_begin();
3824 Et = PC->varlist_end();
3825 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
3826 auto *PC = cast<OMPTaskReductionClause>(Cl);
3827 I = PC->privates().begin();
3828 It = PC->varlist_begin();
3829 Et = PC->varlist_end();
3830 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
3831 auto *PC = cast<OMPInReductionClause>(Cl);
3832 I = PC->privates().begin();
3833 It = PC->varlist_begin();
3834 Et = PC->varlist_end();
3835 } else {
3836 llvm_unreachable("Expected private clause.");
3837 }
3838 for (Expr *E : llvm::make_range(It, Et)) {
3839 if (!*I) {
3840 ++I;
3841 continue;
3842 }
3843 SourceLocation ELoc;
3844 SourceRange ERange;
3845 Expr *SimpleRefExpr = E;
3846 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
3847 /*AllowArraySection=*/true);
3848 DeclToCopy.try_emplace(Res.first,
3849 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
3850 ++I;
3851 }
3852 }
Alexey Bataev471171c2019-03-28 19:15:36 +00003853 for (OMPClause *C : AllocateRange) {
3854 auto *AC = cast<OMPAllocateClause>(C);
3855 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3856 getAllocatorKind(S, Stack, AC->getAllocator());
3857 // OpenMP, 2.11.4 allocate Clause, Restrictions.
3858 // For task, taskloop or target directives, allocation requests to memory
3859 // allocators with the trait access set to thread result in unspecified
3860 // behavior.
3861 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
3862 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
3863 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
3864 S.Diag(AC->getAllocator()->getExprLoc(),
3865 diag::warn_omp_allocate_thread_on_task_target_directive)
3866 << getOpenMPDirectiveName(Stack->getCurrentDirective());
Alexey Bataeve106f252019-04-01 14:25:31 +00003867 }
3868 for (Expr *E : AC->varlists()) {
3869 SourceLocation ELoc;
3870 SourceRange ERange;
3871 Expr *SimpleRefExpr = E;
3872 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
3873 ValueDecl *VD = Res.first;
3874 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
3875 if (!isOpenMPPrivate(Data.CKind)) {
3876 S.Diag(E->getExprLoc(),
3877 diag::err_omp_expected_private_copy_for_allocate);
3878 continue;
3879 }
3880 VarDecl *PrivateVD = DeclToCopy[VD];
3881 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
3882 AllocatorKind, AC->getAllocator()))
3883 continue;
3884 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
3885 E->getSourceRange());
Alexey Bataev471171c2019-03-28 19:15:36 +00003886 }
3887 }
Alexey Bataev471171c2019-03-28 19:15:36 +00003888}
3889
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003890StmtResult Sema::ActOnOpenMPExecutableDirective(
3891 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
3892 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3893 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003894 StmtResult Res = StmtError();
Jonas Hahnfeld64a9e3c2017-02-22 06:49:10 +00003895 // First check CancelRegion which is then used in checkNestingOfRegions.
3896 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3897 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003898 StartLoc))
Alexey Bataev549210e2014-06-24 04:39:47 +00003899 return StmtError();
Alexey Bataev758e55e2013-09-06 18:03:48 +00003900
Alexey Bataevd5af8e42013-10-01 05:32:34 +00003901 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
Alexey Bataeve3727102018-04-18 15:57:46 +00003902 VarsWithInheritedDSAType VarsWithInheritedDSA;
Alexey Bataevd5af8e42013-10-01 05:32:34 +00003903 bool ErrorFound = false;
Alexey Bataev6125da92014-07-21 11:26:11 +00003904 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00003905 if (AStmt && !CurContext->isDependentContext()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00003906 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3907
3908 // Check default data sharing attributes for referenced variables.
3909 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
Arpith Chacko Jacob1f46b702017-01-23 15:38:49 +00003910 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3911 Stmt *S = AStmt;
3912 while (--ThisCaptureLevel >= 0)
3913 S = cast<CapturedStmt>(S)->getCapturedStmt();
3914 DSAChecker.Visit(S);
Alexey Bataev68446b72014-07-18 07:47:19 +00003915 if (DSAChecker.isErrorFound())
3916 return StmtError();
3917 // Generate list of implicitly defined firstprivate variables.
3918 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
Alexey Bataev68446b72014-07-18 07:47:19 +00003919
Alexey Bataev88202be2017-07-27 13:20:36 +00003920 SmallVector<Expr *, 4> ImplicitFirstprivates(
3921 DSAChecker.getImplicitFirstprivate().begin(),
3922 DSAChecker.getImplicitFirstprivate().end());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003923 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3924 DSAChecker.getImplicitMap().end());
Alexey Bataev88202be2017-07-27 13:20:36 +00003925 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
Alexey Bataeve3727102018-04-18 15:57:46 +00003926 for (OMPClause *C : Clauses) {
Alexey Bataev88202be2017-07-27 13:20:36 +00003927 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003928 for (Expr *E : IRC->taskgroup_descriptors())
Alexey Bataev88202be2017-07-27 13:20:36 +00003929 if (E)
3930 ImplicitFirstprivates.emplace_back(E);
3931 }
3932 }
3933 if (!ImplicitFirstprivates.empty()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00003934 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
Alexey Bataev88202be2017-07-27 13:20:36 +00003935 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3936 SourceLocation())) {
Alexey Bataev68446b72014-07-18 07:47:19 +00003937 ClausesWithImplicit.push_back(Implicit);
3938 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
Alexey Bataev88202be2017-07-27 13:20:36 +00003939 ImplicitFirstprivates.size();
Alexey Bataeve3727102018-04-18 15:57:46 +00003940 } else {
Alexey Bataev68446b72014-07-18 07:47:19 +00003941 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003942 }
Alexey Bataev68446b72014-07-18 07:47:19 +00003943 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003944 if (!ImplicitMaps.empty()) {
Michael Kruse4304e9d2019-02-19 16:38:20 +00003945 CXXScopeSpec MapperIdScopeSpec;
3946 DeclarationNameInfo MapperId;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003947 if (OMPClause *Implicit = ActOnOpenMPMapClause(
Michael Kruse4304e9d2019-02-19 16:38:20 +00003948 llvm::None, llvm::None, MapperIdScopeSpec, MapperId,
3949 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(),
3950 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003951 ClausesWithImplicit.emplace_back(Implicit);
3952 ErrorFound |=
3953 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
Alexey Bataeve3727102018-04-18 15:57:46 +00003954 } else {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003955 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003956 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003957 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00003958 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00003959
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003960 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003961 switch (Kind) {
3962 case OMPD_parallel:
Alexey Bataeved09d242014-05-28 05:53:51 +00003963 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3964 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003965 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003966 break;
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003967 case OMPD_simd:
Alexey Bataev4acb8592014-07-07 13:01:15 +00003968 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3969 VarsWithInheritedDSA);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003970 break;
Alexey Bataevf29276e2014-06-18 04:14:57 +00003971 case OMPD_for:
Alexey Bataev4acb8592014-07-07 13:01:15 +00003972 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3973 VarsWithInheritedDSA);
Alexey Bataevf29276e2014-06-18 04:14:57 +00003974 break;
Alexander Musmanf82886e2014-09-18 05:12:34 +00003975 case OMPD_for_simd:
3976 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3977 EndLoc, VarsWithInheritedDSA);
3978 break;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003979 case OMPD_sections:
3980 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3981 EndLoc);
3982 break;
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003983 case OMPD_section:
3984 assert(ClausesWithImplicit.empty() &&
Alexander Musman80c22892014-07-17 08:54:58 +00003985 "No clauses are allowed for 'omp section' directive");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003986 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3987 break;
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003988 case OMPD_single:
3989 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3990 EndLoc);
3991 break;
Alexander Musman80c22892014-07-17 08:54:58 +00003992 case OMPD_master:
3993 assert(ClausesWithImplicit.empty() &&
3994 "No clauses are allowed for 'omp master' directive");
3995 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3996 break;
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003997 case OMPD_critical:
Alexey Bataev28c75412015-12-15 08:19:24 +00003998 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3999 StartLoc, EndLoc);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004000 break;
Alexey Bataev4acb8592014-07-07 13:01:15 +00004001 case OMPD_parallel_for:
4002 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4003 EndLoc, VarsWithInheritedDSA);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004004 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev4acb8592014-07-07 13:01:15 +00004005 break;
Alexander Musmane4e893b2014-09-23 09:33:00 +00004006 case OMPD_parallel_for_simd:
4007 Res = ActOnOpenMPParallelForSimdDirective(
4008 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004009 AllowedNameModifiers.push_back(OMPD_parallel);
Alexander Musmane4e893b2014-09-23 09:33:00 +00004010 break;
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004011 case OMPD_parallel_sections:
4012 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4013 StartLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004014 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004015 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004016 case OMPD_task:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004017 Res =
4018 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004019 AllowedNameModifiers.push_back(OMPD_task);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004020 break;
Alexey Bataev68446b72014-07-18 07:47:19 +00004021 case OMPD_taskyield:
4022 assert(ClausesWithImplicit.empty() &&
4023 "No clauses are allowed for 'omp taskyield' directive");
4024 assert(AStmt == nullptr &&
4025 "No associated statement allowed for 'omp taskyield' directive");
4026 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4027 break;
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004028 case OMPD_barrier:
4029 assert(ClausesWithImplicit.empty() &&
4030 "No clauses are allowed for 'omp barrier' directive");
4031 assert(AStmt == nullptr &&
4032 "No associated statement allowed for 'omp barrier' directive");
4033 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4034 break;
Alexey Bataev2df347a2014-07-18 10:17:07 +00004035 case OMPD_taskwait:
4036 assert(ClausesWithImplicit.empty() &&
4037 "No clauses are allowed for 'omp taskwait' directive");
4038 assert(AStmt == nullptr &&
4039 "No associated statement allowed for 'omp taskwait' directive");
4040 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4041 break;
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004042 case OMPD_taskgroup:
Alexey Bataev169d96a2017-07-18 20:17:46 +00004043 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4044 EndLoc);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004045 break;
Alexey Bataev6125da92014-07-21 11:26:11 +00004046 case OMPD_flush:
4047 assert(AStmt == nullptr &&
4048 "No associated statement allowed for 'omp flush' directive");
4049 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4050 break;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004051 case OMPD_ordered:
Alexey Bataev346265e2015-09-25 10:37:12 +00004052 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4053 EndLoc);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004054 break;
Alexey Bataev0162e452014-07-22 10:10:35 +00004055 case OMPD_atomic:
4056 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4057 EndLoc);
4058 break;
Alexey Bataev13314bf2014-10-09 04:18:56 +00004059 case OMPD_teams:
4060 Res =
4061 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4062 break;
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004063 case OMPD_target:
4064 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4065 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004066 AllowedNameModifiers.push_back(OMPD_target);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004067 break;
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004068 case OMPD_target_parallel:
4069 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4070 StartLoc, EndLoc);
4071 AllowedNameModifiers.push_back(OMPD_target);
4072 AllowedNameModifiers.push_back(OMPD_parallel);
4073 break;
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004074 case OMPD_target_parallel_for:
4075 Res = ActOnOpenMPTargetParallelForDirective(
4076 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4077 AllowedNameModifiers.push_back(OMPD_target);
4078 AllowedNameModifiers.push_back(OMPD_parallel);
4079 break;
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004080 case OMPD_cancellation_point:
4081 assert(ClausesWithImplicit.empty() &&
4082 "No clauses are allowed for 'omp cancellation point' directive");
4083 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
4084 "cancellation point' directive");
4085 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4086 break;
Alexey Bataev80909872015-07-02 11:25:17 +00004087 case OMPD_cancel:
Alexey Bataev80909872015-07-02 11:25:17 +00004088 assert(AStmt == nullptr &&
4089 "No associated statement allowed for 'omp cancel' directive");
Alexey Bataev87933c72015-09-18 08:07:34 +00004090 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4091 CancelRegion);
4092 AllowedNameModifiers.push_back(OMPD_cancel);
Alexey Bataev80909872015-07-02 11:25:17 +00004093 break;
Michael Wong65f367f2015-07-21 13:44:28 +00004094 case OMPD_target_data:
4095 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4096 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004097 AllowedNameModifiers.push_back(OMPD_target_data);
Michael Wong65f367f2015-07-21 13:44:28 +00004098 break;
Samuel Antaodf67fc42016-01-19 19:15:56 +00004099 case OMPD_target_enter_data:
4100 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00004101 EndLoc, AStmt);
Samuel Antaodf67fc42016-01-19 19:15:56 +00004102 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4103 break;
Samuel Antao72590762016-01-19 20:04:50 +00004104 case OMPD_target_exit_data:
4105 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00004106 EndLoc, AStmt);
Samuel Antao72590762016-01-19 20:04:50 +00004107 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4108 break;
Alexey Bataev49f6e782015-12-01 04:18:41 +00004109 case OMPD_taskloop:
4110 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4111 EndLoc, VarsWithInheritedDSA);
4112 AllowedNameModifiers.push_back(OMPD_taskloop);
4113 break;
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004114 case OMPD_taskloop_simd:
4115 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4116 EndLoc, VarsWithInheritedDSA);
4117 AllowedNameModifiers.push_back(OMPD_taskloop);
4118 break;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004119 case OMPD_distribute:
4120 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4121 EndLoc, VarsWithInheritedDSA);
4122 break;
Samuel Antao686c70c2016-05-26 17:30:50 +00004123 case OMPD_target_update:
Alexey Bataev7828b252017-11-21 17:08:48 +00004124 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4125 EndLoc, AStmt);
Samuel Antao686c70c2016-05-26 17:30:50 +00004126 AllowedNameModifiers.push_back(OMPD_target_update);
4127 break;
Carlo Bertolli9925f152016-06-27 14:55:37 +00004128 case OMPD_distribute_parallel_for:
4129 Res = ActOnOpenMPDistributeParallelForDirective(
4130 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4131 AllowedNameModifiers.push_back(OMPD_parallel);
4132 break;
Kelvin Li4a39add2016-07-05 05:00:15 +00004133 case OMPD_distribute_parallel_for_simd:
4134 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4135 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4136 AllowedNameModifiers.push_back(OMPD_parallel);
4137 break;
Kelvin Li787f3fc2016-07-06 04:45:38 +00004138 case OMPD_distribute_simd:
4139 Res = ActOnOpenMPDistributeSimdDirective(
4140 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4141 break;
Kelvin Lia579b912016-07-14 02:54:56 +00004142 case OMPD_target_parallel_for_simd:
4143 Res = ActOnOpenMPTargetParallelForSimdDirective(
4144 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4145 AllowedNameModifiers.push_back(OMPD_target);
4146 AllowedNameModifiers.push_back(OMPD_parallel);
4147 break;
Kelvin Li986330c2016-07-20 22:57:10 +00004148 case OMPD_target_simd:
4149 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4150 EndLoc, VarsWithInheritedDSA);
4151 AllowedNameModifiers.push_back(OMPD_target);
4152 break;
Kelvin Li02532872016-08-05 14:37:37 +00004153 case OMPD_teams_distribute:
David Majnemer9d168222016-08-05 17:44:54 +00004154 Res = ActOnOpenMPTeamsDistributeDirective(
4155 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
Kelvin Li02532872016-08-05 14:37:37 +00004156 break;
Kelvin Li4e325f72016-10-25 12:50:55 +00004157 case OMPD_teams_distribute_simd:
4158 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4159 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4160 break;
Kelvin Li579e41c2016-11-30 23:51:03 +00004161 case OMPD_teams_distribute_parallel_for_simd:
4162 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4163 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4164 AllowedNameModifiers.push_back(OMPD_parallel);
4165 break;
Kelvin Li7ade93f2016-12-09 03:24:30 +00004166 case OMPD_teams_distribute_parallel_for:
4167 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4168 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4169 AllowedNameModifiers.push_back(OMPD_parallel);
4170 break;
Kelvin Libf594a52016-12-17 05:48:59 +00004171 case OMPD_target_teams:
4172 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4173 EndLoc);
4174 AllowedNameModifiers.push_back(OMPD_target);
4175 break;
Kelvin Li83c451e2016-12-25 04:52:54 +00004176 case OMPD_target_teams_distribute:
4177 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4178 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4179 AllowedNameModifiers.push_back(OMPD_target);
4180 break;
Kelvin Li80e8f562016-12-29 22:16:30 +00004181 case OMPD_target_teams_distribute_parallel_for:
4182 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4183 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4184 AllowedNameModifiers.push_back(OMPD_target);
4185 AllowedNameModifiers.push_back(OMPD_parallel);
4186 break;
Kelvin Li1851df52017-01-03 05:23:48 +00004187 case OMPD_target_teams_distribute_parallel_for_simd:
4188 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4189 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4190 AllowedNameModifiers.push_back(OMPD_target);
4191 AllowedNameModifiers.push_back(OMPD_parallel);
4192 break;
Kelvin Lida681182017-01-10 18:08:18 +00004193 case OMPD_target_teams_distribute_simd:
4194 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4196 AllowedNameModifiers.push_back(OMPD_target);
4197 break;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00004198 case OMPD_declare_target:
4199 case OMPD_end_declare_target:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004200 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00004201 case OMPD_allocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00004202 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00004203 case OMPD_declare_mapper:
Alexey Bataev587e1de2016-03-30 10:43:55 +00004204 case OMPD_declare_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00004205 case OMPD_requires:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004206 llvm_unreachable("OpenMP Directive is not allowed");
4207 case OMPD_unknown:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004208 llvm_unreachable("Unknown OpenMP directive");
4209 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00004210
Roman Lebedevb5700602019-03-20 16:32:36 +00004211 ErrorFound = Res.isInvalid() || ErrorFound;
4212
Alexey Bataev412254a2019-05-09 18:44:53 +00004213 // Check variables in the clauses if default(none) was specified.
4214 if (DSAStack->getDefaultDSA() == DSA_none) {
4215 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
4216 for (OMPClause *C : Clauses) {
4217 switch (C->getClauseKind()) {
4218 case OMPC_num_threads:
4219 case OMPC_dist_schedule:
4220 // Do not analyse if no parent teams directive.
4221 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()))
4222 break;
4223 continue;
4224 case OMPC_if:
4225 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) &&
4226 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4227 break;
4228 continue;
4229 case OMPC_schedule:
4230 break;
4231 case OMPC_ordered:
4232 case OMPC_device:
4233 case OMPC_num_teams:
4234 case OMPC_thread_limit:
4235 case OMPC_priority:
4236 case OMPC_grainsize:
4237 case OMPC_num_tasks:
4238 case OMPC_hint:
4239 case OMPC_collapse:
4240 case OMPC_safelen:
4241 case OMPC_simdlen:
4242 case OMPC_final:
4243 case OMPC_default:
4244 case OMPC_proc_bind:
4245 case OMPC_private:
4246 case OMPC_firstprivate:
4247 case OMPC_lastprivate:
4248 case OMPC_shared:
4249 case OMPC_reduction:
4250 case OMPC_task_reduction:
4251 case OMPC_in_reduction:
4252 case OMPC_linear:
4253 case OMPC_aligned:
4254 case OMPC_copyin:
4255 case OMPC_copyprivate:
4256 case OMPC_nowait:
4257 case OMPC_untied:
4258 case OMPC_mergeable:
4259 case OMPC_allocate:
4260 case OMPC_read:
4261 case OMPC_write:
4262 case OMPC_update:
4263 case OMPC_capture:
4264 case OMPC_seq_cst:
4265 case OMPC_depend:
4266 case OMPC_threads:
4267 case OMPC_simd:
4268 case OMPC_map:
4269 case OMPC_nogroup:
4270 case OMPC_defaultmap:
4271 case OMPC_to:
4272 case OMPC_from:
4273 case OMPC_use_device_ptr:
4274 case OMPC_is_device_ptr:
4275 continue;
4276 case OMPC_allocator:
4277 case OMPC_flush:
4278 case OMPC_threadprivate:
4279 case OMPC_uniform:
4280 case OMPC_unknown:
4281 case OMPC_unified_address:
4282 case OMPC_unified_shared_memory:
4283 case OMPC_reverse_offload:
4284 case OMPC_dynamic_allocators:
4285 case OMPC_atomic_default_mem_order:
4286 llvm_unreachable("Unexpected clause");
4287 }
4288 for (Stmt *CC : C->children()) {
4289 if (CC)
4290 DSAChecker.Visit(CC);
4291 }
4292 }
4293 for (auto &P : DSAChecker.getVarsWithInheritedDSA())
4294 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
4295 }
Alexey Bataeve3727102018-04-18 15:57:46 +00004296 for (const auto &P : VarsWithInheritedDSA) {
Alexey Bataev4acb8592014-07-07 13:01:15 +00004297 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4298 << P.first << P.second->getSourceRange();
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00004299 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
Alexey Bataev4acb8592014-07-07 13:01:15 +00004300 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004301 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
4302
4303 if (!AllowedNameModifiers.empty())
4304 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4305 ErrorFound;
Alexey Bataev4acb8592014-07-07 13:01:15 +00004306
Alexey Bataeved09d242014-05-28 05:53:51 +00004307 if (ErrorFound)
4308 return StmtError();
Roman Lebedevb5700602019-03-20 16:32:36 +00004309
4310 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
4311 Res.getAs<OMPExecutableDirective>()
4312 ->getStructuredBlock()
4313 ->setIsOMPStructuredBlock(true);
4314 }
4315
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +00004316 if (!CurContext->isDependentContext() &&
4317 isOpenMPTargetExecutionDirective(Kind) &&
4318 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
4319 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
4320 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
4321 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
4322 // Register target to DSA Stack.
4323 DSAStack->addTargetDirLocation(StartLoc);
4324 }
4325
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004326 return Res;
4327}
4328
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004329Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
4330 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
Alexey Bataevd93d3762016-04-12 09:35:56 +00004331 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
Alexey Bataevecba70f2016-04-12 11:02:11 +00004332 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
4333 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004334 assert(Aligneds.size() == Alignments.size());
Alexey Bataevecba70f2016-04-12 11:02:11 +00004335 assert(Linears.size() == LinModifiers.size());
4336 assert(Linears.size() == Steps.size());
Alexey Bataev587e1de2016-03-30 10:43:55 +00004337 if (!DG || DG.get().isNull())
4338 return DeclGroupPtrTy();
4339
4340 if (!DG.get().isSingleDecl()) {
Alexey Bataev20dfd772016-04-04 10:12:15 +00004341 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
Alexey Bataev587e1de2016-03-30 10:43:55 +00004342 return DG;
4343 }
Alexey Bataeve3727102018-04-18 15:57:46 +00004344 Decl *ADecl = DG.get().getSingleDecl();
Alexey Bataev587e1de2016-03-30 10:43:55 +00004345 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4346 ADecl = FTD->getTemplatedDecl();
4347
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004348 auto *FD = dyn_cast<FunctionDecl>(ADecl);
4349 if (!FD) {
4350 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
Alexey Bataev587e1de2016-03-30 10:43:55 +00004351 return DeclGroupPtrTy();
4352 }
4353
Alexey Bataev2af33e32016-04-07 12:45:37 +00004354 // OpenMP [2.8.2, declare simd construct, Description]
4355 // The parameter of the simdlen clause must be a constant positive integer
4356 // expression.
4357 ExprResult SL;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004358 if (Simdlen)
Alexey Bataev2af33e32016-04-07 12:45:37 +00004359 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004360 // OpenMP [2.8.2, declare simd construct, Description]
4361 // The special this pointer can be used as if was one of the arguments to the
4362 // function in any of the linear, aligned, or uniform clauses.
4363 // The uniform clause declares one or more arguments to have an invariant
4364 // value for all concurrent invocations of the function in the execution of a
4365 // single SIMD loop.
Alexey Bataeve3727102018-04-18 15:57:46 +00004366 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
4367 const Expr *UniformedLinearThis = nullptr;
4368 for (const Expr *E : Uniforms) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004369 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004370 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4371 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004372 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4373 FD->getParamDecl(PVD->getFunctionScopeIndex())
Alexey Bataevecba70f2016-04-12 11:02:11 +00004374 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
Alexey Bataev43a919f2018-04-13 17:48:43 +00004375 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004376 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004377 }
4378 if (isa<CXXThisExpr>(E)) {
4379 UniformedLinearThis = E;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004380 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004381 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004382 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4383 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
Alexey Bataev2af33e32016-04-07 12:45:37 +00004384 }
Alexey Bataevd93d3762016-04-12 09:35:56 +00004385 // OpenMP [2.8.2, declare simd construct, Description]
4386 // The aligned clause declares that the object to which each list item points
4387 // is aligned to the number of bytes expressed in the optional parameter of
4388 // the aligned clause.
4389 // The special this pointer can be used as if was one of the arguments to the
4390 // function in any of the linear, aligned, or uniform clauses.
4391 // The type of list items appearing in the aligned clause must be array,
4392 // pointer, reference to array, or reference to pointer.
Alexey Bataeve3727102018-04-18 15:57:46 +00004393 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
4394 const Expr *AlignedThis = nullptr;
4395 for (const Expr *E : Aligneds) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004396 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004397 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4398 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4399 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevd93d3762016-04-12 09:35:56 +00004400 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4401 FD->getParamDecl(PVD->getFunctionScopeIndex())
4402 ->getCanonicalDecl() == CanonPVD) {
4403 // OpenMP [2.8.1, simd construct, Restrictions]
4404 // A list-item cannot appear in more than one aligned clause.
4405 if (AlignedArgs.count(CanonPVD) > 0) {
4406 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4407 << 1 << E->getSourceRange();
4408 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
4409 diag::note_omp_explicit_dsa)
4410 << getOpenMPClauseName(OMPC_aligned);
4411 continue;
4412 }
4413 AlignedArgs[CanonPVD] = E;
4414 QualType QTy = PVD->getType()
4415 .getNonReferenceType()
4416 .getUnqualifiedType()
4417 .getCanonicalType();
4418 const Type *Ty = QTy.getTypePtrOrNull();
4419 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
4420 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
4421 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
4422 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
4423 }
4424 continue;
4425 }
4426 }
4427 if (isa<CXXThisExpr>(E)) {
4428 if (AlignedThis) {
4429 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4430 << 2 << E->getSourceRange();
4431 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
4432 << getOpenMPClauseName(OMPC_aligned);
4433 }
4434 AlignedThis = E;
4435 continue;
4436 }
4437 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4438 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4439 }
4440 // The optional parameter of the aligned clause, alignment, must be a constant
4441 // positive integer expression. If no optional parameter is specified,
4442 // implementation-defined default alignments for SIMD instructions on the
4443 // target platforms are assumed.
Alexey Bataeve3727102018-04-18 15:57:46 +00004444 SmallVector<const Expr *, 4> NewAligns;
4445 for (Expr *E : Alignments) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004446 ExprResult Align;
4447 if (E)
4448 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
4449 NewAligns.push_back(Align.get());
4450 }
Alexey Bataevecba70f2016-04-12 11:02:11 +00004451 // OpenMP [2.8.2, declare simd construct, Description]
4452 // The linear clause declares one or more list items to be private to a SIMD
4453 // lane and to have a linear relationship with respect to the iteration space
4454 // of a loop.
4455 // The special this pointer can be used as if was one of the arguments to the
4456 // function in any of the linear, aligned, or uniform clauses.
4457 // When a linear-step expression is specified in a linear clause it must be
4458 // either a constant integer expression or an integer-typed parameter that is
4459 // specified in a uniform clause on the directive.
Alexey Bataeve3727102018-04-18 15:57:46 +00004460 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004461 const bool IsUniformedThis = UniformedLinearThis != nullptr;
4462 auto MI = LinModifiers.begin();
Alexey Bataeve3727102018-04-18 15:57:46 +00004463 for (const Expr *E : Linears) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004464 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
4465 ++MI;
4466 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004467 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4468 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4469 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevecba70f2016-04-12 11:02:11 +00004470 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4471 FD->getParamDecl(PVD->getFunctionScopeIndex())
4472 ->getCanonicalDecl() == CanonPVD) {
4473 // OpenMP [2.15.3.7, linear Clause, Restrictions]
4474 // A list-item cannot appear in more than one linear clause.
4475 if (LinearArgs.count(CanonPVD) > 0) {
4476 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4477 << getOpenMPClauseName(OMPC_linear)
4478 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
4479 Diag(LinearArgs[CanonPVD]->getExprLoc(),
4480 diag::note_omp_explicit_dsa)
4481 << getOpenMPClauseName(OMPC_linear);
4482 continue;
4483 }
4484 // Each argument can appear in at most one uniform or linear clause.
4485 if (UniformedArgs.count(CanonPVD) > 0) {
4486 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4487 << getOpenMPClauseName(OMPC_linear)
4488 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
4489 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
4490 diag::note_omp_explicit_dsa)
4491 << getOpenMPClauseName(OMPC_uniform);
4492 continue;
4493 }
4494 LinearArgs[CanonPVD] = E;
4495 if (E->isValueDependent() || E->isTypeDependent() ||
4496 E->isInstantiationDependent() ||
4497 E->containsUnexpandedParameterPack())
4498 continue;
4499 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
4500 PVD->getOriginalType());
4501 continue;
4502 }
4503 }
4504 if (isa<CXXThisExpr>(E)) {
4505 if (UniformedLinearThis) {
4506 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4507 << getOpenMPClauseName(OMPC_linear)
4508 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
4509 << E->getSourceRange();
4510 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
4511 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
4512 : OMPC_linear);
4513 continue;
4514 }
4515 UniformedLinearThis = E;
4516 if (E->isValueDependent() || E->isTypeDependent() ||
4517 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
4518 continue;
4519 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
4520 E->getType());
4521 continue;
4522 }
4523 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4524 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4525 }
4526 Expr *Step = nullptr;
4527 Expr *NewStep = nullptr;
4528 SmallVector<Expr *, 4> NewSteps;
Alexey Bataeve3727102018-04-18 15:57:46 +00004529 for (Expr *E : Steps) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004530 // Skip the same step expression, it was checked already.
4531 if (Step == E || !E) {
4532 NewSteps.push_back(E ? NewStep : nullptr);
4533 continue;
4534 }
4535 Step = E;
Alexey Bataeve3727102018-04-18 15:57:46 +00004536 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
4537 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4538 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevecba70f2016-04-12 11:02:11 +00004539 if (UniformedArgs.count(CanonPVD) == 0) {
4540 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
4541 << Step->getSourceRange();
4542 } else if (E->isValueDependent() || E->isTypeDependent() ||
4543 E->isInstantiationDependent() ||
4544 E->containsUnexpandedParameterPack() ||
Alexey Bataeve3727102018-04-18 15:57:46 +00004545 CanonPVD->getType()->hasIntegerRepresentation()) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004546 NewSteps.push_back(Step);
Alexey Bataeve3727102018-04-18 15:57:46 +00004547 } else {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004548 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
4549 << Step->getSourceRange();
4550 }
4551 continue;
4552 }
4553 NewStep = Step;
4554 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
4555 !Step->isInstantiationDependent() &&
4556 !Step->containsUnexpandedParameterPack()) {
4557 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
4558 .get();
4559 if (NewStep)
4560 NewStep = VerifyIntegerConstantExpression(NewStep).get();
4561 }
4562 NewSteps.push_back(NewStep);
4563 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004564 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
4565 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
Alexey Bataevd93d3762016-04-12 09:35:56 +00004566 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
Alexey Bataevecba70f2016-04-12 11:02:11 +00004567 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
4568 const_cast<Expr **>(Linears.data()), Linears.size(),
4569 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
4570 NewSteps.data(), NewSteps.size(), SR);
Alexey Bataev587e1de2016-03-30 10:43:55 +00004571 ADecl->addAttr(NewAttr);
4572 return ConvertDeclToDeclGroup(ADecl);
4573}
4574
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004575StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
4576 Stmt *AStmt,
4577 SourceLocation StartLoc,
4578 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004579 if (!AStmt)
4580 return StmtError();
4581
Alexey Bataeve3727102018-04-18 15:57:46 +00004582 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev9959db52014-05-06 10:08:46 +00004583 // 1.2.2 OpenMP Language Terminology
4584 // Structured block - An executable statement with a single entry at the
4585 // top and a single exit at the bottom.
4586 // The point of exit cannot be a branch out of the structured block.
4587 // longjmp() and throw() must not violate the entry/exit criteria.
4588 CS->getCapturedDecl()->setNothrow();
4589
Reid Kleckner87a31802018-03-12 21:43:02 +00004590 setFunctionHasBranchProtectedScope();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004591
Alexey Bataev25e5b442015-09-15 12:52:43 +00004592 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
4593 DSAStack->isCancelRegion());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004594}
4595
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004596namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004597/// Helper class for checking canonical form of the OpenMP loops and
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004598/// extracting iteration space of each loop in the loop nest, that will be used
4599/// for IR generation.
4600class OpenMPIterationSpaceChecker {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004601 /// Reference to Sema.
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004602 Sema &SemaRef;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004603 /// Data-sharing stack.
4604 DSAStackTy &Stack;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004605 /// A location for diagnostics (when there is no some better location).
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004606 SourceLocation DefaultLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004607 /// A location for diagnostics (when increment is not compatible).
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004608 SourceLocation ConditionLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004609 /// A source location for referring to loop init later.
Alexander Musmana5f070a2014-10-01 06:03:56 +00004610 SourceRange InitSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004611 /// A source location for referring to condition later.
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004612 SourceRange ConditionSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004613 /// A source location for referring to increment later.
Alexander Musmana5f070a2014-10-01 06:03:56 +00004614 SourceRange IncrementSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004615 /// Loop variable.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004616 ValueDecl *LCDecl = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004617 /// Reference to loop variable.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004618 Expr *LCRef = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004619 /// Lower bound (initializer for the var).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004620 Expr *LB = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004621 /// Upper bound.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004622 Expr *UB = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004623 /// Loop step (increment).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004624 Expr *Step = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004625 /// This flag is true when condition is one of:
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004626 /// Var < UB
4627 /// Var <= UB
4628 /// UB > Var
4629 /// UB >= Var
Kelvin Liefbe4af2018-11-21 19:10:48 +00004630 /// This will have no value when the condition is !=
4631 llvm::Optional<bool> TestIsLessOp;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004632 /// This flag is true when condition is strict ( < or > ).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004633 bool TestIsStrictOp = false;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004634 /// This flag is true when step is subtracted on each iteration.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004635 bool SubtractStep = false;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004636 /// The outer loop counter this loop depends on (if any).
4637 const ValueDecl *DepDecl = nullptr;
4638 /// Contains number of loop (starts from 1) on which loop counter init
4639 /// expression of this loop depends on.
4640 Optional<unsigned> InitDependOnLC;
4641 /// Contains number of loop (starts from 1) on which loop counter condition
4642 /// expression of this loop depends on.
4643 Optional<unsigned> CondDependOnLC;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004644 /// Checks if the provide statement depends on the loop counter.
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004645 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004646
4647public:
Alexey Bataev622af1d2019-04-24 19:58:30 +00004648 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
4649 SourceLocation DefaultLoc)
4650 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
4651 ConditionLoc(DefaultLoc) {}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004652 /// Check init-expr for canonical loop form and save loop counter
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004653 /// variable - #Var and its initialization value - #LB.
Alexey Bataeve3727102018-04-18 15:57:46 +00004654 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004655 /// Check test-expr for canonical form, save upper-bound (#UB), flags
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004656 /// for less/greater and for strict/non-strict comparison.
Alexey Bataeve3727102018-04-18 15:57:46 +00004657 bool checkAndSetCond(Expr *S);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004658 /// Check incr-expr for canonical loop form and return true if it
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004659 /// does not conform, otherwise save loop step (#Step).
Alexey Bataeve3727102018-04-18 15:57:46 +00004660 bool checkAndSetInc(Expr *S);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004661 /// Return the loop counter variable.
Alexey Bataeve3727102018-04-18 15:57:46 +00004662 ValueDecl *getLoopDecl() const { return LCDecl; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004663 /// Return the reference expression to loop counter variable.
Alexey Bataeve3727102018-04-18 15:57:46 +00004664 Expr *getLoopDeclRefExpr() const { return LCRef; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004665 /// Source range of the loop init.
Alexey Bataeve3727102018-04-18 15:57:46 +00004666 SourceRange getInitSrcRange() const { return InitSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004667 /// Source range of the loop condition.
Alexey Bataeve3727102018-04-18 15:57:46 +00004668 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004669 /// Source range of the loop increment.
Alexey Bataeve3727102018-04-18 15:57:46 +00004670 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004671 /// True if the step should be subtracted.
Alexey Bataeve3727102018-04-18 15:57:46 +00004672 bool shouldSubtractStep() const { return SubtractStep; }
Alexey Bataev316ccf62019-01-29 18:51:58 +00004673 /// True, if the compare operator is strict (<, > or !=).
4674 bool isStrictTestOp() const { return TestIsStrictOp; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004675 /// Build the expression to calculate the number of iterations.
Alexey Bataeve3727102018-04-18 15:57:46 +00004676 Expr *buildNumIterations(
4677 Scope *S, const bool LimitedType,
4678 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004679 /// Build the precondition expression for the loops.
Alexey Bataeve3727102018-04-18 15:57:46 +00004680 Expr *
4681 buildPreCond(Scope *S, Expr *Cond,
4682 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004683 /// Build reference expression to the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00004684 DeclRefExpr *
4685 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4686 DSAStackTy &DSA) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004687 /// Build reference expression to the private counter be used for
Alexey Bataeva8899172015-08-06 12:30:57 +00004688 /// codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00004689 Expr *buildPrivateCounterVar() const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004690 /// Build initialization of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00004691 Expr *buildCounterInit() const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004692 /// Build step of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00004693 Expr *buildCounterStep() const;
Alexey Bataevf138fda2018-08-13 19:04:24 +00004694 /// Build loop data with counter value for depend clauses in ordered
4695 /// directives.
4696 Expr *
4697 buildOrderedLoopData(Scope *S, Expr *Counter,
4698 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4699 SourceLocation Loc, Expr *Inc = nullptr,
4700 OverloadedOperatorKind OOK = OO_Amp);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004701 /// Return true if any expression is dependent.
Alexey Bataeve3727102018-04-18 15:57:46 +00004702 bool dependent() const;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004703
4704private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004705 /// Check the right-hand side of an assignment in the increment
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004706 /// expression.
Alexey Bataeve3727102018-04-18 15:57:46 +00004707 bool checkAndSetIncRHS(Expr *RHS);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004708 /// Helper to set loop counter variable and its initializer.
Alexey Bataev622af1d2019-04-24 19:58:30 +00004709 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
4710 bool EmitDiags);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004711 /// Helper to set upper bound.
Kelvin Liefbe4af2018-11-21 19:10:48 +00004712 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
4713 SourceRange SR, SourceLocation SL);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004714 /// Helper to set loop increment.
Alexey Bataeve3727102018-04-18 15:57:46 +00004715 bool setStep(Expr *NewStep, bool Subtract);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004716};
4717
Alexey Bataeve3727102018-04-18 15:57:46 +00004718bool OpenMPIterationSpaceChecker::dependent() const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004719 if (!LCDecl) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004720 assert(!LB && !UB && !Step);
4721 return false;
4722 }
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004723 return LCDecl->getType()->isDependentType() ||
4724 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4725 (Step && Step->isValueDependent());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004726}
4727
Alexey Bataeve3727102018-04-18 15:57:46 +00004728bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004729 Expr *NewLCRefExpr,
Alexey Bataev622af1d2019-04-24 19:58:30 +00004730 Expr *NewLB, bool EmitDiags) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004731 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004732 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
Alexey Bataevcaf09b02014-07-25 06:27:47 +00004733 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004734 if (!NewLCDecl || !NewLB)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004735 return true;
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004736 LCDecl = getCanonicalDecl(NewLCDecl);
4737 LCRef = NewLCRefExpr;
Alexey Bataev3bed68c2015-07-15 12:14:07 +00004738 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4739 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
Alexey Bataev0d08a7f2015-07-16 04:19:43 +00004740 if ((Ctor->isCopyOrMoveConstructor() ||
4741 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4742 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
Alexey Bataev3bed68c2015-07-15 12:14:07 +00004743 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004744 LB = NewLB;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004745 if (EmitDiags)
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004746 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004747 return false;
4748}
4749
Alexey Bataev316ccf62019-01-29 18:51:58 +00004750bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
4751 llvm::Optional<bool> LessOp,
Kelvin Liefbe4af2018-11-21 19:10:48 +00004752 bool StrictOp, SourceRange SR,
4753 SourceLocation SL) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004754 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004755 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
4756 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004757 if (!NewUB)
4758 return true;
4759 UB = NewUB;
Kelvin Liefbe4af2018-11-21 19:10:48 +00004760 if (LessOp)
4761 TestIsLessOp = LessOp;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004762 TestIsStrictOp = StrictOp;
4763 ConditionSrcRange = SR;
4764 ConditionLoc = SL;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004765 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004766 return false;
4767}
4768
Alexey Bataeve3727102018-04-18 15:57:46 +00004769bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004770 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004771 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004772 if (!NewStep)
4773 return true;
4774 if (!NewStep->isValueDependent()) {
4775 // Check that the step is integer expression.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004776 SourceLocation StepLoc = NewStep->getBeginLoc();
Alexey Bataev5372fb82017-08-31 23:06:52 +00004777 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
4778 StepLoc, getExprAsWritten(NewStep));
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004779 if (Val.isInvalid())
4780 return true;
4781 NewStep = Val.get();
4782
4783 // OpenMP [2.6, Canonical Loop Form, Restrictions]
4784 // If test-expr is of form var relational-op b and relational-op is < or
4785 // <= then incr-expr must cause var to increase on each iteration of the
4786 // loop. If test-expr is of form var relational-op b and relational-op is
4787 // > or >= then incr-expr must cause var to decrease on each iteration of
4788 // the loop.
4789 // If test-expr is of form b relational-op var and relational-op is < or
4790 // <= then incr-expr must cause var to decrease on each iteration of the
4791 // loop. If test-expr is of form b relational-op var and relational-op is
4792 // > or >= then incr-expr must cause var to increase on each iteration of
4793 // the loop.
4794 llvm::APSInt Result;
4795 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
4796 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
4797 bool IsConstNeg =
4798 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
Alexander Musmana5f070a2014-10-01 06:03:56 +00004799 bool IsConstPos =
4800 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004801 bool IsConstZero = IsConstant && !Result.getBoolValue();
Kelvin Liefbe4af2018-11-21 19:10:48 +00004802
4803 // != with increment is treated as <; != with decrement is treated as >
4804 if (!TestIsLessOp.hasValue())
4805 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004806 if (UB && (IsConstZero ||
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00004807 (TestIsLessOp.getValue() ?
Kelvin Liefbe4af2018-11-21 19:10:48 +00004808 (IsConstNeg || (IsUnsigned && Subtract)) :
4809 (IsConstPos || (IsUnsigned && !Subtract))))) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004810 SemaRef.Diag(NewStep->getExprLoc(),
4811 diag::err_omp_loop_incr_not_compatible)
Kelvin Liefbe4af2018-11-21 19:10:48 +00004812 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004813 SemaRef.Diag(ConditionLoc,
4814 diag::note_omp_loop_cond_requres_compatible_incr)
Kelvin Liefbe4af2018-11-21 19:10:48 +00004815 << TestIsLessOp.getValue() << ConditionSrcRange;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004816 return true;
4817 }
Kelvin Liefbe4af2018-11-21 19:10:48 +00004818 if (TestIsLessOp.getValue() == Subtract) {
David Majnemer9d168222016-08-05 17:44:54 +00004819 NewStep =
4820 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
4821 .get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00004822 Subtract = !Subtract;
4823 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004824 }
4825
4826 Step = NewStep;
4827 SubtractStep = Subtract;
4828 return false;
4829}
4830
Alexey Bataev622af1d2019-04-24 19:58:30 +00004831namespace {
4832/// Checker for the non-rectangular loops. Checks if the initializer or
4833/// condition expression references loop counter variable.
4834class LoopCounterRefChecker final
4835 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
4836 Sema &SemaRef;
4837 DSAStackTy &Stack;
4838 const ValueDecl *CurLCDecl = nullptr;
Alexey Bataev2f9ef332019-04-25 16:21:13 +00004839 const ValueDecl *DepDecl = nullptr;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004840 const ValueDecl *PrevDepDecl = nullptr;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004841 bool IsInitializer = true;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004842 unsigned BaseLoopId = 0;
4843 bool checkDecl(const Expr *E, const ValueDecl *VD) {
4844 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
4845 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
4846 << (IsInitializer ? 0 : 1);
4847 return false;
4848 }
4849 const auto &&Data = Stack.isLoopControlVariable(VD);
4850 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
4851 // The type of the loop iterator on which we depend may not have a random
4852 // access iterator type.
4853 if (Data.first && VD->getType()->isRecordType()) {
4854 SmallString<128> Name;
4855 llvm::raw_svector_ostream OS(Name);
4856 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4857 /*Qualified=*/true);
4858 SemaRef.Diag(E->getExprLoc(),
4859 diag::err_omp_wrong_dependency_iterator_type)
4860 << OS.str();
4861 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
4862 return false;
4863 }
4864 if (Data.first &&
4865 (DepDecl || (PrevDepDecl &&
4866 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
4867 if (!DepDecl && PrevDepDecl)
4868 DepDecl = PrevDepDecl;
4869 SmallString<128> Name;
4870 llvm::raw_svector_ostream OS(Name);
4871 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4872 /*Qualified=*/true);
4873 SemaRef.Diag(E->getExprLoc(),
4874 diag::err_omp_invariant_or_linear_dependency)
4875 << OS.str();
4876 return false;
4877 }
4878 if (Data.first) {
4879 DepDecl = VD;
4880 BaseLoopId = Data.first;
4881 }
4882 return Data.first;
4883 }
Alexey Bataev622af1d2019-04-24 19:58:30 +00004884
4885public:
4886 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4887 const ValueDecl *VD = E->getDecl();
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004888 if (isa<VarDecl>(VD))
4889 return checkDecl(E, VD);
Alexey Bataev622af1d2019-04-24 19:58:30 +00004890 return false;
4891 }
4892 bool VisitMemberExpr(const MemberExpr *E) {
4893 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
4894 const ValueDecl *VD = E->getMemberDecl();
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004895 return checkDecl(E, VD);
Alexey Bataev622af1d2019-04-24 19:58:30 +00004896 }
4897 return false;
4898 }
4899 bool VisitStmt(const Stmt *S) {
Alexey Bataev2f9ef332019-04-25 16:21:13 +00004900 bool Res = true;
4901 for (const Stmt *Child : S->children())
4902 Res = Child && Visit(Child) && Res;
4903 return Res;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004904 }
4905 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004906 const ValueDecl *CurLCDecl, bool IsInitializer,
4907 const ValueDecl *PrevDepDecl = nullptr)
Alexey Bataev622af1d2019-04-24 19:58:30 +00004908 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004909 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
4910 unsigned getBaseLoopId() const {
4911 assert(CurLCDecl && "Expected loop dependency.");
4912 return BaseLoopId;
4913 }
4914 const ValueDecl *getDepDecl() const {
4915 assert(CurLCDecl && "Expected loop dependency.");
4916 return DepDecl;
4917 }
Alexey Bataev622af1d2019-04-24 19:58:30 +00004918};
4919} // namespace
4920
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004921Optional<unsigned>
4922OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
4923 bool IsInitializer) {
Alexey Bataev622af1d2019-04-24 19:58:30 +00004924 // Check for the non-rectangular loops.
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00004925 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
4926 DepDecl);
4927 if (LoopStmtChecker.Visit(S)) {
4928 DepDecl = LoopStmtChecker.getDepDecl();
4929 return LoopStmtChecker.getBaseLoopId();
4930 }
4931 return llvm::None;
Alexey Bataev622af1d2019-04-24 19:58:30 +00004932}
4933
Alexey Bataeve3727102018-04-18 15:57:46 +00004934bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004935 // Check init-expr for canonical loop form and save loop counter
4936 // variable - #Var and its initialization value - #LB.
4937 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
4938 // var = lb
4939 // integer-type var = lb
4940 // random-access-iterator-type var = lb
4941 // pointer-type var = lb
4942 //
4943 if (!S) {
Alexey Bataev9c821032015-04-30 04:23:23 +00004944 if (EmitDiags) {
4945 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4946 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004947 return true;
4948 }
Tim Shen4a05bb82016-06-21 20:29:17 +00004949 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4950 if (!ExprTemp->cleanupsHaveSideEffects())
4951 S = ExprTemp->getSubExpr();
4952
Alexander Musmana5f070a2014-10-01 06:03:56 +00004953 InitSrcRange = S->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004954 if (Expr *E = dyn_cast<Expr>(S))
4955 S = E->IgnoreParens();
David Majnemer9d168222016-08-05 17:44:54 +00004956 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004957 if (BO->getOpcode() == BO_Assign) {
Alexey Bataeve3727102018-04-18 15:57:46 +00004958 Expr *LHS = BO->getLHS()->IgnoreParens();
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004959 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4960 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4961 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev622af1d2019-04-24 19:58:30 +00004962 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
4963 EmitDiags);
4964 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004965 }
4966 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4967 if (ME->isArrow() &&
4968 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
Alexey Bataev622af1d2019-04-24 19:58:30 +00004969 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
4970 EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004971 }
4972 }
David Majnemer9d168222016-08-05 17:44:54 +00004973 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004974 if (DS->isSingleDecl()) {
David Majnemer9d168222016-08-05 17:44:54 +00004975 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
Alexey Bataeva8899172015-08-06 12:30:57 +00004976 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004977 // Accept non-canonical init form here but emit ext. warning.
Alexey Bataev9c821032015-04-30 04:23:23 +00004978 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004979 SemaRef.Diag(S->getBeginLoc(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004980 diag::ext_omp_loop_not_canonical_init)
4981 << S->getSourceRange();
Alexey Bataevf138fda2018-08-13 19:04:24 +00004982 return setLCDeclAndLB(
4983 Var,
4984 buildDeclRefExpr(SemaRef, Var,
4985 Var->getType().getNonReferenceType(),
4986 DS->getBeginLoc()),
Alexey Bataev622af1d2019-04-24 19:58:30 +00004987 Var->getInit(), EmitDiags);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00004988 }
4989 }
4990 }
David Majnemer9d168222016-08-05 17:44:54 +00004991 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004992 if (CE->getOperator() == OO_Equal) {
Alexey Bataeve3727102018-04-18 15:57:46 +00004993 Expr *LHS = CE->getArg(0);
David Majnemer9d168222016-08-05 17:44:54 +00004994 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00004995 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4996 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev622af1d2019-04-24 19:58:30 +00004997 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
4998 EmitDiags);
4999 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005000 }
5001 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
5002 if (ME->isArrow() &&
5003 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
Alexey Bataev622af1d2019-04-24 19:58:30 +00005004 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5005 EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005006 }
5007 }
5008 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005009
Alexey Bataeve3727102018-04-18 15:57:46 +00005010 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005011 return false;
Alexey Bataev9c821032015-04-30 04:23:23 +00005012 if (EmitDiags) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005013 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
Alexey Bataev9c821032015-04-30 04:23:23 +00005014 << S->getSourceRange();
5015 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005016 return true;
5017}
5018
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005019/// Ignore parenthesizes, implicit casts, copy constructor and return the
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005020/// variable (which may be the loop variable) if possible.
Alexey Bataeve3727102018-04-18 15:57:46 +00005021static const ValueDecl *getInitLCDecl(const Expr *E) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005022 if (!E)
Craig Topper4b566922014-06-09 02:04:02 +00005023 return nullptr;
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005024 E = getExprAsWritten(E);
Alexey Bataeve3727102018-04-18 15:57:46 +00005025 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005026 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
Alexey Bataev0d08a7f2015-07-16 04:19:43 +00005027 if ((Ctor->isCopyOrMoveConstructor() ||
5028 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5029 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005030 E = CE->getArg(0)->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00005031 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
5032 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005033 return getCanonicalDecl(VD);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005034 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005035 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005036 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5037 return getCanonicalDecl(ME->getMemberDecl());
5038 return nullptr;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005039}
5040
Alexey Bataeve3727102018-04-18 15:57:46 +00005041bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005042 // Check test-expr for canonical form, save upper-bound UB, flags for
5043 // less/greater and for strict/non-strict comparison.
5044 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
5045 // var relational-op b
5046 // b relational-op var
5047 //
5048 if (!S) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005049 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005050 return true;
5051 }
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005052 S = getExprAsWritten(S);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005053 SourceLocation CondLoc = S->getBeginLoc();
David Majnemer9d168222016-08-05 17:44:54 +00005054 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005055 if (BO->isRelationalOp()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005056 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5057 return setUB(BO->getRHS(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005058 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
5059 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5060 BO->getSourceRange(), BO->getOperatorLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +00005061 if (getInitLCDecl(BO->getRHS()) == LCDecl)
5062 return setUB(BO->getLHS(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005063 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
5064 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5065 BO->getSourceRange(), BO->getOperatorLoc());
Kelvin Liefbe4af2018-11-21 19:10:48 +00005066 } else if (BO->getOpcode() == BO_NE)
5067 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
5068 BO->getRHS() : BO->getLHS(),
5069 /*LessOp=*/llvm::None,
5070 /*StrictOp=*/true,
5071 BO->getSourceRange(), BO->getOperatorLoc());
David Majnemer9d168222016-08-05 17:44:54 +00005072 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005073 if (CE->getNumArgs() == 2) {
5074 auto Op = CE->getOperator();
5075 switch (Op) {
5076 case OO_Greater:
5077 case OO_GreaterEqual:
5078 case OO_Less:
5079 case OO_LessEqual:
Alexey Bataeve3727102018-04-18 15:57:46 +00005080 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5081 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005082 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5083 CE->getOperatorLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +00005084 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
5085 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005086 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5087 CE->getOperatorLoc());
5088 break;
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00005089 case OO_ExclaimEqual:
Kelvin Liefbe4af2018-11-21 19:10:48 +00005090 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
5091 CE->getArg(1) : CE->getArg(0),
5092 /*LessOp=*/llvm::None,
5093 /*StrictOp=*/true,
5094 CE->getSourceRange(),
5095 CE->getOperatorLoc());
5096 break;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005097 default:
5098 break;
5099 }
5100 }
5101 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005102 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005103 return false;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005104 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005105 << S->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005106 return true;
5107}
5108
Alexey Bataeve3727102018-04-18 15:57:46 +00005109bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005110 // RHS of canonical loop form increment can be:
5111 // var + incr
5112 // incr + var
5113 // var - incr
5114 //
5115 RHS = RHS->IgnoreParenImpCasts();
David Majnemer9d168222016-08-05 17:44:54 +00005116 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005117 if (BO->isAdditiveOp()) {
5118 bool IsAdd = BO->getOpcode() == BO_Add;
Alexey Bataeve3727102018-04-18 15:57:46 +00005119 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5120 return setStep(BO->getRHS(), !IsAdd);
5121 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
5122 return setStep(BO->getLHS(), /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005123 }
David Majnemer9d168222016-08-05 17:44:54 +00005124 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005125 bool IsAdd = CE->getOperator() == OO_Plus;
5126 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005127 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5128 return setStep(CE->getArg(1), !IsAdd);
5129 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
5130 return setStep(CE->getArg(0), /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005131 }
5132 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005133 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005134 return false;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005135 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005136 << RHS->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005137 return true;
5138}
5139
Alexey Bataeve3727102018-04-18 15:57:46 +00005140bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005141 // Check incr-expr for canonical loop form and return true if it
5142 // does not conform.
5143 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
5144 // ++var
5145 // var++
5146 // --var
5147 // var--
5148 // var += incr
5149 // var -= incr
5150 // var = var + incr
5151 // var = incr + var
5152 // var = var - incr
5153 //
5154 if (!S) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005155 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005156 return true;
5157 }
Tim Shen4a05bb82016-06-21 20:29:17 +00005158 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5159 if (!ExprTemp->cleanupsHaveSideEffects())
5160 S = ExprTemp->getSubExpr();
5161
Alexander Musmana5f070a2014-10-01 06:03:56 +00005162 IncrementSrcRange = S->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005163 S = S->IgnoreParens();
David Majnemer9d168222016-08-05 17:44:54 +00005164 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005165 if (UO->isIncrementDecrementOp() &&
Alexey Bataeve3727102018-04-18 15:57:46 +00005166 getInitLCDecl(UO->getSubExpr()) == LCDecl)
5167 return setStep(SemaRef
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005168 .ActOnIntegerConstant(UO->getBeginLoc(),
David Majnemer9d168222016-08-05 17:44:54 +00005169 (UO->isDecrementOp() ? -1 : 1))
5170 .get(),
Alexey Bataeve3727102018-04-18 15:57:46 +00005171 /*Subtract=*/false);
David Majnemer9d168222016-08-05 17:44:54 +00005172 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005173 switch (BO->getOpcode()) {
5174 case BO_AddAssign:
5175 case BO_SubAssign:
Alexey Bataeve3727102018-04-18 15:57:46 +00005176 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5177 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005178 break;
5179 case BO_Assign:
Alexey Bataeve3727102018-04-18 15:57:46 +00005180 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5181 return checkAndSetIncRHS(BO->getRHS());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005182 break;
5183 default:
5184 break;
5185 }
David Majnemer9d168222016-08-05 17:44:54 +00005186 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005187 switch (CE->getOperator()) {
5188 case OO_PlusPlus:
5189 case OO_MinusMinus:
Alexey Bataeve3727102018-04-18 15:57:46 +00005190 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5191 return setStep(SemaRef
David Majnemer9d168222016-08-05 17:44:54 +00005192 .ActOnIntegerConstant(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005193 CE->getBeginLoc(),
David Majnemer9d168222016-08-05 17:44:54 +00005194 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
5195 .get(),
Alexey Bataeve3727102018-04-18 15:57:46 +00005196 /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005197 break;
5198 case OO_PlusEqual:
5199 case OO_MinusEqual:
Alexey Bataeve3727102018-04-18 15:57:46 +00005200 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5201 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005202 break;
5203 case OO_Equal:
Alexey Bataeve3727102018-04-18 15:57:46 +00005204 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5205 return checkAndSetIncRHS(CE->getArg(1));
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005206 break;
5207 default:
5208 break;
5209 }
5210 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005211 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005212 return false;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005213 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005214 << S->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005215 return true;
5216}
Alexander Musmana5f070a2014-10-01 06:03:56 +00005217
Alexey Bataev5a3af132016-03-29 08:58:54 +00005218static ExprResult
5219tryBuildCapture(Sema &SemaRef, Expr *Capture,
Alexey Bataeve3727102018-04-18 15:57:46 +00005220 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataevbe8b8b52016-07-07 11:04:06 +00005221 if (SemaRef.CurContext->isDependentContext())
5222 return ExprResult(Capture);
Alexey Bataev5a3af132016-03-29 08:58:54 +00005223 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
5224 return SemaRef.PerformImplicitConversion(
5225 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
5226 /*AllowExplicit=*/true);
5227 auto I = Captures.find(Capture);
5228 if (I != Captures.end())
5229 return buildCapture(SemaRef, Capture, I->second);
5230 DeclRefExpr *Ref = nullptr;
5231 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
5232 Captures[Capture] = Ref;
5233 return Res;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005234}
5235
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005236/// Build the expression to calculate the number of iterations.
Alexey Bataeve3727102018-04-18 15:57:46 +00005237Expr *OpenMPIterationSpaceChecker::buildNumIterations(
Alexey Bataev5a3af132016-03-29 08:58:54 +00005238 Scope *S, const bool LimitedType,
Alexey Bataeve3727102018-04-18 15:57:46 +00005239 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005240 ExprResult Diff;
Alexey Bataeve3727102018-04-18 15:57:46 +00005241 QualType VarType = LCDecl->getType().getNonReferenceType();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005242 if (VarType->isIntegerType() || VarType->isPointerType() ||
Alexander Musmana5f070a2014-10-01 06:03:56 +00005243 SemaRef.getLangOpts().CPlusPlus) {
5244 // Upper - Lower
Kelvin Liefbe4af2018-11-21 19:10:48 +00005245 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
5246 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
Alexey Bataev5a3af132016-03-29 08:58:54 +00005247 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
5248 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005249 if (!Upper || !Lower)
5250 return nullptr;
Alexander Musmana5f070a2014-10-01 06:03:56 +00005251
5252 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
5253
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005254 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005255 // BuildBinOp already emitted error, this one is to point user to upper
5256 // and lower bound, and to tell what is passed to 'operator-'.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005257 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
Alexander Musmana5f070a2014-10-01 06:03:56 +00005258 << Upper->getSourceRange() << Lower->getSourceRange();
5259 return nullptr;
5260 }
5261 }
5262
5263 if (!Diff.isUsable())
5264 return nullptr;
5265
5266 // Upper - Lower [- 1]
5267 if (TestIsStrictOp)
5268 Diff = SemaRef.BuildBinOp(
5269 S, DefaultLoc, BO_Sub, Diff.get(),
5270 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5271 if (!Diff.isUsable())
5272 return nullptr;
5273
5274 // Upper - Lower [- 1] + Step
Alexey Bataeve3727102018-04-18 15:57:46 +00005275 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00005276 if (!NewStep.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005277 return nullptr;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005278 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00005279 if (!Diff.isUsable())
5280 return nullptr;
5281
5282 // Parentheses (for dumping/debugging purposes only).
5283 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
5284 if (!Diff.isUsable())
5285 return nullptr;
5286
5287 // (Upper - Lower [- 1] + Step) / Step
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005288 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00005289 if (!Diff.isUsable())
5290 return nullptr;
5291
Alexander Musman174b3ca2014-10-06 11:16:29 +00005292 // OpenMP runtime requires 32-bit or 64-bit loop variables.
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005293 QualType Type = Diff.get()->getType();
Alexey Bataeve3727102018-04-18 15:57:46 +00005294 ASTContext &C = SemaRef.Context;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005295 bool UseVarType = VarType->hasIntegerRepresentation() &&
5296 C.getTypeSize(Type) > C.getTypeSize(VarType);
5297 if (!Type->isIntegerType() || UseVarType) {
5298 unsigned NewSize =
5299 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
5300 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
5301 : Type->hasSignedIntegerRepresentation();
5302 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
Alexey Bataev11481f52016-02-17 10:29:05 +00005303 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
5304 Diff = SemaRef.PerformImplicitConversion(
5305 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
5306 if (!Diff.isUsable())
5307 return nullptr;
5308 }
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005309 }
Alexander Musman174b3ca2014-10-06 11:16:29 +00005310 if (LimitedType) {
Alexander Musman174b3ca2014-10-06 11:16:29 +00005311 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
5312 if (NewSize != C.getTypeSize(Type)) {
5313 if (NewSize < C.getTypeSize(Type)) {
5314 assert(NewSize == 64 && "incorrect loop var size");
5315 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
5316 << InitSrcRange << ConditionSrcRange;
5317 }
5318 QualType NewType = C.getIntTypeForBitwidth(
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005319 NewSize, Type->hasSignedIntegerRepresentation() ||
5320 C.getTypeSize(Type) < NewSize);
Alexey Bataev11481f52016-02-17 10:29:05 +00005321 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
5322 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
5323 Sema::AA_Converting, true);
5324 if (!Diff.isUsable())
5325 return nullptr;
5326 }
Alexander Musman174b3ca2014-10-06 11:16:29 +00005327 }
5328 }
5329
Alexander Musmana5f070a2014-10-01 06:03:56 +00005330 return Diff.get();
5331}
5332
Alexey Bataeve3727102018-04-18 15:57:46 +00005333Expr *OpenMPIterationSpaceChecker::buildPreCond(
Alexey Bataev5a3af132016-03-29 08:58:54 +00005334 Scope *S, Expr *Cond,
Alexey Bataeve3727102018-04-18 15:57:46 +00005335 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
Alexey Bataev62dbb972015-04-22 11:59:37 +00005336 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
5337 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
5338 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005339
Alexey Bataeve3727102018-04-18 15:57:46 +00005340 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
5341 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00005342 if (!NewLB.isUsable() || !NewUB.isUsable())
5343 return nullptr;
5344
Alexey Bataeve3727102018-04-18 15:57:46 +00005345 ExprResult CondExpr =
5346 SemaRef.BuildBinOp(S, DefaultLoc,
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00005347 TestIsLessOp.getValue() ?
Kelvin Liefbe4af2018-11-21 19:10:48 +00005348 (TestIsStrictOp ? BO_LT : BO_LE) :
5349 (TestIsStrictOp ? BO_GT : BO_GE),
Alexey Bataeve3727102018-04-18 15:57:46 +00005350 NewLB.get(), NewUB.get());
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005351 if (CondExpr.isUsable()) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00005352 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
5353 SemaRef.Context.BoolTy))
Alexey Bataev11481f52016-02-17 10:29:05 +00005354 CondExpr = SemaRef.PerformImplicitConversion(
5355 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
5356 /*AllowExplicit=*/true);
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005357 }
Alexey Bataev62dbb972015-04-22 11:59:37 +00005358 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
Sergi Mateo Bellidof3e00fe2019-02-01 08:39:01 +00005359 // Otherwise use original loop condition and evaluate it in runtime.
Alexey Bataev62dbb972015-04-22 11:59:37 +00005360 return CondExpr.isUsable() ? CondExpr.get() : Cond;
5361}
5362
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005363/// Build reference expression to the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005364DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
Alexey Bataevf138fda2018-08-13 19:04:24 +00005365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5366 DSAStackTy &DSA) const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005367 auto *VD = dyn_cast<VarDecl>(LCDecl);
5368 if (!VD) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005369 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
5370 DeclRefExpr *Ref = buildDeclRefExpr(
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005371 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
Alexey Bataeve3727102018-04-18 15:57:46 +00005372 const DSAStackTy::DSAVarData Data =
5373 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00005374 // If the loop control decl is explicitly marked as private, do not mark it
5375 // as captured again.
5376 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
5377 Captures.insert(std::make_pair(LCRef, Ref));
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005378 return Ref;
5379 }
Alexey Bataev0d8fcdf2019-03-14 20:36:00 +00005380 return cast<DeclRefExpr>(LCRef);
Alexey Bataeva8899172015-08-06 12:30:57 +00005381}
5382
Alexey Bataeve3727102018-04-18 15:57:46 +00005383Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005384 if (LCDecl && !LCDecl->isInvalidDecl()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005385 QualType Type = LCDecl->getType().getNonReferenceType();
5386 VarDecl *PrivateVar = buildVarDecl(
Alexey Bataev63cc8e92018-03-20 14:45:59 +00005387 SemaRef, DefaultLoc, Type, LCDecl->getName(),
5388 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
5389 isa<VarDecl>(LCDecl)
5390 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
5391 : nullptr);
Alexey Bataeva8899172015-08-06 12:30:57 +00005392 if (PrivateVar->isInvalidDecl())
5393 return nullptr;
5394 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
5395 }
5396 return nullptr;
Alexander Musmana5f070a2014-10-01 06:03:56 +00005397}
5398
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005399/// Build initialization of the counter to be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005400Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005401
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005402/// Build step of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005403Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005404
Alexey Bataevf138fda2018-08-13 19:04:24 +00005405Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
5406 Scope *S, Expr *Counter,
5407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
5408 Expr *Inc, OverloadedOperatorKind OOK) {
5409 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
5410 if (!Cnt)
5411 return nullptr;
5412 if (Inc) {
5413 assert((OOK == OO_Plus || OOK == OO_Minus) &&
5414 "Expected only + or - operations for depend clauses.");
5415 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
5416 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
5417 if (!Cnt)
5418 return nullptr;
5419 }
5420 ExprResult Diff;
5421 QualType VarType = LCDecl->getType().getNonReferenceType();
5422 if (VarType->isIntegerType() || VarType->isPointerType() ||
5423 SemaRef.getLangOpts().CPlusPlus) {
5424 // Upper - Lower
Alexey Bataev316ccf62019-01-29 18:51:58 +00005425 Expr *Upper = TestIsLessOp.getValue()
5426 ? Cnt
5427 : tryBuildCapture(SemaRef, UB, Captures).get();
5428 Expr *Lower = TestIsLessOp.getValue()
5429 ? tryBuildCapture(SemaRef, LB, Captures).get()
5430 : Cnt;
Alexey Bataevf138fda2018-08-13 19:04:24 +00005431 if (!Upper || !Lower)
5432 return nullptr;
5433
5434 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
5435
5436 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
5437 // BuildBinOp already emitted error, this one is to point user to upper
5438 // and lower bound, and to tell what is passed to 'operator-'.
5439 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
5440 << Upper->getSourceRange() << Lower->getSourceRange();
5441 return nullptr;
5442 }
5443 }
5444
5445 if (!Diff.isUsable())
5446 return nullptr;
5447
5448 // Parentheses (for dumping/debugging purposes only).
5449 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
5450 if (!Diff.isUsable())
5451 return nullptr;
5452
5453 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
5454 if (!NewStep.isUsable())
5455 return nullptr;
5456 // (Upper - Lower) / Step
5457 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
5458 if (!Diff.isUsable())
5459 return nullptr;
5460
5461 return Diff.get();
5462}
5463
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005464/// Iteration space of a single for loop.
Alexey Bataev8b427062016-05-25 12:36:08 +00005465struct LoopIterationSpace final {
Alexey Bataev316ccf62019-01-29 18:51:58 +00005466 /// True if the condition operator is the strict compare operator (<, > or
5467 /// !=).
5468 bool IsStrictCompare = false;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005469 /// Condition of the loop.
Alexey Bataev8b427062016-05-25 12:36:08 +00005470 Expr *PreCond = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005471 /// This expression calculates the number of iterations in the loop.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005472 /// It is always possible to calculate it before starting the loop.
Alexey Bataev8b427062016-05-25 12:36:08 +00005473 Expr *NumIterations = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005474 /// The loop counter variable.
Alexey Bataev8b427062016-05-25 12:36:08 +00005475 Expr *CounterVar = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005476 /// Private loop counter variable.
Alexey Bataev8b427062016-05-25 12:36:08 +00005477 Expr *PrivateCounterVar = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005478 /// This is initializer for the initial value of #CounterVar.
Alexey Bataev8b427062016-05-25 12:36:08 +00005479 Expr *CounterInit = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005480 /// This is step for the #CounterVar used to generate its update:
Alexander Musmana5f070a2014-10-01 06:03:56 +00005481 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
Alexey Bataev8b427062016-05-25 12:36:08 +00005482 Expr *CounterStep = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005483 /// Should step be subtracted?
Alexey Bataev8b427062016-05-25 12:36:08 +00005484 bool Subtract = false;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005485 /// Source range of the loop init.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005486 SourceRange InitSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005487 /// Source range of the loop condition.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005488 SourceRange CondSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005489 /// Source range of the loop increment.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005490 SourceRange IncSrcRange;
5491};
5492
Alexey Bataev23b69422014-06-18 07:08:49 +00005493} // namespace
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005494
Alexey Bataev9c821032015-04-30 04:23:23 +00005495void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
5496 assert(getLangOpts().OpenMP && "OpenMP is not active.");
5497 assert(Init && "Expected loop in canonical form.");
Alexey Bataeva636c7f2015-12-23 10:27:45 +00005498 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
5499 if (AssociatedLoops > 0 &&
Alexey Bataev9c821032015-04-30 04:23:23 +00005500 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
Alexey Bataevce901812018-12-19 18:16:37 +00005501 DSAStack->loopStart();
Alexey Bataev622af1d2019-04-24 19:58:30 +00005502 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
Alexey Bataeve3727102018-04-18 15:57:46 +00005503 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
5504 if (ValueDecl *D = ISC.getLoopDecl()) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005505 auto *VD = dyn_cast<VarDecl>(D);
5506 if (!VD) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005507 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005508 VD = Private;
Alexey Bataeve3727102018-04-18 15:57:46 +00005509 } else {
5510 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
5511 /*WithInit=*/false);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005512 VD = cast<VarDecl>(Ref->getDecl());
5513 }
5514 }
5515 DSAStack->addLoopControlVariable(D, VD);
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00005516 const Decl *LD = DSAStack->getPossiblyLoopCunter();
5517 if (LD != D->getCanonicalDecl()) {
5518 DSAStack->resetPossibleLoopCounter();
5519 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
5520 MarkDeclarationsReferencedInExpr(
5521 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
5522 Var->getType().getNonLValueExprType(Context),
5523 ForLoc, /*RefersToCapture=*/true));
5524 }
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005525 }
5526 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +00005527 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
Alexey Bataev9c821032015-04-30 04:23:23 +00005528 }
5529}
5530
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005531/// Called on a for stmt to check and extract its iteration space
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005532/// for further processing (such as collapsing).
Alexey Bataeve3727102018-04-18 15:57:46 +00005533static bool checkOpenMPIterationSpace(
Alexey Bataev4acb8592014-07-07 13:01:15 +00005534 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
5535 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
Alexey Bataevf138fda2018-08-13 19:04:24 +00005536 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
5537 Expr *OrderedLoopCountExpr,
Alexey Bataeve3727102018-04-18 15:57:46 +00005538 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
Alexey Bataev5a3af132016-03-29 08:58:54 +00005539 LoopIterationSpace &ResultIterSpace,
Alexey Bataeve3727102018-04-18 15:57:46 +00005540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005541 // OpenMP [2.6, Canonical Loop Form]
5542 // for (init-expr; test-expr; incr-expr) structured-block
David Majnemer9d168222016-08-05 17:44:54 +00005543 auto *For = dyn_cast_or_null<ForStmt>(S);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005544 if (!For) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005545 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
Alexey Bataev10e775f2015-07-30 11:36:16 +00005546 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
Alexey Bataevf138fda2018-08-13 19:04:24 +00005547 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
Alexey Bataev10e775f2015-07-30 11:36:16 +00005548 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
Alexey Bataevf138fda2018-08-13 19:04:24 +00005549 if (TotalNestedLoopCount > 1) {
Alexey Bataev10e775f2015-07-30 11:36:16 +00005550 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
5551 SemaRef.Diag(DSA.getConstructLoc(),
5552 diag::note_omp_collapse_ordered_expr)
5553 << 2 << CollapseLoopCountExpr->getSourceRange()
5554 << OrderedLoopCountExpr->getSourceRange();
5555 else if (CollapseLoopCountExpr)
5556 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5557 diag::note_omp_collapse_ordered_expr)
5558 << 0 << CollapseLoopCountExpr->getSourceRange();
5559 else
5560 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5561 diag::note_omp_collapse_ordered_expr)
5562 << 1 << OrderedLoopCountExpr->getSourceRange();
5563 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005564 return true;
5565 }
5566 assert(For->getBody());
5567
Alexey Bataev622af1d2019-04-24 19:58:30 +00005568 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005569
5570 // Check init.
Alexey Bataeve3727102018-04-18 15:57:46 +00005571 Stmt *Init = For->getInit();
5572 if (ISC.checkAndSetInit(Init))
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005573 return true;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005574
5575 bool HasErrors = false;
5576
5577 // Check loop variable's type.
Alexey Bataeve3727102018-04-18 15:57:46 +00005578 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
5579 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005580
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005581 // OpenMP [2.6, Canonical Loop Form]
5582 // Var is one of the following:
5583 // A variable of signed or unsigned integer type.
5584 // For C++, a variable of a random access iterator type.
5585 // For C, a variable of a pointer type.
Alexey Bataeve3727102018-04-18 15:57:46 +00005586 QualType VarType = LCDecl->getType().getNonReferenceType();
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005587 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
5588 !VarType->isPointerType() &&
5589 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005590 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005591 << SemaRef.getLangOpts().CPlusPlus;
5592 HasErrors = true;
5593 }
5594
5595 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
5596 // a Construct
5597 // The loop iteration variable(s) in the associated for-loop(s) of a for or
5598 // parallel for construct is (are) private.
5599 // The loop iteration variable in the associated for-loop of a simd
5600 // construct with just one associated for-loop is linear with a
5601 // constant-linear-step that is the increment of the associated for-loop.
5602 // Exclude loop var from the list of variables with implicitly defined data
5603 // sharing attributes.
5604 VarsWithImplicitDSA.erase(LCDecl);
5605
5606 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
5607 // in a Construct, C/C++].
5608 // The loop iteration variable in the associated for-loop of a simd
5609 // construct with just one associated for-loop may be listed in a linear
5610 // clause with a constant-linear-step that is the increment of the
5611 // associated for-loop.
5612 // The loop iteration variable(s) in the associated for-loop(s) of a for or
5613 // parallel for construct may be listed in a private or lastprivate clause.
5614 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
5615 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
5616 // declared in the loop and it is predetermined as a private.
Alexey Bataeve3727102018-04-18 15:57:46 +00005617 OpenMPClauseKind PredeterminedCKind =
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005618 isOpenMPSimdDirective(DKind)
5619 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
5620 : OMPC_private;
5621 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
5622 DVar.CKind != PredeterminedCKind) ||
5623 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
5624 isOpenMPDistributeDirective(DKind)) &&
5625 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
5626 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
5627 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005628 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005629 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
5630 << getOpenMPClauseName(PredeterminedCKind);
5631 if (DVar.RefExpr == nullptr)
5632 DVar.CKind = PredeterminedCKind;
Alexey Bataeve3727102018-04-18 15:57:46 +00005633 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005634 HasErrors = true;
5635 } else if (LoopDeclRefExpr != nullptr) {
5636 // Make the loop iteration variable private (for worksharing constructs),
5637 // linear (for simd directives with the only one associated loop) or
5638 // lastprivate (for simd directives with several collapsed or ordered
5639 // loops).
5640 if (DVar.CKind == OMPC_unknown)
Alexey Bataevc2cdff62019-01-29 21:12:28 +00005641 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005642 }
5643
5644 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
5645
5646 // Check test-expr.
Alexey Bataeve3727102018-04-18 15:57:46 +00005647 HasErrors |= ISC.checkAndSetCond(For->getCond());
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005648
5649 // Check incr-expr.
Alexey Bataeve3727102018-04-18 15:57:46 +00005650 HasErrors |= ISC.checkAndSetInc(For->getInc());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005651 }
5652
Alexey Bataeve3727102018-04-18 15:57:46 +00005653 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005654 return HasErrors;
5655
Alexander Musmana5f070a2014-10-01 06:03:56 +00005656 // Build the loop's iteration space representation.
Alexey Bataev5a3af132016-03-29 08:58:54 +00005657 ResultIterSpace.PreCond =
Alexey Bataeve3727102018-04-18 15:57:46 +00005658 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
5659 ResultIterSpace.NumIterations = ISC.buildNumIterations(
Alexey Bataev5a3af132016-03-29 08:58:54 +00005660 DSA.getCurScope(),
5661 (isOpenMPWorksharingDirective(DKind) ||
5662 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
5663 Captures);
Alexey Bataeve3727102018-04-18 15:57:46 +00005664 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
5665 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
5666 ResultIterSpace.CounterInit = ISC.buildCounterInit();
5667 ResultIterSpace.CounterStep = ISC.buildCounterStep();
5668 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
5669 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
5670 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
5671 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
Alexey Bataev316ccf62019-01-29 18:51:58 +00005672 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
Alexander Musmana5f070a2014-10-01 06:03:56 +00005673
Alexey Bataev62dbb972015-04-22 11:59:37 +00005674 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
5675 ResultIterSpace.NumIterations == nullptr ||
Alexander Musmana5f070a2014-10-01 06:03:56 +00005676 ResultIterSpace.CounterVar == nullptr ||
Alexey Bataeva8899172015-08-06 12:30:57 +00005677 ResultIterSpace.PrivateCounterVar == nullptr ||
Alexander Musmana5f070a2014-10-01 06:03:56 +00005678 ResultIterSpace.CounterInit == nullptr ||
5679 ResultIterSpace.CounterStep == nullptr);
Alexey Bataevf138fda2018-08-13 19:04:24 +00005680 if (!HasErrors && DSA.isOrderedRegion()) {
5681 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
5682 if (CurrentNestedLoopCount <
5683 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
5684 DSA.getOrderedRegionParam().second->setLoopNumIterations(
5685 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
5686 DSA.getOrderedRegionParam().second->setLoopCounter(
5687 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
5688 }
5689 }
5690 for (auto &Pair : DSA.getDoacrossDependClauses()) {
5691 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
5692 // Erroneous case - clause has some problems.
5693 continue;
5694 }
5695 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
5696 Pair.second.size() <= CurrentNestedLoopCount) {
5697 // Erroneous case - clause has some problems.
5698 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
5699 continue;
5700 }
5701 Expr *CntValue;
5702 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5703 CntValue = ISC.buildOrderedLoopData(
5704 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5705 Pair.first->getDependencyLoc());
5706 else
5707 CntValue = ISC.buildOrderedLoopData(
5708 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5709 Pair.first->getDependencyLoc(),
5710 Pair.second[CurrentNestedLoopCount].first,
5711 Pair.second[CurrentNestedLoopCount].second);
5712 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
5713 }
5714 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005715
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005716 return HasErrors;
5717}
5718
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005719/// Build 'VarRef = Start.
Alexey Bataev5a3af132016-03-29 08:58:54 +00005720static ExprResult
Alexey Bataeve3727102018-04-18 15:57:46 +00005721buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
Alexey Bataev5a3af132016-03-29 08:58:54 +00005722 ExprResult Start,
Alexey Bataeve3727102018-04-18 15:57:46 +00005723 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005724 // Build 'VarRef = Start.
Alexey Bataeve3727102018-04-18 15:57:46 +00005725 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00005726 if (!NewStart.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005727 return ExprError();
Alexey Bataev11481f52016-02-17 10:29:05 +00005728 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
Alexey Bataev11481f52016-02-17 10:29:05 +00005729 VarRef.get()->getType())) {
5730 NewStart = SemaRef.PerformImplicitConversion(
5731 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
5732 /*AllowExplicit=*/true);
5733 if (!NewStart.isUsable())
5734 return ExprError();
5735 }
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005736
Alexey Bataeve3727102018-04-18 15:57:46 +00005737 ExprResult Init =
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005738 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
5739 return Init;
5740}
5741
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005742/// Build 'VarRef = Start + Iter * Step'.
Alexey Bataeve3727102018-04-18 15:57:46 +00005743static ExprResult buildCounterUpdate(
5744 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
5745 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
5746 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005747 // Add parentheses (for debugging purposes only).
5748 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
5749 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
5750 !Step.isUsable())
5751 return ExprError();
5752
Alexey Bataev5a3af132016-03-29 08:58:54 +00005753 ExprResult NewStep = Step;
5754 if (Captures)
5755 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005756 if (NewStep.isInvalid())
5757 return ExprError();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005758 ExprResult Update =
5759 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00005760 if (!Update.isUsable())
5761 return ExprError();
5762
Alexey Bataevc0214e02016-02-16 12:13:49 +00005763 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
5764 // 'VarRef = Start (+|-) Iter * Step'.
Alexey Bataev5a3af132016-03-29 08:58:54 +00005765 ExprResult NewStart = Start;
5766 if (Captures)
5767 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005768 if (NewStart.isInvalid())
5769 return ExprError();
Alexander Musmana5f070a2014-10-01 06:03:56 +00005770
Alexey Bataevc0214e02016-02-16 12:13:49 +00005771 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
5772 ExprResult SavedUpdate = Update;
5773 ExprResult UpdateVal;
5774 if (VarRef.get()->getType()->isOverloadableType() ||
5775 NewStart.get()->getType()->isOverloadableType() ||
5776 Update.get()->getType()->isOverloadableType()) {
5777 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
5778 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
5779 Update =
5780 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
5781 if (Update.isUsable()) {
5782 UpdateVal =
5783 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
5784 VarRef.get(), SavedUpdate.get());
5785 if (UpdateVal.isUsable()) {
5786 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
5787 UpdateVal.get());
5788 }
5789 }
5790 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
5791 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005792
Alexey Bataevc0214e02016-02-16 12:13:49 +00005793 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
5794 if (!Update.isUsable() || !UpdateVal.isUsable()) {
5795 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
5796 NewStart.get(), SavedUpdate.get());
5797 if (!Update.isUsable())
5798 return ExprError();
5799
Alexey Bataev11481f52016-02-17 10:29:05 +00005800 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
5801 VarRef.get()->getType())) {
5802 Update = SemaRef.PerformImplicitConversion(
5803 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
5804 if (!Update.isUsable())
5805 return ExprError();
5806 }
Alexey Bataevc0214e02016-02-16 12:13:49 +00005807
5808 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
5809 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005810 return Update;
5811}
5812
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005813/// Convert integer expression \a E to make it have at least \a Bits
Alexander Musmana5f070a2014-10-01 06:03:56 +00005814/// bits.
Alexey Bataeve3727102018-04-18 15:57:46 +00005815static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005816 if (E == nullptr)
5817 return ExprError();
Alexey Bataeve3727102018-04-18 15:57:46 +00005818 ASTContext &C = SemaRef.Context;
Alexander Musmana5f070a2014-10-01 06:03:56 +00005819 QualType OldType = E->getType();
5820 unsigned HasBits = C.getTypeSize(OldType);
5821 if (HasBits >= Bits)
5822 return ExprResult(E);
5823 // OK to convert to signed, because new type has more bits than old.
5824 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
5825 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
5826 true);
5827}
5828
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005829/// Check if the given expression \a E is a constant integer that fits
Alexander Musmana5f070a2014-10-01 06:03:56 +00005830/// into \a Bits bits.
Alexey Bataeve3727102018-04-18 15:57:46 +00005831static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005832 if (E == nullptr)
5833 return false;
5834 llvm::APSInt Result;
5835 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
5836 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5837 return false;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005838}
5839
Alexey Bataev5a3af132016-03-29 08:58:54 +00005840/// Build preinits statement for the given declarations.
5841static Stmt *buildPreInits(ASTContext &Context,
Alexey Bataevc5514062017-10-25 15:44:52 +00005842 MutableArrayRef<Decl *> PreInits) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00005843 if (!PreInits.empty()) {
5844 return new (Context) DeclStmt(
5845 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
5846 SourceLocation(), SourceLocation());
5847 }
5848 return nullptr;
5849}
5850
5851/// Build preinits statement for the given declarations.
Alexey Bataevc5514062017-10-25 15:44:52 +00005852static Stmt *
5853buildPreInits(ASTContext &Context,
Alexey Bataeve3727102018-04-18 15:57:46 +00005854 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00005855 if (!Captures.empty()) {
5856 SmallVector<Decl *, 16> PreInits;
Alexey Bataeve3727102018-04-18 15:57:46 +00005857 for (const auto &Pair : Captures)
Alexey Bataev5a3af132016-03-29 08:58:54 +00005858 PreInits.push_back(Pair.second->getDecl());
5859 return buildPreInits(Context, PreInits);
5860 }
5861 return nullptr;
5862}
5863
5864/// Build postupdate expression for the given list of postupdates expressions.
5865static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
5866 Expr *PostUpdate = nullptr;
5867 if (!PostUpdates.empty()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005868 for (Expr *E : PostUpdates) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00005869 Expr *ConvE = S.BuildCStyleCastExpr(
5870 E->getExprLoc(),
5871 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
5872 E->getExprLoc(), E)
5873 .get();
5874 PostUpdate = PostUpdate
5875 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
5876 PostUpdate, ConvE)
5877 .get()
5878 : ConvE;
5879 }
5880 }
5881 return PostUpdate;
5882}
5883
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005884/// Called on a for stmt to check itself and nested loops (if any).
Alexey Bataevabfc0692014-06-25 06:52:00 +00005885/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
5886/// number of collapsed loops otherwise.
Alexey Bataev4acb8592014-07-07 13:01:15 +00005887static unsigned
Alexey Bataeve3727102018-04-18 15:57:46 +00005888checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Alexey Bataev10e775f2015-07-30 11:36:16 +00005889 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
5890 DSAStackTy &DSA,
Alexey Bataeve3727102018-04-18 15:57:46 +00005891 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
Alexander Musmanc6388682014-12-15 07:07:06 +00005892 OMPLoopDirective::HelperExprs &Built) {
Alexey Bataeve2f07d42014-06-24 12:55:56 +00005893 unsigned NestedLoopCount = 1;
Alexey Bataev10e775f2015-07-30 11:36:16 +00005894 if (CollapseLoopCountExpr) {
Alexey Bataeve2f07d42014-06-24 12:55:56 +00005895 // Found 'collapse' clause - calculate collapse number.
Fangrui Song407659a2018-11-30 23:41:18 +00005896 Expr::EvalResult Result;
Dmitri Gribenko04323c22019-05-17 17:16:53 +00005897 if (!CollapseLoopCountExpr->isValueDependent() &&
5898 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
Fangrui Song407659a2018-11-30 23:41:18 +00005899 NestedLoopCount = Result.Val.getInt().getLimitedValue();
Dmitri Gribenko04323c22019-05-17 17:16:53 +00005900 } else {
5901 Built.clear(/*size=*/1);
5902 return 1;
5903 }
Alexey Bataev10e775f2015-07-30 11:36:16 +00005904 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00005905 unsigned OrderedLoopCount = 1;
Alexey Bataev10e775f2015-07-30 11:36:16 +00005906 if (OrderedLoopCountExpr) {
5907 // Found 'ordered' clause - calculate collapse number.
Fangrui Song407659a2018-11-30 23:41:18 +00005908 Expr::EvalResult EVResult;
Dmitri Gribenko04323c22019-05-17 17:16:53 +00005909 if (!OrderedLoopCountExpr->isValueDependent() &&
5910 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
5911 SemaRef.getASTContext())) {
Fangrui Song407659a2018-11-30 23:41:18 +00005912 llvm::APSInt Result = EVResult.Val.getInt();
Alexey Bataev7b6bc882015-11-26 07:50:39 +00005913 if (Result.getLimitedValue() < NestedLoopCount) {
5914 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5915 diag::err_omp_wrong_ordered_loop_count)
5916 << OrderedLoopCountExpr->getSourceRange();
5917 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5918 diag::note_collapse_loop_count)
5919 << CollapseLoopCountExpr->getSourceRange();
5920 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00005921 OrderedLoopCount = Result.getLimitedValue();
Dmitri Gribenko04323c22019-05-17 17:16:53 +00005922 } else {
5923 Built.clear(/*size=*/1);
5924 return 1;
Alexey Bataev7b6bc882015-11-26 07:50:39 +00005925 }
Alexey Bataeve2f07d42014-06-24 12:55:56 +00005926 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005927 // This is helper routine for loop directives (e.g., 'for', 'simd',
5928 // 'for simd', etc.).
Alexey Bataeve3727102018-04-18 15:57:46 +00005929 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev316ccf62019-01-29 18:51:58 +00005930 SmallVector<LoopIterationSpace, 4> IterSpaces(
5931 std::max(OrderedLoopCount, NestedLoopCount));
Alexander Musmana5f070a2014-10-01 06:03:56 +00005932 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005933 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00005934 if (checkOpenMPIterationSpace(
5935 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5936 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5937 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5938 Captures))
Alexey Bataevabfc0692014-06-25 06:52:00 +00005939 return 0;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005940 // Move on to the next nested for loop, or to the loop body.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005941 // OpenMP [2.8.1, simd construct, Restrictions]
5942 // All loops associated with the construct must be perfectly nested; that
5943 // is, there must be no intervening code nor any OpenMP directive between
5944 // any two loops.
5945 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005946 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00005947 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
5948 if (checkOpenMPIterationSpace(
5949 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5950 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5951 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5952 Captures))
5953 return 0;
5954 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
5955 // Handle initialization of captured loop iterator variables.
5956 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
5957 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
5958 Captures[DRE] = DRE;
5959 }
5960 }
5961 // Move on to the next nested for loop, or to the loop body.
5962 // OpenMP [2.8.1, simd construct, Restrictions]
5963 // All loops associated with the construct must be perfectly nested; that
5964 // is, there must be no intervening code nor any OpenMP directive between
5965 // any two loops.
5966 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5967 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005968
Alexander Musmana5f070a2014-10-01 06:03:56 +00005969 Built.clear(/* size */ NestedLoopCount);
5970
5971 if (SemaRef.CurContext->isDependentContext())
5972 return NestedLoopCount;
5973
5974 // An example of what is generated for the following code:
5975 //
Alexey Bataev10e775f2015-07-30 11:36:16 +00005976 // #pragma omp simd collapse(2) ordered(2)
Alexander Musmana5f070a2014-10-01 06:03:56 +00005977 // for (i = 0; i < NI; ++i)
Alexey Bataev10e775f2015-07-30 11:36:16 +00005978 // for (k = 0; k < NK; ++k)
5979 // for (j = J0; j < NJ; j+=2) {
5980 // <loop body>
5981 // }
Alexander Musmana5f070a2014-10-01 06:03:56 +00005982 //
5983 // We generate the code below.
5984 // Note: the loop body may be outlined in CodeGen.
5985 // Note: some counters may be C++ classes, operator- is used to find number of
5986 // iterations and operator+= to calculate counter value.
5987 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
5988 // or i64 is currently supported).
5989 //
5990 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
5991 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
5992 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
5993 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
5994 // // similar updates for vars in clauses (e.g. 'linear')
5995 // <loop body (using local i and j)>
5996 // }
5997 // i = NI; // assign final values of counters
5998 // j = NJ;
5999 //
6000
6001 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
6002 // the iteration counts of the collapsed for loops.
Alexey Bataev62dbb972015-04-22 11:59:37 +00006003 // Precondition tests if there is at least one iteration (all conditions are
6004 // true).
6005 auto PreCond = ExprResult(IterSpaces[0].PreCond);
Alexey Bataeve3727102018-04-18 15:57:46 +00006006 Expr *N0 = IterSpaces[0].NumIterations;
6007 ExprResult LastIteration32 =
6008 widenIterationCount(/*Bits=*/32,
6009 SemaRef
6010 .PerformImplicitConversion(
6011 N0->IgnoreImpCasts(), N0->getType(),
6012 Sema::AA_Converting, /*AllowExplicit=*/true)
6013 .get(),
6014 SemaRef);
6015 ExprResult LastIteration64 = widenIterationCount(
6016 /*Bits=*/64,
6017 SemaRef
6018 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
6019 Sema::AA_Converting,
6020 /*AllowExplicit=*/true)
6021 .get(),
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006022 SemaRef);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006023
6024 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
6025 return NestedLoopCount;
6026
Alexey Bataeve3727102018-04-18 15:57:46 +00006027 ASTContext &C = SemaRef.Context;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006028 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
6029
6030 Scope *CurScope = DSA.getCurScope();
6031 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
Alexey Bataev62dbb972015-04-22 11:59:37 +00006032 if (PreCond.isUsable()) {
Alexey Bataeva7206b92016-12-20 16:51:02 +00006033 PreCond =
6034 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
6035 PreCond.get(), IterSpaces[Cnt].PreCond);
Alexey Bataev62dbb972015-04-22 11:59:37 +00006036 }
Alexey Bataeve3727102018-04-18 15:57:46 +00006037 Expr *N = IterSpaces[Cnt].NumIterations;
Alexey Bataeva7206b92016-12-20 16:51:02 +00006038 SourceLocation Loc = N->getExprLoc();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006039 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
6040 if (LastIteration32.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006041 LastIteration32 = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00006042 CurScope, Loc, BO_Mul, LastIteration32.get(),
David Majnemer9d168222016-08-05 17:44:54 +00006043 SemaRef
6044 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
6045 Sema::AA_Converting,
6046 /*AllowExplicit=*/true)
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006047 .get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00006048 if (LastIteration64.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006049 LastIteration64 = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00006050 CurScope, Loc, BO_Mul, LastIteration64.get(),
David Majnemer9d168222016-08-05 17:44:54 +00006051 SemaRef
6052 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
6053 Sema::AA_Converting,
6054 /*AllowExplicit=*/true)
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006055 .get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00006056 }
6057
6058 // Choose either the 32-bit or 64-bit version.
6059 ExprResult LastIteration = LastIteration64;
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00006060 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
6061 (LastIteration32.isUsable() &&
6062 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
6063 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
6064 fitsInto(
6065 /*Bits=*/32,
6066 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
6067 LastIteration64.get(), SemaRef))))
Alexander Musmana5f070a2014-10-01 06:03:56 +00006068 LastIteration = LastIteration32;
Alexey Bataev7292c292016-04-25 12:22:29 +00006069 QualType VType = LastIteration.get()->getType();
6070 QualType RealVType = VType;
6071 QualType StrideVType = VType;
6072 if (isOpenMPTaskLoopDirective(DKind)) {
6073 VType =
6074 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
6075 StrideVType =
6076 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
6077 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006078
6079 if (!LastIteration.isUsable())
6080 return 0;
6081
6082 // Save the number of iterations.
6083 ExprResult NumIterations = LastIteration;
6084 {
6085 LastIteration = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00006086 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
6087 LastIteration.get(),
Alexander Musmana5f070a2014-10-01 06:03:56 +00006088 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6089 if (!LastIteration.isUsable())
6090 return 0;
6091 }
6092
6093 // Calculate the last iteration number beforehand instead of doing this on
6094 // each iteration. Do not do this if the number of iterations may be kfold-ed.
6095 llvm::APSInt Result;
6096 bool IsConstant =
6097 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
6098 ExprResult CalcLastIteration;
6099 if (!IsConstant) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00006100 ExprResult SaveRef =
6101 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006102 LastIteration = SaveRef;
6103
6104 // Prepare SaveRef + 1.
6105 NumIterations = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00006106 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
Alexander Musmana5f070a2014-10-01 06:03:56 +00006107 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6108 if (!NumIterations.isUsable())
6109 return 0;
6110 }
6111
6112 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
6113
David Majnemer9d168222016-08-05 17:44:54 +00006114 // Build variables passed into runtime, necessary for worksharing directives.
Carlo Bertolliffafe102017-04-20 00:39:39 +00006115 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00006116 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
6117 isOpenMPDistributeDirective(DKind)) {
Alexander Musmanc6388682014-12-15 07:07:06 +00006118 // Lower bound variable, initialized with zero.
Alexey Bataev39f915b82015-05-08 10:41:21 +00006119 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
6120 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00006121 SemaRef.AddInitializerToDecl(LBDecl,
6122 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
6123 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006124
6125 // Upper bound variable, initialized with last iteration number.
Alexey Bataev39f915b82015-05-08 10:41:21 +00006126 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
6127 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
Alexander Musmanc6388682014-12-15 07:07:06 +00006128 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
Richard Smith3beb7c62017-01-12 02:27:38 +00006129 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006130
6131 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
6132 // This will be used to implement clause 'lastprivate'.
6133 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
Alexey Bataev39f915b82015-05-08 10:41:21 +00006134 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
6135 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00006136 SemaRef.AddInitializerToDecl(ILDecl,
6137 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
6138 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006139
6140 // Stride variable returned by runtime (we initialize it to 1 by default).
Alexey Bataev7292c292016-04-25 12:22:29 +00006141 VarDecl *STDecl =
6142 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
6143 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00006144 SemaRef.AddInitializerToDecl(STDecl,
6145 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
6146 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006147
6148 // Build expression: UB = min(UB, LastIteration)
David Majnemer9d168222016-08-05 17:44:54 +00006149 // It is necessary for CodeGen of directives with static scheduling.
Alexander Musmanc6388682014-12-15 07:07:06 +00006150 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
6151 UB.get(), LastIteration.get());
6152 ExprResult CondOp = SemaRef.ActOnConditionalOp(
Alexey Bataev86ec3fe2018-07-25 14:40:26 +00006153 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
6154 LastIteration.get(), UB.get());
Alexander Musmanc6388682014-12-15 07:07:06 +00006155 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
6156 CondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006157 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
Carlo Bertolli9925f152016-06-27 14:55:37 +00006158
6159 // If we have a combined directive that combines 'distribute', 'for' or
6160 // 'simd' we need to be able to access the bounds of the schedule of the
6161 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
6162 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
6163 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Carlo Bertolliffafe102017-04-20 00:39:39 +00006164 // Lower bound variable, initialized with zero.
6165 VarDecl *CombLBDecl =
6166 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
6167 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
6168 SemaRef.AddInitializerToDecl(
6169 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
6170 /*DirectInit*/ false);
6171
6172 // Upper bound variable, initialized with last iteration number.
6173 VarDecl *CombUBDecl =
6174 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
6175 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
6176 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
6177 /*DirectInit*/ false);
6178
6179 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
6180 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
6181 ExprResult CombCondOp =
6182 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
6183 LastIteration.get(), CombUB.get());
6184 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
6185 CombCondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006186 CombEUB =
6187 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006188
Alexey Bataeve3727102018-04-18 15:57:46 +00006189 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
Carlo Bertolli9925f152016-06-27 14:55:37 +00006190 // We expect to have at least 2 more parameters than the 'parallel'
6191 // directive does - the lower and upper bounds of the previous schedule.
6192 assert(CD->getNumParams() >= 4 &&
6193 "Unexpected number of parameters in loop combined directive");
6194
6195 // Set the proper type for the bounds given what we learned from the
6196 // enclosed loops.
Alexey Bataeve3727102018-04-18 15:57:46 +00006197 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
6198 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
Carlo Bertolli9925f152016-06-27 14:55:37 +00006199
6200 // Previous lower and upper bounds are obtained from the region
6201 // parameters.
6202 PrevLB =
6203 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
6204 PrevUB =
6205 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
6206 }
Alexander Musmanc6388682014-12-15 07:07:06 +00006207 }
6208
6209 // Build the iteration variable and its initialization before loop.
Alexander Musmana5f070a2014-10-01 06:03:56 +00006210 ExprResult IV;
Carlo Bertolliffafe102017-04-20 00:39:39 +00006211 ExprResult Init, CombInit;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006212 {
Alexey Bataev7292c292016-04-25 12:22:29 +00006213 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
6214 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
David Majnemer9d168222016-08-05 17:44:54 +00006215 Expr *RHS =
6216 (isOpenMPWorksharingDirective(DKind) ||
6217 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
6218 ? LB.get()
6219 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
Alexander Musmanc6388682014-12-15 07:07:06 +00006220 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006221 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006222
6223 if (isOpenMPLoopBoundSharingDirective(DKind)) {
6224 Expr *CombRHS =
6225 (isOpenMPWorksharingDirective(DKind) ||
6226 isOpenMPTaskLoopDirective(DKind) ||
6227 isOpenMPDistributeDirective(DKind))
6228 ? CombLB.get()
6229 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
6230 CombInit =
6231 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006232 CombInit =
6233 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006234 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006235 }
6236
Alexey Bataev316ccf62019-01-29 18:51:58 +00006237 bool UseStrictCompare =
6238 RealVType->hasUnsignedIntegerRepresentation() &&
6239 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
6240 return LIS.IsStrictCompare;
6241 });
6242 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
6243 // unsigned IV)) for worksharing loops.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006244 SourceLocation CondLoc = AStmt->getBeginLoc();
Alexey Bataev316ccf62019-01-29 18:51:58 +00006245 Expr *BoundUB = UB.get();
6246 if (UseStrictCompare) {
6247 BoundUB =
6248 SemaRef
6249 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
6250 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
6251 .get();
6252 BoundUB =
6253 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
6254 }
Alexander Musmanc6388682014-12-15 07:07:06 +00006255 ExprResult Cond =
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00006256 (isOpenMPWorksharingDirective(DKind) ||
6257 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
Alexey Bataev316ccf62019-01-29 18:51:58 +00006258 ? SemaRef.BuildBinOp(CurScope, CondLoc,
6259 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
6260 BoundUB)
Alexander Musmanc6388682014-12-15 07:07:06 +00006261 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
6262 NumIterations.get());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006263 ExprResult CombDistCond;
6264 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00006265 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
6266 NumIterations.get());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006267 }
6268
Carlo Bertolliffafe102017-04-20 00:39:39 +00006269 ExprResult CombCond;
6270 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00006271 Expr *BoundCombUB = CombUB.get();
6272 if (UseStrictCompare) {
6273 BoundCombUB =
6274 SemaRef
6275 .BuildBinOp(
6276 CurScope, CondLoc, BO_Add, BoundCombUB,
6277 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
6278 .get();
6279 BoundCombUB =
6280 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
6281 .get();
6282 }
Carlo Bertolliffafe102017-04-20 00:39:39 +00006283 CombCond =
Alexey Bataev316ccf62019-01-29 18:51:58 +00006284 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
6285 IV.get(), BoundCombUB);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006286 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006287 // Loop increment (IV = IV + 1)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006288 SourceLocation IncLoc = AStmt->getBeginLoc();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006289 ExprResult Inc =
6290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
6291 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
6292 if (!Inc.isUsable())
6293 return 0;
6294 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006295 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006296 if (!Inc.isUsable())
6297 return 0;
6298
6299 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
6300 // Used for directives with static scheduling.
Carlo Bertolliffafe102017-04-20 00:39:39 +00006301 // In combined construct, add combined version that use CombLB and CombUB
6302 // base variables for the update
6303 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00006304 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
6305 isOpenMPDistributeDirective(DKind)) {
Alexander Musmanc6388682014-12-15 07:07:06 +00006306 // LB + ST
6307 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
6308 if (!NextLB.isUsable())
6309 return 0;
6310 // LB = LB + ST
6311 NextLB =
6312 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006313 NextLB =
6314 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006315 if (!NextLB.isUsable())
6316 return 0;
6317 // UB + ST
6318 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
6319 if (!NextUB.isUsable())
6320 return 0;
6321 // UB = UB + ST
6322 NextUB =
6323 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006324 NextUB =
6325 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00006326 if (!NextUB.isUsable())
6327 return 0;
Carlo Bertolliffafe102017-04-20 00:39:39 +00006328 if (isOpenMPLoopBoundSharingDirective(DKind)) {
6329 CombNextLB =
6330 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
6331 if (!NextLB.isUsable())
6332 return 0;
6333 // LB = LB + ST
6334 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
6335 CombNextLB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006336 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
6337 /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006338 if (!CombNextLB.isUsable())
6339 return 0;
6340 // UB + ST
6341 CombNextUB =
6342 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
6343 if (!CombNextUB.isUsable())
6344 return 0;
6345 // UB = UB + ST
6346 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
6347 CombNextUB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006348 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
6349 /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00006350 if (!CombNextUB.isUsable())
6351 return 0;
6352 }
Alexander Musmanc6388682014-12-15 07:07:06 +00006353 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006354
Carlo Bertolliffafe102017-04-20 00:39:39 +00006355 // Create increment expression for distribute loop when combined in a same
Carlo Bertolli8429d812017-02-17 21:29:13 +00006356 // directive with for as IV = IV + ST; ensure upper bound expression based
6357 // on PrevUB instead of NumIterations - used to implement 'for' when found
6358 // in combination with 'distribute', like in 'distribute parallel for'
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006359 SourceLocation DistIncLoc = AStmt->getBeginLoc();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006360 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
Carlo Bertolli8429d812017-02-17 21:29:13 +00006361 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00006362 DistCond = SemaRef.BuildBinOp(
6363 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
Carlo Bertolli8429d812017-02-17 21:29:13 +00006364 assert(DistCond.isUsable() && "distribute cond expr was not built");
6365
6366 DistInc =
6367 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
6368 assert(DistInc.isUsable() && "distribute inc expr was not built");
6369 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
6370 DistInc.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006371 DistInc =
6372 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
Carlo Bertolli8429d812017-02-17 21:29:13 +00006373 assert(DistInc.isUsable() && "distribute inc expr was not built");
6374
6375 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
6376 // construct
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006377 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
Carlo Bertolli8429d812017-02-17 21:29:13 +00006378 ExprResult IsUBGreater =
6379 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
6380 ExprResult CondOp = SemaRef.ActOnConditionalOp(
6381 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
6382 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
6383 CondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006384 PrevEUB =
6385 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006386
Alexey Bataev316ccf62019-01-29 18:51:58 +00006387 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
6388 // parallel for is in combination with a distribute directive with
6389 // schedule(static, 1)
6390 Expr *BoundPrevUB = PrevUB.get();
6391 if (UseStrictCompare) {
6392 BoundPrevUB =
6393 SemaRef
6394 .BuildBinOp(
6395 CurScope, CondLoc, BO_Add, BoundPrevUB,
6396 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
6397 .get();
6398 BoundPrevUB =
6399 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
6400 .get();
6401 }
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006402 ParForInDistCond =
Alexey Bataev316ccf62019-01-29 18:51:58 +00006403 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
6404 IV.get(), BoundPrevUB);
Carlo Bertolli8429d812017-02-17 21:29:13 +00006405 }
6406
Alexander Musmana5f070a2014-10-01 06:03:56 +00006407 // Build updates and final values of the loop counters.
6408 bool HasErrors = false;
6409 Built.Counters.resize(NestedLoopCount);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006410 Built.Inits.resize(NestedLoopCount);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006411 Built.Updates.resize(NestedLoopCount);
6412 Built.Finals.resize(NestedLoopCount);
6413 {
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00006414 // We implement the following algorithm for obtaining the
6415 // original loop iteration variable values based on the
6416 // value of the collapsed loop iteration variable IV.
6417 //
6418 // Let n+1 be the number of collapsed loops in the nest.
6419 // Iteration variables (I0, I1, .... In)
6420 // Iteration counts (N0, N1, ... Nn)
6421 //
6422 // Acc = IV;
6423 //
6424 // To compute Ik for loop k, 0 <= k <= n, generate:
6425 // Prod = N(k+1) * N(k+2) * ... * Nn;
6426 // Ik = Acc / Prod;
6427 // Acc -= Ik * Prod;
6428 //
6429 ExprResult Acc = IV;
6430 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00006431 LoopIterationSpace &IS = IterSpaces[Cnt];
6432 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006433 ExprResult Iter;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006434
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00006435 // Compute prod
6436 ExprResult Prod =
6437 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
6438 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
6439 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
6440 IterSpaces[K].NumIterations);
6441
6442 // Iter = Acc / Prod
6443 // If there is at least one more inner loop to avoid
6444 // multiplication by 1.
6445 if (Cnt + 1 < NestedLoopCount)
6446 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
6447 Acc.get(), Prod.get());
6448 else
6449 Iter = Acc;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006450 if (!Iter.isUsable()) {
6451 HasErrors = true;
6452 break;
6453 }
6454
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00006455 // Update Acc:
6456 // Acc -= Iter * Prod
6457 // Check if there is at least one more inner loop to avoid
6458 // multiplication by 1.
6459 if (Cnt + 1 < NestedLoopCount)
6460 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
6461 Iter.get(), Prod.get());
6462 else
6463 Prod = Iter;
6464 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
6465 Acc.get(), Prod.get());
6466
Alexey Bataev39f915b82015-05-08 10:41:21 +00006467 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006468 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
Alexey Bataeve3727102018-04-18 15:57:46 +00006469 DeclRefExpr *CounterVar = buildDeclRefExpr(
6470 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
6471 /*RefersToCapture=*/true);
6472 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
Alexey Bataev5a3af132016-03-29 08:58:54 +00006473 IS.CounterInit, Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006474 if (!Init.isUsable()) {
6475 HasErrors = true;
6476 break;
6477 }
Alexey Bataeve3727102018-04-18 15:57:46 +00006478 ExprResult Update = buildCounterUpdate(
Alexey Bataev5a3af132016-03-29 08:58:54 +00006479 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
6480 IS.CounterStep, IS.Subtract, &Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006481 if (!Update.isUsable()) {
6482 HasErrors = true;
6483 break;
6484 }
6485
6486 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
Alexey Bataeve3727102018-04-18 15:57:46 +00006487 ExprResult Final = buildCounterUpdate(
Alexey Bataev39f915b82015-05-08 10:41:21 +00006488 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
Alexey Bataev5a3af132016-03-29 08:58:54 +00006489 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006490 if (!Final.isUsable()) {
6491 HasErrors = true;
6492 break;
6493 }
6494
Alexander Musmana5f070a2014-10-01 06:03:56 +00006495 if (!Update.isUsable() || !Final.isUsable()) {
6496 HasErrors = true;
6497 break;
6498 }
6499 // Save results
6500 Built.Counters[Cnt] = IS.CounterVar;
Alexey Bataeva8899172015-08-06 12:30:57 +00006501 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006502 Built.Inits[Cnt] = Init.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006503 Built.Updates[Cnt] = Update.get();
6504 Built.Finals[Cnt] = Final.get();
6505 }
6506 }
6507
6508 if (HasErrors)
6509 return 0;
6510
6511 // Save results
6512 Built.IterationVarRef = IV.get();
6513 Built.LastIteration = LastIteration.get();
Alexander Musman3276a272015-03-21 10:12:56 +00006514 Built.NumIterations = NumIterations.get();
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00006515 Built.CalcLastIteration = SemaRef
6516 .ActOnFinishFullExpr(CalcLastIteration.get(),
6517 /*DiscardedValue*/ false)
6518 .get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006519 Built.PreCond = PreCond.get();
Alexey Bataev5a3af132016-03-29 08:58:54 +00006520 Built.PreInits = buildPreInits(C, Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00006521 Built.Cond = Cond.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006522 Built.Init = Init.get();
6523 Built.Inc = Inc.get();
Alexander Musmanc6388682014-12-15 07:07:06 +00006524 Built.LB = LB.get();
6525 Built.UB = UB.get();
6526 Built.IL = IL.get();
6527 Built.ST = ST.get();
6528 Built.EUB = EUB.get();
6529 Built.NLB = NextLB.get();
6530 Built.NUB = NextUB.get();
Carlo Bertolli9925f152016-06-27 14:55:37 +00006531 Built.PrevLB = PrevLB.get();
6532 Built.PrevUB = PrevUB.get();
Carlo Bertolli8429d812017-02-17 21:29:13 +00006533 Built.DistInc = DistInc.get();
6534 Built.PrevEUB = PrevEUB.get();
Carlo Bertolliffafe102017-04-20 00:39:39 +00006535 Built.DistCombinedFields.LB = CombLB.get();
6536 Built.DistCombinedFields.UB = CombUB.get();
6537 Built.DistCombinedFields.EUB = CombEUB.get();
6538 Built.DistCombinedFields.Init = CombInit.get();
6539 Built.DistCombinedFields.Cond = CombCond.get();
6540 Built.DistCombinedFields.NLB = CombNextLB.get();
6541 Built.DistCombinedFields.NUB = CombNextUB.get();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00006542 Built.DistCombinedFields.DistCond = CombDistCond.get();
6543 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006544
Alexey Bataevabfc0692014-06-25 06:52:00 +00006545 return NestedLoopCount;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006546}
6547
Alexey Bataev10e775f2015-07-30 11:36:16 +00006548static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00006549 auto CollapseClauses =
6550 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
6551 if (CollapseClauses.begin() != CollapseClauses.end())
6552 return (*CollapseClauses.begin())->getNumForLoops();
Alexey Bataeve2f07d42014-06-24 12:55:56 +00006553 return nullptr;
6554}
6555
Alexey Bataev10e775f2015-07-30 11:36:16 +00006556static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00006557 auto OrderedClauses =
6558 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
6559 if (OrderedClauses.begin() != OrderedClauses.end())
6560 return (*OrderedClauses.begin())->getNumForLoops();
Alexey Bataev10e775f2015-07-30 11:36:16 +00006561 return nullptr;
6562}
6563
Kelvin Lic5609492016-07-15 04:39:07 +00006564static bool checkSimdlenSafelenSpecified(Sema &S,
6565 const ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006566 const OMPSafelenClause *Safelen = nullptr;
6567 const OMPSimdlenClause *Simdlen = nullptr;
Kelvin Lic5609492016-07-15 04:39:07 +00006568
Alexey Bataeve3727102018-04-18 15:57:46 +00006569 for (const OMPClause *Clause : Clauses) {
Kelvin Lic5609492016-07-15 04:39:07 +00006570 if (Clause->getClauseKind() == OMPC_safelen)
6571 Safelen = cast<OMPSafelenClause>(Clause);
6572 else if (Clause->getClauseKind() == OMPC_simdlen)
6573 Simdlen = cast<OMPSimdlenClause>(Clause);
6574 if (Safelen && Simdlen)
6575 break;
6576 }
6577
6578 if (Simdlen && Safelen) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006579 const Expr *SimdlenLength = Simdlen->getSimdlen();
6580 const Expr *SafelenLength = Safelen->getSafelen();
Kelvin Lic5609492016-07-15 04:39:07 +00006581 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
6582 SimdlenLength->isInstantiationDependent() ||
6583 SimdlenLength->containsUnexpandedParameterPack())
6584 return false;
6585 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
6586 SafelenLength->isInstantiationDependent() ||
6587 SafelenLength->containsUnexpandedParameterPack())
6588 return false;
Fangrui Song407659a2018-11-30 23:41:18 +00006589 Expr::EvalResult SimdlenResult, SafelenResult;
6590 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
6591 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
6592 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
6593 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
Kelvin Lic5609492016-07-15 04:39:07 +00006594 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
6595 // If both simdlen and safelen clauses are specified, the value of the
6596 // simdlen parameter must be less than or equal to the value of the safelen
6597 // parameter.
6598 if (SimdlenRes > SafelenRes) {
6599 S.Diag(SimdlenLength->getExprLoc(),
6600 diag::err_omp_wrong_simdlen_safelen_values)
6601 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
6602 return true;
6603 }
Alexey Bataev66b15b52015-08-21 11:14:16 +00006604 }
6605 return false;
6606}
6607
Alexey Bataeve3727102018-04-18 15:57:46 +00006608StmtResult
6609Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
6610 SourceLocation StartLoc, SourceLocation EndLoc,
6611 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006612 if (!AStmt)
6613 return StmtError();
6614
6615 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00006616 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006617 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6618 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00006619 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataev10e775f2015-07-30 11:36:16 +00006620 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
6621 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
Alexey Bataevabfc0692014-06-25 06:52:00 +00006622 if (NestedLoopCount == 0)
Alexey Bataev1b59ab52014-02-27 08:29:12 +00006623 return StmtError();
Alexey Bataev1b59ab52014-02-27 08:29:12 +00006624
Alexander Musmana5f070a2014-10-01 06:03:56 +00006625 assert((CurContext->isDependentContext() || B.builtAll()) &&
6626 "omp simd loop exprs were not built");
6627
Alexander Musman3276a272015-03-21 10:12:56 +00006628 if (!CurContext->isDependentContext()) {
6629 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006630 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00006631 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexander Musman3276a272015-03-21 10:12:56 +00006632 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006633 B.NumIterations, *this, CurScope,
6634 DSAStack))
Alexander Musman3276a272015-03-21 10:12:56 +00006635 return StmtError();
6636 }
6637 }
6638
Kelvin Lic5609492016-07-15 04:39:07 +00006639 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00006640 return StmtError();
6641
Reid Kleckner87a31802018-03-12 21:43:02 +00006642 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00006643 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
6644 Clauses, AStmt, B);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00006645}
6646
Alexey Bataeve3727102018-04-18 15:57:46 +00006647StmtResult
6648Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
6649 SourceLocation StartLoc, SourceLocation EndLoc,
6650 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006651 if (!AStmt)
6652 return StmtError();
6653
6654 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00006655 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006656 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6657 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00006658 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataev10e775f2015-07-30 11:36:16 +00006659 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
6660 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
Alexey Bataevabfc0692014-06-25 06:52:00 +00006661 if (NestedLoopCount == 0)
Alexey Bataevf29276e2014-06-18 04:14:57 +00006662 return StmtError();
6663
Alexander Musmana5f070a2014-10-01 06:03:56 +00006664 assert((CurContext->isDependentContext() || B.builtAll()) &&
6665 "omp for loop exprs were not built");
6666
Alexey Bataev54acd402015-08-04 11:18:19 +00006667 if (!CurContext->isDependentContext()) {
6668 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006669 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00006670 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev54acd402015-08-04 11:18:19 +00006671 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006672 B.NumIterations, *this, CurScope,
6673 DSAStack))
Alexey Bataev54acd402015-08-04 11:18:19 +00006674 return StmtError();
6675 }
6676 }
6677
Reid Kleckner87a31802018-03-12 21:43:02 +00006678 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00006679 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
Alexey Bataev25e5b442015-09-15 12:52:43 +00006680 Clauses, AStmt, B, DSAStack->isCancelRegion());
Alexey Bataevf29276e2014-06-18 04:14:57 +00006681}
6682
Alexander Musmanf82886e2014-09-18 05:12:34 +00006683StmtResult Sema::ActOnOpenMPForSimdDirective(
6684 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00006685 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006686 if (!AStmt)
6687 return StmtError();
6688
6689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00006690 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006691 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6692 // define the nested loops number.
Alexander Musmanf82886e2014-09-18 05:12:34 +00006693 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00006694 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00006695 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6696 VarsWithImplicitDSA, B);
Alexander Musmanf82886e2014-09-18 05:12:34 +00006697 if (NestedLoopCount == 0)
6698 return StmtError();
6699
Alexander Musmanc6388682014-12-15 07:07:06 +00006700 assert((CurContext->isDependentContext() || B.builtAll()) &&
6701 "omp for simd loop exprs were not built");
6702
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00006703 if (!CurContext->isDependentContext()) {
6704 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006705 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00006706 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00006707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006708 B.NumIterations, *this, CurScope,
6709 DSAStack))
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00006710 return StmtError();
6711 }
6712 }
6713
Kelvin Lic5609492016-07-15 04:39:07 +00006714 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00006715 return StmtError();
6716
Reid Kleckner87a31802018-03-12 21:43:02 +00006717 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00006718 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
6719 Clauses, AStmt, B);
Alexander Musmanf82886e2014-09-18 05:12:34 +00006720}
6721
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006722StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
6723 Stmt *AStmt,
6724 SourceLocation StartLoc,
6725 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006726 if (!AStmt)
6727 return StmtError();
6728
6729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006730 auto BaseStmt = AStmt;
David Majnemer9d168222016-08-05 17:44:54 +00006731 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006732 BaseStmt = CS->getCapturedStmt();
David Majnemer9d168222016-08-05 17:44:54 +00006733 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006734 auto S = C->children();
Benjamin Kramer5733e352015-07-18 17:09:36 +00006735 if (S.begin() == S.end())
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006736 return StmtError();
6737 // All associated statements must be '#pragma omp section' except for
6738 // the first one.
Benjamin Kramer5733e352015-07-18 17:09:36 +00006739 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006740 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6741 if (SectionStmt)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006742 Diag(SectionStmt->getBeginLoc(),
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006743 diag::err_omp_sections_substmt_not_section);
6744 return StmtError();
6745 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00006746 cast<OMPSectionDirective>(SectionStmt)
6747 ->setHasCancel(DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006748 }
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006749 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006750 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006751 return StmtError();
6752 }
6753
Reid Kleckner87a31802018-03-12 21:43:02 +00006754 setFunctionHasBranchProtectedScope();
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006755
Alexey Bataev25e5b442015-09-15 12:52:43 +00006756 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6757 DSAStack->isCancelRegion());
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00006758}
6759
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006760StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
6761 SourceLocation StartLoc,
6762 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006763 if (!AStmt)
6764 return StmtError();
6765
6766 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006767
Reid Kleckner87a31802018-03-12 21:43:02 +00006768 setFunctionHasBranchProtectedScope();
Alexey Bataev25e5b442015-09-15 12:52:43 +00006769 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006770
Alexey Bataev25e5b442015-09-15 12:52:43 +00006771 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
6772 DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00006773}
6774
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00006775StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
6776 Stmt *AStmt,
6777 SourceLocation StartLoc,
6778 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006779 if (!AStmt)
6780 return StmtError();
6781
6782 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev74a05c92014-07-15 02:55:09 +00006783
Reid Kleckner87a31802018-03-12 21:43:02 +00006784 setFunctionHasBranchProtectedScope();
Alexey Bataev74a05c92014-07-15 02:55:09 +00006785
Alexey Bataev3255bf32015-01-19 05:20:46 +00006786 // OpenMP [2.7.3, single Construct, Restrictions]
6787 // The copyprivate clause must not be used with the nowait clause.
Alexey Bataeve3727102018-04-18 15:57:46 +00006788 const OMPClause *Nowait = nullptr;
6789 const OMPClause *Copyprivate = nullptr;
6790 for (const OMPClause *Clause : Clauses) {
Alexey Bataev3255bf32015-01-19 05:20:46 +00006791 if (Clause->getClauseKind() == OMPC_nowait)
6792 Nowait = Clause;
6793 else if (Clause->getClauseKind() == OMPC_copyprivate)
6794 Copyprivate = Clause;
6795 if (Copyprivate && Nowait) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006796 Diag(Copyprivate->getBeginLoc(),
Alexey Bataev3255bf32015-01-19 05:20:46 +00006797 diag::err_omp_single_copyprivate_with_nowait);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006798 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
Alexey Bataev3255bf32015-01-19 05:20:46 +00006799 return StmtError();
6800 }
6801 }
6802
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00006803 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6804}
6805
Alexander Musman80c22892014-07-17 08:54:58 +00006806StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
6807 SourceLocation StartLoc,
6808 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006809 if (!AStmt)
6810 return StmtError();
6811
6812 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musman80c22892014-07-17 08:54:58 +00006813
Reid Kleckner87a31802018-03-12 21:43:02 +00006814 setFunctionHasBranchProtectedScope();
Alexander Musman80c22892014-07-17 08:54:58 +00006815
6816 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
6817}
6818
Alexey Bataev28c75412015-12-15 08:19:24 +00006819StmtResult Sema::ActOnOpenMPCriticalDirective(
6820 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
6821 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006822 if (!AStmt)
6823 return StmtError();
6824
6825 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00006826
Alexey Bataev28c75412015-12-15 08:19:24 +00006827 bool ErrorFound = false;
6828 llvm::APSInt Hint;
6829 SourceLocation HintLoc;
6830 bool DependentHint = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00006831 for (const OMPClause *C : Clauses) {
Alexey Bataev28c75412015-12-15 08:19:24 +00006832 if (C->getClauseKind() == OMPC_hint) {
6833 if (!DirName.getName()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006834 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
Alexey Bataev28c75412015-12-15 08:19:24 +00006835 ErrorFound = true;
6836 }
6837 Expr *E = cast<OMPHintClause>(C)->getHint();
6838 if (E->isTypeDependent() || E->isValueDependent() ||
Alexey Bataeve3727102018-04-18 15:57:46 +00006839 E->isInstantiationDependent()) {
Alexey Bataev28c75412015-12-15 08:19:24 +00006840 DependentHint = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00006841 } else {
Alexey Bataev28c75412015-12-15 08:19:24 +00006842 Hint = E->EvaluateKnownConstInt(Context);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006843 HintLoc = C->getBeginLoc();
Alexey Bataev28c75412015-12-15 08:19:24 +00006844 }
6845 }
6846 }
6847 if (ErrorFound)
6848 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00006849 const auto Pair = DSAStack->getCriticalWithHint(DirName);
Alexey Bataev28c75412015-12-15 08:19:24 +00006850 if (Pair.first && DirName.getName() && !DependentHint) {
6851 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6852 Diag(StartLoc, diag::err_omp_critical_with_hint);
Alexey Bataeve3727102018-04-18 15:57:46 +00006853 if (HintLoc.isValid())
Alexey Bataev28c75412015-12-15 08:19:24 +00006854 Diag(HintLoc, diag::note_omp_critical_hint_here)
6855 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +00006856 else
Alexey Bataev28c75412015-12-15 08:19:24 +00006857 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
Alexey Bataeve3727102018-04-18 15:57:46 +00006858 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006859 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
Alexey Bataev28c75412015-12-15 08:19:24 +00006860 << 1
6861 << C->getHint()->EvaluateKnownConstInt(Context).toString(
6862 /*Radix=*/10, /*Signed=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +00006863 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006864 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
Alexey Bataeve3727102018-04-18 15:57:46 +00006865 }
Alexey Bataev28c75412015-12-15 08:19:24 +00006866 }
6867 }
6868
Reid Kleckner87a31802018-03-12 21:43:02 +00006869 setFunctionHasBranchProtectedScope();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00006870
Alexey Bataev28c75412015-12-15 08:19:24 +00006871 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
6872 Clauses, AStmt);
6873 if (!Pair.first && DirName.getName() && !DependentHint)
6874 DSAStack->addCriticalWithHint(Dir, Hint);
6875 return Dir;
Alexander Musmand9ed09f2014-07-21 09:42:05 +00006876}
6877
Alexey Bataev4acb8592014-07-07 13:01:15 +00006878StmtResult Sema::ActOnOpenMPParallelForDirective(
6879 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00006880 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006881 if (!AStmt)
6882 return StmtError();
6883
Alexey Bataeve3727102018-04-18 15:57:46 +00006884 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev4acb8592014-07-07 13:01:15 +00006885 // 1.2.2 OpenMP Language Terminology
6886 // Structured block - An executable statement with a single entry at the
6887 // top and a single exit at the bottom.
6888 // The point of exit cannot be a branch out of the structured block.
6889 // longjmp() and throw() must not violate the entry/exit criteria.
6890 CS->getCapturedDecl()->setNothrow();
6891
Alexander Musmanc6388682014-12-15 07:07:06 +00006892 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006893 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6894 // define the nested loops number.
Alexey Bataev4acb8592014-07-07 13:01:15 +00006895 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00006896 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00006897 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6898 VarsWithImplicitDSA, B);
Alexey Bataev4acb8592014-07-07 13:01:15 +00006899 if (NestedLoopCount == 0)
6900 return StmtError();
6901
Alexander Musmana5f070a2014-10-01 06:03:56 +00006902 assert((CurContext->isDependentContext() || B.builtAll()) &&
6903 "omp parallel for loop exprs were not built");
6904
Alexey Bataev54acd402015-08-04 11:18:19 +00006905 if (!CurContext->isDependentContext()) {
6906 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006907 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00006908 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev54acd402015-08-04 11:18:19 +00006909 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006910 B.NumIterations, *this, CurScope,
6911 DSAStack))
Alexey Bataev54acd402015-08-04 11:18:19 +00006912 return StmtError();
6913 }
6914 }
6915
Reid Kleckner87a31802018-03-12 21:43:02 +00006916 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00006917 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
Alexey Bataev25e5b442015-09-15 12:52:43 +00006918 NestedLoopCount, Clauses, AStmt, B,
6919 DSAStack->isCancelRegion());
Alexey Bataev4acb8592014-07-07 13:01:15 +00006920}
6921
Alexander Musmane4e893b2014-09-23 09:33:00 +00006922StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
6923 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00006924 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006925 if (!AStmt)
6926 return StmtError();
6927
Alexey Bataeve3727102018-04-18 15:57:46 +00006928 auto *CS = cast<CapturedStmt>(AStmt);
Alexander Musmane4e893b2014-09-23 09:33:00 +00006929 // 1.2.2 OpenMP Language Terminology
6930 // Structured block - An executable statement with a single entry at the
6931 // top and a single exit at the bottom.
6932 // The point of exit cannot be a branch out of the structured block.
6933 // longjmp() and throw() must not violate the entry/exit criteria.
6934 CS->getCapturedDecl()->setNothrow();
6935
Alexander Musmanc6388682014-12-15 07:07:06 +00006936 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006937 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6938 // define the nested loops number.
Alexander Musmane4e893b2014-09-23 09:33:00 +00006939 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00006940 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00006941 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6942 VarsWithImplicitDSA, B);
Alexander Musmane4e893b2014-09-23 09:33:00 +00006943 if (NestedLoopCount == 0)
6944 return StmtError();
6945
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00006946 if (!CurContext->isDependentContext()) {
6947 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006948 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00006949 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00006950 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006951 B.NumIterations, *this, CurScope,
6952 DSAStack))
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00006953 return StmtError();
6954 }
6955 }
6956
Kelvin Lic5609492016-07-15 04:39:07 +00006957 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00006958 return StmtError();
6959
Reid Kleckner87a31802018-03-12 21:43:02 +00006960 setFunctionHasBranchProtectedScope();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006961 return OMPParallelForSimdDirective::Create(
Alexander Musmanc6388682014-12-15 07:07:06 +00006962 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
Alexander Musmane4e893b2014-09-23 09:33:00 +00006963}
6964
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006965StmtResult
6966Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
6967 Stmt *AStmt, SourceLocation StartLoc,
6968 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00006969 if (!AStmt)
6970 return StmtError();
6971
6972 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006973 auto BaseStmt = AStmt;
David Majnemer9d168222016-08-05 17:44:54 +00006974 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006975 BaseStmt = CS->getCapturedStmt();
David Majnemer9d168222016-08-05 17:44:54 +00006976 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006977 auto S = C->children();
Benjamin Kramer5733e352015-07-18 17:09:36 +00006978 if (S.begin() == S.end())
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006979 return StmtError();
6980 // All associated statements must be '#pragma omp section' except for
6981 // the first one.
Benjamin Kramer5733e352015-07-18 17:09:36 +00006982 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006983 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6984 if (SectionStmt)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006985 Diag(SectionStmt->getBeginLoc(),
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006986 diag::err_omp_parallel_sections_substmt_not_section);
6987 return StmtError();
6988 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00006989 cast<OMPSectionDirective>(SectionStmt)
6990 ->setHasCancel(DSAStack->isCancelRegion());
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006991 }
6992 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006993 Diag(AStmt->getBeginLoc(),
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006994 diag::err_omp_parallel_sections_not_compound_stmt);
6995 return StmtError();
6996 }
6997
Reid Kleckner87a31802018-03-12 21:43:02 +00006998 setFunctionHasBranchProtectedScope();
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00006999
Alexey Bataev25e5b442015-09-15 12:52:43 +00007000 return OMPParallelSectionsDirective::Create(
7001 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00007002}
7003
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00007004StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
7005 Stmt *AStmt, SourceLocation StartLoc,
7006 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007007 if (!AStmt)
7008 return StmtError();
7009
David Majnemer9d168222016-08-05 17:44:54 +00007010 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00007011 // 1.2.2 OpenMP Language Terminology
7012 // Structured block - An executable statement with a single entry at the
7013 // top and a single exit at the bottom.
7014 // The point of exit cannot be a branch out of the structured block.
7015 // longjmp() and throw() must not violate the entry/exit criteria.
7016 CS->getCapturedDecl()->setNothrow();
7017
Reid Kleckner87a31802018-03-12 21:43:02 +00007018 setFunctionHasBranchProtectedScope();
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00007019
Alexey Bataev25e5b442015-09-15 12:52:43 +00007020 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7021 DSAStack->isCancelRegion());
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00007022}
7023
Alexey Bataev68446b72014-07-18 07:47:19 +00007024StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
7025 SourceLocation EndLoc) {
7026 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
7027}
7028
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00007029StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
7030 SourceLocation EndLoc) {
7031 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
7032}
7033
Alexey Bataev2df347a2014-07-18 10:17:07 +00007034StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
7035 SourceLocation EndLoc) {
7036 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
7037}
7038
Alexey Bataev169d96a2017-07-18 20:17:46 +00007039StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
7040 Stmt *AStmt,
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00007041 SourceLocation StartLoc,
7042 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007043 if (!AStmt)
7044 return StmtError();
7045
7046 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00007047
Reid Kleckner87a31802018-03-12 21:43:02 +00007048 setFunctionHasBranchProtectedScope();
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00007049
Alexey Bataev169d96a2017-07-18 20:17:46 +00007050 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00007051 AStmt,
7052 DSAStack->getTaskgroupReductionRef());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00007053}
7054
Alexey Bataev6125da92014-07-21 11:26:11 +00007055StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
7056 SourceLocation StartLoc,
7057 SourceLocation EndLoc) {
7058 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
7059 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
7060}
7061
Alexey Bataev346265e2015-09-25 10:37:12 +00007062StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
7063 Stmt *AStmt,
Alexey Bataev9fb6e642014-07-22 06:45:04 +00007064 SourceLocation StartLoc,
7065 SourceLocation EndLoc) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007066 const OMPClause *DependFound = nullptr;
7067 const OMPClause *DependSourceClause = nullptr;
7068 const OMPClause *DependSinkClause = nullptr;
Alexey Bataeveb482352015-12-18 05:05:56 +00007069 bool ErrorFound = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00007070 const OMPThreadsClause *TC = nullptr;
7071 const OMPSIMDClause *SC = nullptr;
7072 for (const OMPClause *C : Clauses) {
Alexey Bataeveb482352015-12-18 05:05:56 +00007073 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
7074 DependFound = C;
7075 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
7076 if (DependSourceClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007077 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
Alexey Bataeveb482352015-12-18 05:05:56 +00007078 << getOpenMPDirectiveName(OMPD_ordered)
7079 << getOpenMPClauseName(OMPC_depend) << 2;
7080 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007081 } else {
Alexey Bataeveb482352015-12-18 05:05:56 +00007082 DependSourceClause = C;
Alexey Bataeve3727102018-04-18 15:57:46 +00007083 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +00007084 if (DependSinkClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007085 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00007086 << 0;
7087 ErrorFound = true;
7088 }
7089 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
7090 if (DependSourceClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007091 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00007092 << 1;
7093 ErrorFound = true;
7094 }
7095 DependSinkClause = C;
Alexey Bataeveb482352015-12-18 05:05:56 +00007096 }
Alexey Bataeve3727102018-04-18 15:57:46 +00007097 } else if (C->getClauseKind() == OMPC_threads) {
Alexey Bataev346265e2015-09-25 10:37:12 +00007098 TC = cast<OMPThreadsClause>(C);
Alexey Bataeve3727102018-04-18 15:57:46 +00007099 } else if (C->getClauseKind() == OMPC_simd) {
Alexey Bataevd14d1e62015-09-28 06:39:35 +00007100 SC = cast<OMPSIMDClause>(C);
Alexey Bataeve3727102018-04-18 15:57:46 +00007101 }
Alexey Bataev346265e2015-09-25 10:37:12 +00007102 }
Alexey Bataeveb482352015-12-18 05:05:56 +00007103 if (!ErrorFound && !SC &&
7104 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
Alexey Bataevd14d1e62015-09-28 06:39:35 +00007105 // OpenMP [2.8.1,simd Construct, Restrictions]
7106 // An ordered construct with the simd clause is the only OpenMP construct
7107 // that can appear in the simd region.
7108 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
Alexey Bataeveb482352015-12-18 05:05:56 +00007109 ErrorFound = true;
7110 } else if (DependFound && (TC || SC)) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007111 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
Alexey Bataeveb482352015-12-18 05:05:56 +00007112 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
7113 ErrorFound = true;
Alexey Bataevf138fda2018-08-13 19:04:24 +00007114 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007115 Diag(DependFound->getBeginLoc(),
Alexey Bataeveb482352015-12-18 05:05:56 +00007116 diag::err_omp_ordered_directive_without_param);
7117 ErrorFound = true;
7118 } else if (TC || Clauses.empty()) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00007119 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007120 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
Alexey Bataeveb482352015-12-18 05:05:56 +00007121 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
7122 << (TC != nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007123 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
Alexey Bataeveb482352015-12-18 05:05:56 +00007124 ErrorFound = true;
7125 }
7126 }
7127 if ((!AStmt && !DependFound) || ErrorFound)
Alexey Bataevd14d1e62015-09-28 06:39:35 +00007128 return StmtError();
Alexey Bataeveb482352015-12-18 05:05:56 +00007129
7130 if (AStmt) {
7131 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7132
Reid Kleckner87a31802018-03-12 21:43:02 +00007133 setFunctionHasBranchProtectedScope();
Alexey Bataevd14d1e62015-09-28 06:39:35 +00007134 }
Alexey Bataev346265e2015-09-25 10:37:12 +00007135
7136 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00007137}
7138
Alexey Bataev1d160b12015-03-13 12:27:31 +00007139namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007140/// Helper class for checking expression in 'omp atomic [update]'
Alexey Bataev1d160b12015-03-13 12:27:31 +00007141/// construct.
7142class OpenMPAtomicUpdateChecker {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007143 /// Error results for atomic update expressions.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007144 enum ExprAnalysisErrorCode {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007145 /// A statement is not an expression statement.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007146 NotAnExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007147 /// Expression is not builtin binary or unary operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007148 NotABinaryOrUnaryExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007149 /// Unary operation is not post-/pre- increment/decrement operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007150 NotAnUnaryIncDecExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007151 /// An expression is not of scalar type.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007152 NotAScalarType,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007153 /// A binary operation is not an assignment operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007154 NotAnAssignmentOp,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007155 /// RHS part of the binary operation is not a binary expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007156 NotABinaryExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007157 /// RHS part is not additive/multiplicative/shift/biwise binary
Alexey Bataev1d160b12015-03-13 12:27:31 +00007158 /// expression.
7159 NotABinaryOperator,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007160 /// RHS binary operation does not have reference to the updated LHS
Alexey Bataev1d160b12015-03-13 12:27:31 +00007161 /// part.
7162 NotAnUpdateExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007163 /// No errors is found.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007164 NoError
7165 };
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007166 /// Reference to Sema.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007167 Sema &SemaRef;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007168 /// A location for note diagnostics (when error is found).
Alexey Bataev1d160b12015-03-13 12:27:31 +00007169 SourceLocation NoteLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007170 /// 'x' lvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007171 Expr *X;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007172 /// 'expr' rvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007173 Expr *E;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007174 /// Helper expression of the form
Alexey Bataevb4505a72015-03-30 05:20:59 +00007175 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
7176 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
7177 Expr *UpdateExpr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007178 /// Is 'x' a LHS in a RHS part of full update expression. It is
Alexey Bataevb4505a72015-03-30 05:20:59 +00007179 /// important for non-associative operations.
7180 bool IsXLHSInRHSPart;
7181 BinaryOperatorKind Op;
7182 SourceLocation OpLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007183 /// true if the source expression is a postfix unary operation, false
Alexey Bataevb78ca832015-04-01 03:33:17 +00007184 /// if it is a prefix unary operation.
7185 bool IsPostfixUpdate;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007186
7187public:
7188 OpenMPAtomicUpdateChecker(Sema &SemaRef)
Alexey Bataevb4505a72015-03-30 05:20:59 +00007189 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
Alexey Bataevb78ca832015-04-01 03:33:17 +00007190 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007191 /// Check specified statement that it is suitable for 'atomic update'
Alexey Bataev1d160b12015-03-13 12:27:31 +00007192 /// constructs and extract 'x', 'expr' and Operation from the original
Alexey Bataevb78ca832015-04-01 03:33:17 +00007193 /// expression. If DiagId and NoteId == 0, then only check is performed
7194 /// without error notification.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007195 /// \param DiagId Diagnostic which should be emitted if error is found.
7196 /// \param NoteId Diagnostic note for the main error message.
7197 /// \return true if statement is not an update expression, false otherwise.
Alexey Bataevb78ca832015-04-01 03:33:17 +00007198 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007199 /// Return the 'x' lvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007200 Expr *getX() const { return X; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007201 /// Return the 'expr' rvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00007202 Expr *getExpr() const { return E; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007203 /// Return the update expression used in calculation of the updated
Alexey Bataevb4505a72015-03-30 05:20:59 +00007204 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
7205 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
7206 Expr *getUpdateExpr() const { return UpdateExpr; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007207 /// Return true if 'x' is LHS in RHS part of full update expression,
Alexey Bataevb4505a72015-03-30 05:20:59 +00007208 /// false otherwise.
7209 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
7210
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007211 /// true if the source expression is a postfix unary operation, false
Alexey Bataevb78ca832015-04-01 03:33:17 +00007212 /// if it is a prefix unary operation.
7213 bool isPostfixUpdate() const { return IsPostfixUpdate; }
7214
Alexey Bataev1d160b12015-03-13 12:27:31 +00007215private:
Alexey Bataevb78ca832015-04-01 03:33:17 +00007216 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
7217 unsigned NoteId = 0);
Alexey Bataev1d160b12015-03-13 12:27:31 +00007218};
7219} // namespace
7220
7221bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
7222 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
7223 ExprAnalysisErrorCode ErrorFound = NoError;
7224 SourceLocation ErrorLoc, NoteLoc;
7225 SourceRange ErrorRange, NoteRange;
7226 // Allowed constructs are:
7227 // x = x binop expr;
7228 // x = expr binop x;
7229 if (AtomicBinOp->getOpcode() == BO_Assign) {
7230 X = AtomicBinOp->getLHS();
Alexey Bataeve3727102018-04-18 15:57:46 +00007231 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
Alexey Bataev1d160b12015-03-13 12:27:31 +00007232 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
7233 if (AtomicInnerBinOp->isMultiplicativeOp() ||
7234 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
7235 AtomicInnerBinOp->isBitwiseOp()) {
Alexey Bataevb4505a72015-03-30 05:20:59 +00007236 Op = AtomicInnerBinOp->getOpcode();
7237 OpLoc = AtomicInnerBinOp->getOperatorLoc();
Alexey Bataeve3727102018-04-18 15:57:46 +00007238 Expr *LHS = AtomicInnerBinOp->getLHS();
7239 Expr *RHS = AtomicInnerBinOp->getRHS();
Alexey Bataev1d160b12015-03-13 12:27:31 +00007240 llvm::FoldingSetNodeID XId, LHSId, RHSId;
7241 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
7242 /*Canonical=*/true);
7243 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
7244 /*Canonical=*/true);
7245 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
7246 /*Canonical=*/true);
7247 if (XId == LHSId) {
7248 E = RHS;
Alexey Bataevb4505a72015-03-30 05:20:59 +00007249 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007250 } else if (XId == RHSId) {
7251 E = LHS;
Alexey Bataevb4505a72015-03-30 05:20:59 +00007252 IsXLHSInRHSPart = false;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007253 } else {
7254 ErrorLoc = AtomicInnerBinOp->getExprLoc();
7255 ErrorRange = AtomicInnerBinOp->getSourceRange();
7256 NoteLoc = X->getExprLoc();
7257 NoteRange = X->getSourceRange();
7258 ErrorFound = NotAnUpdateExpression;
7259 }
7260 } else {
7261 ErrorLoc = AtomicInnerBinOp->getExprLoc();
7262 ErrorRange = AtomicInnerBinOp->getSourceRange();
7263 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
7264 NoteRange = SourceRange(NoteLoc, NoteLoc);
7265 ErrorFound = NotABinaryOperator;
7266 }
7267 } else {
7268 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
7269 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
7270 ErrorFound = NotABinaryExpression;
7271 }
7272 } else {
7273 ErrorLoc = AtomicBinOp->getExprLoc();
7274 ErrorRange = AtomicBinOp->getSourceRange();
7275 NoteLoc = AtomicBinOp->getOperatorLoc();
7276 NoteRange = SourceRange(NoteLoc, NoteLoc);
7277 ErrorFound = NotAnAssignmentOp;
7278 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00007279 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00007280 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
7281 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
7282 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007283 }
7284 if (SemaRef.CurContext->isDependentContext())
Alexey Bataevb4505a72015-03-30 05:20:59 +00007285 E = X = UpdateExpr = nullptr;
Alexey Bataev5e018f92015-04-23 06:35:10 +00007286 return ErrorFound != NoError;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007287}
7288
7289bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
7290 unsigned NoteId) {
7291 ExprAnalysisErrorCode ErrorFound = NoError;
7292 SourceLocation ErrorLoc, NoteLoc;
7293 SourceRange ErrorRange, NoteRange;
7294 // Allowed constructs are:
7295 // x++;
7296 // x--;
7297 // ++x;
7298 // --x;
7299 // x binop= expr;
7300 // x = x binop expr;
7301 // x = expr binop x;
7302 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
7303 AtomicBody = AtomicBody->IgnoreParenImpCasts();
7304 if (AtomicBody->getType()->isScalarType() ||
7305 AtomicBody->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007306 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
Alexey Bataev1d160b12015-03-13 12:27:31 +00007307 AtomicBody->IgnoreParenImpCasts())) {
7308 // Check for Compound Assignment Operation
Alexey Bataevb4505a72015-03-30 05:20:59 +00007309 Op = BinaryOperator::getOpForCompoundAssignment(
Alexey Bataev1d160b12015-03-13 12:27:31 +00007310 AtomicCompAssignOp->getOpcode());
Alexey Bataevb4505a72015-03-30 05:20:59 +00007311 OpLoc = AtomicCompAssignOp->getOperatorLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00007312 E = AtomicCompAssignOp->getRHS();
Kelvin Li4f161cf2016-07-20 19:41:17 +00007313 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
Alexey Bataevb4505a72015-03-30 05:20:59 +00007314 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007315 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
7316 AtomicBody->IgnoreParenImpCasts())) {
7317 // Check for Binary Operation
David Majnemer9d168222016-08-05 17:44:54 +00007318 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
Alexey Bataevb4505a72015-03-30 05:20:59 +00007319 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007320 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
David Majnemer9d168222016-08-05 17:44:54 +00007321 AtomicBody->IgnoreParenImpCasts())) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00007322 // Check for Unary Operation
7323 if (AtomicUnaryOp->isIncrementDecrementOp()) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007324 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
Alexey Bataevb4505a72015-03-30 05:20:59 +00007325 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
7326 OpLoc = AtomicUnaryOp->getOperatorLoc();
Kelvin Li4f161cf2016-07-20 19:41:17 +00007327 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
Alexey Bataevb4505a72015-03-30 05:20:59 +00007328 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
7329 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007330 } else {
7331 ErrorFound = NotAnUnaryIncDecExpression;
7332 ErrorLoc = AtomicUnaryOp->getExprLoc();
7333 ErrorRange = AtomicUnaryOp->getSourceRange();
7334 NoteLoc = AtomicUnaryOp->getOperatorLoc();
7335 NoteRange = SourceRange(NoteLoc, NoteLoc);
7336 }
Alexey Bataev5a195472015-09-04 12:55:50 +00007337 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00007338 ErrorFound = NotABinaryOrUnaryExpression;
7339 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
7340 NoteRange = ErrorRange = AtomicBody->getSourceRange();
7341 }
7342 } else {
7343 ErrorFound = NotAScalarType;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007344 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00007345 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
7346 }
7347 } else {
7348 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007349 NoteLoc = ErrorLoc = S->getBeginLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00007350 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
7351 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00007352 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00007353 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
7354 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
7355 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007356 }
7357 if (SemaRef.CurContext->isDependentContext())
Alexey Bataevb4505a72015-03-30 05:20:59 +00007358 E = X = UpdateExpr = nullptr;
Alexey Bataev5e018f92015-04-23 06:35:10 +00007359 if (ErrorFound == NoError && E && X) {
Alexey Bataevb4505a72015-03-30 05:20:59 +00007360 // Build an update expression of form 'OpaqueValueExpr(x) binop
7361 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
7362 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
7363 auto *OVEX = new (SemaRef.getASTContext())
7364 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
7365 auto *OVEExpr = new (SemaRef.getASTContext())
7366 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
Alexey Bataeve3727102018-04-18 15:57:46 +00007367 ExprResult Update =
Alexey Bataevb4505a72015-03-30 05:20:59 +00007368 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
7369 IsXLHSInRHSPart ? OVEExpr : OVEX);
7370 if (Update.isInvalid())
7371 return true;
7372 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
7373 Sema::AA_Casting);
7374 if (Update.isInvalid())
7375 return true;
7376 UpdateExpr = Update.get();
7377 }
Alexey Bataev5e018f92015-04-23 06:35:10 +00007378 return ErrorFound != NoError;
Alexey Bataev1d160b12015-03-13 12:27:31 +00007379}
7380
Alexey Bataev0162e452014-07-22 10:10:35 +00007381StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
7382 Stmt *AStmt,
7383 SourceLocation StartLoc,
7384 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007385 if (!AStmt)
7386 return StmtError();
7387
David Majnemer9d168222016-08-05 17:44:54 +00007388 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev0162e452014-07-22 10:10:35 +00007389 // 1.2.2 OpenMP Language Terminology
7390 // Structured block - An executable statement with a single entry at the
7391 // top and a single exit at the bottom.
7392 // The point of exit cannot be a branch out of the structured block.
7393 // longjmp() and throw() must not violate the entry/exit criteria.
Alexey Bataevdea47612014-07-23 07:46:59 +00007394 OpenMPClauseKind AtomicKind = OMPC_unknown;
7395 SourceLocation AtomicKindLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +00007396 for (const OMPClause *C : Clauses) {
Alexey Bataev67a4f222014-07-23 10:25:33 +00007397 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
Alexey Bataev459dec02014-07-24 06:46:57 +00007398 C->getClauseKind() == OMPC_update ||
7399 C->getClauseKind() == OMPC_capture) {
Alexey Bataevdea47612014-07-23 07:46:59 +00007400 if (AtomicKind != OMPC_unknown) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007401 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00007402 << SourceRange(C->getBeginLoc(), C->getEndLoc());
Alexey Bataevdea47612014-07-23 07:46:59 +00007403 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
7404 << getOpenMPClauseName(AtomicKind);
7405 } else {
7406 AtomicKind = C->getClauseKind();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007407 AtomicKindLoc = C->getBeginLoc();
Alexey Bataevf98b00c2014-07-23 02:27:21 +00007408 }
7409 }
7410 }
Alexey Bataev62cec442014-11-18 10:14:22 +00007411
Alexey Bataeve3727102018-04-18 15:57:46 +00007412 Stmt *Body = CS->getCapturedStmt();
Alexey Bataev10fec572015-03-11 04:48:56 +00007413 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
7414 Body = EWC->getSubExpr();
7415
Alexey Bataev62cec442014-11-18 10:14:22 +00007416 Expr *X = nullptr;
7417 Expr *V = nullptr;
7418 Expr *E = nullptr;
Alexey Bataevb4505a72015-03-30 05:20:59 +00007419 Expr *UE = nullptr;
7420 bool IsXLHSInRHSPart = false;
Alexey Bataevb78ca832015-04-01 03:33:17 +00007421 bool IsPostfixUpdate = false;
Alexey Bataev62cec442014-11-18 10:14:22 +00007422 // OpenMP [2.12.6, atomic Construct]
7423 // In the next expressions:
7424 // * x and v (as applicable) are both l-value expressions with scalar type.
7425 // * During the execution of an atomic region, multiple syntactic
7426 // occurrences of x must designate the same storage location.
7427 // * Neither of v and expr (as applicable) may access the storage location
7428 // designated by x.
7429 // * Neither of x and expr (as applicable) may access the storage location
7430 // designated by v.
7431 // * expr is an expression with scalar type.
7432 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
7433 // * binop, binop=, ++, and -- are not overloaded operators.
7434 // * The expression x binop expr must be numerically equivalent to x binop
7435 // (expr). This requirement is satisfied if the operators in expr have
7436 // precedence greater than binop, or by using parentheses around expr or
7437 // subexpressions of expr.
7438 // * The expression expr binop x must be numerically equivalent to (expr)
7439 // binop x. This requirement is satisfied if the operators in expr have
7440 // precedence equal to or greater than binop, or by using parentheses around
7441 // expr or subexpressions of expr.
7442 // * For forms that allow multiple occurrences of x, the number of times
7443 // that x is evaluated is unspecified.
Alexey Bataevdea47612014-07-23 07:46:59 +00007444 if (AtomicKind == OMPC_read) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007445 enum {
7446 NotAnExpression,
7447 NotAnAssignmentOp,
7448 NotAScalarType,
7449 NotAnLValue,
7450 NoError
7451 } ErrorFound = NoError;
Alexey Bataev62cec442014-11-18 10:14:22 +00007452 SourceLocation ErrorLoc, NoteLoc;
7453 SourceRange ErrorRange, NoteRange;
7454 // If clause is read:
7455 // v = x;
Alexey Bataeve3727102018-04-18 15:57:46 +00007456 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7457 const auto *AtomicBinOp =
Alexey Bataev62cec442014-11-18 10:14:22 +00007458 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7459 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
7460 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
7461 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
7462 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
7463 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
7464 if (!X->isLValue() || !V->isLValue()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007465 const Expr *NotLValueExpr = X->isLValue() ? V : X;
Alexey Bataev62cec442014-11-18 10:14:22 +00007466 ErrorFound = NotAnLValue;
7467 ErrorLoc = AtomicBinOp->getExprLoc();
7468 ErrorRange = AtomicBinOp->getSourceRange();
7469 NoteLoc = NotLValueExpr->getExprLoc();
7470 NoteRange = NotLValueExpr->getSourceRange();
7471 }
7472 } else if (!X->isInstantiationDependent() ||
7473 !V->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007474 const Expr *NotScalarExpr =
Alexey Bataev62cec442014-11-18 10:14:22 +00007475 (X->isInstantiationDependent() || X->getType()->isScalarType())
7476 ? V
7477 : X;
7478 ErrorFound = NotAScalarType;
7479 ErrorLoc = AtomicBinOp->getExprLoc();
7480 ErrorRange = AtomicBinOp->getSourceRange();
7481 NoteLoc = NotScalarExpr->getExprLoc();
7482 NoteRange = NotScalarExpr->getSourceRange();
7483 }
Alexey Bataev5a195472015-09-04 12:55:50 +00007484 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataev62cec442014-11-18 10:14:22 +00007485 ErrorFound = NotAnAssignmentOp;
7486 ErrorLoc = AtomicBody->getExprLoc();
7487 ErrorRange = AtomicBody->getSourceRange();
7488 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7489 : AtomicBody->getExprLoc();
7490 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7491 : AtomicBody->getSourceRange();
7492 }
7493 } else {
7494 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007495 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataev62cec442014-11-18 10:14:22 +00007496 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
Alexey Bataevdea47612014-07-23 07:46:59 +00007497 }
Alexey Bataev62cec442014-11-18 10:14:22 +00007498 if (ErrorFound != NoError) {
7499 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
7500 << ErrorRange;
Alexey Bataevf33eba62014-11-28 07:21:40 +00007501 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7502 << NoteRange;
Alexey Bataev62cec442014-11-18 10:14:22 +00007503 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00007504 }
7505 if (CurContext->isDependentContext())
Alexey Bataev62cec442014-11-18 10:14:22 +00007506 V = X = nullptr;
Alexey Bataevdea47612014-07-23 07:46:59 +00007507 } else if (AtomicKind == OMPC_write) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007508 enum {
7509 NotAnExpression,
7510 NotAnAssignmentOp,
7511 NotAScalarType,
7512 NotAnLValue,
7513 NoError
7514 } ErrorFound = NoError;
Alexey Bataevf33eba62014-11-28 07:21:40 +00007515 SourceLocation ErrorLoc, NoteLoc;
7516 SourceRange ErrorRange, NoteRange;
7517 // If clause is write:
7518 // x = expr;
Alexey Bataeve3727102018-04-18 15:57:46 +00007519 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7520 const auto *AtomicBinOp =
Alexey Bataevf33eba62014-11-28 07:21:40 +00007521 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7522 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
Alexey Bataevb8329262015-02-27 06:33:30 +00007523 X = AtomicBinOp->getLHS();
7524 E = AtomicBinOp->getRHS();
Alexey Bataevf33eba62014-11-28 07:21:40 +00007525 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
7526 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
7527 if (!X->isLValue()) {
7528 ErrorFound = NotAnLValue;
7529 ErrorLoc = AtomicBinOp->getExprLoc();
7530 ErrorRange = AtomicBinOp->getSourceRange();
7531 NoteLoc = X->getExprLoc();
7532 NoteRange = X->getSourceRange();
7533 }
7534 } else if (!X->isInstantiationDependent() ||
7535 !E->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007536 const Expr *NotScalarExpr =
Alexey Bataevf33eba62014-11-28 07:21:40 +00007537 (X->isInstantiationDependent() || X->getType()->isScalarType())
7538 ? E
7539 : X;
7540 ErrorFound = NotAScalarType;
7541 ErrorLoc = AtomicBinOp->getExprLoc();
7542 ErrorRange = AtomicBinOp->getSourceRange();
7543 NoteLoc = NotScalarExpr->getExprLoc();
7544 NoteRange = NotScalarExpr->getSourceRange();
7545 }
Alexey Bataev5a195472015-09-04 12:55:50 +00007546 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataevf33eba62014-11-28 07:21:40 +00007547 ErrorFound = NotAnAssignmentOp;
7548 ErrorLoc = AtomicBody->getExprLoc();
7549 ErrorRange = AtomicBody->getSourceRange();
7550 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7551 : AtomicBody->getExprLoc();
7552 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7553 : AtomicBody->getSourceRange();
7554 }
7555 } else {
7556 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007557 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevf33eba62014-11-28 07:21:40 +00007558 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
Alexey Bataevdea47612014-07-23 07:46:59 +00007559 }
Alexey Bataevf33eba62014-11-28 07:21:40 +00007560 if (ErrorFound != NoError) {
7561 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
7562 << ErrorRange;
7563 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7564 << NoteRange;
7565 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00007566 }
7567 if (CurContext->isDependentContext())
Alexey Bataevf33eba62014-11-28 07:21:40 +00007568 E = X = nullptr;
Alexey Bataev67a4f222014-07-23 10:25:33 +00007569 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00007570 // If clause is update:
7571 // x++;
7572 // x--;
7573 // ++x;
7574 // --x;
7575 // x binop= expr;
7576 // x = x binop expr;
7577 // x = expr binop x;
7578 OpenMPAtomicUpdateChecker Checker(*this);
7579 if (Checker.checkStatement(
7580 Body, (AtomicKind == OMPC_update)
7581 ? diag::err_omp_atomic_update_not_expression_statement
7582 : diag::err_omp_atomic_not_expression_statement,
7583 diag::note_omp_atomic_update))
Alexey Bataev67a4f222014-07-23 10:25:33 +00007584 return StmtError();
Alexey Bataev1d160b12015-03-13 12:27:31 +00007585 if (!CurContext->isDependentContext()) {
7586 E = Checker.getExpr();
7587 X = Checker.getX();
Alexey Bataevb4505a72015-03-30 05:20:59 +00007588 UE = Checker.getUpdateExpr();
7589 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev67a4f222014-07-23 10:25:33 +00007590 }
Alexey Bataev459dec02014-07-24 06:46:57 +00007591 } else if (AtomicKind == OMPC_capture) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007592 enum {
7593 NotAnAssignmentOp,
7594 NotACompoundStatement,
7595 NotTwoSubstatements,
7596 NotASpecificExpression,
7597 NoError
7598 } ErrorFound = NoError;
7599 SourceLocation ErrorLoc, NoteLoc;
7600 SourceRange ErrorRange, NoteRange;
Alexey Bataeve3727102018-04-18 15:57:46 +00007601 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007602 // If clause is a capture:
7603 // v = x++;
7604 // v = x--;
7605 // v = ++x;
7606 // v = --x;
7607 // v = x binop= expr;
7608 // v = x = x binop expr;
7609 // v = x = expr binop x;
Alexey Bataeve3727102018-04-18 15:57:46 +00007610 const auto *AtomicBinOp =
Alexey Bataevb78ca832015-04-01 03:33:17 +00007611 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
7612 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
7613 V = AtomicBinOp->getLHS();
7614 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
7615 OpenMPAtomicUpdateChecker Checker(*this);
7616 if (Checker.checkStatement(
7617 Body, diag::err_omp_atomic_capture_not_expression_statement,
7618 diag::note_omp_atomic_update))
7619 return StmtError();
7620 E = Checker.getExpr();
7621 X = Checker.getX();
7622 UE = Checker.getUpdateExpr();
7623 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7624 IsPostfixUpdate = Checker.isPostfixUpdate();
Alexey Bataev5a195472015-09-04 12:55:50 +00007625 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007626 ErrorLoc = AtomicBody->getExprLoc();
7627 ErrorRange = AtomicBody->getSourceRange();
7628 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
7629 : AtomicBody->getExprLoc();
7630 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
7631 : AtomicBody->getSourceRange();
7632 ErrorFound = NotAnAssignmentOp;
7633 }
7634 if (ErrorFound != NoError) {
7635 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
7636 << ErrorRange;
7637 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7638 return StmtError();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007639 }
Alexey Bataeve3727102018-04-18 15:57:46 +00007640 if (CurContext->isDependentContext())
7641 UE = V = E = X = nullptr;
Alexey Bataevb78ca832015-04-01 03:33:17 +00007642 } else {
7643 // If clause is a capture:
7644 // { v = x; x = expr; }
7645 // { v = x; x++; }
7646 // { v = x; x--; }
7647 // { v = x; ++x; }
7648 // { v = x; --x; }
7649 // { v = x; x binop= expr; }
7650 // { v = x; x = x binop expr; }
7651 // { v = x; x = expr binop x; }
7652 // { x++; v = x; }
7653 // { x--; v = x; }
7654 // { ++x; v = x; }
7655 // { --x; v = x; }
7656 // { x binop= expr; v = x; }
7657 // { x = x binop expr; v = x; }
7658 // { x = expr binop x; v = x; }
7659 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
7660 // Check that this is { expr1; expr2; }
7661 if (CS->size() == 2) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007662 Stmt *First = CS->body_front();
7663 Stmt *Second = CS->body_back();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007664 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
7665 First = EWC->getSubExpr()->IgnoreParenImpCasts();
7666 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
7667 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
7668 // Need to find what subexpression is 'v' and what is 'x'.
7669 OpenMPAtomicUpdateChecker Checker(*this);
7670 bool IsUpdateExprFound = !Checker.checkStatement(Second);
7671 BinaryOperator *BinOp = nullptr;
7672 if (IsUpdateExprFound) {
7673 BinOp = dyn_cast<BinaryOperator>(First);
7674 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
7675 }
7676 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7677 // { v = x; x++; }
7678 // { v = x; x--; }
7679 // { v = x; ++x; }
7680 // { v = x; --x; }
7681 // { v = x; x binop= expr; }
7682 // { v = x; x = x binop expr; }
7683 // { v = x; x = expr binop x; }
7684 // Check that the first expression has form v = x.
Alexey Bataeve3727102018-04-18 15:57:46 +00007685 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007686 llvm::FoldingSetNodeID XId, PossibleXId;
7687 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
7688 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
7689 IsUpdateExprFound = XId == PossibleXId;
7690 if (IsUpdateExprFound) {
7691 V = BinOp->getLHS();
7692 X = Checker.getX();
7693 E = Checker.getExpr();
7694 UE = Checker.getUpdateExpr();
7695 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev5e018f92015-04-23 06:35:10 +00007696 IsPostfixUpdate = true;
Alexey Bataevb78ca832015-04-01 03:33:17 +00007697 }
7698 }
7699 if (!IsUpdateExprFound) {
7700 IsUpdateExprFound = !Checker.checkStatement(First);
7701 BinOp = nullptr;
7702 if (IsUpdateExprFound) {
7703 BinOp = dyn_cast<BinaryOperator>(Second);
7704 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
7705 }
7706 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7707 // { x++; v = x; }
7708 // { x--; v = x; }
7709 // { ++x; v = x; }
7710 // { --x; v = x; }
7711 // { x binop= expr; v = x; }
7712 // { x = x binop expr; v = x; }
7713 // { x = expr binop x; v = x; }
7714 // Check that the second expression has form v = x.
Alexey Bataeve3727102018-04-18 15:57:46 +00007715 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007716 llvm::FoldingSetNodeID XId, PossibleXId;
7717 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
7718 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
7719 IsUpdateExprFound = XId == PossibleXId;
7720 if (IsUpdateExprFound) {
7721 V = BinOp->getLHS();
7722 X = Checker.getX();
7723 E = Checker.getExpr();
7724 UE = Checker.getUpdateExpr();
7725 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev5e018f92015-04-23 06:35:10 +00007726 IsPostfixUpdate = false;
Alexey Bataevb78ca832015-04-01 03:33:17 +00007727 }
7728 }
7729 }
7730 if (!IsUpdateExprFound) {
7731 // { v = x; x = expr; }
Alexey Bataev5a195472015-09-04 12:55:50 +00007732 auto *FirstExpr = dyn_cast<Expr>(First);
7733 auto *SecondExpr = dyn_cast<Expr>(Second);
7734 if (!FirstExpr || !SecondExpr ||
7735 !(FirstExpr->isInstantiationDependent() ||
7736 SecondExpr->isInstantiationDependent())) {
7737 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
7738 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00007739 ErrorFound = NotAnAssignmentOp;
Alexey Bataev5a195472015-09-04 12:55:50 +00007740 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007741 : First->getBeginLoc();
Alexey Bataev5a195472015-09-04 12:55:50 +00007742 NoteRange = ErrorRange = FirstBinOp
7743 ? FirstBinOp->getSourceRange()
Alexey Bataevb78ca832015-04-01 03:33:17 +00007744 : SourceRange(ErrorLoc, ErrorLoc);
7745 } else {
Alexey Bataev5a195472015-09-04 12:55:50 +00007746 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
7747 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
7748 ErrorFound = NotAnAssignmentOp;
7749 NoteLoc = ErrorLoc = SecondBinOp
7750 ? SecondBinOp->getOperatorLoc()
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007751 : Second->getBeginLoc();
Alexey Bataev5a195472015-09-04 12:55:50 +00007752 NoteRange = ErrorRange =
7753 SecondBinOp ? SecondBinOp->getSourceRange()
7754 : SourceRange(ErrorLoc, ErrorLoc);
Alexey Bataevb78ca832015-04-01 03:33:17 +00007755 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +00007756 Expr *PossibleXRHSInFirst =
Alexey Bataev5a195472015-09-04 12:55:50 +00007757 FirstBinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00007758 Expr *PossibleXLHSInSecond =
Alexey Bataev5a195472015-09-04 12:55:50 +00007759 SecondBinOp->getLHS()->IgnoreParenImpCasts();
7760 llvm::FoldingSetNodeID X1Id, X2Id;
7761 PossibleXRHSInFirst->Profile(X1Id, Context,
7762 /*Canonical=*/true);
7763 PossibleXLHSInSecond->Profile(X2Id, Context,
7764 /*Canonical=*/true);
7765 IsUpdateExprFound = X1Id == X2Id;
7766 if (IsUpdateExprFound) {
7767 V = FirstBinOp->getLHS();
7768 X = SecondBinOp->getLHS();
7769 E = SecondBinOp->getRHS();
7770 UE = nullptr;
7771 IsXLHSInRHSPart = false;
7772 IsPostfixUpdate = true;
7773 } else {
7774 ErrorFound = NotASpecificExpression;
7775 ErrorLoc = FirstBinOp->getExprLoc();
7776 ErrorRange = FirstBinOp->getSourceRange();
7777 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
7778 NoteRange = SecondBinOp->getRHS()->getSourceRange();
7779 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00007780 }
7781 }
7782 }
7783 }
7784 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007785 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007786 NoteRange = ErrorRange =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007787 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
Alexey Bataevb78ca832015-04-01 03:33:17 +00007788 ErrorFound = NotTwoSubstatements;
7789 }
7790 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007791 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007792 NoteRange = ErrorRange =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007793 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
Alexey Bataevb78ca832015-04-01 03:33:17 +00007794 ErrorFound = NotACompoundStatement;
7795 }
7796 if (ErrorFound != NoError) {
7797 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
7798 << ErrorRange;
7799 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7800 return StmtError();
Alexey Bataevb78ca832015-04-01 03:33:17 +00007801 }
Alexey Bataeve3727102018-04-18 15:57:46 +00007802 if (CurContext->isDependentContext())
7803 UE = V = E = X = nullptr;
Alexey Bataev459dec02014-07-24 06:46:57 +00007804 }
Alexey Bataevdea47612014-07-23 07:46:59 +00007805 }
Alexey Bataev0162e452014-07-22 10:10:35 +00007806
Reid Kleckner87a31802018-03-12 21:43:02 +00007807 setFunctionHasBranchProtectedScope();
Alexey Bataev0162e452014-07-22 10:10:35 +00007808
Alexey Bataev62cec442014-11-18 10:14:22 +00007809 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
Alexey Bataevb78ca832015-04-01 03:33:17 +00007810 X, V, E, UE, IsXLHSInRHSPart,
7811 IsPostfixUpdate);
Alexey Bataev0162e452014-07-22 10:10:35 +00007812}
7813
Alexey Bataev0bd520b2014-09-19 08:19:49 +00007814StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
7815 Stmt *AStmt,
7816 SourceLocation StartLoc,
7817 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007818 if (!AStmt)
7819 return StmtError();
7820
Alexey Bataeve3727102018-04-18 15:57:46 +00007821 auto *CS = cast<CapturedStmt>(AStmt);
Samuel Antao4af1b7b2015-12-02 17:44:43 +00007822 // 1.2.2 OpenMP Language Terminology
7823 // Structured block - An executable statement with a single entry at the
7824 // top and a single exit at the bottom.
7825 // The point of exit cannot be a branch out of the structured block.
7826 // longjmp() and throw() must not violate the entry/exit criteria.
7827 CS->getCapturedDecl()->setNothrow();
Alexey Bataev8451efa2018-01-15 19:06:12 +00007828 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
7829 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7830 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7831 // 1.2.2 OpenMP Language Terminology
7832 // Structured block - An executable statement with a single entry at the
7833 // top and a single exit at the bottom.
7834 // The point of exit cannot be a branch out of the structured block.
7835 // longjmp() and throw() must not violate the entry/exit criteria.
7836 CS->getCapturedDecl()->setNothrow();
7837 }
Alexey Bataev0bd520b2014-09-19 08:19:49 +00007838
Alexey Bataev13314bf2014-10-09 04:18:56 +00007839 // OpenMP [2.16, Nesting of Regions]
7840 // If specified, a teams construct must be contained within a target
7841 // construct. That target construct must contain no statements or directives
7842 // outside of the teams construct.
7843 if (DSAStack->hasInnerTeamsRegion()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007844 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
Alexey Bataev13314bf2014-10-09 04:18:56 +00007845 bool OMPTeamsFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007846 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00007847 auto I = CS->body_begin();
7848 while (I != CS->body_end()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007849 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
Kelvin Li620ba602019-02-05 16:43:00 +00007850 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
7851 OMPTeamsFound) {
7852
Alexey Bataev13314bf2014-10-09 04:18:56 +00007853 OMPTeamsFound = false;
7854 break;
7855 }
7856 ++I;
7857 }
7858 assert(I != CS->body_end() && "Not found statement");
7859 S = *I;
Kelvin Li3834dce2016-06-27 19:15:43 +00007860 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +00007861 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
Kelvin Li3834dce2016-06-27 19:15:43 +00007862 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
Alexey Bataev13314bf2014-10-09 04:18:56 +00007863 }
7864 if (!OMPTeamsFound) {
7865 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7866 Diag(DSAStack->getInnerTeamsRegionLoc(),
7867 diag::note_omp_nested_teams_construct_here);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007868 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
Alexey Bataev13314bf2014-10-09 04:18:56 +00007869 << isa<OMPExecutableDirective>(S);
7870 return StmtError();
7871 }
7872 }
7873
Reid Kleckner87a31802018-03-12 21:43:02 +00007874 setFunctionHasBranchProtectedScope();
Alexey Bataev0bd520b2014-09-19 08:19:49 +00007875
7876 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7877}
7878
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00007879StmtResult
7880Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
7881 Stmt *AStmt, SourceLocation StartLoc,
7882 SourceLocation EndLoc) {
7883 if (!AStmt)
7884 return StmtError();
7885
Alexey Bataeve3727102018-04-18 15:57:46 +00007886 auto *CS = cast<CapturedStmt>(AStmt);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00007887 // 1.2.2 OpenMP Language Terminology
7888 // Structured block - An executable statement with a single entry at the
7889 // top and a single exit at the bottom.
7890 // The point of exit cannot be a branch out of the structured block.
7891 // longjmp() and throw() must not violate the entry/exit criteria.
7892 CS->getCapturedDecl()->setNothrow();
Alexey Bataev8451efa2018-01-15 19:06:12 +00007893 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7894 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7895 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7896 // 1.2.2 OpenMP Language Terminology
7897 // Structured block - An executable statement with a single entry at the
7898 // top and a single exit at the bottom.
7899 // The point of exit cannot be a branch out of the structured block.
7900 // longjmp() and throw() must not violate the entry/exit criteria.
7901 CS->getCapturedDecl()->setNothrow();
7902 }
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00007903
Reid Kleckner87a31802018-03-12 21:43:02 +00007904 setFunctionHasBranchProtectedScope();
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00007905
7906 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7907 AStmt);
7908}
7909
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007910StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
7911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00007912 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007913 if (!AStmt)
7914 return StmtError();
7915
Alexey Bataeve3727102018-04-18 15:57:46 +00007916 auto *CS = cast<CapturedStmt>(AStmt);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007917 // 1.2.2 OpenMP Language Terminology
7918 // Structured block - An executable statement with a single entry at the
7919 // top and a single exit at the bottom.
7920 // The point of exit cannot be a branch out of the structured block.
7921 // longjmp() and throw() must not violate the entry/exit criteria.
7922 CS->getCapturedDecl()->setNothrow();
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00007923 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7924 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7925 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7926 // 1.2.2 OpenMP Language Terminology
7927 // Structured block - An executable statement with a single entry at the
7928 // top and a single exit at the bottom.
7929 // The point of exit cannot be a branch out of the structured block.
7930 // longjmp() and throw() must not violate the entry/exit criteria.
7931 CS->getCapturedDecl()->setNothrow();
7932 }
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007933
7934 OMPLoopDirective::HelperExprs B;
7935 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7936 // define the nested loops number.
7937 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00007938 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00007939 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007940 VarsWithImplicitDSA, B);
7941 if (NestedLoopCount == 0)
7942 return StmtError();
7943
7944 assert((CurContext->isDependentContext() || B.builtAll()) &&
7945 "omp target parallel for loop exprs were not built");
7946
7947 if (!CurContext->isDependentContext()) {
7948 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007949 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007950 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007952 B.NumIterations, *this, CurScope,
7953 DSAStack))
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007954 return StmtError();
7955 }
7956 }
7957
Reid Kleckner87a31802018-03-12 21:43:02 +00007958 setFunctionHasBranchProtectedScope();
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00007959 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
7960 NestedLoopCount, Clauses, AStmt,
7961 B, DSAStack->isCancelRegion());
7962}
7963
Alexey Bataev95b64a92017-05-30 16:00:04 +00007964/// Check for existence of a map clause in the list of clauses.
7965static bool hasClauses(ArrayRef<OMPClause *> Clauses,
7966 const OpenMPClauseKind K) {
7967 return llvm::any_of(
7968 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
7969}
Samuel Antaodf67fc42016-01-19 19:15:56 +00007970
Alexey Bataev95b64a92017-05-30 16:00:04 +00007971template <typename... Params>
7972static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
7973 const Params... ClauseTypes) {
7974 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
Samuel Antaodf67fc42016-01-19 19:15:56 +00007975}
7976
Michael Wong65f367f2015-07-21 13:44:28 +00007977StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
7978 Stmt *AStmt,
7979 SourceLocation StartLoc,
7980 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007981 if (!AStmt)
7982 return StmtError();
7983
7984 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7985
Arpith Chacko Jacob46a04bb2016-01-21 19:57:55 +00007986 // OpenMP [2.10.1, Restrictions, p. 97]
7987 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00007988 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7989 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7990 << "'map' or 'use_device_ptr'"
David Majnemer9d168222016-08-05 17:44:54 +00007991 << getOpenMPDirectiveName(OMPD_target_data);
Arpith Chacko Jacob46a04bb2016-01-21 19:57:55 +00007992 return StmtError();
7993 }
7994
Reid Kleckner87a31802018-03-12 21:43:02 +00007995 setFunctionHasBranchProtectedScope();
Michael Wong65f367f2015-07-21 13:44:28 +00007996
7997 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7998 AStmt);
7999}
8000
Samuel Antaodf67fc42016-01-19 19:15:56 +00008001StmtResult
8002Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
8003 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00008004 SourceLocation EndLoc, Stmt *AStmt) {
8005 if (!AStmt)
8006 return StmtError();
8007
Alexey Bataeve3727102018-04-18 15:57:46 +00008008 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00008009 // 1.2.2 OpenMP Language Terminology
8010 // Structured block - An executable statement with a single entry at the
8011 // top and a single exit at the bottom.
8012 // The point of exit cannot be a branch out of the structured block.
8013 // longjmp() and throw() must not violate the entry/exit criteria.
8014 CS->getCapturedDecl()->setNothrow();
8015 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
8016 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8017 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8018 // 1.2.2 OpenMP Language Terminology
8019 // Structured block - An executable statement with a single entry at the
8020 // top and a single exit at the bottom.
8021 // The point of exit cannot be a branch out of the structured block.
8022 // longjmp() and throw() must not violate the entry/exit criteria.
8023 CS->getCapturedDecl()->setNothrow();
8024 }
8025
Samuel Antaodf67fc42016-01-19 19:15:56 +00008026 // OpenMP [2.10.2, Restrictions, p. 99]
8027 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00008028 if (!hasClauses(Clauses, OMPC_map)) {
8029 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
8030 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
Samuel Antaodf67fc42016-01-19 19:15:56 +00008031 return StmtError();
8032 }
8033
Alexey Bataev7828b252017-11-21 17:08:48 +00008034 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
8035 AStmt);
Samuel Antaodf67fc42016-01-19 19:15:56 +00008036}
8037
Samuel Antao72590762016-01-19 20:04:50 +00008038StmtResult
8039Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
8040 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00008041 SourceLocation EndLoc, Stmt *AStmt) {
8042 if (!AStmt)
8043 return StmtError();
8044
Alexey Bataeve3727102018-04-18 15:57:46 +00008045 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00008046 // 1.2.2 OpenMP Language Terminology
8047 // Structured block - An executable statement with a single entry at the
8048 // top and a single exit at the bottom.
8049 // The point of exit cannot be a branch out of the structured block.
8050 // longjmp() and throw() must not violate the entry/exit criteria.
8051 CS->getCapturedDecl()->setNothrow();
8052 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
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
Samuel Antao72590762016-01-19 20:04:50 +00008063 // OpenMP [2.10.3, Restrictions, p. 102]
8064 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00008065 if (!hasClauses(Clauses, OMPC_map)) {
8066 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
8067 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
Samuel Antao72590762016-01-19 20:04:50 +00008068 return StmtError();
8069 }
8070
Alexey Bataev7828b252017-11-21 17:08:48 +00008071 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
8072 AStmt);
Samuel Antao72590762016-01-19 20:04:50 +00008073}
8074
Samuel Antao686c70c2016-05-26 17:30:50 +00008075StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
8076 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00008077 SourceLocation EndLoc,
8078 Stmt *AStmt) {
8079 if (!AStmt)
8080 return StmtError();
8081
Alexey Bataeve3727102018-04-18 15:57:46 +00008082 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00008083 // 1.2.2 OpenMP Language Terminology
8084 // Structured block - An executable statement with a single entry at the
8085 // top and a single exit at the bottom.
8086 // The point of exit cannot be a branch out of the structured block.
8087 // longjmp() and throw() must not violate the entry/exit criteria.
8088 CS->getCapturedDecl()->setNothrow();
8089 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
8090 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8091 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8092 // 1.2.2 OpenMP Language Terminology
8093 // Structured block - An executable statement with a single entry at the
8094 // top and a single exit at the bottom.
8095 // The point of exit cannot be a branch out of the structured block.
8096 // longjmp() and throw() must not violate the entry/exit criteria.
8097 CS->getCapturedDecl()->setNothrow();
8098 }
8099
Alexey Bataev95b64a92017-05-30 16:00:04 +00008100 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
Samuel Antao686c70c2016-05-26 17:30:50 +00008101 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
8102 return StmtError();
8103 }
Alexey Bataev7828b252017-11-21 17:08:48 +00008104 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
8105 AStmt);
Samuel Antao686c70c2016-05-26 17:30:50 +00008106}
8107
Alexey Bataev13314bf2014-10-09 04:18:56 +00008108StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
8109 Stmt *AStmt, SourceLocation StartLoc,
8110 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008111 if (!AStmt)
8112 return StmtError();
8113
Alexey Bataeve3727102018-04-18 15:57:46 +00008114 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev13314bf2014-10-09 04:18:56 +00008115 // 1.2.2 OpenMP Language Terminology
8116 // Structured block - An executable statement with a single entry at the
8117 // top and a single exit at the bottom.
8118 // The point of exit cannot be a branch out of the structured block.
8119 // longjmp() and throw() must not violate the entry/exit criteria.
8120 CS->getCapturedDecl()->setNothrow();
8121
Reid Kleckner87a31802018-03-12 21:43:02 +00008122 setFunctionHasBranchProtectedScope();
Alexey Bataev13314bf2014-10-09 04:18:56 +00008123
Alexey Bataevceabd412017-11-30 18:01:54 +00008124 DSAStack->setParentTeamsRegionLoc(StartLoc);
8125
Alexey Bataev13314bf2014-10-09 04:18:56 +00008126 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8127}
8128
Alexey Bataev6d4ed052015-07-01 06:57:41 +00008129StmtResult
8130Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
8131 SourceLocation EndLoc,
8132 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +00008133 if (DSAStack->isParentNowaitRegion()) {
8134 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
8135 return StmtError();
8136 }
8137 if (DSAStack->isParentOrderedRegion()) {
8138 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
8139 return StmtError();
8140 }
8141 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
8142 CancelRegion);
8143}
8144
Alexey Bataev87933c72015-09-18 08:07:34 +00008145StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
8146 SourceLocation StartLoc,
Alexey Bataev80909872015-07-02 11:25:17 +00008147 SourceLocation EndLoc,
8148 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev80909872015-07-02 11:25:17 +00008149 if (DSAStack->isParentNowaitRegion()) {
8150 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
8151 return StmtError();
8152 }
8153 if (DSAStack->isParentOrderedRegion()) {
8154 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
8155 return StmtError();
8156 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00008157 DSAStack->setParentCancelRegion(/*Cancel=*/true);
Alexey Bataev87933c72015-09-18 08:07:34 +00008158 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
8159 CancelRegion);
Alexey Bataev80909872015-07-02 11:25:17 +00008160}
8161
Alexey Bataev382967a2015-12-08 12:06:20 +00008162static bool checkGrainsizeNumTasksClauses(Sema &S,
8163 ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008164 const OMPClause *PrevClause = nullptr;
Alexey Bataev382967a2015-12-08 12:06:20 +00008165 bool ErrorFound = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00008166 for (const OMPClause *C : Clauses) {
Alexey Bataev382967a2015-12-08 12:06:20 +00008167 if (C->getClauseKind() == OMPC_grainsize ||
8168 C->getClauseKind() == OMPC_num_tasks) {
8169 if (!PrevClause)
8170 PrevClause = C;
8171 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008172 S.Diag(C->getBeginLoc(),
Alexey Bataev382967a2015-12-08 12:06:20 +00008173 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
8174 << getOpenMPClauseName(C->getClauseKind())
8175 << getOpenMPClauseName(PrevClause->getClauseKind());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008176 S.Diag(PrevClause->getBeginLoc(),
Alexey Bataev382967a2015-12-08 12:06:20 +00008177 diag::note_omp_previous_grainsize_num_tasks)
8178 << getOpenMPClauseName(PrevClause->getClauseKind());
8179 ErrorFound = true;
8180 }
8181 }
8182 }
8183 return ErrorFound;
8184}
8185
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00008186static bool checkReductionClauseWithNogroup(Sema &S,
8187 ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008188 const OMPClause *ReductionClause = nullptr;
8189 const OMPClause *NogroupClause = nullptr;
8190 for (const OMPClause *C : Clauses) {
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00008191 if (C->getClauseKind() == OMPC_reduction) {
8192 ReductionClause = C;
8193 if (NogroupClause)
8194 break;
8195 continue;
8196 }
8197 if (C->getClauseKind() == OMPC_nogroup) {
8198 NogroupClause = C;
8199 if (ReductionClause)
8200 break;
8201 continue;
8202 }
8203 }
8204 if (ReductionClause && NogroupClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008205 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
8206 << SourceRange(NogroupClause->getBeginLoc(),
Stephen Kelly1c301dc2018-08-09 21:09:38 +00008207 NogroupClause->getEndLoc());
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00008208 return true;
8209 }
8210 return false;
8211}
8212
Alexey Bataev49f6e782015-12-01 04:18:41 +00008213StmtResult Sema::ActOnOpenMPTaskLoopDirective(
8214 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008215 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev49f6e782015-12-01 04:18:41 +00008216 if (!AStmt)
8217 return StmtError();
8218
8219 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8220 OMPLoopDirective::HelperExprs B;
8221 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8222 // define the nested loops number.
8223 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008224 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
Alexey Bataev0a6ed842015-12-03 09:40:15 +00008225 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
Alexey Bataev49f6e782015-12-01 04:18:41 +00008226 VarsWithImplicitDSA, B);
8227 if (NestedLoopCount == 0)
8228 return StmtError();
8229
8230 assert((CurContext->isDependentContext() || B.builtAll()) &&
8231 "omp for loop exprs were not built");
8232
Alexey Bataev382967a2015-12-08 12:06:20 +00008233 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
8234 // The grainsize clause and num_tasks clause are mutually exclusive and may
8235 // not appear on the same taskloop directive.
8236 if (checkGrainsizeNumTasksClauses(*this, Clauses))
8237 return StmtError();
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00008238 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
8239 // If a reduction clause is present on the taskloop directive, the nogroup
8240 // clause must not be specified.
8241 if (checkReductionClauseWithNogroup(*this, Clauses))
8242 return StmtError();
Alexey Bataev382967a2015-12-08 12:06:20 +00008243
Reid Kleckner87a31802018-03-12 21:43:02 +00008244 setFunctionHasBranchProtectedScope();
Alexey Bataev49f6e782015-12-01 04:18:41 +00008245 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
8246 NestedLoopCount, Clauses, AStmt, B);
8247}
8248
Alexey Bataev0a6ed842015-12-03 09:40:15 +00008249StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
8250 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008251 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev0a6ed842015-12-03 09:40:15 +00008252 if (!AStmt)
8253 return StmtError();
8254
8255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8256 OMPLoopDirective::HelperExprs B;
8257 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8258 // define the nested loops number.
8259 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008260 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev0a6ed842015-12-03 09:40:15 +00008261 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
8262 VarsWithImplicitDSA, B);
8263 if (NestedLoopCount == 0)
8264 return StmtError();
8265
8266 assert((CurContext->isDependentContext() || B.builtAll()) &&
8267 "omp for loop exprs were not built");
8268
Alexey Bataev5a3af132016-03-29 08:58:54 +00008269 if (!CurContext->isDependentContext()) {
8270 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008271 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00008272 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev5a3af132016-03-29 08:58:54 +00008273 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00008274 B.NumIterations, *this, CurScope,
8275 DSAStack))
Alexey Bataev5a3af132016-03-29 08:58:54 +00008276 return StmtError();
8277 }
8278 }
8279
Alexey Bataev382967a2015-12-08 12:06:20 +00008280 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
8281 // The grainsize clause and num_tasks clause are mutually exclusive and may
8282 // not appear on the same taskloop directive.
8283 if (checkGrainsizeNumTasksClauses(*this, Clauses))
8284 return StmtError();
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00008285 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
8286 // If a reduction clause is present on the taskloop directive, the nogroup
8287 // clause must not be specified.
8288 if (checkReductionClauseWithNogroup(*this, Clauses))
8289 return StmtError();
Alexey Bataev438388c2017-11-22 18:34:02 +00008290 if (checkSimdlenSafelenSpecified(*this, Clauses))
8291 return StmtError();
Alexey Bataev382967a2015-12-08 12:06:20 +00008292
Reid Kleckner87a31802018-03-12 21:43:02 +00008293 setFunctionHasBranchProtectedScope();
Alexey Bataev0a6ed842015-12-03 09:40:15 +00008294 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
8295 NestedLoopCount, Clauses, AStmt, B);
8296}
8297
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00008298StmtResult Sema::ActOnOpenMPDistributeDirective(
8299 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008300 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00008301 if (!AStmt)
8302 return StmtError();
8303
8304 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8305 OMPLoopDirective::HelperExprs B;
8306 // In presence of clause 'collapse' with number of loops, it will
8307 // define the nested loops number.
8308 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008309 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00008310 nullptr /*ordered not a clause on distribute*/, AStmt,
8311 *this, *DSAStack, VarsWithImplicitDSA, B);
8312 if (NestedLoopCount == 0)
8313 return StmtError();
8314
8315 assert((CurContext->isDependentContext() || B.builtAll()) &&
8316 "omp for loop exprs were not built");
8317
Reid Kleckner87a31802018-03-12 21:43:02 +00008318 setFunctionHasBranchProtectedScope();
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00008319 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
8320 NestedLoopCount, Clauses, AStmt, B);
8321}
8322
Carlo Bertolli9925f152016-06-27 14:55:37 +00008323StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
8324 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008325 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Carlo Bertolli9925f152016-06-27 14:55:37 +00008326 if (!AStmt)
8327 return StmtError();
8328
Alexey Bataeve3727102018-04-18 15:57:46 +00008329 auto *CS = cast<CapturedStmt>(AStmt);
Carlo Bertolli9925f152016-06-27 14:55:37 +00008330 // 1.2.2 OpenMP Language Terminology
8331 // Structured block - An executable statement with a single entry at the
8332 // top and a single exit at the bottom.
8333 // The point of exit cannot be a branch out of the structured block.
8334 // longjmp() and throw() must not violate the entry/exit criteria.
8335 CS->getCapturedDecl()->setNothrow();
Alexey Bataev7f96c372017-11-22 17:19:31 +00008336 for (int ThisCaptureLevel =
8337 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
8338 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8339 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8340 // 1.2.2 OpenMP Language Terminology
8341 // Structured block - An executable statement with a single entry at the
8342 // top and a single exit at the bottom.
8343 // The point of exit cannot be a branch out of the structured block.
8344 // longjmp() and throw() must not violate the entry/exit criteria.
8345 CS->getCapturedDecl()->setNothrow();
8346 }
Carlo Bertolli9925f152016-06-27 14:55:37 +00008347
8348 OMPLoopDirective::HelperExprs B;
8349 // In presence of clause 'collapse' with number of loops, it will
8350 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008351 unsigned NestedLoopCount = checkOpenMPLoop(
Carlo Bertolli9925f152016-06-27 14:55:37 +00008352 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataev7f96c372017-11-22 17:19:31 +00008353 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Carlo Bertolli9925f152016-06-27 14:55:37 +00008354 VarsWithImplicitDSA, B);
8355 if (NestedLoopCount == 0)
8356 return StmtError();
8357
8358 assert((CurContext->isDependentContext() || B.builtAll()) &&
8359 "omp for loop exprs were not built");
8360
Reid Kleckner87a31802018-03-12 21:43:02 +00008361 setFunctionHasBranchProtectedScope();
Carlo Bertolli9925f152016-06-27 14:55:37 +00008362 return OMPDistributeParallelForDirective::Create(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00008363 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8364 DSAStack->isCancelRegion());
Carlo Bertolli9925f152016-06-27 14:55:37 +00008365}
8366
Kelvin Li4a39add2016-07-05 05:00:15 +00008367StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
8368 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008369 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li4a39add2016-07-05 05:00:15 +00008370 if (!AStmt)
8371 return StmtError();
8372
Alexey Bataeve3727102018-04-18 15:57:46 +00008373 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li4a39add2016-07-05 05:00:15 +00008374 // 1.2.2 OpenMP Language Terminology
8375 // Structured block - An executable statement with a single entry at the
8376 // top and a single exit at the bottom.
8377 // The point of exit cannot be a branch out of the structured block.
8378 // longjmp() and throw() must not violate the entry/exit criteria.
8379 CS->getCapturedDecl()->setNothrow();
Alexey Bataev974acd62017-11-27 19:38:52 +00008380 for (int ThisCaptureLevel =
8381 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
8382 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8383 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8384 // 1.2.2 OpenMP Language Terminology
8385 // Structured block - An executable statement with a single entry at the
8386 // top and a single exit at the bottom.
8387 // The point of exit cannot be a branch out of the structured block.
8388 // longjmp() and throw() must not violate the entry/exit criteria.
8389 CS->getCapturedDecl()->setNothrow();
8390 }
Kelvin Li4a39add2016-07-05 05:00:15 +00008391
8392 OMPLoopDirective::HelperExprs B;
8393 // In presence of clause 'collapse' with number of loops, it will
8394 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008395 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li4a39add2016-07-05 05:00:15 +00008396 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev974acd62017-11-27 19:38:52 +00008397 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li4a39add2016-07-05 05:00:15 +00008398 VarsWithImplicitDSA, B);
8399 if (NestedLoopCount == 0)
8400 return StmtError();
8401
8402 assert((CurContext->isDependentContext() || B.builtAll()) &&
8403 "omp for loop exprs were not built");
8404
Alexey Bataev438388c2017-11-22 18:34:02 +00008405 if (!CurContext->isDependentContext()) {
8406 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008407 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +00008408 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8410 B.NumIterations, *this, CurScope,
8411 DSAStack))
8412 return StmtError();
8413 }
8414 }
8415
Kelvin Lic5609492016-07-15 04:39:07 +00008416 if (checkSimdlenSafelenSpecified(*this, Clauses))
8417 return StmtError();
8418
Reid Kleckner87a31802018-03-12 21:43:02 +00008419 setFunctionHasBranchProtectedScope();
Kelvin Li4a39add2016-07-05 05:00:15 +00008420 return OMPDistributeParallelForSimdDirective::Create(
8421 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8422}
8423
Kelvin Li787f3fc2016-07-06 04:45:38 +00008424StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
8425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li787f3fc2016-07-06 04:45:38 +00008427 if (!AStmt)
8428 return StmtError();
8429
Alexey Bataeve3727102018-04-18 15:57:46 +00008430 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li787f3fc2016-07-06 04:45:38 +00008431 // 1.2.2 OpenMP Language Terminology
8432 // Structured block - An executable statement with a single entry at the
8433 // top and a single exit at the bottom.
8434 // The point of exit cannot be a branch out of the structured block.
8435 // longjmp() and throw() must not violate the entry/exit criteria.
8436 CS->getCapturedDecl()->setNothrow();
Alexey Bataev617db5f2017-12-04 15:38:33 +00008437 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
8438 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8439 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8440 // 1.2.2 OpenMP Language Terminology
8441 // Structured block - An executable statement with a single entry at the
8442 // top and a single exit at the bottom.
8443 // The point of exit cannot be a branch out of the structured block.
8444 // longjmp() and throw() must not violate the entry/exit criteria.
8445 CS->getCapturedDecl()->setNothrow();
8446 }
Kelvin Li787f3fc2016-07-06 04:45:38 +00008447
8448 OMPLoopDirective::HelperExprs B;
8449 // In presence of clause 'collapse' with number of loops, it will
8450 // define the nested loops number.
8451 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008452 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev617db5f2017-12-04 15:38:33 +00008453 nullptr /*ordered not a clause on distribute*/, CS, *this,
8454 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li787f3fc2016-07-06 04:45:38 +00008455 if (NestedLoopCount == 0)
8456 return StmtError();
8457
8458 assert((CurContext->isDependentContext() || B.builtAll()) &&
8459 "omp for loop exprs were not built");
8460
Alexey Bataev438388c2017-11-22 18:34:02 +00008461 if (!CurContext->isDependentContext()) {
8462 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008463 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +00008464 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8465 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8466 B.NumIterations, *this, CurScope,
8467 DSAStack))
8468 return StmtError();
8469 }
8470 }
8471
Kelvin Lic5609492016-07-15 04:39:07 +00008472 if (checkSimdlenSafelenSpecified(*this, Clauses))
8473 return StmtError();
8474
Reid Kleckner87a31802018-03-12 21:43:02 +00008475 setFunctionHasBranchProtectedScope();
Kelvin Li787f3fc2016-07-06 04:45:38 +00008476 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
8477 NestedLoopCount, Clauses, AStmt, B);
8478}
8479
Kelvin Lia579b912016-07-14 02:54:56 +00008480StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
8481 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008482 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Lia579b912016-07-14 02:54:56 +00008483 if (!AStmt)
8484 return StmtError();
8485
Alexey Bataeve3727102018-04-18 15:57:46 +00008486 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Lia579b912016-07-14 02:54:56 +00008487 // 1.2.2 OpenMP Language Terminology
8488 // Structured block - An executable statement with a single entry at the
8489 // top and a single exit at the bottom.
8490 // The point of exit cannot be a branch out of the structured block.
8491 // longjmp() and throw() must not violate the entry/exit criteria.
8492 CS->getCapturedDecl()->setNothrow();
Alexey Bataev5d7edca2017-11-09 17:32:15 +00008493 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8494 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8495 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8496 // 1.2.2 OpenMP Language Terminology
8497 // Structured block - An executable statement with a single entry at the
8498 // top and a single exit at the bottom.
8499 // The point of exit cannot be a branch out of the structured block.
8500 // longjmp() and throw() must not violate the entry/exit criteria.
8501 CS->getCapturedDecl()->setNothrow();
8502 }
Kelvin Lia579b912016-07-14 02:54:56 +00008503
8504 OMPLoopDirective::HelperExprs B;
8505 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8506 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008507 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Lia579b912016-07-14 02:54:56 +00008508 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev5d7edca2017-11-09 17:32:15 +00008509 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Kelvin Lia579b912016-07-14 02:54:56 +00008510 VarsWithImplicitDSA, B);
8511 if (NestedLoopCount == 0)
8512 return StmtError();
8513
8514 assert((CurContext->isDependentContext() || B.builtAll()) &&
8515 "omp target parallel for simd loop exprs were not built");
8516
8517 if (!CurContext->isDependentContext()) {
8518 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008519 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00008520 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Kelvin Lia579b912016-07-14 02:54:56 +00008521 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8522 B.NumIterations, *this, CurScope,
8523 DSAStack))
8524 return StmtError();
8525 }
8526 }
Kelvin Lic5609492016-07-15 04:39:07 +00008527 if (checkSimdlenSafelenSpecified(*this, Clauses))
Kelvin Lia579b912016-07-14 02:54:56 +00008528 return StmtError();
8529
Reid Kleckner87a31802018-03-12 21:43:02 +00008530 setFunctionHasBranchProtectedScope();
Kelvin Lia579b912016-07-14 02:54:56 +00008531 return OMPTargetParallelForSimdDirective::Create(
8532 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8533}
8534
Kelvin Li986330c2016-07-20 22:57:10 +00008535StmtResult Sema::ActOnOpenMPTargetSimdDirective(
8536 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008537 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li986330c2016-07-20 22:57:10 +00008538 if (!AStmt)
8539 return StmtError();
8540
Alexey Bataeve3727102018-04-18 15:57:46 +00008541 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li986330c2016-07-20 22:57:10 +00008542 // 1.2.2 OpenMP Language Terminology
8543 // Structured block - An executable statement with a single entry at the
8544 // top and a single exit at the bottom.
8545 // The point of exit cannot be a branch out of the structured block.
8546 // longjmp() and throw() must not violate the entry/exit criteria.
8547 CS->getCapturedDecl()->setNothrow();
Alexey Bataevf8365372017-11-17 17:57:25 +00008548 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
8549 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8550 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8551 // 1.2.2 OpenMP Language Terminology
8552 // Structured block - An executable statement with a single entry at the
8553 // top and a single exit at the bottom.
8554 // The point of exit cannot be a branch out of the structured block.
8555 // longjmp() and throw() must not violate the entry/exit criteria.
8556 CS->getCapturedDecl()->setNothrow();
8557 }
8558
Kelvin Li986330c2016-07-20 22:57:10 +00008559 OMPLoopDirective::HelperExprs B;
8560 // In presence of clause 'collapse' with number of loops, it will define the
8561 // nested loops number.
David Majnemer9d168222016-08-05 17:44:54 +00008562 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008563 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
Alexey Bataevf8365372017-11-17 17:57:25 +00008564 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Kelvin Li986330c2016-07-20 22:57:10 +00008565 VarsWithImplicitDSA, B);
8566 if (NestedLoopCount == 0)
8567 return StmtError();
8568
8569 assert((CurContext->isDependentContext() || B.builtAll()) &&
8570 "omp target simd loop exprs were not built");
8571
8572 if (!CurContext->isDependentContext()) {
8573 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008574 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00008575 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Kelvin Li986330c2016-07-20 22:57:10 +00008576 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8577 B.NumIterations, *this, CurScope,
8578 DSAStack))
8579 return StmtError();
8580 }
8581 }
8582
8583 if (checkSimdlenSafelenSpecified(*this, Clauses))
8584 return StmtError();
8585
Reid Kleckner87a31802018-03-12 21:43:02 +00008586 setFunctionHasBranchProtectedScope();
Kelvin Li986330c2016-07-20 22:57:10 +00008587 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
8588 NestedLoopCount, Clauses, AStmt, B);
8589}
8590
Kelvin Li02532872016-08-05 14:37:37 +00008591StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
8592 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008593 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li02532872016-08-05 14:37:37 +00008594 if (!AStmt)
8595 return StmtError();
8596
Alexey Bataeve3727102018-04-18 15:57:46 +00008597 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li02532872016-08-05 14:37:37 +00008598 // 1.2.2 OpenMP Language Terminology
8599 // Structured block - An executable statement with a single entry at the
8600 // top and a single exit at the bottom.
8601 // The point of exit cannot be a branch out of the structured block.
8602 // longjmp() and throw() must not violate the entry/exit criteria.
8603 CS->getCapturedDecl()->setNothrow();
Alexey Bataev95c6dd42017-11-29 15:14:16 +00008604 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
8605 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8606 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8607 // 1.2.2 OpenMP Language Terminology
8608 // Structured block - An executable statement with a single entry at the
8609 // top and a single exit at the bottom.
8610 // The point of exit cannot be a branch out of the structured block.
8611 // longjmp() and throw() must not violate the entry/exit criteria.
8612 CS->getCapturedDecl()->setNothrow();
8613 }
Kelvin Li02532872016-08-05 14:37:37 +00008614
8615 OMPLoopDirective::HelperExprs B;
8616 // In presence of clause 'collapse' with number of loops, it will
8617 // define the nested loops number.
8618 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008619 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
Alexey Bataev95c6dd42017-11-29 15:14:16 +00008620 nullptr /*ordered not a clause on distribute*/, CS, *this,
8621 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li02532872016-08-05 14:37:37 +00008622 if (NestedLoopCount == 0)
8623 return StmtError();
8624
8625 assert((CurContext->isDependentContext() || B.builtAll()) &&
8626 "omp teams distribute loop exprs were not built");
8627
Reid Kleckner87a31802018-03-12 21:43:02 +00008628 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00008629
8630 DSAStack->setParentTeamsRegionLoc(StartLoc);
8631
David Majnemer9d168222016-08-05 17:44:54 +00008632 return OMPTeamsDistributeDirective::Create(
8633 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
Kelvin Li02532872016-08-05 14:37:37 +00008634}
8635
Kelvin Li4e325f72016-10-25 12:50:55 +00008636StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
8637 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008638 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li4e325f72016-10-25 12:50:55 +00008639 if (!AStmt)
8640 return StmtError();
8641
Alexey Bataeve3727102018-04-18 15:57:46 +00008642 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li4e325f72016-10-25 12:50:55 +00008643 // 1.2.2 OpenMP Language Terminology
8644 // Structured block - An executable statement with a single entry at the
8645 // top and a single exit at the bottom.
8646 // The point of exit cannot be a branch out of the structured block.
8647 // longjmp() and throw() must not violate the entry/exit criteria.
8648 CS->getCapturedDecl()->setNothrow();
Alexey Bataev999277a2017-12-06 14:31:09 +00008649 for (int ThisCaptureLevel =
8650 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
8651 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8652 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8653 // 1.2.2 OpenMP Language Terminology
8654 // Structured block - An executable statement with a single entry at the
8655 // top and a single exit at the bottom.
8656 // The point of exit cannot be a branch out of the structured block.
8657 // longjmp() and throw() must not violate the entry/exit criteria.
8658 CS->getCapturedDecl()->setNothrow();
8659 }
8660
Kelvin Li4e325f72016-10-25 12:50:55 +00008661
8662 OMPLoopDirective::HelperExprs B;
8663 // In presence of clause 'collapse' with number of loops, it will
8664 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008665 unsigned NestedLoopCount = checkOpenMPLoop(
Samuel Antao4c8035b2016-12-12 18:00:20 +00008666 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev999277a2017-12-06 14:31:09 +00008667 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Samuel Antao4c8035b2016-12-12 18:00:20 +00008668 VarsWithImplicitDSA, B);
Kelvin Li4e325f72016-10-25 12:50:55 +00008669
8670 if (NestedLoopCount == 0)
8671 return StmtError();
8672
8673 assert((CurContext->isDependentContext() || B.builtAll()) &&
8674 "omp teams distribute simd loop exprs were not built");
8675
8676 if (!CurContext->isDependentContext()) {
8677 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008678 for (OMPClause *C : Clauses) {
Kelvin Li4e325f72016-10-25 12:50:55 +00008679 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8680 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8681 B.NumIterations, *this, CurScope,
8682 DSAStack))
8683 return StmtError();
8684 }
8685 }
8686
8687 if (checkSimdlenSafelenSpecified(*this, Clauses))
8688 return StmtError();
8689
Reid Kleckner87a31802018-03-12 21:43:02 +00008690 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00008691
8692 DSAStack->setParentTeamsRegionLoc(StartLoc);
8693
Kelvin Li4e325f72016-10-25 12:50:55 +00008694 return OMPTeamsDistributeSimdDirective::Create(
8695 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8696}
8697
Kelvin Li579e41c2016-11-30 23:51:03 +00008698StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
8699 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008700 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li579e41c2016-11-30 23:51:03 +00008701 if (!AStmt)
8702 return StmtError();
8703
Alexey Bataeve3727102018-04-18 15:57:46 +00008704 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li579e41c2016-11-30 23:51:03 +00008705 // 1.2.2 OpenMP Language Terminology
8706 // Structured block - An executable statement with a single entry at the
8707 // top and a single exit at the bottom.
8708 // The point of exit cannot be a branch out of the structured block.
8709 // longjmp() and throw() must not violate the entry/exit criteria.
8710 CS->getCapturedDecl()->setNothrow();
8711
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00008712 for (int ThisCaptureLevel =
8713 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
8714 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8715 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8716 // 1.2.2 OpenMP Language Terminology
8717 // Structured block - An executable statement with a single entry at the
8718 // top and a single exit at the bottom.
8719 // The point of exit cannot be a branch out of the structured block.
8720 // longjmp() and throw() must not violate the entry/exit criteria.
8721 CS->getCapturedDecl()->setNothrow();
8722 }
8723
Kelvin Li579e41c2016-11-30 23:51:03 +00008724 OMPLoopDirective::HelperExprs B;
8725 // In presence of clause 'collapse' with number of loops, it will
8726 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008727 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li579e41c2016-11-30 23:51:03 +00008728 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00008729 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li579e41c2016-11-30 23:51:03 +00008730 VarsWithImplicitDSA, B);
8731
8732 if (NestedLoopCount == 0)
8733 return StmtError();
8734
8735 assert((CurContext->isDependentContext() || B.builtAll()) &&
8736 "omp for loop exprs were not built");
8737
8738 if (!CurContext->isDependentContext()) {
8739 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008740 for (OMPClause *C : Clauses) {
Kelvin Li579e41c2016-11-30 23:51:03 +00008741 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8742 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8743 B.NumIterations, *this, CurScope,
8744 DSAStack))
8745 return StmtError();
8746 }
8747 }
8748
8749 if (checkSimdlenSafelenSpecified(*this, Clauses))
8750 return StmtError();
8751
Reid Kleckner87a31802018-03-12 21:43:02 +00008752 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00008753
8754 DSAStack->setParentTeamsRegionLoc(StartLoc);
8755
Kelvin Li579e41c2016-11-30 23:51:03 +00008756 return OMPTeamsDistributeParallelForSimdDirective::Create(
8757 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8758}
8759
Kelvin Li7ade93f2016-12-09 03:24:30 +00008760StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
8761 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008762 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li7ade93f2016-12-09 03:24:30 +00008763 if (!AStmt)
8764 return StmtError();
8765
Alexey Bataeve3727102018-04-18 15:57:46 +00008766 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li7ade93f2016-12-09 03:24:30 +00008767 // 1.2.2 OpenMP Language Terminology
8768 // Structured block - An executable statement with a single entry at the
8769 // top and a single exit at the bottom.
8770 // The point of exit cannot be a branch out of the structured block.
8771 // longjmp() and throw() must not violate the entry/exit criteria.
8772 CS->getCapturedDecl()->setNothrow();
8773
Carlo Bertolli62fae152017-11-20 20:46:39 +00008774 for (int ThisCaptureLevel =
8775 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
8776 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8777 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8778 // 1.2.2 OpenMP Language Terminology
8779 // Structured block - An executable statement with a single entry at the
8780 // top and a single exit at the bottom.
8781 // The point of exit cannot be a branch out of the structured block.
8782 // longjmp() and throw() must not violate the entry/exit criteria.
8783 CS->getCapturedDecl()->setNothrow();
8784 }
8785
Kelvin Li7ade93f2016-12-09 03:24:30 +00008786 OMPLoopDirective::HelperExprs B;
8787 // In presence of clause 'collapse' with number of loops, it will
8788 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008789 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li7ade93f2016-12-09 03:24:30 +00008790 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
Carlo Bertolli62fae152017-11-20 20:46:39 +00008791 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li7ade93f2016-12-09 03:24:30 +00008792 VarsWithImplicitDSA, B);
8793
8794 if (NestedLoopCount == 0)
8795 return StmtError();
8796
8797 assert((CurContext->isDependentContext() || B.builtAll()) &&
8798 "omp for loop exprs were not built");
8799
Reid Kleckner87a31802018-03-12 21:43:02 +00008800 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00008801
8802 DSAStack->setParentTeamsRegionLoc(StartLoc);
8803
Kelvin Li7ade93f2016-12-09 03:24:30 +00008804 return OMPTeamsDistributeParallelForDirective::Create(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00008805 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8806 DSAStack->isCancelRegion());
Kelvin Li7ade93f2016-12-09 03:24:30 +00008807}
8808
Kelvin Libf594a52016-12-17 05:48:59 +00008809StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
8810 Stmt *AStmt,
8811 SourceLocation StartLoc,
8812 SourceLocation EndLoc) {
8813 if (!AStmt)
8814 return StmtError();
8815
Alexey Bataeve3727102018-04-18 15:57:46 +00008816 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Libf594a52016-12-17 05:48:59 +00008817 // 1.2.2 OpenMP Language Terminology
8818 // Structured block - An executable statement with a single entry at the
8819 // top and a single exit at the bottom.
8820 // The point of exit cannot be a branch out of the structured block.
8821 // longjmp() and throw() must not violate the entry/exit criteria.
8822 CS->getCapturedDecl()->setNothrow();
8823
Alexey Bataevf9fc42e2017-11-22 14:25:55 +00008824 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
8825 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8826 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8827 // 1.2.2 OpenMP Language Terminology
8828 // Structured block - An executable statement with a single entry at the
8829 // top and a single exit at the bottom.
8830 // The point of exit cannot be a branch out of the structured block.
8831 // longjmp() and throw() must not violate the entry/exit criteria.
8832 CS->getCapturedDecl()->setNothrow();
8833 }
Reid Kleckner87a31802018-03-12 21:43:02 +00008834 setFunctionHasBranchProtectedScope();
Kelvin Libf594a52016-12-17 05:48:59 +00008835
8836 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
8837 AStmt);
8838}
8839
Kelvin Li83c451e2016-12-25 04:52:54 +00008840StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
8841 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008842 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li83c451e2016-12-25 04:52:54 +00008843 if (!AStmt)
8844 return StmtError();
8845
Alexey Bataeve3727102018-04-18 15:57:46 +00008846 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li83c451e2016-12-25 04:52:54 +00008847 // 1.2.2 OpenMP Language Terminology
8848 // Structured block - An executable statement with a single entry at the
8849 // top and a single exit at the bottom.
8850 // The point of exit cannot be a branch out of the structured block.
8851 // longjmp() and throw() must not violate the entry/exit criteria.
8852 CS->getCapturedDecl()->setNothrow();
Alexey Bataevdfa430f2017-12-08 15:03:50 +00008853 for (int ThisCaptureLevel =
8854 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8855 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8856 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8857 // 1.2.2 OpenMP Language Terminology
8858 // Structured block - An executable statement with a single entry at the
8859 // top and a single exit at the bottom.
8860 // The point of exit cannot be a branch out of the structured block.
8861 // longjmp() and throw() must not violate the entry/exit criteria.
8862 CS->getCapturedDecl()->setNothrow();
8863 }
Kelvin Li83c451e2016-12-25 04:52:54 +00008864
8865 OMPLoopDirective::HelperExprs B;
8866 // In presence of clause 'collapse' with number of loops, it will
8867 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008868 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataevdfa430f2017-12-08 15:03:50 +00008869 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
8870 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li83c451e2016-12-25 04:52:54 +00008871 VarsWithImplicitDSA, B);
8872 if (NestedLoopCount == 0)
8873 return StmtError();
8874
8875 assert((CurContext->isDependentContext() || B.builtAll()) &&
8876 "omp target teams distribute loop exprs were not built");
8877
Reid Kleckner87a31802018-03-12 21:43:02 +00008878 setFunctionHasBranchProtectedScope();
Kelvin Li83c451e2016-12-25 04:52:54 +00008879 return OMPTargetTeamsDistributeDirective::Create(
8880 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8881}
8882
Kelvin Li80e8f562016-12-29 22:16:30 +00008883StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
8884 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008885 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li80e8f562016-12-29 22:16:30 +00008886 if (!AStmt)
8887 return StmtError();
8888
Alexey Bataeve3727102018-04-18 15:57:46 +00008889 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li80e8f562016-12-29 22:16:30 +00008890 // 1.2.2 OpenMP Language Terminology
8891 // Structured block - An executable statement with a single entry at the
8892 // top and a single exit at the bottom.
8893 // The point of exit cannot be a branch out of the structured block.
8894 // longjmp() and throw() must not violate the entry/exit criteria.
8895 CS->getCapturedDecl()->setNothrow();
Carlo Bertolli52978c32018-01-03 21:12:44 +00008896 for (int ThisCaptureLevel =
8897 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8898 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8899 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8900 // 1.2.2 OpenMP Language Terminology
8901 // Structured block - An executable statement with a single entry at the
8902 // top and a single exit at the bottom.
8903 // The point of exit cannot be a branch out of the structured block.
8904 // longjmp() and throw() must not violate the entry/exit criteria.
8905 CS->getCapturedDecl()->setNothrow();
8906 }
8907
Kelvin Li80e8f562016-12-29 22:16:30 +00008908 OMPLoopDirective::HelperExprs B;
8909 // In presence of clause 'collapse' with number of loops, it will
8910 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008911 unsigned NestedLoopCount = checkOpenMPLoop(
Carlo Bertolli52978c32018-01-03 21:12:44 +00008912 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8913 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li80e8f562016-12-29 22:16:30 +00008914 VarsWithImplicitDSA, B);
8915 if (NestedLoopCount == 0)
8916 return StmtError();
8917
8918 assert((CurContext->isDependentContext() || B.builtAll()) &&
8919 "omp target teams distribute parallel for loop exprs were not built");
8920
Alexey Bataev647dd842018-01-15 20:59:40 +00008921 if (!CurContext->isDependentContext()) {
8922 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008923 for (OMPClause *C : Clauses) {
Alexey Bataev647dd842018-01-15 20:59:40 +00008924 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8925 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8926 B.NumIterations, *this, CurScope,
8927 DSAStack))
8928 return StmtError();
8929 }
8930 }
8931
Reid Kleckner87a31802018-03-12 21:43:02 +00008932 setFunctionHasBranchProtectedScope();
Kelvin Li80e8f562016-12-29 22:16:30 +00008933 return OMPTargetTeamsDistributeParallelForDirective::Create(
Alexey Bataev16e79882017-11-22 21:12:03 +00008934 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8935 DSAStack->isCancelRegion());
Kelvin Li80e8f562016-12-29 22:16:30 +00008936}
8937
Kelvin Li1851df52017-01-03 05:23:48 +00008938StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
8939 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008940 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li1851df52017-01-03 05:23:48 +00008941 if (!AStmt)
8942 return StmtError();
8943
Alexey Bataeve3727102018-04-18 15:57:46 +00008944 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li1851df52017-01-03 05:23:48 +00008945 // 1.2.2 OpenMP Language Terminology
8946 // Structured block - An executable statement with a single entry at the
8947 // top and a single exit at the bottom.
8948 // The point of exit cannot be a branch out of the structured block.
8949 // longjmp() and throw() must not violate the entry/exit criteria.
8950 CS->getCapturedDecl()->setNothrow();
Alexey Bataev647dd842018-01-15 20:59:40 +00008951 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
8952 OMPD_target_teams_distribute_parallel_for_simd);
8953 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8954 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8955 // 1.2.2 OpenMP Language Terminology
8956 // Structured block - An executable statement with a single entry at the
8957 // top and a single exit at the bottom.
8958 // The point of exit cannot be a branch out of the structured block.
8959 // longjmp() and throw() must not violate the entry/exit criteria.
8960 CS->getCapturedDecl()->setNothrow();
8961 }
Kelvin Li1851df52017-01-03 05:23:48 +00008962
8963 OMPLoopDirective::HelperExprs B;
8964 // In presence of clause 'collapse' with number of loops, it will
8965 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00008966 unsigned NestedLoopCount =
8967 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
Alexey Bataev647dd842018-01-15 20:59:40 +00008968 getCollapseNumberExpr(Clauses),
8969 nullptr /*ordered not a clause on distribute*/, CS, *this,
8970 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li1851df52017-01-03 05:23:48 +00008971 if (NestedLoopCount == 0)
8972 return StmtError();
8973
8974 assert((CurContext->isDependentContext() || B.builtAll()) &&
8975 "omp target teams distribute parallel for simd loop exprs were not "
8976 "built");
8977
8978 if (!CurContext->isDependentContext()) {
8979 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008980 for (OMPClause *C : Clauses) {
Kelvin Li1851df52017-01-03 05:23:48 +00008981 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8982 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8983 B.NumIterations, *this, CurScope,
8984 DSAStack))
8985 return StmtError();
8986 }
8987 }
8988
Alexey Bataev438388c2017-11-22 18:34:02 +00008989 if (checkSimdlenSafelenSpecified(*this, Clauses))
8990 return StmtError();
8991
Reid Kleckner87a31802018-03-12 21:43:02 +00008992 setFunctionHasBranchProtectedScope();
Kelvin Li1851df52017-01-03 05:23:48 +00008993 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
8994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8995}
8996
Kelvin Lida681182017-01-10 18:08:18 +00008997StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
8998 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008999 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Lida681182017-01-10 18:08:18 +00009000 if (!AStmt)
9001 return StmtError();
9002
9003 auto *CS = cast<CapturedStmt>(AStmt);
9004 // 1.2.2 OpenMP Language Terminology
9005 // Structured block - An executable statement with a single entry at the
9006 // top and a single exit at the bottom.
9007 // The point of exit cannot be a branch out of the structured block.
9008 // longjmp() and throw() must not violate the entry/exit criteria.
9009 CS->getCapturedDecl()->setNothrow();
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00009010 for (int ThisCaptureLevel =
9011 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
9012 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9013 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9014 // 1.2.2 OpenMP Language Terminology
9015 // Structured block - An executable statement with a single entry at the
9016 // top and a single exit at the bottom.
9017 // The point of exit cannot be a branch out of the structured block.
9018 // longjmp() and throw() must not violate the entry/exit criteria.
9019 CS->getCapturedDecl()->setNothrow();
9020 }
Kelvin Lida681182017-01-10 18:08:18 +00009021
9022 OMPLoopDirective::HelperExprs B;
9023 // In presence of clause 'collapse' with number of loops, it will
9024 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009025 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Lida681182017-01-10 18:08:18 +00009026 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00009027 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Lida681182017-01-10 18:08:18 +00009028 VarsWithImplicitDSA, B);
9029 if (NestedLoopCount == 0)
9030 return StmtError();
9031
9032 assert((CurContext->isDependentContext() || B.builtAll()) &&
9033 "omp target teams distribute simd loop exprs were not built");
9034
Alexey Bataev438388c2017-11-22 18:34:02 +00009035 if (!CurContext->isDependentContext()) {
9036 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009037 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +00009038 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9039 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9040 B.NumIterations, *this, CurScope,
9041 DSAStack))
9042 return StmtError();
9043 }
9044 }
9045
9046 if (checkSimdlenSafelenSpecified(*this, Clauses))
9047 return StmtError();
9048
Reid Kleckner87a31802018-03-12 21:43:02 +00009049 setFunctionHasBranchProtectedScope();
Kelvin Lida681182017-01-10 18:08:18 +00009050 return OMPTargetTeamsDistributeSimdDirective::Create(
9051 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9052}
9053
Alexey Bataeved09d242014-05-28 05:53:51 +00009054OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009055 SourceLocation StartLoc,
9056 SourceLocation LParenLoc,
9057 SourceLocation EndLoc) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +00009058 OMPClause *Res = nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009059 switch (Kind) {
Alexey Bataev3778b602014-07-17 07:32:53 +00009060 case OMPC_final:
9061 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
9062 break;
Alexey Bataev568a8332014-03-06 06:15:19 +00009063 case OMPC_num_threads:
9064 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
9065 break;
Alexey Bataev62c87d22014-03-21 04:51:18 +00009066 case OMPC_safelen:
9067 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
9068 break;
Alexey Bataev66b15b52015-08-21 11:14:16 +00009069 case OMPC_simdlen:
9070 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
9071 break;
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009072 case OMPC_allocator:
9073 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
9074 break;
Alexander Musman8bd31e62014-05-27 15:12:19 +00009075 case OMPC_collapse:
9076 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
9077 break;
Alexey Bataev10e775f2015-07-30 11:36:16 +00009078 case OMPC_ordered:
9079 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
9080 break;
Michael Wonge710d542015-08-07 16:16:36 +00009081 case OMPC_device:
9082 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
9083 break;
Kelvin Li099bb8c2015-11-24 20:50:12 +00009084 case OMPC_num_teams:
9085 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
9086 break;
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009087 case OMPC_thread_limit:
9088 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
9089 break;
Alexey Bataeva0569352015-12-01 10:17:31 +00009090 case OMPC_priority:
9091 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
9092 break;
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00009093 case OMPC_grainsize:
9094 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
9095 break;
Alexey Bataev382967a2015-12-08 12:06:20 +00009096 case OMPC_num_tasks:
9097 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
9098 break;
Alexey Bataev28c75412015-12-15 08:19:24 +00009099 case OMPC_hint:
9100 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
9101 break;
Alexey Bataev6b8046a2015-09-03 07:23:48 +00009102 case OMPC_if:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009103 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +00009104 case OMPC_proc_bind:
Alexey Bataev56dafe82014-06-20 07:16:17 +00009105 case OMPC_schedule:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009106 case OMPC_private:
9107 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +00009108 case OMPC_lastprivate:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009109 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +00009110 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00009111 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00009112 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +00009113 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +00009114 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +00009115 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +00009116 case OMPC_copyprivate:
Alexey Bataev236070f2014-06-20 11:19:47 +00009117 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +00009118 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +00009119 case OMPC_mergeable:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009120 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009121 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +00009122 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +00009123 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +00009124 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +00009125 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +00009126 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +00009127 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00009128 case OMPC_depend:
Alexey Bataev346265e2015-09-25 10:37:12 +00009129 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +00009130 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +00009131 case OMPC_map:
Alexey Bataevb825de12015-12-07 10:51:44 +00009132 case OMPC_nogroup:
Carlo Bertollib4adf552016-01-15 18:50:31 +00009133 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00009134 case OMPC_defaultmap:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009135 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00009136 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +00009137 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +00009138 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +00009139 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +00009140 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +00009141 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +00009142 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00009143 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00009144 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00009145 case OMPC_atomic_default_mem_order:
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009146 llvm_unreachable("Clause is not allowed.");
9147 }
9148 return Res;
9149}
9150
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009151// An OpenMP directive such as 'target parallel' has two captured regions:
9152// for the 'target' and 'parallel' respectively. This function returns
9153// the region in which to capture expressions associated with a clause.
9154// A return value of OMPD_unknown signifies that the expression should not
9155// be captured.
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009156static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
9157 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
9158 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009159 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009160 switch (CKind) {
9161 case OMPC_if:
9162 switch (DKind) {
9163 case OMPD_target_parallel:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009164 case OMPD_target_parallel_for:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009165 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009166 // If this clause applies to the nested 'parallel' region, capture within
9167 // the 'target' region, otherwise do not capture.
9168 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
9169 CaptureRegion = OMPD_target;
9170 break;
Carlo Bertolli52978c32018-01-03 21:12:44 +00009171 case OMPD_target_teams_distribute_parallel_for:
9172 case OMPD_target_teams_distribute_parallel_for_simd:
9173 // If this clause applies to the nested 'parallel' region, capture within
9174 // the 'teams' region, otherwise do not capture.
9175 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
9176 CaptureRegion = OMPD_teams;
9177 break;
Carlo Bertolli62fae152017-11-20 20:46:39 +00009178 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009179 case OMPD_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009180 CaptureRegion = OMPD_teams;
9181 break;
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009182 case OMPD_target_update:
Alexey Bataevfab20e42017-12-27 18:49:38 +00009183 case OMPD_target_enter_data:
9184 case OMPD_target_exit_data:
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009185 CaptureRegion = OMPD_task;
9186 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009187 case OMPD_cancel:
9188 case OMPD_parallel:
9189 case OMPD_parallel_sections:
9190 case OMPD_parallel_for:
9191 case OMPD_parallel_for_simd:
9192 case OMPD_target:
9193 case OMPD_target_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009194 case OMPD_target_teams:
9195 case OMPD_target_teams_distribute:
9196 case OMPD_target_teams_distribute_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009197 case OMPD_distribute_parallel_for:
9198 case OMPD_distribute_parallel_for_simd:
9199 case OMPD_task:
9200 case OMPD_taskloop:
9201 case OMPD_taskloop_simd:
9202 case OMPD_target_data:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009203 // Do not capture if-clause expressions.
9204 break;
9205 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009206 case OMPD_allocate:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009207 case OMPD_taskyield:
9208 case OMPD_barrier:
9209 case OMPD_taskwait:
9210 case OMPD_cancellation_point:
9211 case OMPD_flush:
9212 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009213 case OMPD_declare_mapper:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009214 case OMPD_declare_simd:
9215 case OMPD_declare_target:
9216 case OMPD_end_declare_target:
9217 case OMPD_teams:
9218 case OMPD_simd:
9219 case OMPD_for:
9220 case OMPD_for_simd:
9221 case OMPD_sections:
9222 case OMPD_section:
9223 case OMPD_single:
9224 case OMPD_master:
9225 case OMPD_critical:
9226 case OMPD_taskgroup:
9227 case OMPD_distribute:
9228 case OMPD_ordered:
9229 case OMPD_atomic:
9230 case OMPD_distribute_simd:
9231 case OMPD_teams_distribute:
9232 case OMPD_teams_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009233 case OMPD_requires:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009234 llvm_unreachable("Unexpected OpenMP directive with if-clause");
9235 case OMPD_unknown:
9236 llvm_unreachable("Unknown OpenMP directive");
9237 }
9238 break;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009239 case OMPC_num_threads:
9240 switch (DKind) {
9241 case OMPD_target_parallel:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009242 case OMPD_target_parallel_for:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009243 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009244 CaptureRegion = OMPD_target;
9245 break;
Carlo Bertolli62fae152017-11-20 20:46:39 +00009246 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009247 case OMPD_teams_distribute_parallel_for_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +00009248 case OMPD_target_teams_distribute_parallel_for:
9249 case OMPD_target_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009250 CaptureRegion = OMPD_teams;
9251 break;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009252 case OMPD_parallel:
9253 case OMPD_parallel_sections:
9254 case OMPD_parallel_for:
9255 case OMPD_parallel_for_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009256 case OMPD_distribute_parallel_for:
9257 case OMPD_distribute_parallel_for_simd:
9258 // Do not capture num_threads-clause expressions.
9259 break;
9260 case OMPD_target_data:
9261 case OMPD_target_enter_data:
9262 case OMPD_target_exit_data:
9263 case OMPD_target_update:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009264 case OMPD_target:
9265 case OMPD_target_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009266 case OMPD_target_teams:
9267 case OMPD_target_teams_distribute:
9268 case OMPD_target_teams_distribute_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009269 case OMPD_cancel:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009270 case OMPD_task:
9271 case OMPD_taskloop:
9272 case OMPD_taskloop_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009273 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009274 case OMPD_allocate:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009275 case OMPD_taskyield:
9276 case OMPD_barrier:
9277 case OMPD_taskwait:
9278 case OMPD_cancellation_point:
9279 case OMPD_flush:
9280 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009281 case OMPD_declare_mapper:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009282 case OMPD_declare_simd:
9283 case OMPD_declare_target:
9284 case OMPD_end_declare_target:
9285 case OMPD_teams:
9286 case OMPD_simd:
9287 case OMPD_for:
9288 case OMPD_for_simd:
9289 case OMPD_sections:
9290 case OMPD_section:
9291 case OMPD_single:
9292 case OMPD_master:
9293 case OMPD_critical:
9294 case OMPD_taskgroup:
9295 case OMPD_distribute:
9296 case OMPD_ordered:
9297 case OMPD_atomic:
9298 case OMPD_distribute_simd:
9299 case OMPD_teams_distribute:
9300 case OMPD_teams_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009301 case OMPD_requires:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009302 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
9303 case OMPD_unknown:
9304 llvm_unreachable("Unknown OpenMP directive");
9305 }
9306 break;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009307 case OMPC_num_teams:
9308 switch (DKind) {
9309 case OMPD_target_teams:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009310 case OMPD_target_teams_distribute:
9311 case OMPD_target_teams_distribute_simd:
9312 case OMPD_target_teams_distribute_parallel_for:
9313 case OMPD_target_teams_distribute_parallel_for_simd:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009314 CaptureRegion = OMPD_target;
9315 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009316 case OMPD_teams_distribute_parallel_for:
9317 case OMPD_teams_distribute_parallel_for_simd:
9318 case OMPD_teams:
9319 case OMPD_teams_distribute:
9320 case OMPD_teams_distribute_simd:
9321 // Do not capture num_teams-clause expressions.
9322 break;
9323 case OMPD_distribute_parallel_for:
9324 case OMPD_distribute_parallel_for_simd:
9325 case OMPD_task:
9326 case OMPD_taskloop:
9327 case OMPD_taskloop_simd:
9328 case OMPD_target_data:
9329 case OMPD_target_enter_data:
9330 case OMPD_target_exit_data:
9331 case OMPD_target_update:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009332 case OMPD_cancel:
9333 case OMPD_parallel:
9334 case OMPD_parallel_sections:
9335 case OMPD_parallel_for:
9336 case OMPD_parallel_for_simd:
9337 case OMPD_target:
9338 case OMPD_target_simd:
9339 case OMPD_target_parallel:
9340 case OMPD_target_parallel_for:
9341 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009342 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009343 case OMPD_allocate:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009344 case OMPD_taskyield:
9345 case OMPD_barrier:
9346 case OMPD_taskwait:
9347 case OMPD_cancellation_point:
9348 case OMPD_flush:
9349 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009350 case OMPD_declare_mapper:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009351 case OMPD_declare_simd:
9352 case OMPD_declare_target:
9353 case OMPD_end_declare_target:
9354 case OMPD_simd:
9355 case OMPD_for:
9356 case OMPD_for_simd:
9357 case OMPD_sections:
9358 case OMPD_section:
9359 case OMPD_single:
9360 case OMPD_master:
9361 case OMPD_critical:
9362 case OMPD_taskgroup:
9363 case OMPD_distribute:
9364 case OMPD_ordered:
9365 case OMPD_atomic:
9366 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009367 case OMPD_requires:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00009368 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
9369 case OMPD_unknown:
9370 llvm_unreachable("Unknown OpenMP directive");
9371 }
9372 break;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009373 case OMPC_thread_limit:
9374 switch (DKind) {
9375 case OMPD_target_teams:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009376 case OMPD_target_teams_distribute:
9377 case OMPD_target_teams_distribute_simd:
9378 case OMPD_target_teams_distribute_parallel_for:
9379 case OMPD_target_teams_distribute_parallel_for_simd:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009380 CaptureRegion = OMPD_target;
9381 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009382 case OMPD_teams_distribute_parallel_for:
9383 case OMPD_teams_distribute_parallel_for_simd:
9384 case OMPD_teams:
9385 case OMPD_teams_distribute:
9386 case OMPD_teams_distribute_simd:
9387 // Do not capture thread_limit-clause expressions.
9388 break;
9389 case OMPD_distribute_parallel_for:
9390 case OMPD_distribute_parallel_for_simd:
9391 case OMPD_task:
9392 case OMPD_taskloop:
9393 case OMPD_taskloop_simd:
9394 case OMPD_target_data:
9395 case OMPD_target_enter_data:
9396 case OMPD_target_exit_data:
9397 case OMPD_target_update:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009398 case OMPD_cancel:
9399 case OMPD_parallel:
9400 case OMPD_parallel_sections:
9401 case OMPD_parallel_for:
9402 case OMPD_parallel_for_simd:
9403 case OMPD_target:
9404 case OMPD_target_simd:
9405 case OMPD_target_parallel:
9406 case OMPD_target_parallel_for:
9407 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009408 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009409 case OMPD_allocate:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009410 case OMPD_taskyield:
9411 case OMPD_barrier:
9412 case OMPD_taskwait:
9413 case OMPD_cancellation_point:
9414 case OMPD_flush:
9415 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009416 case OMPD_declare_mapper:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009417 case OMPD_declare_simd:
9418 case OMPD_declare_target:
9419 case OMPD_end_declare_target:
9420 case OMPD_simd:
9421 case OMPD_for:
9422 case OMPD_for_simd:
9423 case OMPD_sections:
9424 case OMPD_section:
9425 case OMPD_single:
9426 case OMPD_master:
9427 case OMPD_critical:
9428 case OMPD_taskgroup:
9429 case OMPD_distribute:
9430 case OMPD_ordered:
9431 case OMPD_atomic:
9432 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009433 case OMPD_requires:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00009434 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
9435 case OMPD_unknown:
9436 llvm_unreachable("Unknown OpenMP directive");
9437 }
9438 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009439 case OMPC_schedule:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009440 switch (DKind) {
Alexey Bataev2ba67042017-11-28 21:11:44 +00009441 case OMPD_parallel_for:
9442 case OMPD_parallel_for_simd:
Alexey Bataev7f96c372017-11-22 17:19:31 +00009443 case OMPD_distribute_parallel_for:
Alexey Bataev974acd62017-11-27 19:38:52 +00009444 case OMPD_distribute_parallel_for_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +00009445 case OMPD_teams_distribute_parallel_for:
9446 case OMPD_teams_distribute_parallel_for_simd:
9447 case OMPD_target_parallel_for:
9448 case OMPD_target_parallel_for_simd:
9449 case OMPD_target_teams_distribute_parallel_for:
9450 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataev7f96c372017-11-22 17:19:31 +00009451 CaptureRegion = OMPD_parallel;
9452 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009453 case OMPD_for:
9454 case OMPD_for_simd:
9455 // Do not capture schedule-clause expressions.
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009456 break;
9457 case OMPD_task:
9458 case OMPD_taskloop:
9459 case OMPD_taskloop_simd:
9460 case OMPD_target_data:
9461 case OMPD_target_enter_data:
9462 case OMPD_target_exit_data:
9463 case OMPD_target_update:
9464 case OMPD_teams:
9465 case OMPD_teams_distribute:
9466 case OMPD_teams_distribute_simd:
9467 case OMPD_target_teams_distribute:
9468 case OMPD_target_teams_distribute_simd:
9469 case OMPD_target:
9470 case OMPD_target_simd:
9471 case OMPD_target_parallel:
9472 case OMPD_cancel:
9473 case OMPD_parallel:
9474 case OMPD_parallel_sections:
9475 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009476 case OMPD_allocate:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009477 case OMPD_taskyield:
9478 case OMPD_barrier:
9479 case OMPD_taskwait:
9480 case OMPD_cancellation_point:
9481 case OMPD_flush:
9482 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009483 case OMPD_declare_mapper:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009484 case OMPD_declare_simd:
9485 case OMPD_declare_target:
9486 case OMPD_end_declare_target:
9487 case OMPD_simd:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009488 case OMPD_sections:
9489 case OMPD_section:
9490 case OMPD_single:
9491 case OMPD_master:
9492 case OMPD_critical:
9493 case OMPD_taskgroup:
9494 case OMPD_distribute:
9495 case OMPD_ordered:
9496 case OMPD_atomic:
9497 case OMPD_distribute_simd:
9498 case OMPD_target_teams:
Kelvin Li1408f912018-09-26 04:28:39 +00009499 case OMPD_requires:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009500 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
9501 case OMPD_unknown:
9502 llvm_unreachable("Unknown OpenMP directive");
9503 }
9504 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009505 case OMPC_dist_schedule:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009506 switch (DKind) {
9507 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009508 case OMPD_teams_distribute_parallel_for_simd:
9509 case OMPD_teams_distribute:
9510 case OMPD_teams_distribute_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009511 case OMPD_target_teams_distribute_parallel_for:
9512 case OMPD_target_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009513 case OMPD_target_teams_distribute:
9514 case OMPD_target_teams_distribute_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +00009515 CaptureRegion = OMPD_teams;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009516 break;
9517 case OMPD_distribute_parallel_for:
9518 case OMPD_distribute_parallel_for_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009519 case OMPD_distribute:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009520 case OMPD_distribute_simd:
9521 // Do not capture thread_limit-clause expressions.
9522 break;
9523 case OMPD_parallel_for:
9524 case OMPD_parallel_for_simd:
9525 case OMPD_target_parallel_for_simd:
9526 case OMPD_target_parallel_for:
9527 case OMPD_task:
9528 case OMPD_taskloop:
9529 case OMPD_taskloop_simd:
9530 case OMPD_target_data:
9531 case OMPD_target_enter_data:
9532 case OMPD_target_exit_data:
9533 case OMPD_target_update:
9534 case OMPD_teams:
9535 case OMPD_target:
9536 case OMPD_target_simd:
9537 case OMPD_target_parallel:
9538 case OMPD_cancel:
9539 case OMPD_parallel:
9540 case OMPD_parallel_sections:
9541 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009542 case OMPD_allocate:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009543 case OMPD_taskyield:
9544 case OMPD_barrier:
9545 case OMPD_taskwait:
9546 case OMPD_cancellation_point:
9547 case OMPD_flush:
9548 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009549 case OMPD_declare_mapper:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009550 case OMPD_declare_simd:
9551 case OMPD_declare_target:
9552 case OMPD_end_declare_target:
9553 case OMPD_simd:
9554 case OMPD_for:
9555 case OMPD_for_simd:
9556 case OMPD_sections:
9557 case OMPD_section:
9558 case OMPD_single:
9559 case OMPD_master:
9560 case OMPD_critical:
9561 case OMPD_taskgroup:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009562 case OMPD_ordered:
9563 case OMPD_atomic:
9564 case OMPD_target_teams:
Kelvin Li1408f912018-09-26 04:28:39 +00009565 case OMPD_requires:
Carlo Bertolli62fae152017-11-20 20:46:39 +00009566 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
9567 case OMPD_unknown:
9568 llvm_unreachable("Unknown OpenMP directive");
9569 }
9570 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009571 case OMPC_device:
9572 switch (DKind) {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009573 case OMPD_target_update:
Alexey Bataevfab20e42017-12-27 18:49:38 +00009574 case OMPD_target_enter_data:
9575 case OMPD_target_exit_data:
Alexey Bataev8451efa2018-01-15 19:06:12 +00009576 case OMPD_target:
Alexey Bataevf41c88f2018-01-16 15:05:16 +00009577 case OMPD_target_simd:
Alexey Bataev0c869ef2018-01-16 15:57:07 +00009578 case OMPD_target_teams:
Alexey Bataev54d5c7d2018-01-16 16:27:49 +00009579 case OMPD_target_parallel:
Alexey Bataev79df7562018-01-16 16:46:46 +00009580 case OMPD_target_teams_distribute:
Alexey Bataev8d16a432018-01-16 17:22:50 +00009581 case OMPD_target_teams_distribute_simd:
Alexey Bataev8ed895512018-01-16 17:41:04 +00009582 case OMPD_target_parallel_for:
Alexey Bataevd60d1ba2018-01-16 17:55:15 +00009583 case OMPD_target_parallel_for_simd:
Alexey Bataev9f9fb0b2018-01-16 19:02:33 +00009584 case OMPD_target_teams_distribute_parallel_for:
Alexey Bataev9350fc32018-01-16 19:18:24 +00009585 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009586 CaptureRegion = OMPD_task;
9587 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +00009588 case OMPD_target_data:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009589 // Do not capture device-clause expressions.
9590 break;
9591 case OMPD_teams_distribute_parallel_for:
9592 case OMPD_teams_distribute_parallel_for_simd:
9593 case OMPD_teams:
9594 case OMPD_teams_distribute:
9595 case OMPD_teams_distribute_simd:
9596 case OMPD_distribute_parallel_for:
9597 case OMPD_distribute_parallel_for_simd:
9598 case OMPD_task:
9599 case OMPD_taskloop:
9600 case OMPD_taskloop_simd:
9601 case OMPD_cancel:
9602 case OMPD_parallel:
9603 case OMPD_parallel_sections:
9604 case OMPD_parallel_for:
9605 case OMPD_parallel_for_simd:
9606 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009607 case OMPD_allocate:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009608 case OMPD_taskyield:
9609 case OMPD_barrier:
9610 case OMPD_taskwait:
9611 case OMPD_cancellation_point:
9612 case OMPD_flush:
9613 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009614 case OMPD_declare_mapper:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009615 case OMPD_declare_simd:
9616 case OMPD_declare_target:
9617 case OMPD_end_declare_target:
9618 case OMPD_simd:
9619 case OMPD_for:
9620 case OMPD_for_simd:
9621 case OMPD_sections:
9622 case OMPD_section:
9623 case OMPD_single:
9624 case OMPD_master:
9625 case OMPD_critical:
9626 case OMPD_taskgroup:
9627 case OMPD_distribute:
9628 case OMPD_ordered:
9629 case OMPD_atomic:
9630 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009631 case OMPD_requires:
Alexey Bataev2ba67042017-11-28 21:11:44 +00009632 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
9633 case OMPD_unknown:
9634 llvm_unreachable("Unknown OpenMP directive");
9635 }
9636 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009637 case OMPC_firstprivate:
9638 case OMPC_lastprivate:
9639 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +00009640 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +00009641 case OMPC_in_reduction:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009642 case OMPC_linear:
9643 case OMPC_default:
9644 case OMPC_proc_bind:
9645 case OMPC_final:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009646 case OMPC_safelen:
9647 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009648 case OMPC_allocator:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009649 case OMPC_collapse:
9650 case OMPC_private:
9651 case OMPC_shared:
9652 case OMPC_aligned:
9653 case OMPC_copyin:
9654 case OMPC_copyprivate:
9655 case OMPC_ordered:
9656 case OMPC_nowait:
9657 case OMPC_untied:
9658 case OMPC_mergeable:
9659 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009660 case OMPC_allocate:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009661 case OMPC_flush:
9662 case OMPC_read:
9663 case OMPC_write:
9664 case OMPC_update:
9665 case OMPC_capture:
9666 case OMPC_seq_cst:
9667 case OMPC_depend:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009668 case OMPC_threads:
9669 case OMPC_simd:
9670 case OMPC_map:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009671 case OMPC_priority:
9672 case OMPC_grainsize:
9673 case OMPC_nogroup:
9674 case OMPC_num_tasks:
9675 case OMPC_hint:
9676 case OMPC_defaultmap:
9677 case OMPC_unknown:
9678 case OMPC_uniform:
9679 case OMPC_to:
9680 case OMPC_from:
9681 case OMPC_use_device_ptr:
9682 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +00009683 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +00009684 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00009685 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +00009686 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00009687 case OMPC_atomic_default_mem_order:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009688 llvm_unreachable("Unexpected OpenMP clause.");
9689 }
9690 return CaptureRegion;
9691}
9692
Alexey Bataev6b8046a2015-09-03 07:23:48 +00009693OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
9694 Expr *Condition, SourceLocation StartLoc,
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009695 SourceLocation LParenLoc,
Alexey Bataev6b8046a2015-09-03 07:23:48 +00009696 SourceLocation NameModifierLoc,
9697 SourceLocation ColonLoc,
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009698 SourceLocation EndLoc) {
9699 Expr *ValExpr = Condition;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009700 Stmt *HelperValStmt = nullptr;
9701 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009702 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
9703 !Condition->isInstantiationDependent() &&
9704 !Condition->containsUnexpandedParameterPack()) {
Richard Smith03a4aa32016-06-23 19:02:52 +00009705 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009706 if (Val.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +00009707 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009708
Alexey Bataev8e769ee2017-12-22 21:01:52 +00009709 ValExpr = Val.get();
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009710
9711 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9712 CaptureRegion =
9713 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
Alexey Bataev2ba67042017-11-28 21:11:44 +00009714 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00009715 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +00009716 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009717 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9718 HelperValStmt = buildPreInits(Context, Captures);
9719 }
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009720 }
9721
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00009722 return new (Context)
9723 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
9724 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00009725}
9726
Alexey Bataev3778b602014-07-17 07:32:53 +00009727OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
9728 SourceLocation StartLoc,
9729 SourceLocation LParenLoc,
9730 SourceLocation EndLoc) {
9731 Expr *ValExpr = Condition;
9732 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
9733 !Condition->isInstantiationDependent() &&
9734 !Condition->containsUnexpandedParameterPack()) {
Richard Smith03a4aa32016-06-23 19:02:52 +00009735 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
Alexey Bataev3778b602014-07-17 07:32:53 +00009736 if (Val.isInvalid())
9737 return nullptr;
9738
Richard Smith03a4aa32016-06-23 19:02:52 +00009739 ValExpr = MakeFullExpr(Val.get()).get();
Alexey Bataev3778b602014-07-17 07:32:53 +00009740 }
9741
9742 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
9743}
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00009744ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
9745 Expr *Op) {
Alexey Bataev568a8332014-03-06 06:15:19 +00009746 if (!Op)
9747 return ExprError();
9748
9749 class IntConvertDiagnoser : public ICEConvertDiagnoser {
9750 public:
9751 IntConvertDiagnoser()
Alexey Bataeved09d242014-05-28 05:53:51 +00009752 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
Craig Toppere14c0f82014-03-12 04:55:44 +00009753 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
9754 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009755 return S.Diag(Loc, diag::err_omp_not_integral) << T;
9756 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009757 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
9758 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009759 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
9760 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009761 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
9762 QualType T,
9763 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009764 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
9765 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009766 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
9767 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009768 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
Alexey Bataeved09d242014-05-28 05:53:51 +00009769 << ConvTy->isEnumeralType() << ConvTy;
Alexey Bataev568a8332014-03-06 06:15:19 +00009770 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009771 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
9772 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009773 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
9774 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009775 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
9776 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009777 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
Alexey Bataeved09d242014-05-28 05:53:51 +00009778 << ConvTy->isEnumeralType() << ConvTy;
Alexey Bataev568a8332014-03-06 06:15:19 +00009779 }
Alexey Bataeved09d242014-05-28 05:53:51 +00009780 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
9781 QualType) override {
Alexey Bataev568a8332014-03-06 06:15:19 +00009782 llvm_unreachable("conversion functions are permitted");
9783 }
9784 } ConvertDiagnoser;
9785 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
9786}
9787
Alexey Bataeve3727102018-04-18 15:57:46 +00009788static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
Alexey Bataeva0569352015-12-01 10:17:31 +00009789 OpenMPClauseKind CKind,
9790 bool StrictlyPositive) {
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009791 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
9792 !ValExpr->isInstantiationDependent()) {
9793 SourceLocation Loc = ValExpr->getExprLoc();
9794 ExprResult Value =
9795 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
9796 if (Value.isInvalid())
9797 return false;
9798
9799 ValExpr = Value.get();
9800 // The expression must evaluate to a non-negative integer value.
9801 llvm::APSInt Result;
9802 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
Alexey Bataeva0569352015-12-01 10:17:31 +00009803 Result.isSigned() &&
9804 !((!StrictlyPositive && Result.isNonNegative()) ||
9805 (StrictlyPositive && Result.isStrictlyPositive()))) {
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009806 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
Alexey Bataeva0569352015-12-01 10:17:31 +00009807 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
9808 << ValExpr->getSourceRange();
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009809 return false;
9810 }
9811 }
9812 return true;
9813}
9814
Alexey Bataev568a8332014-03-06 06:15:19 +00009815OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
9816 SourceLocation StartLoc,
9817 SourceLocation LParenLoc,
9818 SourceLocation EndLoc) {
9819 Expr *ValExpr = NumThreads;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009820 Stmt *HelperValStmt = nullptr;
Alexey Bataev568a8332014-03-06 06:15:19 +00009821
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009822 // OpenMP [2.5, Restrictions]
9823 // The num_threads expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +00009824 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
Alexey Bataeva0569352015-12-01 10:17:31 +00009825 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +00009826 return nullptr;
Alexey Bataev568a8332014-03-06 06:15:19 +00009827
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009828 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +00009829 OpenMPDirectiveKind CaptureRegion =
9830 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
9831 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00009832 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +00009833 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009834 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9835 HelperValStmt = buildPreInits(Context, Captures);
9836 }
9837
9838 return new (Context) OMPNumThreadsClause(
9839 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
Alexey Bataev568a8332014-03-06 06:15:19 +00009840}
9841
Alexey Bataev62c87d22014-03-21 04:51:18 +00009842ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
Alexey Bataeva636c7f2015-12-23 10:27:45 +00009843 OpenMPClauseKind CKind,
9844 bool StrictlyPositive) {
Alexey Bataev62c87d22014-03-21 04:51:18 +00009845 if (!E)
9846 return ExprError();
9847 if (E->isValueDependent() || E->isTypeDependent() ||
9848 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00009849 return E;
Alexey Bataev62c87d22014-03-21 04:51:18 +00009850 llvm::APSInt Result;
9851 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
9852 if (ICE.isInvalid())
9853 return ExprError();
Alexey Bataeva636c7f2015-12-23 10:27:45 +00009854 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
9855 (!StrictlyPositive && !Result.isNonNegative())) {
Alexey Bataev62c87d22014-03-21 04:51:18 +00009856 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00009857 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
9858 << E->getSourceRange();
Alexey Bataev62c87d22014-03-21 04:51:18 +00009859 return ExprError();
9860 }
Alexander Musman09184fe2014-09-30 05:29:28 +00009861 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9862 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
9863 << E->getSourceRange();
9864 return ExprError();
9865 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +00009866 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
9867 DSAStack->setAssociatedLoops(Result.getExtValue());
Alexey Bataev7b6bc882015-11-26 07:50:39 +00009868 else if (CKind == OMPC_ordered)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00009869 DSAStack->setAssociatedLoops(Result.getExtValue());
Alexey Bataev62c87d22014-03-21 04:51:18 +00009870 return ICE;
9871}
9872
9873OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
9874 SourceLocation LParenLoc,
9875 SourceLocation EndLoc) {
9876 // OpenMP [2.8.1, simd construct, Description]
9877 // The parameter of the safelen clause must be a constant
9878 // positive integer expression.
9879 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9880 if (Safelen.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +00009881 return nullptr;
Alexey Bataev62c87d22014-03-21 04:51:18 +00009882 return new (Context)
Nikola Smiljanic01a75982014-05-29 10:55:11 +00009883 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
Alexey Bataev62c87d22014-03-21 04:51:18 +00009884}
9885
Alexey Bataev66b15b52015-08-21 11:14:16 +00009886OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
9887 SourceLocation LParenLoc,
9888 SourceLocation EndLoc) {
9889 // OpenMP [2.8.1, simd construct, Description]
9890 // The parameter of the simdlen clause must be a constant
9891 // positive integer expression.
9892 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9893 if (Simdlen.isInvalid())
9894 return nullptr;
9895 return new (Context)
9896 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
9897}
9898
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009899/// Tries to find omp_allocator_handle_t type.
Alexey Bataev27ef9512019-03-20 20:14:22 +00009900static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
9901 DSAStackTy *Stack) {
9902 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009903 if (!OMPAllocatorHandleT.isNull())
9904 return true;
Alexey Bataev27ef9512019-03-20 20:14:22 +00009905 // Build the predefined allocator expressions.
9906 bool ErrorFound = false;
9907 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
9908 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
9909 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
9910 StringRef Allocator =
9911 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
9912 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
9913 auto *VD = dyn_cast_or_null<ValueDecl>(
9914 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
9915 if (!VD) {
9916 ErrorFound = true;
9917 break;
9918 }
9919 QualType AllocatorType =
9920 VD->getType().getNonLValueExprType(S.getASTContext());
9921 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
9922 if (!Res.isUsable()) {
9923 ErrorFound = true;
9924 break;
9925 }
9926 if (OMPAllocatorHandleT.isNull())
9927 OMPAllocatorHandleT = AllocatorType;
9928 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
9929 ErrorFound = true;
9930 break;
9931 }
9932 Stack->setAllocator(AllocatorKind, Res.get());
9933 }
9934 if (ErrorFound) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009935 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
9936 return false;
9937 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00009938 OMPAllocatorHandleT.addConst();
9939 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009940 return true;
9941}
9942
9943OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
9944 SourceLocation LParenLoc,
9945 SourceLocation EndLoc) {
9946 // OpenMP [2.11.3, allocate Directive, Description]
9947 // allocator is an expression of omp_allocator_handle_t type.
Alexey Bataev27ef9512019-03-20 20:14:22 +00009948 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009949 return nullptr;
9950
9951 ExprResult Allocator = DefaultLvalueConversion(A);
9952 if (Allocator.isInvalid())
9953 return nullptr;
Alexey Bataev27ef9512019-03-20 20:14:22 +00009954 Allocator = PerformImplicitConversion(Allocator.get(),
9955 DSAStack->getOMPAllocatorHandleT(),
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00009956 Sema::AA_Initializing,
9957 /*AllowExplicit=*/true);
9958 if (Allocator.isInvalid())
9959 return nullptr;
9960 return new (Context)
9961 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
9962}
9963
Alexander Musman64d33f12014-06-04 07:53:32 +00009964OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
9965 SourceLocation StartLoc,
Alexander Musman8bd31e62014-05-27 15:12:19 +00009966 SourceLocation LParenLoc,
9967 SourceLocation EndLoc) {
Alexander Musman64d33f12014-06-04 07:53:32 +00009968 // OpenMP [2.7.1, loop construct, Description]
Alexander Musman8bd31e62014-05-27 15:12:19 +00009969 // OpenMP [2.8.1, simd construct, Description]
Alexander Musman64d33f12014-06-04 07:53:32 +00009970 // OpenMP [2.9.6, distribute construct, Description]
Alexander Musman8bd31e62014-05-27 15:12:19 +00009971 // The parameter of the collapse clause must be a constant
9972 // positive integer expression.
Alexander Musman64d33f12014-06-04 07:53:32 +00009973 ExprResult NumForLoopsResult =
9974 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9975 if (NumForLoopsResult.isInvalid())
Alexander Musman8bd31e62014-05-27 15:12:19 +00009976 return nullptr;
9977 return new (Context)
Alexander Musman64d33f12014-06-04 07:53:32 +00009978 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
Alexander Musman8bd31e62014-05-27 15:12:19 +00009979}
9980
Alexey Bataev10e775f2015-07-30 11:36:16 +00009981OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
9982 SourceLocation EndLoc,
9983 SourceLocation LParenLoc,
9984 Expr *NumForLoops) {
Alexey Bataev10e775f2015-07-30 11:36:16 +00009985 // OpenMP [2.7.1, loop construct, Description]
9986 // OpenMP [2.8.1, simd construct, Description]
9987 // OpenMP [2.9.6, distribute construct, Description]
9988 // The parameter of the ordered clause must be a constant
9989 // positive integer expression if any.
9990 if (NumForLoops && LParenLoc.isValid()) {
9991 ExprResult NumForLoopsResult =
9992 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9993 if (NumForLoopsResult.isInvalid())
9994 return nullptr;
9995 NumForLoops = NumForLoopsResult.get();
Alexey Bataeve3727102018-04-18 15:57:46 +00009996 } else {
Alexey Bataev346265e2015-09-25 10:37:12 +00009997 NumForLoops = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +00009998 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00009999 auto *Clause = OMPOrderedClause::Create(
10000 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
10001 StartLoc, LParenLoc, EndLoc);
10002 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
10003 return Clause;
Alexey Bataev10e775f2015-07-30 11:36:16 +000010004}
10005
Alexey Bataeved09d242014-05-28 05:53:51 +000010006OMPClause *Sema::ActOnOpenMPSimpleClause(
10007 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
10008 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010009 OMPClause *Res = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010010 switch (Kind) {
10011 case OMPC_default:
Alexey Bataev758e55e2013-09-06 18:03:48 +000010012 Res =
Alexey Bataeved09d242014-05-28 05:53:51 +000010013 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
10014 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010015 break;
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010016 case OMPC_proc_bind:
Alexey Bataeved09d242014-05-28 05:53:51 +000010017 Res = ActOnOpenMPProcBindClause(
10018 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
10019 LParenLoc, EndLoc);
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010020 break;
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010021 case OMPC_atomic_default_mem_order:
10022 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
10023 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
10024 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
10025 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010026 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000010027 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +000010028 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +000010029 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000010030 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010031 case OMPC_allocator:
Alexander Musman8bd31e62014-05-27 15:12:19 +000010032 case OMPC_collapse:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010033 case OMPC_schedule:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010034 case OMPC_private:
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010035 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +000010036 case OMPC_lastprivate:
Alexey Bataev758e55e2013-09-06 18:03:48 +000010037 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +000010038 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000010039 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000010040 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +000010041 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +000010042 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +000010043 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010044 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010045 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000010046 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010047 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010048 case OMPC_mergeable:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010049 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010050 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000010051 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010052 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000010053 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000010054 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000010055 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010056 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010057 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000010058 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000010059 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010060 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +000010061 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000010062 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000010063 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000010064 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000010065 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000010066 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000010067 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000010068 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000010069 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010070 case OMPC_defaultmap:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010071 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000010072 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000010073 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000010074 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000010075 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000010076 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000010077 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000010078 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010079 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010080 case OMPC_dynamic_allocators:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010081 llvm_unreachable("Clause is not allowed.");
10082 }
10083 return Res;
10084}
10085
Alexey Bataev6402bca2015-12-28 07:25:51 +000010086static std::string
10087getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
10088 ArrayRef<unsigned> Exclude = llvm::None) {
Alexey Bataeve3727102018-04-18 15:57:46 +000010089 SmallString<256> Buffer;
10090 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev6402bca2015-12-28 07:25:51 +000010091 unsigned Bound = Last >= 2 ? Last - 2 : 0;
10092 unsigned Skipped = Exclude.size();
10093 auto S = Exclude.begin(), E = Exclude.end();
Alexey Bataeve3727102018-04-18 15:57:46 +000010094 for (unsigned I = First; I < Last; ++I) {
10095 if (std::find(S, E, I) != E) {
Alexey Bataev6402bca2015-12-28 07:25:51 +000010096 --Skipped;
10097 continue;
10098 }
Alexey Bataeve3727102018-04-18 15:57:46 +000010099 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
10100 if (I == Bound - Skipped)
10101 Out << " or ";
10102 else if (I != Bound + 1 - Skipped)
10103 Out << ", ";
Alexey Bataev6402bca2015-12-28 07:25:51 +000010104 }
Alexey Bataeve3727102018-04-18 15:57:46 +000010105 return Out.str();
Alexey Bataev6402bca2015-12-28 07:25:51 +000010106}
10107
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010108OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
10109 SourceLocation KindKwLoc,
10110 SourceLocation StartLoc,
10111 SourceLocation LParenLoc,
10112 SourceLocation EndLoc) {
10113 if (Kind == OMPC_DEFAULT_unknown) {
Alexey Bataev4ca40ed2014-05-12 04:23:46 +000010114 static_assert(OMPC_DEFAULT_unknown > 0,
10115 "OMPC_DEFAULT_unknown not greater than 0");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010116 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000010117 << getListOfPossibleValues(OMPC_default, /*First=*/0,
10118 /*Last=*/OMPC_DEFAULT_unknown)
10119 << getOpenMPClauseName(OMPC_default);
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010120 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010121 }
Alexey Bataev758e55e2013-09-06 18:03:48 +000010122 switch (Kind) {
10123 case OMPC_DEFAULT_none:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010124 DSAStack->setDefaultDSANone(KindKwLoc);
Alexey Bataev758e55e2013-09-06 18:03:48 +000010125 break;
10126 case OMPC_DEFAULT_shared:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010127 DSAStack->setDefaultDSAShared(KindKwLoc);
Alexey Bataev758e55e2013-09-06 18:03:48 +000010128 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010129 case OMPC_DEFAULT_unknown:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010130 llvm_unreachable("Clause kind is not allowed.");
Alexey Bataev758e55e2013-09-06 18:03:48 +000010131 break;
10132 }
Alexey Bataeved09d242014-05-28 05:53:51 +000010133 return new (Context)
10134 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010135}
10136
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010137OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
10138 SourceLocation KindKwLoc,
10139 SourceLocation StartLoc,
10140 SourceLocation LParenLoc,
10141 SourceLocation EndLoc) {
10142 if (Kind == OMPC_PROC_BIND_unknown) {
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010143 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000010144 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
10145 /*Last=*/OMPC_PROC_BIND_unknown)
10146 << getOpenMPClauseName(OMPC_proc_bind);
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010147 return nullptr;
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010148 }
Alexey Bataeved09d242014-05-28 05:53:51 +000010149 return new (Context)
10150 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010151}
10152
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010153OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
10154 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
10155 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
10156 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
10157 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
10158 << getListOfPossibleValues(
10159 OMPC_atomic_default_mem_order, /*First=*/0,
10160 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
10161 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
10162 return nullptr;
10163 }
10164 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
10165 LParenLoc, EndLoc);
10166}
10167
Alexey Bataev56dafe82014-06-20 07:16:17 +000010168OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000010169 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
Alexey Bataev56dafe82014-06-20 07:16:17 +000010170 SourceLocation StartLoc, SourceLocation LParenLoc,
Alexey Bataev6402bca2015-12-28 07:25:51 +000010171 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
Alexey Bataev56dafe82014-06-20 07:16:17 +000010172 SourceLocation EndLoc) {
10173 OMPClause *Res = nullptr;
10174 switch (Kind) {
10175 case OMPC_schedule:
Alexey Bataev6402bca2015-12-28 07:25:51 +000010176 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
10177 assert(Argument.size() == NumberOfElements &&
10178 ArgumentLoc.size() == NumberOfElements);
Alexey Bataev56dafe82014-06-20 07:16:17 +000010179 Res = ActOnOpenMPScheduleClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000010180 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
10181 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
10182 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
10183 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
10184 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
Alexey Bataev56dafe82014-06-20 07:16:17 +000010185 break;
10186 case OMPC_if:
Alexey Bataev6402bca2015-12-28 07:25:51 +000010187 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
10188 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
10189 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
10190 DelimLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +000010191 break;
Carlo Bertollib4adf552016-01-15 18:50:31 +000010192 case OMPC_dist_schedule:
10193 Res = ActOnOpenMPDistScheduleClause(
10194 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
10195 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
10196 break;
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010197 case OMPC_defaultmap:
10198 enum { Modifier, DefaultmapKind };
10199 Res = ActOnOpenMPDefaultmapClause(
10200 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
10201 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
David Majnemer9d168222016-08-05 17:44:54 +000010202 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
10203 EndLoc);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010204 break;
Alexey Bataev3778b602014-07-17 07:32:53 +000010205 case OMPC_final:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010206 case OMPC_num_threads:
10207 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000010208 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010209 case OMPC_allocator:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010210 case OMPC_collapse:
10211 case OMPC_default:
10212 case OMPC_proc_bind:
10213 case OMPC_private:
10214 case OMPC_firstprivate:
10215 case OMPC_lastprivate:
10216 case OMPC_shared:
10217 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000010218 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000010219 case OMPC_in_reduction:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010220 case OMPC_linear:
10221 case OMPC_aligned:
10222 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010223 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010224 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000010225 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010226 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010227 case OMPC_mergeable:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010228 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010229 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000010230 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010231 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000010232 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000010233 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000010234 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010235 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010236 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000010237 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000010238 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010239 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +000010240 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000010241 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000010242 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000010243 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000010244 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000010245 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000010246 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000010247 case OMPC_hint:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010248 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000010249 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000010250 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000010251 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000010252 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000010253 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000010254 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000010255 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010256 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010257 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010258 case OMPC_atomic_default_mem_order:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010259 llvm_unreachable("Clause is not allowed.");
10260 }
10261 return Res;
10262}
10263
Alexey Bataev6402bca2015-12-28 07:25:51 +000010264static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
10265 OpenMPScheduleClauseModifier M2,
10266 SourceLocation M1Loc, SourceLocation M2Loc) {
10267 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
10268 SmallVector<unsigned, 2> Excluded;
10269 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
10270 Excluded.push_back(M2);
10271 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
10272 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
10273 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
10274 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
10275 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
10276 << getListOfPossibleValues(OMPC_schedule,
10277 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
10278 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
10279 Excluded)
10280 << getOpenMPClauseName(OMPC_schedule);
10281 return true;
10282 }
10283 return false;
10284}
10285
Alexey Bataev56dafe82014-06-20 07:16:17 +000010286OMPClause *Sema::ActOnOpenMPScheduleClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000010287 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
Alexey Bataev56dafe82014-06-20 07:16:17 +000010288 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
Alexey Bataev6402bca2015-12-28 07:25:51 +000010289 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
10290 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
10291 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
10292 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
10293 return nullptr;
10294 // OpenMP, 2.7.1, Loop Construct, Restrictions
10295 // Either the monotonic modifier or the nonmonotonic modifier can be specified
10296 // but not both.
10297 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
10298 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
10299 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
10300 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
10301 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
10302 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
10303 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
10304 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
10305 return nullptr;
10306 }
Alexey Bataev56dafe82014-06-20 07:16:17 +000010307 if (Kind == OMPC_SCHEDULE_unknown) {
10308 std::string Values;
Alexey Bataev6402bca2015-12-28 07:25:51 +000010309 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
10310 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
10311 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
10312 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
10313 Exclude);
10314 } else {
10315 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
10316 /*Last=*/OMPC_SCHEDULE_unknown);
Alexey Bataev56dafe82014-06-20 07:16:17 +000010317 }
10318 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
10319 << Values << getOpenMPClauseName(OMPC_schedule);
10320 return nullptr;
10321 }
Alexey Bataev6402bca2015-12-28 07:25:51 +000010322 // OpenMP, 2.7.1, Loop Construct, Restrictions
10323 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
10324 // schedule(guided).
10325 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
10326 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
10327 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
10328 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
10329 diag::err_omp_schedule_nonmonotonic_static);
10330 return nullptr;
10331 }
Alexey Bataev56dafe82014-06-20 07:16:17 +000010332 Expr *ValExpr = ChunkSize;
Alexey Bataev3392d762016-02-16 11:18:12 +000010333 Stmt *HelperValStmt = nullptr;
Alexey Bataev56dafe82014-06-20 07:16:17 +000010334 if (ChunkSize) {
10335 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
10336 !ChunkSize->isInstantiationDependent() &&
10337 !ChunkSize->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000010338 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
Alexey Bataev56dafe82014-06-20 07:16:17 +000010339 ExprResult Val =
10340 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
10341 if (Val.isInvalid())
10342 return nullptr;
10343
10344 ValExpr = Val.get();
10345
10346 // OpenMP [2.7.1, Restrictions]
10347 // chunk_size must be a loop invariant integer expression with a positive
10348 // value.
10349 llvm::APSInt Result;
Alexey Bataev040d5402015-05-12 08:35:28 +000010350 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
10351 if (Result.isSigned() && !Result.isStrictlyPositive()) {
10352 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
Alexey Bataeva0569352015-12-01 10:17:31 +000010353 << "schedule" << 1 << ChunkSize->getSourceRange();
Alexey Bataev040d5402015-05-12 08:35:28 +000010354 return nullptr;
10355 }
Alexey Bataev2ba67042017-11-28 21:11:44 +000010356 } else if (getOpenMPCaptureRegionForClause(
10357 DSAStack->getCurrentDirective(), OMPC_schedule) !=
10358 OMPD_unknown &&
Alexey Bataevb46cdea2016-06-15 11:20:48 +000010359 !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000010360 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000010361 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev5a3af132016-03-29 08:58:54 +000010362 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
10363 HelperValStmt = buildPreInits(Context, Captures);
Alexey Bataev56dafe82014-06-20 07:16:17 +000010364 }
10365 }
10366 }
10367
Alexey Bataev6402bca2015-12-28 07:25:51 +000010368 return new (Context)
10369 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
Alexey Bataev3392d762016-02-16 11:18:12 +000010370 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
Alexey Bataev56dafe82014-06-20 07:16:17 +000010371}
10372
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010373OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
10374 SourceLocation StartLoc,
10375 SourceLocation EndLoc) {
10376 OMPClause *Res = nullptr;
10377 switch (Kind) {
10378 case OMPC_ordered:
10379 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
10380 break;
Alexey Bataev236070f2014-06-20 11:19:47 +000010381 case OMPC_nowait:
10382 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
10383 break;
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010384 case OMPC_untied:
10385 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
10386 break;
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010387 case OMPC_mergeable:
10388 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
10389 break;
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010390 case OMPC_read:
10391 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
10392 break;
Alexey Bataevdea47612014-07-23 07:46:59 +000010393 case OMPC_write:
10394 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
10395 break;
Alexey Bataev67a4f222014-07-23 10:25:33 +000010396 case OMPC_update:
10397 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
10398 break;
Alexey Bataev459dec02014-07-24 06:46:57 +000010399 case OMPC_capture:
10400 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
10401 break;
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010402 case OMPC_seq_cst:
10403 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
10404 break;
Alexey Bataev346265e2015-09-25 10:37:12 +000010405 case OMPC_threads:
10406 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
10407 break;
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010408 case OMPC_simd:
10409 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
10410 break;
Alexey Bataevb825de12015-12-07 10:51:44 +000010411 case OMPC_nogroup:
10412 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
10413 break;
Kelvin Li1408f912018-09-26 04:28:39 +000010414 case OMPC_unified_address:
10415 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
10416 break;
Patrick Lyster4a370b92018-10-01 13:47:43 +000010417 case OMPC_unified_shared_memory:
10418 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
10419 break;
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010420 case OMPC_reverse_offload:
10421 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
10422 break;
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010423 case OMPC_dynamic_allocators:
10424 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
10425 break;
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010426 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000010427 case OMPC_final:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010428 case OMPC_num_threads:
10429 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000010430 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010431 case OMPC_allocator:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010432 case OMPC_collapse:
10433 case OMPC_schedule:
10434 case OMPC_private:
10435 case OMPC_firstprivate:
10436 case OMPC_lastprivate:
10437 case OMPC_shared:
10438 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000010439 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000010440 case OMPC_in_reduction:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010441 case OMPC_linear:
10442 case OMPC_aligned:
10443 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010444 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010445 case OMPC_default:
10446 case OMPC_proc_bind:
10447 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010448 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000010449 case OMPC_flush:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010450 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000010451 case OMPC_device:
Kelvin Li0bff7af2015-11-23 05:32:03 +000010452 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000010453 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000010454 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000010455 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000010456 case OMPC_grainsize:
Alexey Bataev382967a2015-12-08 12:06:20 +000010457 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000010458 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000010459 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010460 case OMPC_defaultmap:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010461 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000010462 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000010463 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000010464 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000010465 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000010466 case OMPC_is_device_ptr:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010467 case OMPC_atomic_default_mem_order:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010468 llvm_unreachable("Clause is not allowed.");
10469 }
10470 return Res;
10471}
10472
Alexey Bataev236070f2014-06-20 11:19:47 +000010473OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
10474 SourceLocation EndLoc) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +000010475 DSAStack->setNowaitRegion();
Alexey Bataev236070f2014-06-20 11:19:47 +000010476 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
10477}
10478
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010479OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
10480 SourceLocation EndLoc) {
10481 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
10482}
10483
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010484OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
10485 SourceLocation EndLoc) {
10486 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
10487}
10488
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010489OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
10490 SourceLocation EndLoc) {
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010491 return new (Context) OMPReadClause(StartLoc, EndLoc);
10492}
10493
Alexey Bataevdea47612014-07-23 07:46:59 +000010494OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
10495 SourceLocation EndLoc) {
10496 return new (Context) OMPWriteClause(StartLoc, EndLoc);
10497}
10498
Alexey Bataev67a4f222014-07-23 10:25:33 +000010499OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
10500 SourceLocation EndLoc) {
10501 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
10502}
10503
Alexey Bataev459dec02014-07-24 06:46:57 +000010504OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
10505 SourceLocation EndLoc) {
10506 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
10507}
10508
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010509OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
10510 SourceLocation EndLoc) {
10511 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
10512}
10513
Alexey Bataev346265e2015-09-25 10:37:12 +000010514OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
10515 SourceLocation EndLoc) {
10516 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
10517}
10518
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010519OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
10520 SourceLocation EndLoc) {
10521 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
10522}
10523
Alexey Bataevb825de12015-12-07 10:51:44 +000010524OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
10525 SourceLocation EndLoc) {
10526 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
10527}
10528
Kelvin Li1408f912018-09-26 04:28:39 +000010529OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
10530 SourceLocation EndLoc) {
10531 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
10532}
10533
Patrick Lyster4a370b92018-10-01 13:47:43 +000010534OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
10535 SourceLocation EndLoc) {
10536 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
10537}
10538
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010539OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
10540 SourceLocation EndLoc) {
10541 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
10542}
10543
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010544OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
10545 SourceLocation EndLoc) {
10546 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
10547}
10548
Alexey Bataevc5e02582014-06-16 07:08:35 +000010549OMPClause *Sema::ActOnOpenMPVarListClause(
10550 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
Michael Kruse4304e9d2019-02-19 16:38:20 +000010551 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
10552 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
10553 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind,
Kelvin Lief579432018-12-18 22:18:41 +000010554 OpenMPLinearClauseKind LinKind,
10555 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
Michael Kruse4304e9d2019-02-19 16:38:20 +000010556 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType,
10557 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) {
10558 SourceLocation StartLoc = Locs.StartLoc;
10559 SourceLocation LParenLoc = Locs.LParenLoc;
10560 SourceLocation EndLoc = Locs.EndLoc;
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010561 OMPClause *Res = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010562 switch (Kind) {
10563 case OMPC_private:
10564 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10565 break;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010566 case OMPC_firstprivate:
10567 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10568 break;
Alexander Musman1bb328c2014-06-04 13:06:39 +000010569 case OMPC_lastprivate:
10570 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10571 break;
Alexey Bataev758e55e2013-09-06 18:03:48 +000010572 case OMPC_shared:
10573 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
10574 break;
Alexey Bataevc5e02582014-06-16 07:08:35 +000010575 case OMPC_reduction:
Alexey Bataev23b69422014-06-18 07:08:49 +000010576 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
Michael Kruse4304e9d2019-02-19 16:38:20 +000010577 EndLoc, ReductionOrMapperIdScopeSpec,
10578 ReductionOrMapperId);
Alexey Bataevc5e02582014-06-16 07:08:35 +000010579 break;
Alexey Bataev169d96a2017-07-18 20:17:46 +000010580 case OMPC_task_reduction:
10581 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
Michael Kruse4304e9d2019-02-19 16:38:20 +000010582 EndLoc, ReductionOrMapperIdScopeSpec,
10583 ReductionOrMapperId);
Alexey Bataev169d96a2017-07-18 20:17:46 +000010584 break;
Alexey Bataevfa312f32017-07-21 18:48:21 +000010585 case OMPC_in_reduction:
Michael Kruse4304e9d2019-02-19 16:38:20 +000010586 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10587 EndLoc, ReductionOrMapperIdScopeSpec,
10588 ReductionOrMapperId);
Alexey Bataevfa312f32017-07-21 18:48:21 +000010589 break;
Alexander Musman8dba6642014-04-22 13:09:42 +000010590 case OMPC_linear:
10591 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
Kelvin Li0bff7af2015-11-23 05:32:03 +000010592 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
Alexander Musman8dba6642014-04-22 13:09:42 +000010593 break;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000010594 case OMPC_aligned:
10595 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
10596 ColonLoc, EndLoc);
10597 break;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000010598 case OMPC_copyin:
10599 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
10600 break;
Alexey Bataevbae9a792014-06-27 10:37:06 +000010601 case OMPC_copyprivate:
10602 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10603 break;
Alexey Bataev6125da92014-07-21 11:26:11 +000010604 case OMPC_flush:
10605 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
10606 break;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010607 case OMPC_depend:
David Majnemer9d168222016-08-05 17:44:54 +000010608 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
Kelvin Li0bff7af2015-11-23 05:32:03 +000010609 StartLoc, LParenLoc, EndLoc);
10610 break;
10611 case OMPC_map:
Michael Kruse4304e9d2019-02-19 16:38:20 +000010612 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
10613 ReductionOrMapperIdScopeSpec,
10614 ReductionOrMapperId, MapType, IsMapTypeImplicit,
10615 DepLinMapLoc, ColonLoc, VarList, Locs);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010616 break;
Samuel Antao661c0902016-05-26 17:39:58 +000010617 case OMPC_to:
Michael Kruse01f670d2019-02-22 22:29:42 +000010618 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
10619 ReductionOrMapperId, Locs);
Samuel Antao661c0902016-05-26 17:39:58 +000010620 break;
Samuel Antaoec172c62016-05-26 17:49:04 +000010621 case OMPC_from:
Michael Kruse0336c752019-02-25 20:34:15 +000010622 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
10623 ReductionOrMapperId, Locs);
Samuel Antaoec172c62016-05-26 17:49:04 +000010624 break;
Carlo Bertolli2404b172016-07-13 15:37:16 +000010625 case OMPC_use_device_ptr:
Michael Kruse4304e9d2019-02-19 16:38:20 +000010626 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
Carlo Bertolli2404b172016-07-13 15:37:16 +000010627 break;
Carlo Bertolli70594e92016-07-13 17:16:49 +000010628 case OMPC_is_device_ptr:
Michael Kruse4304e9d2019-02-19 16:38:20 +000010629 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
Carlo Bertolli70594e92016-07-13 17:16:49 +000010630 break;
Alexey Bataeve04483e2019-03-27 14:14:31 +000010631 case OMPC_allocate:
10632 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
10633 ColonLoc, EndLoc);
10634 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010635 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000010636 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +000010637 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +000010638 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000010639 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010640 case OMPC_allocator:
Alexander Musman8bd31e62014-05-27 15:12:19 +000010641 case OMPC_collapse:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010642 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010643 case OMPC_proc_bind:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010644 case OMPC_schedule:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000010645 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000010646 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010647 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010648 case OMPC_mergeable:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010649 case OMPC_threadprivate:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010650 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000010651 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000010652 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000010653 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010654 case OMPC_seq_cst:
Michael Wonge710d542015-08-07 16:16:36 +000010655 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000010656 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010657 case OMPC_simd:
Kelvin Li099bb8c2015-11-24 20:50:12 +000010658 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000010659 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000010660 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000010661 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000010662 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000010663 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000010664 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000010665 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010666 case OMPC_defaultmap:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010667 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000010668 case OMPC_uniform:
Kelvin Li1408f912018-09-26 04:28:39 +000010669 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000010670 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010671 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010672 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010673 case OMPC_atomic_default_mem_order:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010674 llvm_unreachable("Clause is not allowed.");
10675 }
10676 return Res;
10677}
10678
Alexey Bataev90c228f2016-02-08 09:29:13 +000010679ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
Alexey Bataev61205072016-03-02 04:57:40 +000010680 ExprObjectKind OK, SourceLocation Loc) {
Alexey Bataev90c228f2016-02-08 09:29:13 +000010681 ExprResult Res = BuildDeclRefExpr(
10682 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
10683 if (!Res.isUsable())
10684 return ExprError();
10685 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
10686 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
10687 if (!Res.isUsable())
10688 return ExprError();
10689 }
10690 if (VK != VK_LValue && Res.get()->isGLValue()) {
10691 Res = DefaultLvalueConversion(Res.get());
10692 if (!Res.isUsable())
10693 return ExprError();
10694 }
10695 return Res;
10696}
10697
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010698OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
10699 SourceLocation StartLoc,
10700 SourceLocation LParenLoc,
10701 SourceLocation EndLoc) {
10702 SmallVector<Expr *, 8> Vars;
Alexey Bataev03b340a2014-10-21 03:16:40 +000010703 SmallVector<Expr *, 8> PrivateCopies;
Alexey Bataeve3727102018-04-18 15:57:46 +000010704 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000010705 assert(RefExpr && "NULL expr in OpenMP private clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000010706 SourceLocation ELoc;
10707 SourceRange ERange;
10708 Expr *SimpleRefExpr = RefExpr;
10709 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevd985eda2016-02-10 11:29:16 +000010710 if (Res.second) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010711 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000010712 Vars.push_back(RefExpr);
Alexey Bataev03b340a2014-10-21 03:16:40 +000010713 PrivateCopies.push_back(nullptr);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010714 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000010715 ValueDecl *D = Res.first;
10716 if (!D)
10717 continue;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010718
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010719 QualType Type = D->getType();
10720 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010721
10722 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10723 // A variable that appears in a private clause must not have an incomplete
10724 // type or a reference type.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010725 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010726 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000010727 Type = Type.getNonReferenceType();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010728
Joel E. Dennye6234d1422019-01-04 22:11:31 +000010729 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10730 // A variable that is privatized must not have a const-qualified type
10731 // unless it is of class type with a mutable member. This restriction does
10732 // not apply to the firstprivate clause.
10733 //
10734 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
10735 // A variable that appears in a private clause must not have a
10736 // const-qualified type unless it is of class type with a mutable member.
Joel E. Dennyd2649292019-01-04 22:11:56 +000010737 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
Joel E. Dennye6234d1422019-01-04 22:11:31 +000010738 continue;
10739
Alexey Bataev758e55e2013-09-06 18:03:48 +000010740 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10741 // in a Construct]
10742 // Variables with the predetermined data-sharing attributes may not be
10743 // listed in data-sharing attributes clauses, except for the cases
10744 // listed below. For these exceptions only, listing a predetermined
10745 // variable in a data-sharing attribute clause is allowed and overrides
10746 // the variable's predetermined data-sharing attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +000010747 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataev758e55e2013-09-06 18:03:48 +000010748 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
Alexey Bataeved09d242014-05-28 05:53:51 +000010749 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10750 << getOpenMPClauseName(OMPC_private);
Alexey Bataeve3727102018-04-18 15:57:46 +000010751 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev758e55e2013-09-06 18:03:48 +000010752 continue;
10753 }
10754
Alexey Bataeve3727102018-04-18 15:57:46 +000010755 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010756 // Variably modified types are not supported for tasks.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000010757 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
Kelvin Libf594a52016-12-17 05:48:59 +000010758 isOpenMPTaskingDirective(CurrDir)) {
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010759 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10760 << getOpenMPClauseName(OMPC_private) << Type
Kelvin Libf594a52016-12-17 05:48:59 +000010761 << getOpenMPDirectiveName(CurrDir);
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010762 bool IsDecl =
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010763 !VD ||
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010764 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010765 Diag(D->getLocation(),
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010766 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010767 << D;
Alexey Bataevccb59ec2015-05-19 08:44:56 +000010768 continue;
10769 }
10770
Carlo Bertollib74bfc82016-03-18 21:43:32 +000010771 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10772 // A list item cannot appear in both a map clause and a data-sharing
10773 // attribute clause on the same construct
Alexey Bataeve3727102018-04-18 15:57:46 +000010774 if (isOpenMPTargetExecutionDirective(CurrDir)) {
Samuel Antao6890b092016-07-28 14:25:09 +000010775 OpenMPClauseKind ConflictKind;
Samuel Antao90927002016-04-26 14:54:23 +000010776 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000010777 VD, /*CurrentRegionOnly=*/true,
Samuel Antao6890b092016-07-28 14:25:09 +000010778 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
10779 OpenMPClauseKind WhereFoundClauseKind) -> bool {
10780 ConflictKind = WhereFoundClauseKind;
10781 return true;
10782 })) {
10783 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000010784 << getOpenMPClauseName(OMPC_private)
Samuel Antao6890b092016-07-28 14:25:09 +000010785 << getOpenMPClauseName(ConflictKind)
Kelvin Libf594a52016-12-17 05:48:59 +000010786 << getOpenMPDirectiveName(CurrDir);
Alexey Bataeve3727102018-04-18 15:57:46 +000010787 reportOriginalDsa(*this, DSAStack, D, DVar);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000010788 continue;
10789 }
10790 }
10791
Alexey Bataevf120c0d2015-05-19 07:46:42 +000010792 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
10793 // A variable of class type (or array thereof) that appears in a private
10794 // clause requires an accessible, unambiguous default constructor for the
10795 // class type.
Alexey Bataev03b340a2014-10-21 03:16:40 +000010796 // Generate helper private variable and initialize it with the default
10797 // value. The address of the original variable is replaced by the address of
10798 // the new private variable in CodeGen. This new variable is not added to
10799 // IdResolver, so the code in the OpenMP region uses original variable for
10800 // proper diagnostics.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000010801 Type = Type.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000010802 VarDecl *VDPrivate =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000010803 buildVarDecl(*this, ELoc, Type, D->getName(),
10804 D->hasAttrs() ? &D->getAttrs() : nullptr,
10805 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Richard Smith3beb7c62017-01-12 02:27:38 +000010806 ActOnUninitializedDecl(VDPrivate);
Alexey Bataev03b340a2014-10-21 03:16:40 +000010807 if (VDPrivate->isInvalidDecl())
10808 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +000010809 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000010810 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
Alexey Bataev03b340a2014-10-21 03:16:40 +000010811
Alexey Bataev90c228f2016-02-08 09:29:13 +000010812 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000010813 if (!VD && !CurContext->isDependentContext())
Alexey Bataev61205072016-03-02 04:57:40 +000010814 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataev90c228f2016-02-08 09:29:13 +000010815 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000010816 Vars.push_back((VD || CurContext->isDependentContext())
10817 ? RefExpr->IgnoreParens()
10818 : Ref);
Alexey Bataev03b340a2014-10-21 03:16:40 +000010819 PrivateCopies.push_back(VDPrivateRefExpr);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010820 }
10821
Alexey Bataeved09d242014-05-28 05:53:51 +000010822 if (Vars.empty())
10823 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010824
Alexey Bataev03b340a2014-10-21 03:16:40 +000010825 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
10826 PrivateCopies);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000010827}
10828
Alexey Bataev4a5bb772014-10-08 14:01:46 +000010829namespace {
10830class DiagsUninitializedSeveretyRAII {
10831private:
10832 DiagnosticsEngine &Diags;
10833 SourceLocation SavedLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +000010834 bool IsIgnored = false;
Alexey Bataev4a5bb772014-10-08 14:01:46 +000010835
10836public:
10837 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
10838 bool IsIgnored)
10839 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
10840 if (!IsIgnored) {
10841 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
10842 /*Map*/ diag::Severity::Ignored, Loc);
10843 }
10844 }
10845 ~DiagsUninitializedSeveretyRAII() {
10846 if (!IsIgnored)
10847 Diags.popMappings(SavedLoc);
10848 }
10849};
Alexander Kornienkoab9db512015-06-22 23:07:51 +000010850}
Alexey Bataev4a5bb772014-10-08 14:01:46 +000010851
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010852OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
10853 SourceLocation StartLoc,
10854 SourceLocation LParenLoc,
10855 SourceLocation EndLoc) {
10856 SmallVector<Expr *, 8> Vars;
Alexey Bataev4a5bb772014-10-08 14:01:46 +000010857 SmallVector<Expr *, 8> PrivateCopies;
10858 SmallVector<Expr *, 8> Inits;
Alexey Bataev417089f2016-02-17 13:19:37 +000010859 SmallVector<Decl *, 4> ExprCaptures;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010860 bool IsImplicitClause =
10861 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
Alexey Bataeve3727102018-04-18 15:57:46 +000010862 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010863
Alexey Bataeve3727102018-04-18 15:57:46 +000010864 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000010865 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000010866 SourceLocation ELoc;
10867 SourceRange ERange;
10868 Expr *SimpleRefExpr = RefExpr;
10869 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevd985eda2016-02-10 11:29:16 +000010870 if (Res.second) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010871 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000010872 Vars.push_back(RefExpr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000010873 PrivateCopies.push_back(nullptr);
10874 Inits.push_back(nullptr);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010875 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000010876 ValueDecl *D = Res.first;
10877 if (!D)
10878 continue;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010879
Alexey Bataev60da77e2016-02-29 05:54:20 +000010880 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
Alexey Bataevd985eda2016-02-10 11:29:16 +000010881 QualType Type = D->getType();
10882 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010883
10884 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10885 // A variable that appears in a private clause must not have an incomplete
10886 // type or a reference type.
10887 if (RequireCompleteType(ELoc, Type,
Alexey Bataevd985eda2016-02-10 11:29:16 +000010888 diag::err_omp_firstprivate_incomplete_type))
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010889 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000010890 Type = Type.getNonReferenceType();
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010891
10892 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
10893 // A variable of class type (or array thereof) that appears in a private
Alexey Bataev23b69422014-06-18 07:08:49 +000010894 // clause requires an accessible, unambiguous copy constructor for the
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010895 // class type.
Alexey Bataeve3727102018-04-18 15:57:46 +000010896 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010897
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010898 // If an implicit firstprivate variable found it was checked already.
Alexey Bataev005248a2016-02-25 05:25:57 +000010899 DSAStackTy::DSAVarData TopDVar;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010900 if (!IsImplicitClause) {
Alexey Bataeve3727102018-04-18 15:57:46 +000010901 DSAStackTy::DSAVarData DVar =
10902 DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataev005248a2016-02-25 05:25:57 +000010903 TopDVar = DVar;
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010904 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexey Bataevf120c0d2015-05-19 07:46:42 +000010905 bool IsConstant = ElemType.isConstant(Context);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010906 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
10907 // A list item that specifies a given variable may not appear in more
10908 // than one clause on the same directive, except that a variable may be
10909 // specified in both firstprivate and lastprivate clauses.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010910 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10911 // A list item may appear in a firstprivate or lastprivate clause but not
10912 // both.
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010913 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
Alexey Bataevb358f992017-12-01 17:40:15 +000010914 (isOpenMPDistributeDirective(CurrDir) ||
10915 DVar.CKind != OMPC_lastprivate) &&
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010916 DVar.RefExpr) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010917 Diag(ELoc, diag::err_omp_wrong_dsa)
Alexey Bataeved09d242014-05-28 05:53:51 +000010918 << getOpenMPClauseName(DVar.CKind)
10919 << getOpenMPClauseName(OMPC_firstprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000010920 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010921 continue;
10922 }
10923
10924 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10925 // in a Construct]
10926 // Variables with the predetermined data-sharing attributes may not be
10927 // listed in data-sharing attributes clauses, except for the cases
10928 // listed below. For these exceptions only, listing a predetermined
10929 // variable in a data-sharing attribute clause is allowed and overrides
10930 // the variable's predetermined data-sharing attributes.
10931 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10932 // in a Construct, C/C++, p.2]
10933 // Variables with const-qualified type having no mutable member may be
10934 // listed in a firstprivate clause, even if they are static data members.
Alexey Bataevd985eda2016-02-10 11:29:16 +000010935 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010936 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
10937 Diag(ELoc, diag::err_omp_wrong_dsa)
Alexey Bataeved09d242014-05-28 05:53:51 +000010938 << getOpenMPClauseName(DVar.CKind)
10939 << getOpenMPClauseName(OMPC_firstprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000010940 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010941 continue;
10942 }
10943
10944 // OpenMP [2.9.3.4, Restrictions, p.2]
10945 // A list item that is private within a parallel region must not appear
10946 // in a firstprivate clause on a worksharing construct if any of the
10947 // worksharing regions arising from the worksharing construct ever bind
10948 // to any of the parallel regions arising from the parallel construct.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010949 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10950 // A list item that is private within a teams region must not appear in a
10951 // firstprivate clause on a distribute construct if any of the distribute
10952 // regions arising from the distribute construct ever bind to any of the
10953 // teams regions arising from the teams construct.
10954 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10955 // A list item that appears in a reduction clause of a teams construct
10956 // must not appear in a firstprivate clause on a distribute construct if
10957 // any of the distribute regions arising from the distribute construct
10958 // ever bind to any of the teams regions arising from the teams construct.
10959 if ((isOpenMPWorksharingDirective(CurrDir) ||
10960 isOpenMPDistributeDirective(CurrDir)) &&
Kelvin Li579e41c2016-11-30 23:51:03 +000010961 !isOpenMPParallelDirective(CurrDir) &&
10962 !isOpenMPTeamsDirective(CurrDir)) {
Alexey Bataevd985eda2016-02-10 11:29:16 +000010963 DVar = DSAStack->getImplicitDSA(D, true);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010964 if (DVar.CKind != OMPC_shared &&
10965 (isOpenMPParallelDirective(DVar.DKind) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010966 isOpenMPTeamsDirective(DVar.DKind) ||
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010967 DVar.DKind == OMPD_unknown)) {
Alexey Bataevf29276e2014-06-18 04:14:57 +000010968 Diag(ELoc, diag::err_omp_required_access)
10969 << getOpenMPClauseName(OMPC_firstprivate)
10970 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000010971 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevf29276e2014-06-18 04:14:57 +000010972 continue;
10973 }
10974 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +000010975 // OpenMP [2.9.3.4, Restrictions, p.3]
10976 // A list item that appears in a reduction clause of a parallel construct
10977 // must not appear in a firstprivate clause on a worksharing or task
10978 // construct if any of the worksharing or task regions arising from the
10979 // worksharing or task construct ever bind to any of the parallel regions
10980 // arising from the parallel construct.
10981 // OpenMP [2.9.3.4, Restrictions, p.4]
10982 // A list item that appears in a reduction clause in worksharing
10983 // construct must not appear in a firstprivate clause in a task construct
10984 // encountered during execution of any of the worksharing regions arising
10985 // from the worksharing construct.
Alexey Bataev35aaee62016-04-13 13:36:48 +000010986 if (isOpenMPTaskingDirective(CurrDir)) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000010987 DVar = DSAStack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +000010988 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
10989 [](OpenMPDirectiveKind K) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000010990 return isOpenMPParallelDirective(K) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010991 isOpenMPWorksharingDirective(K) ||
10992 isOpenMPTeamsDirective(K);
Alexey Bataev7ace49d2016-05-17 08:55:33 +000010993 },
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010994 /*FromParent=*/true);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010995 if (DVar.CKind == OMPC_reduction &&
10996 (isOpenMPParallelDirective(DVar.DKind) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000010997 isOpenMPWorksharingDirective(DVar.DKind) ||
10998 isOpenMPTeamsDirective(DVar.DKind))) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000010999 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
11000 << getOpenMPDirectiveName(DVar.DKind);
Alexey Bataeve3727102018-04-18 15:57:46 +000011001 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000011002 continue;
11003 }
11004 }
Carlo Bertolli6200a3d2015-12-14 14:51:25 +000011005
Carlo Bertollib74bfc82016-03-18 21:43:32 +000011006 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
11007 // A list item cannot appear in both a map clause and a data-sharing
11008 // attribute clause on the same construct
Alexey Bataevb358f992017-12-01 17:40:15 +000011009 if (isOpenMPTargetExecutionDirective(CurrDir)) {
Samuel Antao6890b092016-07-28 14:25:09 +000011010 OpenMPClauseKind ConflictKind;
Samuel Antao90927002016-04-26 14:54:23 +000011011 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000011012 VD, /*CurrentRegionOnly=*/true,
Alexey Bataeve3727102018-04-18 15:57:46 +000011013 [&ConflictKind](
11014 OMPClauseMappableExprCommon::MappableExprComponentListRef,
11015 OpenMPClauseKind WhereFoundClauseKind) {
Samuel Antao6890b092016-07-28 14:25:09 +000011016 ConflictKind = WhereFoundClauseKind;
11017 return true;
11018 })) {
11019 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000011020 << getOpenMPClauseName(OMPC_firstprivate)
Samuel Antao6890b092016-07-28 14:25:09 +000011021 << getOpenMPClauseName(ConflictKind)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000011022 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000011023 reportOriginalDsa(*this, DSAStack, D, DVar);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000011024 continue;
11025 }
11026 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011027 }
11028
Alexey Bataevccb59ec2015-05-19 08:44:56 +000011029 // Variably modified types are not supported for tasks.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000011030 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
Alexey Bataev35aaee62016-04-13 13:36:48 +000011031 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
Alexey Bataevccb59ec2015-05-19 08:44:56 +000011032 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11033 << getOpenMPClauseName(OMPC_firstprivate) << Type
11034 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11035 bool IsDecl =
Alexey Bataevd985eda2016-02-10 11:29:16 +000011036 !VD ||
Alexey Bataevccb59ec2015-05-19 08:44:56 +000011037 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataevd985eda2016-02-10 11:29:16 +000011038 Diag(D->getLocation(),
Alexey Bataevccb59ec2015-05-19 08:44:56 +000011039 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataevd985eda2016-02-10 11:29:16 +000011040 << D;
Alexey Bataevccb59ec2015-05-19 08:44:56 +000011041 continue;
11042 }
11043
Alexey Bataevf120c0d2015-05-19 07:46:42 +000011044 Type = Type.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000011045 VarDecl *VDPrivate =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000011046 buildVarDecl(*this, ELoc, Type, D->getName(),
11047 D->hasAttrs() ? &D->getAttrs() : nullptr,
11048 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011049 // Generate helper private variable and initialize it with the value of the
11050 // original variable. The address of the original variable is replaced by
11051 // the address of the new private variable in the CodeGen. This new variable
11052 // is not added to IdResolver, so the code in the OpenMP region uses
11053 // original variable for proper diagnostics and variable capturing.
11054 Expr *VDInitRefExpr = nullptr;
11055 // For arrays generate initializer for single element and replace it by the
11056 // original array element in CodeGen.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000011057 if (Type->isArrayType()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011058 VarDecl *VDInit =
Alexey Bataevd985eda2016-02-10 11:29:16 +000011059 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
Alexey Bataevf120c0d2015-05-19 07:46:42 +000011060 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
Alexey Bataeve3727102018-04-18 15:57:46 +000011061 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
Alexey Bataevf120c0d2015-05-19 07:46:42 +000011062 ElemType = ElemType.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000011063 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
11064 ".firstprivate.temp");
Alexey Bataev69c62a92015-04-15 04:52:20 +000011065 InitializedEntity Entity =
11066 InitializedEntity::InitializeVariable(VDInitTemp);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011067 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
11068
11069 InitializationSequence InitSeq(*this, Entity, Kind, Init);
11070 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
11071 if (Result.isInvalid())
11072 VDPrivate->setInvalidDecl();
11073 else
11074 VDPrivate->setInit(Result.getAs<Expr>());
Alexey Bataevf24e7b12015-10-08 09:10:53 +000011075 // Remove temp variable declaration.
11076 Context.Deallocate(VDInitTemp);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011077 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +000011078 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
11079 ".firstprivate.temp");
Alexey Bataevd985eda2016-02-10 11:29:16 +000011080 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
11081 RefExpr->getExprLoc());
Alexey Bataev69c62a92015-04-15 04:52:20 +000011082 AddInitializerToDecl(VDPrivate,
11083 DefaultLvalueConversion(VDInitRefExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000011084 /*DirectInit=*/false);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011085 }
11086 if (VDPrivate->isInvalidDecl()) {
11087 if (IsImplicitClause) {
Alexey Bataevd985eda2016-02-10 11:29:16 +000011088 Diag(RefExpr->getExprLoc(),
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011089 diag::note_omp_task_predetermined_firstprivate_here);
11090 }
11091 continue;
11092 }
11093 CurContext->addDecl(VDPrivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000011094 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Alexey Bataevd985eda2016-02-10 11:29:16 +000011095 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
11096 RefExpr->getExprLoc());
11097 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000011098 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011099 if (TopDVar.CKind == OMPC_lastprivate) {
Alexey Bataev005248a2016-02-25 05:25:57 +000011100 Ref = TopDVar.PrivateCopy;
Alexey Bataeve3727102018-04-18 15:57:46 +000011101 } else {
Alexey Bataev61205072016-03-02 04:57:40 +000011102 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
Alexey Bataeve3727102018-04-18 15:57:46 +000011103 if (!isOpenMPCapturedDecl(D))
Alexey Bataev005248a2016-02-25 05:25:57 +000011104 ExprCaptures.push_back(Ref->getDecl());
11105 }
Alexey Bataev417089f2016-02-17 13:19:37 +000011106 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000011107 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000011108 Vars.push_back((VD || CurContext->isDependentContext())
11109 ? RefExpr->IgnoreParens()
11110 : Ref);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000011111 PrivateCopies.push_back(VDPrivateRefExpr);
11112 Inits.push_back(VDInitRefExpr);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011113 }
11114
Alexey Bataeved09d242014-05-28 05:53:51 +000011115 if (Vars.empty())
11116 return nullptr;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011117
11118 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataev5a3af132016-03-29 08:58:54 +000011119 Vars, PrivateCopies, Inits,
11120 buildPreInits(Context, ExprCaptures));
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011121}
11122
Alexander Musman1bb328c2014-06-04 13:06:39 +000011123OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
11124 SourceLocation StartLoc,
11125 SourceLocation LParenLoc,
11126 SourceLocation EndLoc) {
11127 SmallVector<Expr *, 8> Vars;
Alexey Bataev38e89532015-04-16 04:54:05 +000011128 SmallVector<Expr *, 8> SrcExprs;
11129 SmallVector<Expr *, 8> DstExprs;
11130 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataev005248a2016-02-25 05:25:57 +000011131 SmallVector<Decl *, 4> ExprCaptures;
11132 SmallVector<Expr *, 4> ExprPostUpdates;
Alexey Bataeve3727102018-04-18 15:57:46 +000011133 for (Expr *RefExpr : VarList) {
Alexander Musman1bb328c2014-06-04 13:06:39 +000011134 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000011135 SourceLocation ELoc;
11136 SourceRange ERange;
11137 Expr *SimpleRefExpr = RefExpr;
11138 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev74caaf22016-02-20 04:09:36 +000011139 if (Res.second) {
Alexander Musman1bb328c2014-06-04 13:06:39 +000011140 // It will be analyzed later.
11141 Vars.push_back(RefExpr);
Alexey Bataev38e89532015-04-16 04:54:05 +000011142 SrcExprs.push_back(nullptr);
11143 DstExprs.push_back(nullptr);
11144 AssignmentOps.push_back(nullptr);
Alexander Musman1bb328c2014-06-04 13:06:39 +000011145 }
Alexey Bataev74caaf22016-02-20 04:09:36 +000011146 ValueDecl *D = Res.first;
11147 if (!D)
11148 continue;
Alexander Musman1bb328c2014-06-04 13:06:39 +000011149
Alexey Bataev74caaf22016-02-20 04:09:36 +000011150 QualType Type = D->getType();
11151 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musman1bb328c2014-06-04 13:06:39 +000011152
11153 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
11154 // A variable that appears in a lastprivate clause must not have an
11155 // incomplete type or a reference type.
11156 if (RequireCompleteType(ELoc, Type,
Alexey Bataev74caaf22016-02-20 04:09:36 +000011157 diag::err_omp_lastprivate_incomplete_type))
Alexander Musman1bb328c2014-06-04 13:06:39 +000011158 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000011159 Type = Type.getNonReferenceType();
Alexander Musman1bb328c2014-06-04 13:06:39 +000011160
Joel E. Dennye6234d1422019-01-04 22:11:31 +000011161 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
11162 // A variable that is privatized must not have a const-qualified type
11163 // unless it is of class type with a mutable member. This restriction does
11164 // not apply to the firstprivate clause.
11165 //
11166 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
11167 // A variable that appears in a lastprivate clause must not have a
11168 // const-qualified type unless it is of class type with a mutable member.
Joel E. Dennyd2649292019-01-04 22:11:56 +000011169 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
Joel E. Dennye6234d1422019-01-04 22:11:31 +000011170 continue;
11171
Alexey Bataeveffbdf12017-07-21 17:24:30 +000011172 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexander Musman1bb328c2014-06-04 13:06:39 +000011173 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11174 // in a Construct]
11175 // Variables with the predetermined data-sharing attributes may not be
11176 // listed in data-sharing attributes clauses, except for the cases
11177 // listed below.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000011178 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
11179 // A list item may appear in a firstprivate or lastprivate clause but not
11180 // both.
Alexey Bataeve3727102018-04-18 15:57:46 +000011181 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexander Musman1bb328c2014-06-04 13:06:39 +000011182 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
Alexey Bataevb358f992017-12-01 17:40:15 +000011183 (isOpenMPDistributeDirective(CurrDir) ||
11184 DVar.CKind != OMPC_firstprivate) &&
Alexander Musman1bb328c2014-06-04 13:06:39 +000011185 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
11186 Diag(ELoc, diag::err_omp_wrong_dsa)
11187 << getOpenMPClauseName(DVar.CKind)
11188 << getOpenMPClauseName(OMPC_lastprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000011189 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexander Musman1bb328c2014-06-04 13:06:39 +000011190 continue;
11191 }
11192
Alexey Bataevf29276e2014-06-18 04:14:57 +000011193 // OpenMP [2.14.3.5, Restrictions, p.2]
11194 // A list item that is private within a parallel region, or that appears in
11195 // the reduction clause of a parallel construct, must not appear in a
11196 // lastprivate clause on a worksharing construct if any of the corresponding
11197 // worksharing regions ever binds to any of the corresponding parallel
11198 // regions.
Alexey Bataev39f915b82015-05-08 10:41:21 +000011199 DSAStackTy::DSAVarData TopDVar = DVar;
Alexey Bataev549210e2014-06-24 04:39:47 +000011200 if (isOpenMPWorksharingDirective(CurrDir) &&
Kelvin Li579e41c2016-11-30 23:51:03 +000011201 !isOpenMPParallelDirective(CurrDir) &&
11202 !isOpenMPTeamsDirective(CurrDir)) {
Alexey Bataev74caaf22016-02-20 04:09:36 +000011203 DVar = DSAStack->getImplicitDSA(D, true);
Alexey Bataevf29276e2014-06-18 04:14:57 +000011204 if (DVar.CKind != OMPC_shared) {
11205 Diag(ELoc, diag::err_omp_required_access)
11206 << getOpenMPClauseName(OMPC_lastprivate)
11207 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000011208 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevf29276e2014-06-18 04:14:57 +000011209 continue;
11210 }
11211 }
Alexey Bataev74caaf22016-02-20 04:09:36 +000011212
Alexander Musman1bb328c2014-06-04 13:06:39 +000011213 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
Alexey Bataevf29276e2014-06-18 04:14:57 +000011214 // A variable of class type (or array thereof) that appears in a
11215 // lastprivate clause requires an accessible, unambiguous default
11216 // constructor for the class type, unless the list item is also specified
11217 // in a firstprivate clause.
Alexander Musman1bb328c2014-06-04 13:06:39 +000011218 // A variable of class type (or array thereof) that appears in a
11219 // lastprivate clause requires an accessible, unambiguous copy assignment
11220 // operator for the class type.
Alexey Bataev38e89532015-04-16 04:54:05 +000011221 Type = Context.getBaseElementType(Type).getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000011222 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
11223 Type.getUnqualifiedType(), ".lastprivate.src",
11224 D->hasAttrs() ? &D->getAttrs() : nullptr);
11225 DeclRefExpr *PseudoSrcExpr =
Alexey Bataev74caaf22016-02-20 04:09:36 +000011226 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
Alexey Bataeve3727102018-04-18 15:57:46 +000011227 VarDecl *DstVD =
Alexey Bataev60da77e2016-02-29 05:54:20 +000011228 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
Alexey Bataev74caaf22016-02-20 04:09:36 +000011229 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000011230 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
Alexey Bataev38e89532015-04-16 04:54:05 +000011231 // For arrays generate assignment operation for single element and replace
11232 // it by the original array element in CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000011233 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
11234 PseudoDstExpr, PseudoSrcExpr);
Alexey Bataev38e89532015-04-16 04:54:05 +000011235 if (AssignmentOp.isInvalid())
11236 continue;
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000011237 AssignmentOp =
11238 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev38e89532015-04-16 04:54:05 +000011239 if (AssignmentOp.isInvalid())
11240 continue;
Alexander Musman1bb328c2014-06-04 13:06:39 +000011241
Alexey Bataev74caaf22016-02-20 04:09:36 +000011242 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000011243 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011244 if (TopDVar.CKind == OMPC_firstprivate) {
Alexey Bataev005248a2016-02-25 05:25:57 +000011245 Ref = TopDVar.PrivateCopy;
Alexey Bataeve3727102018-04-18 15:57:46 +000011246 } else {
Alexey Bataev61205072016-03-02 04:57:40 +000011247 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000011248 if (!isOpenMPCapturedDecl(D))
Alexey Bataev005248a2016-02-25 05:25:57 +000011249 ExprCaptures.push_back(Ref->getDecl());
11250 }
11251 if (TopDVar.CKind == OMPC_firstprivate ||
Alexey Bataeve3727102018-04-18 15:57:46 +000011252 (!isOpenMPCapturedDecl(D) &&
Alexey Bataev2bbf7212016-03-03 03:52:24 +000011253 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
Alexey Bataev005248a2016-02-25 05:25:57 +000011254 ExprResult RefRes = DefaultLvalueConversion(Ref);
11255 if (!RefRes.isUsable())
11256 continue;
11257 ExprResult PostUpdateRes =
Alexey Bataev60da77e2016-02-29 05:54:20 +000011258 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11259 RefRes.get());
Alexey Bataev005248a2016-02-25 05:25:57 +000011260 if (!PostUpdateRes.isUsable())
11261 continue;
Alexey Bataev78849fb2016-03-09 09:49:00 +000011262 ExprPostUpdates.push_back(
11263 IgnoredValueConversions(PostUpdateRes.get()).get());
Alexey Bataev005248a2016-02-25 05:25:57 +000011264 }
11265 }
Alexey Bataev7ace49d2016-05-17 08:55:33 +000011266 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000011267 Vars.push_back((VD || CurContext->isDependentContext())
11268 ? RefExpr->IgnoreParens()
11269 : Ref);
Alexey Bataev38e89532015-04-16 04:54:05 +000011270 SrcExprs.push_back(PseudoSrcExpr);
11271 DstExprs.push_back(PseudoDstExpr);
11272 AssignmentOps.push_back(AssignmentOp.get());
Alexander Musman1bb328c2014-06-04 13:06:39 +000011273 }
11274
11275 if (Vars.empty())
11276 return nullptr;
11277
11278 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataev005248a2016-02-25 05:25:57 +000011279 Vars, SrcExprs, DstExprs, AssignmentOps,
Alexey Bataev5a3af132016-03-29 08:58:54 +000011280 buildPreInits(Context, ExprCaptures),
11281 buildPostUpdate(*this, ExprPostUpdates));
Alexander Musman1bb328c2014-06-04 13:06:39 +000011282}
11283
Alexey Bataev758e55e2013-09-06 18:03:48 +000011284OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
11285 SourceLocation StartLoc,
11286 SourceLocation LParenLoc,
11287 SourceLocation EndLoc) {
11288 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +000011289 for (Expr *RefExpr : VarList) {
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011290 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000011291 SourceLocation ELoc;
11292 SourceRange ERange;
11293 Expr *SimpleRefExpr = RefExpr;
11294 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011295 if (Res.second) {
Alexey Bataev758e55e2013-09-06 18:03:48 +000011296 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000011297 Vars.push_back(RefExpr);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011298 }
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011299 ValueDecl *D = Res.first;
11300 if (!D)
11301 continue;
Alexey Bataev758e55e2013-09-06 18:03:48 +000011302
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011303 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011304 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
11305 // in a Construct]
11306 // Variables with the predetermined data-sharing attributes may not be
11307 // listed in data-sharing attributes clauses, except for the cases
11308 // listed below. For these exceptions only, listing a predetermined
11309 // variable in a data-sharing attribute clause is allowed and overrides
11310 // the variable's predetermined data-sharing attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +000011311 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataeved09d242014-05-28 05:53:51 +000011312 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
11313 DVar.RefExpr) {
11314 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11315 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000011316 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011317 continue;
11318 }
11319
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011320 DeclRefExpr *Ref = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000011321 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
Alexey Bataev61205072016-03-02 04:57:40 +000011322 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
Alexey Bataevb7a34b62016-02-25 03:59:29 +000011323 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000011324 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
11325 ? RefExpr->IgnoreParens()
11326 : Ref);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011327 }
11328
Alexey Bataeved09d242014-05-28 05:53:51 +000011329 if (Vars.empty())
11330 return nullptr;
Alexey Bataev758e55e2013-09-06 18:03:48 +000011331
11332 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
11333}
11334
Alexey Bataevc5e02582014-06-16 07:08:35 +000011335namespace {
11336class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
11337 DSAStackTy *Stack;
11338
11339public:
11340 bool VisitDeclRefExpr(DeclRefExpr *E) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011341 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
11342 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataevc5e02582014-06-16 07:08:35 +000011343 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
11344 return false;
11345 if (DVar.CKind != OMPC_unknown)
11346 return true;
Alexey Bataev7ace49d2016-05-17 08:55:33 +000011347 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +000011348 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
Alexey Bataeveffbdf12017-07-21 17:24:30 +000011349 /*FromParent=*/true);
Alexey Bataeve3727102018-04-18 15:57:46 +000011350 return DVarPrivate.CKind != OMPC_unknown;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011351 }
11352 return false;
11353 }
11354 bool VisitStmt(Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011355 for (Stmt *Child : S->children()) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000011356 if (Child && Visit(Child))
11357 return true;
11358 }
11359 return false;
11360 }
Alexey Bataev23b69422014-06-18 07:08:49 +000011361 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
Alexey Bataevc5e02582014-06-16 07:08:35 +000011362};
Alexey Bataev23b69422014-06-18 07:08:49 +000011363} // namespace
Alexey Bataevc5e02582014-06-16 07:08:35 +000011364
Alexey Bataev60da77e2016-02-29 05:54:20 +000011365namespace {
11366// Transform MemberExpression for specified FieldDecl of current class to
11367// DeclRefExpr to specified OMPCapturedExprDecl.
11368class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
11369 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
Alexey Bataeve3727102018-04-18 15:57:46 +000011370 ValueDecl *Field = nullptr;
11371 DeclRefExpr *CapturedExpr = nullptr;
Alexey Bataev60da77e2016-02-29 05:54:20 +000011372
11373public:
11374 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
11375 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
11376
11377 ExprResult TransformMemberExpr(MemberExpr *E) {
11378 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
11379 E->getMemberDecl() == Field) {
Alexey Bataev61205072016-03-02 04:57:40 +000011380 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
Alexey Bataev60da77e2016-02-29 05:54:20 +000011381 return CapturedExpr;
11382 }
11383 return BaseTransform::TransformMemberExpr(E);
11384 }
11385 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
11386};
11387} // namespace
11388
Alexey Bataev97d18bf2018-04-11 19:21:00 +000011389template <typename T, typename U>
Michael Kruse4304e9d2019-02-19 16:38:20 +000011390static T filterLookupForUDReductionAndMapper(
11391 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011392 for (U &Set : Lookups) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011393 for (auto *D : Set) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011394 if (T Res = Gen(cast<ValueDecl>(D)))
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011395 return Res;
11396 }
11397 }
11398 return T();
11399}
11400
Alexey Bataev43b90b72018-09-12 16:31:59 +000011401static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
11402 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
11403
11404 for (auto RD : D->redecls()) {
11405 // Don't bother with extra checks if we already know this one isn't visible.
11406 if (RD == D)
11407 continue;
11408
11409 auto ND = cast<NamedDecl>(RD);
11410 if (LookupResult::isVisible(SemaRef, ND))
11411 return ND;
11412 }
11413
11414 return nullptr;
11415}
11416
11417static void
Michael Kruse4304e9d2019-02-19 16:38:20 +000011418argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
Alexey Bataev43b90b72018-09-12 16:31:59 +000011419 SourceLocation Loc, QualType Ty,
11420 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
11421 // Find all of the associated namespaces and classes based on the
11422 // arguments we have.
11423 Sema::AssociatedNamespaceSet AssociatedNamespaces;
11424 Sema::AssociatedClassSet AssociatedClasses;
11425 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
11426 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
11427 AssociatedClasses);
11428
11429 // C++ [basic.lookup.argdep]p3:
11430 // Let X be the lookup set produced by unqualified lookup (3.4.1)
11431 // and let Y be the lookup set produced by argument dependent
11432 // lookup (defined as follows). If X contains [...] then Y is
11433 // empty. Otherwise Y is the set of declarations found in the
11434 // namespaces associated with the argument types as described
11435 // below. The set of declarations found by the lookup of the name
11436 // is the union of X and Y.
11437 //
11438 // Here, we compute Y and add its members to the overloaded
11439 // candidate set.
11440 for (auto *NS : AssociatedNamespaces) {
11441 // When considering an associated namespace, the lookup is the
11442 // same as the lookup performed when the associated namespace is
11443 // used as a qualifier (3.4.3.2) except that:
11444 //
11445 // -- Any using-directives in the associated namespace are
11446 // ignored.
11447 //
11448 // -- Any namespace-scope friend functions declared in
11449 // associated classes are visible within their respective
11450 // namespaces even if they are not visible during an ordinary
11451 // lookup (11.4).
Michael Kruse4304e9d2019-02-19 16:38:20 +000011452 DeclContext::lookup_result R = NS->lookup(Id.getName());
Alexey Bataev43b90b72018-09-12 16:31:59 +000011453 for (auto *D : R) {
11454 auto *Underlying = D;
11455 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
11456 Underlying = USD->getTargetDecl();
11457
Michael Kruse4304e9d2019-02-19 16:38:20 +000011458 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
11459 !isa<OMPDeclareMapperDecl>(Underlying))
Alexey Bataev43b90b72018-09-12 16:31:59 +000011460 continue;
11461
11462 if (!SemaRef.isVisible(D)) {
11463 D = findAcceptableDecl(SemaRef, D);
11464 if (!D)
11465 continue;
11466 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
11467 Underlying = USD->getTargetDecl();
11468 }
11469 Lookups.emplace_back();
11470 Lookups.back().addDecl(Underlying);
11471 }
11472 }
11473}
11474
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011475static ExprResult
11476buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
11477 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
11478 const DeclarationNameInfo &ReductionId, QualType Ty,
11479 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
11480 if (ReductionIdScopeSpec.isInvalid())
11481 return ExprError();
11482 SmallVector<UnresolvedSet<8>, 4> Lookups;
11483 if (S) {
11484 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
11485 Lookup.suppressDiagnostics();
11486 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011487 NamedDecl *D = Lookup.getRepresentativeDecl();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011488 do {
11489 S = S->getParent();
11490 } while (S && !S->isDeclScope(D));
11491 if (S)
11492 S = S->getParent();
Alexey Bataev43b90b72018-09-12 16:31:59 +000011493 Lookups.emplace_back();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011494 Lookups.back().append(Lookup.begin(), Lookup.end());
11495 Lookup.clear();
11496 }
11497 } else if (auto *ULE =
11498 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
11499 Lookups.push_back(UnresolvedSet<8>());
11500 Decl *PrevD = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000011501 for (NamedDecl *D : ULE->decls()) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011502 if (D == PrevD)
11503 Lookups.push_back(UnresolvedSet<8>());
Don Hintonf170dff2019-03-19 06:14:14 +000011504 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011505 Lookups.back().addDecl(DRD);
11506 PrevD = D;
11507 }
11508 }
Alexey Bataevfdc20352017-08-25 15:43:55 +000011509 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
11510 Ty->isInstantiationDependentType() ||
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011511 Ty->containsUnexpandedParameterPack() ||
Michael Kruse4304e9d2019-02-19 16:38:20 +000011512 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011513 return !D->isInvalidDecl() &&
11514 (D->getType()->isDependentType() ||
11515 D->getType()->isInstantiationDependentType() ||
11516 D->getType()->containsUnexpandedParameterPack());
11517 })) {
11518 UnresolvedSet<8> ResSet;
Alexey Bataeve3727102018-04-18 15:57:46 +000011519 for (const UnresolvedSet<8> &Set : Lookups) {
Alexey Bataev43b90b72018-09-12 16:31:59 +000011520 if (Set.empty())
11521 continue;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011522 ResSet.append(Set.begin(), Set.end());
11523 // The last item marks the end of all declarations at the specified scope.
11524 ResSet.addDecl(Set[Set.size() - 1]);
11525 }
11526 return UnresolvedLookupExpr::Create(
11527 SemaRef.Context, /*NamingClass=*/nullptr,
11528 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
11529 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
11530 }
Alexey Bataev43b90b72018-09-12 16:31:59 +000011531 // Lookup inside the classes.
11532 // C++ [over.match.oper]p3:
11533 // For a unary operator @ with an operand of a type whose
11534 // cv-unqualified version is T1, and for a binary operator @ with
11535 // a left operand of a type whose cv-unqualified version is T1 and
11536 // a right operand of a type whose cv-unqualified version is T2,
11537 // three sets of candidate functions, designated member
11538 // candidates, non-member candidates and built-in candidates, are
11539 // constructed as follows:
11540 // -- If T1 is a complete class type or a class currently being
11541 // defined, the set of member candidates is the result of the
11542 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
11543 // the set of member candidates is empty.
11544 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
11545 Lookup.suppressDiagnostics();
11546 if (const auto *TyRec = Ty->getAs<RecordType>()) {
11547 // Complete the type if it can be completed.
11548 // If the type is neither complete nor being defined, bail out now.
11549 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
11550 TyRec->getDecl()->getDefinition()) {
11551 Lookup.clear();
11552 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
11553 if (Lookup.empty()) {
11554 Lookups.emplace_back();
11555 Lookups.back().append(Lookup.begin(), Lookup.end());
11556 }
11557 }
11558 }
11559 // Perform ADL.
Alexey Bataev09232662019-04-04 17:28:22 +000011560 if (SemaRef.getLangOpts().CPlusPlus)
Alexey Bataev74a04e82019-03-13 19:31:34 +000011561 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
Alexey Bataev09232662019-04-04 17:28:22 +000011562 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11563 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
11564 if (!D->isInvalidDecl() &&
11565 SemaRef.Context.hasSameType(D->getType(), Ty))
11566 return D;
11567 return nullptr;
11568 }))
11569 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
11570 VK_LValue, Loc);
11571 if (SemaRef.getLangOpts().CPlusPlus) {
Alexey Bataev74a04e82019-03-13 19:31:34 +000011572 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11573 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
11574 if (!D->isInvalidDecl() &&
11575 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
11576 !Ty.isMoreQualifiedThan(D->getType()))
11577 return D;
11578 return nullptr;
11579 })) {
11580 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
11581 /*DetectVirtual=*/false);
11582 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
11583 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
11584 VD->getType().getUnqualifiedType()))) {
11585 if (SemaRef.CheckBaseClassAccess(
11586 Loc, VD->getType(), Ty, Paths.front(),
11587 /*DiagID=*/0) != Sema::AR_inaccessible) {
11588 SemaRef.BuildBasePathArray(Paths, BasePath);
11589 return SemaRef.BuildDeclRefExpr(
11590 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
11591 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011592 }
11593 }
11594 }
11595 }
11596 if (ReductionIdScopeSpec.isSet()) {
11597 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
11598 return ExprError();
11599 }
11600 return ExprEmpty();
11601}
11602
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011603namespace {
11604/// Data for the reduction-based clauses.
11605struct ReductionData {
11606 /// List of original reduction items.
11607 SmallVector<Expr *, 8> Vars;
11608 /// List of private copies of the reduction items.
11609 SmallVector<Expr *, 8> Privates;
11610 /// LHS expressions for the reduction_op expressions.
11611 SmallVector<Expr *, 8> LHSs;
11612 /// RHS expressions for the reduction_op expressions.
11613 SmallVector<Expr *, 8> RHSs;
11614 /// Reduction operation expression.
11615 SmallVector<Expr *, 8> ReductionOps;
Alexey Bataev88202be2017-07-27 13:20:36 +000011616 /// Taskgroup descriptors for the corresponding reduction items in
11617 /// in_reduction clauses.
11618 SmallVector<Expr *, 8> TaskgroupDescriptors;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011619 /// List of captures for clause.
11620 SmallVector<Decl *, 4> ExprCaptures;
11621 /// List of postupdate expressions.
11622 SmallVector<Expr *, 4> ExprPostUpdates;
11623 ReductionData() = delete;
11624 /// Reserves required memory for the reduction data.
11625 ReductionData(unsigned Size) {
11626 Vars.reserve(Size);
11627 Privates.reserve(Size);
11628 LHSs.reserve(Size);
11629 RHSs.reserve(Size);
11630 ReductionOps.reserve(Size);
Alexey Bataev88202be2017-07-27 13:20:36 +000011631 TaskgroupDescriptors.reserve(Size);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011632 ExprCaptures.reserve(Size);
11633 ExprPostUpdates.reserve(Size);
11634 }
11635 /// Stores reduction item and reduction operation only (required for dependent
11636 /// reduction item).
11637 void push(Expr *Item, Expr *ReductionOp) {
11638 Vars.emplace_back(Item);
11639 Privates.emplace_back(nullptr);
11640 LHSs.emplace_back(nullptr);
11641 RHSs.emplace_back(nullptr);
11642 ReductionOps.emplace_back(ReductionOp);
Alexey Bataev88202be2017-07-27 13:20:36 +000011643 TaskgroupDescriptors.emplace_back(nullptr);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011644 }
11645 /// Stores reduction data.
Alexey Bataev88202be2017-07-27 13:20:36 +000011646 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
11647 Expr *TaskgroupDescriptor) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011648 Vars.emplace_back(Item);
11649 Privates.emplace_back(Private);
11650 LHSs.emplace_back(LHS);
11651 RHSs.emplace_back(RHS);
11652 ReductionOps.emplace_back(ReductionOp);
Alexey Bataev88202be2017-07-27 13:20:36 +000011653 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011654 }
11655};
11656} // namespace
11657
Alexey Bataeve3727102018-04-18 15:57:46 +000011658static bool checkOMPArraySectionConstantForReduction(
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000011659 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
11660 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
11661 const Expr *Length = OASE->getLength();
11662 if (Length == nullptr) {
11663 // For array sections of the form [1:] or [:], we would need to analyze
11664 // the lower bound...
11665 if (OASE->getColonLoc().isValid())
11666 return false;
11667
11668 // This is an array subscript which has implicit length 1!
11669 SingleElement = true;
11670 ArraySizes.push_back(llvm::APSInt::get(1));
11671 } else {
Fangrui Song407659a2018-11-30 23:41:18 +000011672 Expr::EvalResult Result;
11673 if (!Length->EvaluateAsInt(Result, Context))
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000011674 return false;
11675
Fangrui Song407659a2018-11-30 23:41:18 +000011676 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000011677 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
11678 ArraySizes.push_back(ConstantLengthValue);
11679 }
11680
11681 // Get the base of this array section and walk up from there.
11682 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
11683
11684 // We require length = 1 for all array sections except the right-most to
11685 // guarantee that the memory region is contiguous and has no holes in it.
11686 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
11687 Length = TempOASE->getLength();
11688 if (Length == nullptr) {
11689 // For array sections of the form [1:] or [:], we would need to analyze
11690 // the lower bound...
11691 if (OASE->getColonLoc().isValid())
11692 return false;
11693
11694 // This is an array subscript which has implicit length 1!
11695 ArraySizes.push_back(llvm::APSInt::get(1));
11696 } else {
Fangrui Song407659a2018-11-30 23:41:18 +000011697 Expr::EvalResult Result;
11698 if (!Length->EvaluateAsInt(Result, Context))
11699 return false;
11700
11701 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
11702 if (ConstantLengthValue.getSExtValue() != 1)
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000011703 return false;
11704
11705 ArraySizes.push_back(ConstantLengthValue);
11706 }
11707 Base = TempOASE->getBase()->IgnoreParenImpCasts();
11708 }
11709
11710 // If we have a single element, we don't need to add the implicit lengths.
11711 if (!SingleElement) {
11712 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
11713 // Has implicit length 1!
11714 ArraySizes.push_back(llvm::APSInt::get(1));
11715 Base = TempASE->getBase()->IgnoreParenImpCasts();
11716 }
11717 }
11718
11719 // This array section can be privatized as a single value or as a constant
11720 // sized array.
11721 return true;
11722}
11723
Alexey Bataeve3727102018-04-18 15:57:46 +000011724static bool actOnOMPReductionKindClause(
Alexey Bataev169d96a2017-07-18 20:17:46 +000011725 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
11726 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11727 SourceLocation ColonLoc, SourceLocation EndLoc,
11728 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011729 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011730 DeclarationName DN = ReductionId.getName();
11731 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
Alexey Bataevc5e02582014-06-16 07:08:35 +000011732 BinaryOperatorKind BOK = BO_Comma;
11733
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011734 ASTContext &Context = S.Context;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011735 // OpenMP [2.14.3.6, reduction clause]
11736 // C
11737 // reduction-identifier is either an identifier or one of the following
11738 // operators: +, -, *, &, |, ^, && and ||
11739 // C++
11740 // reduction-identifier is either an id-expression or one of the following
11741 // operators: +, -, *, &, |, ^, && and ||
Alexey Bataevc5e02582014-06-16 07:08:35 +000011742 switch (OOK) {
11743 case OO_Plus:
11744 case OO_Minus:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011745 BOK = BO_Add;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011746 break;
11747 case OO_Star:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011748 BOK = BO_Mul;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011749 break;
11750 case OO_Amp:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011751 BOK = BO_And;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011752 break;
11753 case OO_Pipe:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011754 BOK = BO_Or;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011755 break;
11756 case OO_Caret:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011757 BOK = BO_Xor;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011758 break;
11759 case OO_AmpAmp:
11760 BOK = BO_LAnd;
11761 break;
11762 case OO_PipePipe:
11763 BOK = BO_LOr;
11764 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011765 case OO_New:
11766 case OO_Delete:
11767 case OO_Array_New:
11768 case OO_Array_Delete:
11769 case OO_Slash:
11770 case OO_Percent:
11771 case OO_Tilde:
11772 case OO_Exclaim:
11773 case OO_Equal:
11774 case OO_Less:
11775 case OO_Greater:
11776 case OO_LessEqual:
11777 case OO_GreaterEqual:
11778 case OO_PlusEqual:
11779 case OO_MinusEqual:
11780 case OO_StarEqual:
11781 case OO_SlashEqual:
11782 case OO_PercentEqual:
11783 case OO_CaretEqual:
11784 case OO_AmpEqual:
11785 case OO_PipeEqual:
11786 case OO_LessLess:
11787 case OO_GreaterGreater:
11788 case OO_LessLessEqual:
11789 case OO_GreaterGreaterEqual:
11790 case OO_EqualEqual:
11791 case OO_ExclaimEqual:
Richard Smithd30b23d2017-12-01 02:13:10 +000011792 case OO_Spaceship:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011793 case OO_PlusPlus:
11794 case OO_MinusMinus:
11795 case OO_Comma:
11796 case OO_ArrowStar:
11797 case OO_Arrow:
11798 case OO_Call:
11799 case OO_Subscript:
11800 case OO_Conditional:
Richard Smith9be594e2015-10-22 05:12:22 +000011801 case OO_Coawait:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000011802 case NUM_OVERLOADED_OPERATORS:
11803 llvm_unreachable("Unexpected reduction identifier");
11804 case OO_None:
Alexey Bataeve3727102018-04-18 15:57:46 +000011805 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000011806 if (II->isStr("max"))
11807 BOK = BO_GT;
11808 else if (II->isStr("min"))
11809 BOK = BO_LT;
11810 }
11811 break;
11812 }
11813 SourceRange ReductionIdRange;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011814 if (ReductionIdScopeSpec.isValid())
Alexey Bataevc5e02582014-06-16 07:08:35 +000011815 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
Alexey Bataev4d4624c2017-07-20 16:47:47 +000011816 else
11817 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
Alexey Bataevc5e02582014-06-16 07:08:35 +000011818 ReductionIdRange.setEnd(ReductionId.getEndLoc());
Alexey Bataevc5e02582014-06-16 07:08:35 +000011819
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011820 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
11821 bool FirstIter = true;
Alexey Bataeve3727102018-04-18 15:57:46 +000011822 for (Expr *RefExpr : VarList) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000011823 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
Alexey Bataevc5e02582014-06-16 07:08:35 +000011824 // OpenMP [2.1, C/C++]
11825 // A list item is a variable or array section, subject to the restrictions
11826 // specified in Section 2.4 on page 42 and in each of the sections
11827 // describing clauses and directives for which a list appears.
11828 // OpenMP [2.14.3.3, Restrictions, p.1]
11829 // A variable that is part of another variable (as an array or
11830 // structure element) cannot appear in a private clause.
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011831 if (!FirstIter && IR != ER)
11832 ++IR;
11833 FirstIter = false;
Alexey Bataev60da77e2016-02-29 05:54:20 +000011834 SourceLocation ELoc;
11835 SourceRange ERange;
11836 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011837 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
Alexey Bataev60da77e2016-02-29 05:54:20 +000011838 /*AllowArraySection=*/true);
11839 if (Res.second) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011840 // Try to find 'declare reduction' corresponding construct before using
11841 // builtin/overloaded operators.
11842 QualType Type = Context.DependentTy;
11843 CXXCastPath BasePath;
11844 ExprResult DeclareReductionRef = buildDeclareReductionRef(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011845 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011846 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011847 Expr *ReductionOp = nullptr;
11848 if (S.CurContext->isDependentContext() &&
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011849 (DeclareReductionRef.isUnset() ||
11850 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011851 ReductionOp = DeclareReductionRef.get();
11852 // It will be analyzed later.
11853 RD.push(RefExpr, ReductionOp);
Alexey Bataevc5e02582014-06-16 07:08:35 +000011854 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000011855 ValueDecl *D = Res.first;
11856 if (!D)
11857 continue;
11858
Alexey Bataev88202be2017-07-27 13:20:36 +000011859 Expr *TaskgroupDescriptor = nullptr;
Alexey Bataeva1764212015-09-30 09:22:36 +000011860 QualType Type;
Alexey Bataev60da77e2016-02-29 05:54:20 +000011861 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
11862 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
Alexey Bataeve3727102018-04-18 15:57:46 +000011863 if (ASE) {
Alexey Bataev31300ed2016-02-04 11:27:03 +000011864 Type = ASE->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000011865 } else if (OASE) {
11866 QualType BaseType =
11867 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
11868 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
Alexey Bataeva1764212015-09-30 09:22:36 +000011869 Type = ATy->getElementType();
11870 else
11871 Type = BaseType->getPointeeType();
Alexey Bataev31300ed2016-02-04 11:27:03 +000011872 Type = Type.getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000011873 } else {
Alexey Bataev60da77e2016-02-29 05:54:20 +000011874 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
Alexey Bataeve3727102018-04-18 15:57:46 +000011875 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000011876 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataeva1764212015-09-30 09:22:36 +000011877
Alexey Bataevc5e02582014-06-16 07:08:35 +000011878 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
11879 // A variable that appears in a private clause must not have an incomplete
11880 // type or a reference type.
Joel E. Denny3cabf732018-06-28 19:54:49 +000011881 if (S.RequireCompleteType(ELoc, D->getType(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011882 diag::err_omp_reduction_incomplete_type))
Alexey Bataevc5e02582014-06-16 07:08:35 +000011883 continue;
11884 // OpenMP [2.14.3.6, reduction clause, Restrictions]
Alexey Bataevc5e02582014-06-16 07:08:35 +000011885 // A list item that appears in a reduction clause must not be
11886 // const-qualified.
Joel E. Dennyd2649292019-01-04 22:11:56 +000011887 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
11888 /*AcceptIfMutable*/ false, ASE || OASE))
Alexey Bataevc5e02582014-06-16 07:08:35 +000011889 continue;
Alexey Bataevbc529672018-09-28 19:33:14 +000011890
11891 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
Alexey Bataevc5e02582014-06-16 07:08:35 +000011892 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
11893 // If a list-item is a reference type then it must bind to the same object
11894 // for all threads of the team.
Alexey Bataevbc529672018-09-28 19:33:14 +000011895 if (!ASE && !OASE) {
11896 if (VD) {
11897 VarDecl *VDDef = VD->getDefinition();
11898 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
11899 DSARefChecker Check(Stack);
11900 if (Check.Visit(VDDef->getInit())) {
11901 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11902 << getOpenMPClauseName(ClauseKind) << ERange;
11903 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
11904 continue;
11905 }
Alexey Bataeva1764212015-09-30 09:22:36 +000011906 }
Alexey Bataevc5e02582014-06-16 07:08:35 +000011907 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011908
Alexey Bataevbc529672018-09-28 19:33:14 +000011909 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11910 // in a Construct]
11911 // Variables with the predetermined data-sharing attributes may not be
11912 // listed in data-sharing attributes clauses, except for the cases
11913 // listed below. For these exceptions only, listing a predetermined
11914 // variable in a data-sharing attribute clause is allowed and overrides
11915 // the variable's predetermined data-sharing attributes.
11916 // OpenMP [2.14.3.6, Restrictions, p.3]
11917 // Any number of reduction clauses can be specified on the directive,
11918 // but a list item can appear only once in the reduction clauses for that
11919 // directive.
11920 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
11921 if (DVar.CKind == OMPC_reduction) {
11922 S.Diag(ELoc, diag::err_omp_once_referenced)
11923 << getOpenMPClauseName(ClauseKind);
11924 if (DVar.RefExpr)
11925 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11926 continue;
11927 }
11928 if (DVar.CKind != OMPC_unknown) {
11929 S.Diag(ELoc, diag::err_omp_wrong_dsa)
11930 << getOpenMPClauseName(DVar.CKind)
11931 << getOpenMPClauseName(OMPC_reduction);
Alexey Bataeve3727102018-04-18 15:57:46 +000011932 reportOriginalDsa(S, Stack, D, DVar);
Alexey Bataevf24e7b12015-10-08 09:10:53 +000011933 continue;
Alexey Bataevf29276e2014-06-18 04:14:57 +000011934 }
Alexey Bataevbc529672018-09-28 19:33:14 +000011935
11936 // OpenMP [2.14.3.6, Restrictions, p.1]
11937 // A list item that appears in a reduction clause of a worksharing
11938 // construct must be shared in the parallel regions to which any of the
11939 // worksharing regions arising from the worksharing construct bind.
11940 if (isOpenMPWorksharingDirective(CurrDir) &&
11941 !isOpenMPParallelDirective(CurrDir) &&
11942 !isOpenMPTeamsDirective(CurrDir)) {
11943 DVar = Stack->getImplicitDSA(D, true);
11944 if (DVar.CKind != OMPC_shared) {
11945 S.Diag(ELoc, diag::err_omp_required_access)
11946 << getOpenMPClauseName(OMPC_reduction)
11947 << getOpenMPClauseName(OMPC_shared);
11948 reportOriginalDsa(S, Stack, D, DVar);
11949 continue;
11950 }
11951 }
Alexey Bataevf29276e2014-06-18 04:14:57 +000011952 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000011953
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011954 // Try to find 'declare reduction' corresponding construct before using
11955 // builtin/overloaded operators.
11956 CXXCastPath BasePath;
11957 ExprResult DeclareReductionRef = buildDeclareReductionRef(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011958 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011959 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11960 if (DeclareReductionRef.isInvalid())
11961 continue;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011962 if (S.CurContext->isDependentContext() &&
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011963 (DeclareReductionRef.isUnset() ||
11964 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011965 RD.push(RefExpr, DeclareReductionRef.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011966 continue;
11967 }
11968 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
11969 // Not allowed reduction identifier is found.
Stephen Kellyf2ceec42018-08-09 21:08:08 +000011970 S.Diag(ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011971 diag::err_omp_unknown_reduction_identifier)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011972 << Type << ReductionIdRange;
11973 continue;
11974 }
11975
11976 // OpenMP [2.14.3.6, reduction clause, Restrictions]
11977 // The type of a list item that appears in a reduction clause must be valid
11978 // for the reduction-identifier. For a max or min reduction in C, the type
11979 // of the list item must be an allowed arithmetic data type: char, int,
11980 // float, double, or _Bool, possibly modified with long, short, signed, or
11981 // unsigned. For a max or min reduction in C++, the type of the list item
11982 // must be an allowed arithmetic data type: char, wchar_t, int, float,
11983 // double, or bool, possibly modified with long, short, signed, or unsigned.
11984 if (DeclareReductionRef.isUnset()) {
11985 if ((BOK == BO_GT || BOK == BO_LT) &&
11986 !(Type->isScalarType() ||
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011987 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11988 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
Alexey Bataev169d96a2017-07-18 20:17:46 +000011989 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011990 if (!ASE && !OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000011991 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11992 VarDecl::DeclarationOnly;
11993 S.Diag(D->getLocation(),
11994 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000011995 << D;
11996 }
11997 continue;
11998 }
11999 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012000 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
Alexey Bataev169d96a2017-07-18 20:17:46 +000012001 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
12002 << getOpenMPClauseName(ClauseKind);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012003 if (!ASE && !OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012004 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
12005 VarDecl::DeclarationOnly;
12006 S.Diag(D->getLocation(),
12007 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012008 << D;
12009 }
12010 continue;
12011 }
12012 }
12013
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012014 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012015 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
12016 D->hasAttrs() ? &D->getAttrs() : nullptr);
12017 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
12018 D->hasAttrs() ? &D->getAttrs() : nullptr);
12019 QualType PrivateTy = Type;
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000012020
12021 // Try if we can determine constant lengths for all array sections and avoid
12022 // the VLA.
12023 bool ConstantLengthOASE = false;
12024 if (OASE) {
12025 bool SingleElement;
12026 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
Alexey Bataeve3727102018-04-18 15:57:46 +000012027 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000012028 Context, OASE, SingleElement, ArraySizes);
12029
12030 // If we don't have a single element, we must emit a constant array type.
12031 if (ConstantLengthOASE && !SingleElement) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012032 for (llvm::APSInt &Size : ArraySizes)
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000012033 PrivateTy = Context.getConstantArrayType(
12034 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000012035 }
12036 }
12037
12038 if ((OASE && !ConstantLengthOASE) ||
Jonas Hahnfeld96087f32017-11-02 13:30:42 +000012039 (!OASE && !ASE &&
Alexey Bataev60da77e2016-02-29 05:54:20 +000012040 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
Jonas Hahnfeld87d44262017-11-18 21:00:46 +000012041 if (!Context.getTargetInfo().isVLASupported() &&
12042 S.shouldDiagnoseTargetSupportFromOpenMP()) {
12043 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
12044 S.Diag(ELoc, diag::note_vla_unsupported);
12045 continue;
12046 }
David Majnemer9d168222016-08-05 17:44:54 +000012047 // For arrays/array sections only:
Alexey Bataevf24e7b12015-10-08 09:10:53 +000012048 // Create pseudo array type for private copy. The size for this array will
12049 // be generated during codegen.
12050 // For array subscripts or single variables Private Ty is the same as Type
12051 // (type of the variable or single array element).
12052 PrivateTy = Context.getVariableArrayType(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012053 Type,
Alexey Bataevd070a582017-10-25 15:54:04 +000012054 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
Alexey Bataevf24e7b12015-10-08 09:10:53 +000012055 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
Alexey Bataev60da77e2016-02-29 05:54:20 +000012056 } else if (!ASE && !OASE &&
Alexey Bataeve3727102018-04-18 15:57:46 +000012057 Context.getAsArrayType(D->getType().getNonReferenceType())) {
Alexey Bataev60da77e2016-02-29 05:54:20 +000012058 PrivateTy = D->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012059 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000012060 // Private copy.
Alexey Bataeve3727102018-04-18 15:57:46 +000012061 VarDecl *PrivateVD =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000012062 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
12063 D->hasAttrs() ? &D->getAttrs() : nullptr,
12064 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012065 // Add initializer for private variable.
12066 Expr *Init = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000012067 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
12068 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012069 if (DeclareReductionRef.isUsable()) {
12070 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
12071 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
12072 if (DRD->getInitializer()) {
12073 Init = DRDRef;
12074 RHSVD->setInit(DRDRef);
12075 RHSVD->setInitStyle(VarDecl::CallInit);
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012076 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012077 } else {
12078 switch (BOK) {
12079 case BO_Add:
12080 case BO_Xor:
12081 case BO_Or:
12082 case BO_LOr:
12083 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
12084 if (Type->isScalarType() || Type->isAnyComplexType())
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012085 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012086 break;
12087 case BO_Mul:
12088 case BO_LAnd:
12089 if (Type->isScalarType() || Type->isAnyComplexType()) {
12090 // '*' and '&&' reduction ops - initializer is '1'.
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012091 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
Alexey Bataevc5e02582014-06-16 07:08:35 +000012092 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012093 break;
12094 case BO_And: {
12095 // '&' reduction op - initializer is '~0'.
12096 QualType OrigType = Type;
12097 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
12098 Type = ComplexTy->getElementType();
12099 if (Type->isRealFloatingType()) {
12100 llvm::APFloat InitValue =
12101 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
12102 /*isIEEE=*/true);
12103 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
12104 Type, ELoc);
12105 } else if (Type->isScalarType()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012106 uint64_t Size = Context.getTypeSize(Type);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012107 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
12108 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
12109 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
12110 }
12111 if (Init && OrigType->isAnyComplexType()) {
12112 // Init = 0xFFFF + 0xFFFFi;
12113 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012114 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012115 }
12116 Type = OrigType;
12117 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012118 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012119 case BO_LT:
12120 case BO_GT: {
12121 // 'min' reduction op - initializer is 'Largest representable number in
12122 // the reduction list item type'.
12123 // 'max' reduction op - initializer is 'Least representable number in
12124 // the reduction list item type'.
12125 if (Type->isIntegerType() || Type->isPointerType()) {
12126 bool IsSigned = Type->hasSignedIntegerRepresentation();
Alexey Bataeve3727102018-04-18 15:57:46 +000012127 uint64_t Size = Context.getTypeSize(Type);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012128 QualType IntTy =
12129 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
12130 llvm::APInt InitValue =
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012131 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
12132 : llvm::APInt::getMinValue(Size)
12133 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
12134 : llvm::APInt::getMaxValue(Size);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012135 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
12136 if (Type->isPointerType()) {
12137 // Cast to pointer type.
Alexey Bataeve3727102018-04-18 15:57:46 +000012138 ExprResult CastExpr = S.BuildCStyleCastExpr(
Alexey Bataevd070a582017-10-25 15:54:04 +000012139 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012140 if (CastExpr.isInvalid())
12141 continue;
12142 Init = CastExpr.get();
12143 }
12144 } else if (Type->isRealFloatingType()) {
12145 llvm::APFloat InitValue = llvm::APFloat::getLargest(
12146 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
12147 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
12148 Type, ELoc);
12149 }
12150 break;
12151 }
12152 case BO_PtrMemD:
12153 case BO_PtrMemI:
12154 case BO_MulAssign:
12155 case BO_Div:
12156 case BO_Rem:
12157 case BO_Sub:
12158 case BO_Shl:
12159 case BO_Shr:
12160 case BO_LE:
12161 case BO_GE:
12162 case BO_EQ:
12163 case BO_NE:
Richard Smithc70f1d62017-12-14 15:16:18 +000012164 case BO_Cmp:
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012165 case BO_AndAssign:
12166 case BO_XorAssign:
12167 case BO_OrAssign:
12168 case BO_Assign:
12169 case BO_AddAssign:
12170 case BO_SubAssign:
12171 case BO_DivAssign:
12172 case BO_RemAssign:
12173 case BO_ShlAssign:
12174 case BO_ShrAssign:
12175 case BO_Comma:
12176 llvm_unreachable("Unexpected reduction operation");
12177 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012178 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012179 if (Init && DeclareReductionRef.isUnset())
12180 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
12181 else if (!Init)
12182 S.ActOnUninitializedDecl(RHSVD);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012183 if (RHSVD->isInvalidDecl())
12184 continue;
Alexey Bataev09232662019-04-04 17:28:22 +000012185 if (!RHSVD->hasInit() &&
12186 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012187 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
12188 << Type << ReductionIdRange;
12189 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
12190 VarDecl::DeclarationOnly;
12191 S.Diag(D->getLocation(),
12192 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev60da77e2016-02-29 05:54:20 +000012193 << D;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012194 continue;
12195 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000012196 // Store initializer for single element in private copy. Will be used during
12197 // codegen.
12198 PrivateVD->setInit(RHSVD->getInit());
12199 PrivateVD->setInitStyle(RHSVD->getInitStyle());
Alexey Bataeve3727102018-04-18 15:57:46 +000012200 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012201 ExprResult ReductionOp;
12202 if (DeclareReductionRef.isUsable()) {
12203 QualType RedTy = DeclareReductionRef.get()->getType();
12204 QualType PtrRedTy = Context.getPointerType(RedTy);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012205 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
12206 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012207 if (!BasePath.empty()) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012208 LHS = S.DefaultLvalueConversion(LHS.get());
12209 RHS = S.DefaultLvalueConversion(RHS.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012210 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
12211 CK_UncheckedDerivedToBase, LHS.get(),
12212 &BasePath, LHS.get()->getValueKind());
12213 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
12214 CK_UncheckedDerivedToBase, RHS.get(),
12215 &BasePath, RHS.get()->getValueKind());
Alexey Bataev794ba0d2015-04-10 10:43:45 +000012216 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012217 FunctionProtoType::ExtProtoInfo EPI;
12218 QualType Params[] = {PtrRedTy, PtrRedTy};
12219 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
12220 auto *OVE = new (Context) OpaqueValueExpr(
12221 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012222 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012223 Expr *Args[] = {LHS.get(), RHS.get()};
Bruno Riccic5885cf2018-12-21 15:20:32 +000012224 ReductionOp =
12225 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012226 } else {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012227 ReductionOp = S.BuildBinOp(
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012228 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012229 if (ReductionOp.isUsable()) {
12230 if (BOK != BO_LT && BOK != BO_GT) {
12231 ReductionOp =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012232 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012233 BO_Assign, LHSDRE, ReductionOp.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012234 } else {
Alexey Bataevd070a582017-10-25 15:54:04 +000012235 auto *ConditionalOp = new (Context)
12236 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
12237 Type, VK_LValue, OK_Ordinary);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012238 ReductionOp =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012239 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012240 BO_Assign, LHSDRE, ConditionalOp);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012241 }
Alexey Bataev4d4624c2017-07-20 16:47:47 +000012242 if (ReductionOp.isUsable())
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012243 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
12244 /*DiscardedValue*/ false);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012245 }
Alexey Bataev4d4624c2017-07-20 16:47:47 +000012246 if (!ReductionOp.isUsable())
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012247 continue;
Alexey Bataevc5e02582014-06-16 07:08:35 +000012248 }
12249
Alexey Bataevfa312f32017-07-21 18:48:21 +000012250 // OpenMP [2.15.4.6, Restrictions, p.2]
12251 // A list item that appears in an in_reduction clause of a task construct
12252 // must appear in a task_reduction clause of a construct associated with a
12253 // taskgroup region that includes the participating task in its taskgroup
12254 // set. The construct associated with the innermost region that meets this
12255 // condition must specify the same reduction-identifier as the in_reduction
12256 // clause.
12257 if (ClauseKind == OMPC_in_reduction) {
Alexey Bataevfa312f32017-07-21 18:48:21 +000012258 SourceRange ParentSR;
12259 BinaryOperatorKind ParentBOK;
12260 const Expr *ParentReductionOp;
Alexey Bataev88202be2017-07-27 13:20:36 +000012261 Expr *ParentBOKTD, *ParentReductionOpTD;
Alexey Bataevf189cb72017-07-24 14:52:13 +000012262 DSAStackTy::DSAVarData ParentBOKDSA =
Alexey Bataev88202be2017-07-27 13:20:36 +000012263 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
12264 ParentBOKTD);
Alexey Bataevf189cb72017-07-24 14:52:13 +000012265 DSAStackTy::DSAVarData ParentReductionOpDSA =
Alexey Bataev88202be2017-07-27 13:20:36 +000012266 Stack->getTopMostTaskgroupReductionData(
12267 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
Alexey Bataevf189cb72017-07-24 14:52:13 +000012268 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
12269 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
12270 if (!IsParentBOK && !IsParentReductionOp) {
12271 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
12272 continue;
12273 }
Alexey Bataevfa312f32017-07-21 18:48:21 +000012274 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
12275 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
12276 IsParentReductionOp) {
12277 bool EmitError = true;
12278 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
12279 llvm::FoldingSetNodeID RedId, ParentRedId;
12280 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
12281 DeclareReductionRef.get()->Profile(RedId, Context,
12282 /*Canonical=*/true);
12283 EmitError = RedId != ParentRedId;
12284 }
12285 if (EmitError) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012286 S.Diag(ReductionId.getBeginLoc(),
Alexey Bataevfa312f32017-07-21 18:48:21 +000012287 diag::err_omp_reduction_identifier_mismatch)
12288 << ReductionIdRange << RefExpr->getSourceRange();
12289 S.Diag(ParentSR.getBegin(),
12290 diag::note_omp_previous_reduction_identifier)
Alexey Bataevf189cb72017-07-24 14:52:13 +000012291 << ParentSR
12292 << (IsParentBOK ? ParentBOKDSA.RefExpr
12293 : ParentReductionOpDSA.RefExpr)
12294 ->getSourceRange();
Alexey Bataevfa312f32017-07-21 18:48:21 +000012295 continue;
12296 }
12297 }
Alexey Bataev88202be2017-07-27 13:20:36 +000012298 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
12299 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
Alexey Bataevfa312f32017-07-21 18:48:21 +000012300 }
12301
Alexey Bataev60da77e2016-02-29 05:54:20 +000012302 DeclRefExpr *Ref = nullptr;
12303 Expr *VarsExpr = RefExpr->IgnoreParens();
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012304 if (!VD && !S.CurContext->isDependentContext()) {
Alexey Bataev60da77e2016-02-29 05:54:20 +000012305 if (ASE || OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012306 TransformExprToCaptures RebuildToCapture(S, D);
Alexey Bataev60da77e2016-02-29 05:54:20 +000012307 VarsExpr =
12308 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
12309 Ref = RebuildToCapture.getCapturedExpr();
Alexey Bataev61205072016-03-02 04:57:40 +000012310 } else {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012311 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataev5a3af132016-03-29 08:58:54 +000012312 }
Alexey Bataeve3727102018-04-18 15:57:46 +000012313 if (!S.isOpenMPCapturedDecl(D)) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012314 RD.ExprCaptures.emplace_back(Ref->getDecl());
Alexey Bataev5a3af132016-03-29 08:58:54 +000012315 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012316 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
Alexey Bataev5a3af132016-03-29 08:58:54 +000012317 if (!RefRes.isUsable())
12318 continue;
12319 ExprResult PostUpdateRes =
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012320 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
12321 RefRes.get());
Alexey Bataev5a3af132016-03-29 08:58:54 +000012322 if (!PostUpdateRes.isUsable())
12323 continue;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012324 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
12325 Stack->getCurrentDirective() == OMPD_taskgroup) {
12326 S.Diag(RefExpr->getExprLoc(),
12327 diag::err_omp_reduction_non_addressable_expression)
Alexey Bataevbcd0ae02017-07-11 19:16:44 +000012328 << RefExpr->getSourceRange();
12329 continue;
12330 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012331 RD.ExprPostUpdates.emplace_back(
12332 S.IgnoredValueConversions(PostUpdateRes.get()).get());
Alexey Bataev61205072016-03-02 04:57:40 +000012333 }
12334 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000012335 }
Alexey Bataev169d96a2017-07-18 20:17:46 +000012336 // All reduction items are still marked as reduction (to do not increase
12337 // code base size).
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012338 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
Alexey Bataevf189cb72017-07-24 14:52:13 +000012339 if (CurrDir == OMPD_taskgroup) {
12340 if (DeclareReductionRef.isUsable())
Alexey Bataev3b1b8952017-07-25 15:53:26 +000012341 Stack->addTaskgroupReductionData(D, ReductionIdRange,
12342 DeclareReductionRef.get());
Alexey Bataevf189cb72017-07-24 14:52:13 +000012343 else
Alexey Bataev3b1b8952017-07-25 15:53:26 +000012344 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
Alexey Bataevf189cb72017-07-24 14:52:13 +000012345 }
Alexey Bataev88202be2017-07-27 13:20:36 +000012346 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
12347 TaskgroupDescriptor);
Alexey Bataevc5e02582014-06-16 07:08:35 +000012348 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012349 return RD.Vars.empty();
12350}
Alexey Bataevc5e02582014-06-16 07:08:35 +000012351
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012352OMPClause *Sema::ActOnOpenMPReductionClause(
12353 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
12354 SourceLocation ColonLoc, SourceLocation EndLoc,
12355 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
12356 ArrayRef<Expr *> UnresolvedReductions) {
12357 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000012358 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
Alexey Bataev169d96a2017-07-18 20:17:46 +000012359 StartLoc, LParenLoc, ColonLoc, EndLoc,
12360 ReductionIdScopeSpec, ReductionId,
12361 UnresolvedReductions, RD))
Alexey Bataevc5e02582014-06-16 07:08:35 +000012362 return nullptr;
Alexey Bataev61205072016-03-02 04:57:40 +000012363
Alexey Bataevc5e02582014-06-16 07:08:35 +000012364 return OMPReductionClause::Create(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012365 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12366 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
12367 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
12368 buildPreInits(Context, RD.ExprCaptures),
12369 buildPostUpdate(*this, RD.ExprPostUpdates));
Alexey Bataevc5e02582014-06-16 07:08:35 +000012370}
12371
Alexey Bataev169d96a2017-07-18 20:17:46 +000012372OMPClause *Sema::ActOnOpenMPTaskReductionClause(
12373 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
12374 SourceLocation ColonLoc, SourceLocation EndLoc,
12375 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
12376 ArrayRef<Expr *> UnresolvedReductions) {
12377 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000012378 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
12379 StartLoc, LParenLoc, ColonLoc, EndLoc,
12380 ReductionIdScopeSpec, ReductionId,
Alexey Bataev169d96a2017-07-18 20:17:46 +000012381 UnresolvedReductions, RD))
12382 return nullptr;
12383
12384 return OMPTaskReductionClause::Create(
12385 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12386 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
12387 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
12388 buildPreInits(Context, RD.ExprCaptures),
12389 buildPostUpdate(*this, RD.ExprPostUpdates));
12390}
12391
Alexey Bataevfa312f32017-07-21 18:48:21 +000012392OMPClause *Sema::ActOnOpenMPInReductionClause(
12393 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
12394 SourceLocation ColonLoc, SourceLocation EndLoc,
12395 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
12396 ArrayRef<Expr *> UnresolvedReductions) {
12397 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000012398 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
Alexey Bataevfa312f32017-07-21 18:48:21 +000012399 StartLoc, LParenLoc, ColonLoc, EndLoc,
12400 ReductionIdScopeSpec, ReductionId,
12401 UnresolvedReductions, RD))
12402 return nullptr;
12403
12404 return OMPInReductionClause::Create(
12405 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12406 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
Alexey Bataev88202be2017-07-27 13:20:36 +000012407 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
Alexey Bataevfa312f32017-07-21 18:48:21 +000012408 buildPreInits(Context, RD.ExprCaptures),
12409 buildPostUpdate(*this, RD.ExprPostUpdates));
12410}
12411
Alexey Bataevecba70f2016-04-12 11:02:11 +000012412bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
12413 SourceLocation LinLoc) {
12414 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
12415 LinKind == OMPC_LINEAR_unknown) {
12416 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
12417 return true;
12418 }
12419 return false;
12420}
12421
Alexey Bataeve3727102018-04-18 15:57:46 +000012422bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
Alexey Bataevecba70f2016-04-12 11:02:11 +000012423 OpenMPLinearClauseKind LinKind,
12424 QualType Type) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012425 const auto *VD = dyn_cast_or_null<VarDecl>(D);
Alexey Bataevecba70f2016-04-12 11:02:11 +000012426 // A variable must not have an incomplete type or a reference type.
12427 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
12428 return true;
12429 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
12430 !Type->isReferenceType()) {
12431 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
12432 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
12433 return true;
12434 }
12435 Type = Type.getNonReferenceType();
12436
Joel E. Dennybae586f2019-01-04 22:12:13 +000012437 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12438 // A variable that is privatized must not have a const-qualified type
12439 // unless it is of class type with a mutable member. This restriction does
12440 // not apply to the firstprivate clause.
12441 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
Alexey Bataevecba70f2016-04-12 11:02:11 +000012442 return true;
Alexey Bataevecba70f2016-04-12 11:02:11 +000012443
12444 // A list item must be of integral or pointer type.
12445 Type = Type.getUnqualifiedType().getCanonicalType();
12446 const auto *Ty = Type.getTypePtrOrNull();
12447 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
12448 !Ty->isPointerType())) {
12449 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
12450 if (D) {
12451 bool IsDecl =
12452 !VD ||
12453 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12454 Diag(D->getLocation(),
12455 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12456 << D;
12457 }
12458 return true;
12459 }
12460 return false;
12461}
12462
Alexey Bataev182227b2015-08-20 10:54:39 +000012463OMPClause *Sema::ActOnOpenMPLinearClause(
12464 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
12465 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
12466 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
Alexander Musman8dba6642014-04-22 13:09:42 +000012467 SmallVector<Expr *, 8> Vars;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012468 SmallVector<Expr *, 8> Privates;
Alexander Musman3276a272015-03-21 10:12:56 +000012469 SmallVector<Expr *, 8> Inits;
Alexey Bataev78849fb2016-03-09 09:49:00 +000012470 SmallVector<Decl *, 4> ExprCaptures;
12471 SmallVector<Expr *, 4> ExprPostUpdates;
Alexey Bataevecba70f2016-04-12 11:02:11 +000012472 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
Alexey Bataev182227b2015-08-20 10:54:39 +000012473 LinKind = OMPC_LINEAR_val;
Alexey Bataeve3727102018-04-18 15:57:46 +000012474 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000012475 assert(RefExpr && "NULL expr in OpenMP linear clause.");
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012476 SourceLocation ELoc;
12477 SourceRange ERange;
12478 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000012479 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012480 if (Res.second) {
Alexander Musman8dba6642014-04-22 13:09:42 +000012481 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000012482 Vars.push_back(RefExpr);
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012483 Privates.push_back(nullptr);
Alexander Musman3276a272015-03-21 10:12:56 +000012484 Inits.push_back(nullptr);
Alexander Musman8dba6642014-04-22 13:09:42 +000012485 }
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012486 ValueDecl *D = Res.first;
12487 if (!D)
Alexander Musman8dba6642014-04-22 13:09:42 +000012488 continue;
Alexander Musman8dba6642014-04-22 13:09:42 +000012489
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012490 QualType Type = D->getType();
12491 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musman8dba6642014-04-22 13:09:42 +000012492
12493 // OpenMP [2.14.3.7, linear clause]
12494 // A list-item cannot appear in more than one linear clause.
12495 // A list-item that appears in a linear clause cannot appear in any
12496 // other data-sharing attribute clause.
Alexey Bataeve3727102018-04-18 15:57:46 +000012497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexander Musman8dba6642014-04-22 13:09:42 +000012498 if (DVar.RefExpr) {
12499 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12500 << getOpenMPClauseName(OMPC_linear);
Alexey Bataeve3727102018-04-18 15:57:46 +000012501 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexander Musman8dba6642014-04-22 13:09:42 +000012502 continue;
12503 }
12504
Alexey Bataevecba70f2016-04-12 11:02:11 +000012505 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
Alexander Musman8dba6642014-04-22 13:09:42 +000012506 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +000012507 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
Alexander Musman8dba6642014-04-22 13:09:42 +000012508
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012509 // Build private copy of original var.
Alexey Bataeve3727102018-04-18 15:57:46 +000012510 VarDecl *Private =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000012511 buildVarDecl(*this, ELoc, Type, D->getName(),
12512 D->hasAttrs() ? &D->getAttrs() : nullptr,
12513 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012514 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
Alexander Musman3276a272015-03-21 10:12:56 +000012515 // Build var to save initial value.
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012516 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000012517 Expr *InitExpr;
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012518 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012519 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataev78849fb2016-03-09 09:49:00 +000012520 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000012521 if (!isOpenMPCapturedDecl(D)) {
Alexey Bataev78849fb2016-03-09 09:49:00 +000012522 ExprCaptures.push_back(Ref->getDecl());
12523 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
12524 ExprResult RefRes = DefaultLvalueConversion(Ref);
12525 if (!RefRes.isUsable())
12526 continue;
12527 ExprResult PostUpdateRes =
12528 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
12529 SimpleRefExpr, RefRes.get());
12530 if (!PostUpdateRes.isUsable())
12531 continue;
12532 ExprPostUpdates.push_back(
12533 IgnoredValueConversions(PostUpdateRes.get()).get());
12534 }
12535 }
12536 }
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000012537 if (LinKind == OMPC_LINEAR_uval)
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012538 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000012539 else
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012540 InitExpr = VD ? SimpleRefExpr : Ref;
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000012541 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000012542 /*DirectInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000012543 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012544
12545 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012546 Vars.push_back((VD || CurContext->isDependentContext())
12547 ? RefExpr->IgnoreParens()
12548 : Ref);
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012549 Privates.push_back(PrivateRef);
Alexander Musman3276a272015-03-21 10:12:56 +000012550 Inits.push_back(InitRef);
Alexander Musman8dba6642014-04-22 13:09:42 +000012551 }
12552
12553 if (Vars.empty())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000012554 return nullptr;
Alexander Musman8dba6642014-04-22 13:09:42 +000012555
12556 Expr *StepExpr = Step;
Alexander Musman3276a272015-03-21 10:12:56 +000012557 Expr *CalcStepExpr = nullptr;
Alexander Musman8dba6642014-04-22 13:09:42 +000012558 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
12559 !Step->isInstantiationDependent() &&
12560 !Step->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012561 SourceLocation StepLoc = Step->getBeginLoc();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +000012562 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
Alexander Musman8dba6642014-04-22 13:09:42 +000012563 if (Val.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000012564 return nullptr;
Nikola Smiljanic01a75982014-05-29 10:55:11 +000012565 StepExpr = Val.get();
Alexander Musman8dba6642014-04-22 13:09:42 +000012566
Alexander Musman3276a272015-03-21 10:12:56 +000012567 // Build var to save the step value.
12568 VarDecl *SaveVar =
Alexey Bataev39f915b82015-05-08 10:41:21 +000012569 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
Alexander Musman3276a272015-03-21 10:12:56 +000012570 ExprResult SaveRef =
Alexey Bataev39f915b82015-05-08 10:41:21 +000012571 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
Alexander Musman3276a272015-03-21 10:12:56 +000012572 ExprResult CalcStep =
12573 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012574 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
Alexander Musman3276a272015-03-21 10:12:56 +000012575
Alexander Musman8dba6642014-04-22 13:09:42 +000012576 // Warn about zero linear step (it would be probably better specified as
12577 // making corresponding variables 'const').
12578 llvm::APSInt Result;
Alexander Musman3276a272015-03-21 10:12:56 +000012579 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
12580 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
Alexander Musman8dba6642014-04-22 13:09:42 +000012581 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
12582 << (Vars.size() > 1);
Alexander Musman3276a272015-03-21 10:12:56 +000012583 if (!IsConstant && CalcStep.isUsable()) {
12584 // Calculate the step beforehand instead of doing this on each iteration.
12585 // (This is not used if the number of iterations may be kfold-ed).
12586 CalcStepExpr = CalcStep.get();
12587 }
Alexander Musman8dba6642014-04-22 13:09:42 +000012588 }
12589
Alexey Bataev182227b2015-08-20 10:54:39 +000012590 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
12591 ColonLoc, EndLoc, Vars, Privates, Inits,
Alexey Bataev5a3af132016-03-29 08:58:54 +000012592 StepExpr, CalcStepExpr,
12593 buildPreInits(Context, ExprCaptures),
12594 buildPostUpdate(*this, ExprPostUpdates));
Alexander Musman3276a272015-03-21 10:12:56 +000012595}
12596
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012597static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
12598 Expr *NumIterations, Sema &SemaRef,
12599 Scope *S, DSAStackTy *Stack) {
Alexander Musman3276a272015-03-21 10:12:56 +000012600 // Walk the vars and build update/final expressions for the CodeGen.
12601 SmallVector<Expr *, 8> Updates;
12602 SmallVector<Expr *, 8> Finals;
12603 Expr *Step = Clause.getStep();
12604 Expr *CalcStep = Clause.getCalcStep();
12605 // OpenMP [2.14.3.7, linear clause]
12606 // If linear-step is not specified it is assumed to be 1.
Alexey Bataeve3727102018-04-18 15:57:46 +000012607 if (!Step)
Alexander Musman3276a272015-03-21 10:12:56 +000012608 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000012609 else if (CalcStep)
Alexander Musman3276a272015-03-21 10:12:56 +000012610 Step = cast<BinaryOperator>(CalcStep)->getLHS();
12611 bool HasErrors = false;
12612 auto CurInit = Clause.inits().begin();
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012613 auto CurPrivate = Clause.privates().begin();
Alexey Bataeve3727102018-04-18 15:57:46 +000012614 OpenMPLinearClauseKind LinKind = Clause.getModifier();
12615 for (Expr *RefExpr : Clause.varlists()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012616 SourceLocation ELoc;
12617 SourceRange ERange;
12618 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000012619 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012620 ValueDecl *D = Res.first;
12621 if (Res.second || !D) {
12622 Updates.push_back(nullptr);
12623 Finals.push_back(nullptr);
12624 HasErrors = true;
12625 continue;
12626 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012627 auto &&Info = Stack->isLoopControlVariable(D);
Alexey Bataev2b86f212017-11-29 21:31:48 +000012628 // OpenMP [2.15.11, distribute simd Construct]
12629 // A list item may not appear in a linear clause, unless it is the loop
12630 // iteration variable.
12631 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
12632 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
12633 SemaRef.Diag(ELoc,
12634 diag::err_omp_linear_distribute_var_non_loop_iteration);
12635 Updates.push_back(nullptr);
12636 Finals.push_back(nullptr);
12637 HasErrors = true;
12638 continue;
12639 }
Alexander Musman3276a272015-03-21 10:12:56 +000012640 Expr *InitExpr = *CurInit;
12641
12642 // Build privatized reference to the current linear var.
David Majnemer9d168222016-08-05 17:44:54 +000012643 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000012644 Expr *CapturedRef;
12645 if (LinKind == OMPC_LINEAR_uval)
12646 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
12647 else
12648 CapturedRef =
12649 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
12650 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
12651 /*RefersToCapture=*/true);
Alexander Musman3276a272015-03-21 10:12:56 +000012652
12653 // Build update: Var = InitExpr + IV * Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012654 ExprResult Update;
Alexey Bataeve3727102018-04-18 15:57:46 +000012655 if (!Info.first)
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012656 Update =
Alexey Bataeve3727102018-04-18 15:57:46 +000012657 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012658 InitExpr, IV, Step, /* Subtract */ false);
Alexey Bataeve3727102018-04-18 15:57:46 +000012659 else
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012660 Update = *CurPrivate;
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012661 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012662 /*DiscardedValue*/ false);
Alexander Musman3276a272015-03-21 10:12:56 +000012663
12664 // Build final: Var = InitExpr + NumIterations * Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012665 ExprResult Final;
Alexey Bataeve3727102018-04-18 15:57:46 +000012666 if (!Info.first)
12667 Final =
12668 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
12669 InitExpr, NumIterations, Step, /*Subtract=*/false);
12670 else
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012671 Final = *CurPrivate;
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012672 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012673 /*DiscardedValue*/ false);
Alexey Bataev5dff95c2016-04-22 03:56:56 +000012674
Alexander Musman3276a272015-03-21 10:12:56 +000012675 if (!Update.isUsable() || !Final.isUsable()) {
12676 Updates.push_back(nullptr);
12677 Finals.push_back(nullptr);
12678 HasErrors = true;
12679 } else {
12680 Updates.push_back(Update.get());
12681 Finals.push_back(Final.get());
12682 }
Richard Trieucc3949d2016-02-18 22:34:54 +000012683 ++CurInit;
12684 ++CurPrivate;
Alexander Musman3276a272015-03-21 10:12:56 +000012685 }
12686 Clause.setUpdates(Updates);
12687 Clause.setFinals(Finals);
12688 return HasErrors;
Alexander Musman8dba6642014-04-22 13:09:42 +000012689}
12690
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012691OMPClause *Sema::ActOnOpenMPAlignedClause(
12692 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
12693 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012694 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +000012695 for (Expr *RefExpr : VarList) {
Alexey Bataev1efd1662016-03-29 10:59:56 +000012696 assert(RefExpr && "NULL expr in OpenMP linear clause.");
12697 SourceLocation ELoc;
12698 SourceRange ERange;
12699 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000012700 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev1efd1662016-03-29 10:59:56 +000012701 if (Res.second) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012702 // It will be analyzed later.
12703 Vars.push_back(RefExpr);
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012704 }
Alexey Bataev1efd1662016-03-29 10:59:56 +000012705 ValueDecl *D = Res.first;
12706 if (!D)
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012707 continue;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012708
Alexey Bataev1efd1662016-03-29 10:59:56 +000012709 QualType QType = D->getType();
12710 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012711
12712 // OpenMP [2.8.1, simd construct, Restrictions]
12713 // The type of list items appearing in the aligned clause must be
12714 // array, pointer, reference to array, or reference to pointer.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012715 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012716 const Type *Ty = QType.getTypePtrOrNull();
Alexey Bataev1efd1662016-03-29 10:59:56 +000012717 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012718 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
Alexey Bataev1efd1662016-03-29 10:59:56 +000012719 << QType << getLangOpts().CPlusPlus << ERange;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012720 bool IsDecl =
Alexey Bataev1efd1662016-03-29 10:59:56 +000012721 !VD ||
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012722 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev1efd1662016-03-29 10:59:56 +000012723 Diag(D->getLocation(),
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012724 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev1efd1662016-03-29 10:59:56 +000012725 << D;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012726 continue;
12727 }
12728
12729 // OpenMP [2.8.1, simd construct, Restrictions]
12730 // A list-item cannot appear in more than one aligned clause.
Alexey Bataeve3727102018-04-18 15:57:46 +000012731 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
Alexey Bataevd93d3762016-04-12 09:35:56 +000012732 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012733 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
12734 << getOpenMPClauseName(OMPC_aligned);
12735 continue;
12736 }
12737
Alexey Bataev1efd1662016-03-29 10:59:56 +000012738 DeclRefExpr *Ref = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000012739 if (!VD && isOpenMPCapturedDecl(D))
Alexey Bataev1efd1662016-03-29 10:59:56 +000012740 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12741 Vars.push_back(DefaultFunctionArrayConversion(
12742 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
12743 .get());
Alexander Musmanf0d76e72014-05-29 14:36:25 +000012744 }
12745
12746 // OpenMP [2.8.1, simd construct, Description]
12747 // The parameter of the aligned clause, alignment, must be a constant
12748 // positive integer expression.
12749 // If no optional parameter is specified, implementation-defined default
12750 // alignments for SIMD instructions on the target platforms are assumed.
12751 if (Alignment != nullptr) {
12752 ExprResult AlignResult =
12753 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
12754 if (AlignResult.isInvalid())
12755 return nullptr;
12756 Alignment = AlignResult.get();
12757 }
12758 if (Vars.empty())
12759 return nullptr;
12760
12761 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
12762 EndLoc, Vars, Alignment);
12763}
12764
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012765OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
12766 SourceLocation StartLoc,
12767 SourceLocation LParenLoc,
12768 SourceLocation EndLoc) {
12769 SmallVector<Expr *, 8> Vars;
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012770 SmallVector<Expr *, 8> SrcExprs;
12771 SmallVector<Expr *, 8> DstExprs;
12772 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataeve3727102018-04-18 15:57:46 +000012773 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000012774 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
12775 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012776 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000012777 Vars.push_back(RefExpr);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012778 SrcExprs.push_back(nullptr);
12779 DstExprs.push_back(nullptr);
12780 AssignmentOps.push_back(nullptr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012781 continue;
12782 }
12783
Alexey Bataeved09d242014-05-28 05:53:51 +000012784 SourceLocation ELoc = RefExpr->getExprLoc();
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012785 // OpenMP [2.1, C/C++]
12786 // A list item is a variable name.
12787 // OpenMP [2.14.4.1, Restrictions, p.1]
12788 // A list item that appears in a copyin clause must be threadprivate.
Alexey Bataeve3727102018-04-18 15:57:46 +000012789 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012790 if (!DE || !isa<VarDecl>(DE->getDecl())) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012791 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
12792 << 0 << RefExpr->getSourceRange();
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012793 continue;
12794 }
12795
12796 Decl *D = DE->getDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +000012797 auto *VD = cast<VarDecl>(D);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012798
12799 QualType Type = VD->getType();
12800 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
12801 // It will be analyzed later.
12802 Vars.push_back(DE);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012803 SrcExprs.push_back(nullptr);
12804 DstExprs.push_back(nullptr);
12805 AssignmentOps.push_back(nullptr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012806 continue;
12807 }
12808
12809 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
12810 // A list item that appears in a copyin clause must be threadprivate.
12811 if (!DSAStack->isThreadPrivate(VD)) {
12812 Diag(ELoc, diag::err_omp_required_access)
Alexey Bataeved09d242014-05-28 05:53:51 +000012813 << getOpenMPClauseName(OMPC_copyin)
12814 << getOpenMPDirectiveName(OMPD_threadprivate);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012815 continue;
12816 }
12817
12818 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12819 // A variable of class type (or array thereof) that appears in a
Alexey Bataev23b69422014-06-18 07:08:49 +000012820 // copyin clause requires an accessible, unambiguous copy assignment
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012821 // operator for the class type.
Alexey Bataeve3727102018-04-18 15:57:46 +000012822 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
12823 VarDecl *SrcVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012824 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +000012825 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012826 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012827 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +000012828 VarDecl *DstVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012829 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +000012830 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012831 DeclRefExpr *PseudoDstExpr =
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012832 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012833 // For arrays generate assignment operation for single element and replace
12834 // it by the original array element in CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000012835 ExprResult AssignmentOp =
12836 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
12837 PseudoSrcExpr);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012838 if (AssignmentOp.isInvalid())
12839 continue;
12840 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012841 /*DiscardedValue*/ false);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012842 if (AssignmentOp.isInvalid())
12843 continue;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012844
12845 DSAStack->addDSA(VD, DE, OMPC_copyin);
12846 Vars.push_back(DE);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012847 SrcExprs.push_back(PseudoSrcExpr);
12848 DstExprs.push_back(PseudoDstExpr);
12849 AssignmentOps.push_back(AssignmentOp.get());
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012850 }
12851
Alexey Bataeved09d242014-05-28 05:53:51 +000012852 if (Vars.empty())
12853 return nullptr;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012854
Alexey Bataevf56f98c2015-04-16 05:39:01 +000012855 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
12856 SrcExprs, DstExprs, AssignmentOps);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000012857}
12858
Alexey Bataevbae9a792014-06-27 10:37:06 +000012859OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
12860 SourceLocation StartLoc,
12861 SourceLocation LParenLoc,
12862 SourceLocation EndLoc) {
12863 SmallVector<Expr *, 8> Vars;
Alexey Bataeva63048e2015-03-23 06:18:07 +000012864 SmallVector<Expr *, 8> SrcExprs;
12865 SmallVector<Expr *, 8> DstExprs;
12866 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataeve3727102018-04-18 15:57:46 +000012867 for (Expr *RefExpr : VarList) {
Alexey Bataeve122da12016-03-17 10:50:17 +000012868 assert(RefExpr && "NULL expr in OpenMP linear clause.");
12869 SourceLocation ELoc;
12870 SourceRange ERange;
12871 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000012872 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataeve122da12016-03-17 10:50:17 +000012873 if (Res.second) {
Alexey Bataevbae9a792014-06-27 10:37:06 +000012874 // It will be analyzed later.
12875 Vars.push_back(RefExpr);
Alexey Bataeva63048e2015-03-23 06:18:07 +000012876 SrcExprs.push_back(nullptr);
12877 DstExprs.push_back(nullptr);
12878 AssignmentOps.push_back(nullptr);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012879 }
Alexey Bataeve122da12016-03-17 10:50:17 +000012880 ValueDecl *D = Res.first;
12881 if (!D)
Alexey Bataevbae9a792014-06-27 10:37:06 +000012882 continue;
Alexey Bataevbae9a792014-06-27 10:37:06 +000012883
Alexey Bataeve122da12016-03-17 10:50:17 +000012884 QualType Type = D->getType();
12885 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012886
12887 // OpenMP [2.14.4.2, Restrictions, p.2]
12888 // A list item that appears in a copyprivate clause may not appear in a
12889 // private or firstprivate clause on the single construct.
Alexey Bataeve122da12016-03-17 10:50:17 +000012890 if (!VD || !DSAStack->isThreadPrivate(VD)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012891 DSAStackTy::DSAVarData DVar =
12892 DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataeva63048e2015-03-23 06:18:07 +000012893 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12894 DVar.RefExpr) {
Alexey Bataevbae9a792014-06-27 10:37:06 +000012895 Diag(ELoc, diag::err_omp_wrong_dsa)
12896 << getOpenMPClauseName(DVar.CKind)
12897 << getOpenMPClauseName(OMPC_copyprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000012898 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012899 continue;
12900 }
12901
12902 // OpenMP [2.11.4.2, Restrictions, p.1]
12903 // All list items that appear in a copyprivate clause must be either
12904 // threadprivate or private in the enclosing context.
12905 if (DVar.CKind == OMPC_unknown) {
Alexey Bataeve122da12016-03-17 10:50:17 +000012906 DVar = DSAStack->getImplicitDSA(D, false);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012907 if (DVar.CKind == OMPC_shared) {
12908 Diag(ELoc, diag::err_omp_required_access)
12909 << getOpenMPClauseName(OMPC_copyprivate)
12910 << "threadprivate or private in the enclosing context";
Alexey Bataeve3727102018-04-18 15:57:46 +000012911 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012912 continue;
12913 }
12914 }
12915 }
12916
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012917 // Variably modified types are not supported.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000012918 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012919 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012920 << getOpenMPClauseName(OMPC_copyprivate) << Type
12921 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012922 bool IsDecl =
Alexey Bataeve122da12016-03-17 10:50:17 +000012923 !VD ||
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012924 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataeve122da12016-03-17 10:50:17 +000012925 Diag(D->getLocation(),
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012926 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeve122da12016-03-17 10:50:17 +000012927 << D;
Alexey Bataev7a3e5852015-05-19 08:19:24 +000012928 continue;
12929 }
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012930
Alexey Bataevbae9a792014-06-27 10:37:06 +000012931 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12932 // A variable of class type (or array thereof) that appears in a
12933 // copyin clause requires an accessible, unambiguous copy assignment
12934 // operator for the class type.
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012935 Type = Context.getBaseElementType(Type.getNonReferenceType())
12936 .getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012937 VarDecl *SrcVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012938 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
Alexey Bataeve122da12016-03-17 10:50:17 +000012939 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012940 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
12941 VarDecl *DstVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000012942 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
Alexey Bataeve122da12016-03-17 10:50:17 +000012943 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012944 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12945 ExprResult AssignmentOp = BuildBinOp(
12946 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
Alexey Bataeva63048e2015-03-23 06:18:07 +000012947 if (AssignmentOp.isInvalid())
12948 continue;
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012949 AssignmentOp =
12950 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataeva63048e2015-03-23 06:18:07 +000012951 if (AssignmentOp.isInvalid())
12952 continue;
Alexey Bataevbae9a792014-06-27 10:37:06 +000012953
12954 // No need to mark vars as copyprivate, they are already threadprivate or
12955 // implicitly private.
Alexey Bataeve3727102018-04-18 15:57:46 +000012956 assert(VD || isOpenMPCapturedDecl(D));
Alexey Bataeve122da12016-03-17 10:50:17 +000012957 Vars.push_back(
12958 VD ? RefExpr->IgnoreParens()
12959 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
Alexey Bataeva63048e2015-03-23 06:18:07 +000012960 SrcExprs.push_back(PseudoSrcExpr);
12961 DstExprs.push_back(PseudoDstExpr);
12962 AssignmentOps.push_back(AssignmentOp.get());
Alexey Bataevbae9a792014-06-27 10:37:06 +000012963 }
12964
12965 if (Vars.empty())
12966 return nullptr;
12967
Alexey Bataeva63048e2015-03-23 06:18:07 +000012968 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12969 Vars, SrcExprs, DstExprs, AssignmentOps);
Alexey Bataevbae9a792014-06-27 10:37:06 +000012970}
12971
Alexey Bataev6125da92014-07-21 11:26:11 +000012972OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
12973 SourceLocation StartLoc,
12974 SourceLocation LParenLoc,
12975 SourceLocation EndLoc) {
12976 if (VarList.empty())
12977 return nullptr;
12978
12979 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
12980}
Alexey Bataevdea47612014-07-23 07:46:59 +000012981
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000012982OMPClause *
12983Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
12984 SourceLocation DepLoc, SourceLocation ColonLoc,
12985 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12986 SourceLocation LParenLoc, SourceLocation EndLoc) {
Alexey Bataeveb482352015-12-18 05:05:56 +000012987 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
Alexey Bataeva636c7f2015-12-23 10:27:45 +000012988 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
Alexey Bataeveb482352015-12-18 05:05:56 +000012989 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000012990 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
Alexey Bataeveb482352015-12-18 05:05:56 +000012991 return nullptr;
12992 }
12993 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
Alexey Bataeva636c7f2015-12-23 10:27:45 +000012994 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
12995 DepKind == OMPC_DEPEND_sink)) {
Alexey Bataev6402bca2015-12-28 07:25:51 +000012996 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000012997 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000012998 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12999 /*Last=*/OMPC_DEPEND_unknown, Except)
13000 << getOpenMPClauseName(OMPC_depend);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000013001 return nullptr;
13002 }
13003 SmallVector<Expr *, 8> Vars;
Alexey Bataev8b427062016-05-25 12:36:08 +000013004 DSAStackTy::OperatorOffsetTy OpsOffs;
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013005 llvm::APSInt DepCounter(/*BitWidth=*/32);
13006 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
Alexey Bataevf138fda2018-08-13 19:04:24 +000013007 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
13008 if (const Expr *OrderedCountExpr =
13009 DSAStack->getParentOrderedRegionParam().first) {
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013010 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
13011 TotalDepCount.setIsUnsigned(/*Val=*/true);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000013012 }
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000013013 }
Alexey Bataeve3727102018-04-18 15:57:46 +000013014 for (Expr *RefExpr : VarList) {
Alexey Bataev17daedf2018-02-15 22:42:57 +000013015 assert(RefExpr && "NULL expr in OpenMP shared clause.");
13016 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
13017 // It will be analyzed later.
13018 Vars.push_back(RefExpr);
13019 continue;
13020 }
13021
13022 SourceLocation ELoc = RefExpr->getExprLoc();
Alexey Bataeve3727102018-04-18 15:57:46 +000013023 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
Alexey Bataev17daedf2018-02-15 22:42:57 +000013024 if (DepKind == OMPC_DEPEND_sink) {
Alexey Bataevf138fda2018-08-13 19:04:24 +000013025 if (DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000013026 DepCounter >= TotalDepCount) {
13027 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
13028 continue;
13029 }
13030 ++DepCounter;
13031 // OpenMP [2.13.9, Summary]
13032 // depend(dependence-type : vec), where dependence-type is:
13033 // 'sink' and where vec is the iteration vector, which has the form:
13034 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
13035 // where n is the value specified by the ordered clause in the loop
13036 // directive, xi denotes the loop iteration variable of the i-th nested
13037 // loop associated with the loop directive, and di is a constant
13038 // non-negative integer.
13039 if (CurContext->isDependentContext()) {
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013040 // It will be analyzed later.
13041 Vars.push_back(RefExpr);
13042 continue;
13043 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000013044 SimpleExpr = SimpleExpr->IgnoreImplicit();
13045 OverloadedOperatorKind OOK = OO_None;
13046 SourceLocation OOLoc;
13047 Expr *LHS = SimpleExpr;
13048 Expr *RHS = nullptr;
13049 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
13050 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
13051 OOLoc = BO->getOperatorLoc();
13052 LHS = BO->getLHS()->IgnoreParenImpCasts();
13053 RHS = BO->getRHS()->IgnoreParenImpCasts();
13054 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
13055 OOK = OCE->getOperator();
13056 OOLoc = OCE->getOperatorLoc();
13057 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
13058 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
13059 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
13060 OOK = MCE->getMethodDecl()
13061 ->getNameInfo()
13062 .getName()
13063 .getCXXOverloadedOperator();
13064 OOLoc = MCE->getCallee()->getExprLoc();
13065 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
13066 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013067 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000013068 SourceLocation ELoc;
13069 SourceRange ERange;
Alexey Bataevbc529672018-09-28 19:33:14 +000013070 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
Alexey Bataev17daedf2018-02-15 22:42:57 +000013071 if (Res.second) {
13072 // It will be analyzed later.
13073 Vars.push_back(RefExpr);
13074 }
13075 ValueDecl *D = Res.first;
13076 if (!D)
13077 continue;
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013078
Alexey Bataev17daedf2018-02-15 22:42:57 +000013079 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
13080 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
13081 continue;
13082 }
13083 if (RHS) {
13084 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
13085 RHS, OMPC_depend, /*StrictlyPositive=*/false);
13086 if (RHSRes.isInvalid())
13087 continue;
13088 }
13089 if (!CurContext->isDependentContext() &&
Alexey Bataevf138fda2018-08-13 19:04:24 +000013090 DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000013091 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013092 const ValueDecl *VD =
Alexey Bataev17daedf2018-02-15 22:42:57 +000013093 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
Alexey Bataeve3727102018-04-18 15:57:46 +000013094 if (VD)
Alexey Bataev17daedf2018-02-15 22:42:57 +000013095 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
13096 << 1 << VD;
Alexey Bataeve3727102018-04-18 15:57:46 +000013097 else
Alexey Bataev17daedf2018-02-15 22:42:57 +000013098 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
Alexey Bataev17daedf2018-02-15 22:42:57 +000013099 continue;
13100 }
Alexey Bataeve3727102018-04-18 15:57:46 +000013101 OpsOffs.emplace_back(RHS, OOK);
Alexey Bataev17daedf2018-02-15 22:42:57 +000013102 } else {
13103 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
13104 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
13105 (ASE &&
13106 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
13107 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
13108 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
13109 << RefExpr->getSourceRange();
13110 continue;
13111 }
13112 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
13113 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
13114 ExprResult Res =
13115 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
13116 getDiagnostics().setSuppressAllDiagnostics(Suppress);
13117 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
13118 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
13119 << RefExpr->getSourceRange();
13120 continue;
13121 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013122 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000013123 Vars.push_back(RefExpr->IgnoreParenImpCasts());
Alexey Bataeva636c7f2015-12-23 10:27:45 +000013124 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000013125
13126 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
13127 TotalDepCount > VarList.size() &&
Alexey Bataevf138fda2018-08-13 19:04:24 +000013128 DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000013129 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
13130 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
13131 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
13132 }
13133 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
13134 Vars.empty())
13135 return nullptr;
13136
Alexey Bataev8b427062016-05-25 12:36:08 +000013137 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataevf138fda2018-08-13 19:04:24 +000013138 DepKind, DepLoc, ColonLoc, Vars,
13139 TotalDepCount.getZExtValue());
Alexey Bataev17daedf2018-02-15 22:42:57 +000013140 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
13141 DSAStack->isParentOrderedRegion())
Alexey Bataev8b427062016-05-25 12:36:08 +000013142 DSAStack->addDoacrossDependClause(C, OpsOffs);
13143 return C;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000013144}
Michael Wonge710d542015-08-07 16:16:36 +000013145
13146OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
13147 SourceLocation LParenLoc,
13148 SourceLocation EndLoc) {
13149 Expr *ValExpr = Device;
Alexey Bataev931e19b2017-10-02 16:32:39 +000013150 Stmt *HelperValStmt = nullptr;
Michael Wonge710d542015-08-07 16:16:36 +000013151
Kelvin Lia15fb1a2015-11-27 18:47:36 +000013152 // OpenMP [2.9.1, Restrictions]
13153 // The device expression must evaluate to a non-negative integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000013154 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
Alexey Bataeva0569352015-12-01 10:17:31 +000013155 /*StrictlyPositive=*/false))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000013156 return nullptr;
13157
Alexey Bataev931e19b2017-10-02 16:32:39 +000013158 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000013159 OpenMPDirectiveKind CaptureRegion =
13160 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
13161 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000013162 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000013163 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev931e19b2017-10-02 16:32:39 +000013164 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13165 HelperValStmt = buildPreInits(Context, Captures);
13166 }
13167
Alexey Bataev8451efa2018-01-15 19:06:12 +000013168 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
13169 StartLoc, LParenLoc, EndLoc);
Michael Wonge710d542015-08-07 16:16:36 +000013170}
Kelvin Li0bff7af2015-11-23 05:32:03 +000013171
Alexey Bataeve3727102018-04-18 15:57:46 +000013172static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
Alexey Bataev95c23e72018-02-27 21:31:11 +000013173 DSAStackTy *Stack, QualType QTy,
13174 bool FullCheck = true) {
Kelvin Li0bff7af2015-11-23 05:32:03 +000013175 NamedDecl *ND;
13176 if (QTy->isIncompleteType(&ND)) {
13177 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
13178 return false;
Kelvin Li0bff7af2015-11-23 05:32:03 +000013179 }
Alexey Bataev95c23e72018-02-27 21:31:11 +000013180 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
13181 !QTy.isTrivialType(SemaRef.Context))
13182 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
Kelvin Li0bff7af2015-11-23 05:32:03 +000013183 return true;
13184}
13185
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000013186/// Return true if it can be proven that the provided array expression
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013187/// (array section or array subscript) does NOT specify the whole size of the
13188/// array whose base type is \a BaseQTy.
Alexey Bataeve3727102018-04-18 15:57:46 +000013189static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013190 const Expr *E,
13191 QualType BaseQTy) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013192 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013193
13194 // If this is an array subscript, it refers to the whole size if the size of
13195 // the dimension is constant and equals 1. Also, an array section assumes the
13196 // format of an array subscript if no colon is used.
13197 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013198 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013199 return ATy->getSize().getSExtValue() != 1;
13200 // Size can't be evaluated statically.
13201 return false;
13202 }
13203
13204 assert(OASE && "Expecting array section if not an array subscript.");
Alexey Bataeve3727102018-04-18 15:57:46 +000013205 const Expr *LowerBound = OASE->getLowerBound();
13206 const Expr *Length = OASE->getLength();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013207
13208 // If there is a lower bound that does not evaluates to zero, we are not
David Majnemer9d168222016-08-05 17:44:54 +000013209 // covering the whole dimension.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013210 if (LowerBound) {
Fangrui Song407659a2018-11-30 23:41:18 +000013211 Expr::EvalResult Result;
13212 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013213 return false; // Can't get the integer value as a constant.
Fangrui Song407659a2018-11-30 23:41:18 +000013214
13215 llvm::APSInt ConstLowerBound = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013216 if (ConstLowerBound.getSExtValue())
13217 return true;
13218 }
13219
13220 // If we don't have a length we covering the whole dimension.
13221 if (!Length)
13222 return false;
13223
13224 // If the base is a pointer, we don't have a way to get the size of the
13225 // pointee.
13226 if (BaseQTy->isPointerType())
13227 return false;
13228
13229 // We can only check if the length is the same as the size of the dimension
13230 // if we have a constant array.
Alexey Bataeve3727102018-04-18 15:57:46 +000013231 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013232 if (!CATy)
13233 return false;
13234
Fangrui Song407659a2018-11-30 23:41:18 +000013235 Expr::EvalResult Result;
13236 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013237 return false; // Can't get the integer value as a constant.
13238
Fangrui Song407659a2018-11-30 23:41:18 +000013239 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013240 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
13241}
13242
13243// Return true if it can be proven that the provided array expression (array
13244// section or array subscript) does NOT specify a single element of the array
13245// whose base type is \a BaseQTy.
Alexey Bataeve3727102018-04-18 15:57:46 +000013246static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
David Majnemer9d168222016-08-05 17:44:54 +000013247 const Expr *E,
13248 QualType BaseQTy) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013249 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013250
13251 // An array subscript always refer to a single element. Also, an array section
13252 // assumes the format of an array subscript if no colon is used.
13253 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
13254 return false;
13255
13256 assert(OASE && "Expecting array section if not an array subscript.");
Alexey Bataeve3727102018-04-18 15:57:46 +000013257 const Expr *Length = OASE->getLength();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013258
13259 // If we don't have a length we have to check if the array has unitary size
13260 // for this dimension. Also, we should always expect a length if the base type
13261 // is pointer.
13262 if (!Length) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013263 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013264 return ATy->getSize().getSExtValue() != 1;
13265 // We cannot assume anything.
13266 return false;
13267 }
13268
13269 // Check if the length evaluates to 1.
Fangrui Song407659a2018-11-30 23:41:18 +000013270 Expr::EvalResult Result;
13271 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013272 return false; // Can't get the integer value as a constant.
13273
Fangrui Song407659a2018-11-30 23:41:18 +000013274 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013275 return ConstLength.getSExtValue() != 1;
13276}
13277
Samuel Antao661c0902016-05-26 17:39:58 +000013278// Return the expression of the base of the mappable expression or null if it
13279// cannot be determined and do all the necessary checks to see if the expression
13280// is valid as a standalone mappable expression. In the process, record all the
Samuel Antao90927002016-04-26 14:54:23 +000013281// components of the expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000013282static const Expr *checkMapClauseExpressionBase(
Samuel Antao90927002016-04-26 14:54:23 +000013283 Sema &SemaRef, Expr *E,
Samuel Antao661c0902016-05-26 17:39:58 +000013284 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013285 OpenMPClauseKind CKind, bool NoDiagnose) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013286 SourceLocation ELoc = E->getExprLoc();
13287 SourceRange ERange = E->getSourceRange();
13288
13289 // The base of elements of list in a map clause have to be either:
13290 // - a reference to variable or field.
13291 // - a member expression.
13292 // - an array expression.
13293 //
13294 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
13295 // reference to 'r'.
13296 //
13297 // If we have:
13298 //
13299 // struct SS {
13300 // Bla S;
13301 // foo() {
13302 // #pragma omp target map (S.Arr[:12]);
13303 // }
13304 // }
13305 //
13306 // We want to retrieve the member expression 'this->S';
13307
Alexey Bataeve3727102018-04-18 15:57:46 +000013308 const Expr *RelevantExpr = nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013309
Samuel Antao5de996e2016-01-22 20:21:36 +000013310 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
13311 // If a list item is an array section, it must specify contiguous storage.
13312 //
13313 // For this restriction it is sufficient that we make sure only references
13314 // to variables or fields and array expressions, and that no array sections
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013315 // exist except in the rightmost expression (unless they cover the whole
13316 // dimension of the array). E.g. these would be invalid:
Samuel Antao5de996e2016-01-22 20:21:36 +000013317 //
13318 // r.ArrS[3:5].Arr[6:7]
13319 //
13320 // r.ArrS[3:5].x
13321 //
13322 // but these would be valid:
13323 // r.ArrS[3].Arr[6:7]
13324 //
13325 // r.ArrS[3].x
13326
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013327 bool AllowUnitySizeArraySection = true;
13328 bool AllowWholeSizeArraySection = true;
Samuel Antao5de996e2016-01-22 20:21:36 +000013329
Dmitry Polukhin644a9252016-03-11 07:58:34 +000013330 while (!RelevantExpr) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013331 E = E->IgnoreParenImpCasts();
13332
13333 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
13334 if (!isa<VarDecl>(CurE->getDecl()))
Alexey Bataev27041fa2017-12-05 15:22:49 +000013335 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013336
13337 RelevantExpr = CurE;
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013338
13339 // If we got a reference to a declaration, we should not expect any array
13340 // section before that.
13341 AllowUnitySizeArraySection = false;
13342 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000013343
13344 // Record the component.
Alexey Bataev27041fa2017-12-05 15:22:49 +000013345 CurComponents.emplace_back(CurE, CurE->getDecl());
13346 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013347 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
Samuel Antao5de996e2016-01-22 20:21:36 +000013348
13349 if (isa<CXXThisExpr>(BaseE))
13350 // We found a base expression: this->Val.
13351 RelevantExpr = CurE;
13352 else
13353 E = BaseE;
13354
13355 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013356 if (!NoDiagnose) {
13357 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
13358 << CurE->getSourceRange();
13359 return nullptr;
13360 }
13361 if (RelevantExpr)
13362 return nullptr;
13363 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000013364 }
13365
13366 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
13367
13368 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
13369 // A bit-field cannot appear in a map clause.
13370 //
13371 if (FD->isBitField()) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013372 if (!NoDiagnose) {
13373 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
13374 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
13375 return nullptr;
13376 }
13377 if (RelevantExpr)
13378 return nullptr;
13379 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000013380 }
13381
13382 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13383 // If the type of a list item is a reference to a type T then the type
13384 // will be considered to be T for all purposes of this clause.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013385 QualType CurType = BaseE->getType().getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000013386
13387 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
13388 // A list item cannot be a variable that is a member of a structure with
13389 // a union type.
13390 //
Alexey Bataeve3727102018-04-18 15:57:46 +000013391 if (CurType->isUnionType()) {
13392 if (!NoDiagnose) {
13393 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
13394 << CurE->getSourceRange();
13395 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013396 }
Alexey Bataeve3727102018-04-18 15:57:46 +000013397 continue;
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013398 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013399
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013400 // If we got a member expression, we should not expect any array section
13401 // before that:
13402 //
13403 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
13404 // If a list item is an element of a structure, only the rightmost symbol
13405 // of the variable reference can be an array section.
13406 //
13407 AllowUnitySizeArraySection = false;
13408 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000013409
13410 // Record the component.
Alexey Bataev27041fa2017-12-05 15:22:49 +000013411 CurComponents.emplace_back(CurE, FD);
13412 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013413 E = CurE->getBase()->IgnoreParenImpCasts();
13414
13415 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013416 if (!NoDiagnose) {
13417 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
13418 << 0 << CurE->getSourceRange();
13419 return nullptr;
13420 }
13421 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000013422 }
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013423
13424 // If we got an array subscript that express the whole dimension we
13425 // can have any array expressions before. If it only expressing part of
13426 // the dimension, we can only have unitary-size array expressions.
Alexey Bataeve3727102018-04-18 15:57:46 +000013427 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013428 E->getType()))
13429 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000013430
Patrick Lystere13b1e32019-01-02 19:28:48 +000013431 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13432 Expr::EvalResult Result;
13433 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
13434 if (!Result.Val.getInt().isNullValue()) {
13435 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
13436 diag::err_omp_invalid_map_this_expr);
13437 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
13438 diag::note_omp_invalid_subscript_on_this_ptr_map);
13439 }
13440 }
13441 RelevantExpr = TE;
13442 }
13443
Samuel Antao90927002016-04-26 14:54:23 +000013444 // Record the component - we don't have any declaration associated.
Alexey Bataev27041fa2017-12-05 15:22:49 +000013445 CurComponents.emplace_back(CurE, nullptr);
13446 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013447 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
Samuel Antao5de996e2016-01-22 20:21:36 +000013448 E = CurE->getBase()->IgnoreParenImpCasts();
13449
Alexey Bataev27041fa2017-12-05 15:22:49 +000013450 QualType CurType =
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013451 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
13452
Samuel Antao5de996e2016-01-22 20:21:36 +000013453 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13454 // If the type of a list item is a reference to a type T then the type
13455 // will be considered to be T for all purposes of this clause.
Samuel Antao5de996e2016-01-22 20:21:36 +000013456 if (CurType->isReferenceType())
13457 CurType = CurType->getPointeeType();
13458
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013459 bool IsPointer = CurType->isAnyPointerType();
13460
13461 if (!IsPointer && !CurType->isArrayType()) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013462 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
13463 << 0 << CurE->getSourceRange();
Alexey Bataev27041fa2017-12-05 15:22:49 +000013464 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013465 }
13466
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013467 bool NotWhole =
Alexey Bataeve3727102018-04-18 15:57:46 +000013468 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013469 bool NotUnity =
Alexey Bataeve3727102018-04-18 15:57:46 +000013470 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013471
Samuel Antaodab51bb2016-07-18 23:22:11 +000013472 if (AllowWholeSizeArraySection) {
13473 // Any array section is currently allowed. Allowing a whole size array
13474 // section implies allowing a unity array section as well.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013475 //
13476 // If this array section refers to the whole dimension we can still
13477 // accept other array sections before this one, except if the base is a
13478 // pointer. Otherwise, only unitary sections are accepted.
13479 if (NotWhole || IsPointer)
13480 AllowWholeSizeArraySection = false;
Samuel Antaodab51bb2016-07-18 23:22:11 +000013481 } else if (AllowUnitySizeArraySection && NotUnity) {
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013482 // A unity or whole array section is not allowed and that is not
13483 // compatible with the properties of the current array section.
13484 SemaRef.Diag(
13485 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
13486 << CurE->getSourceRange();
Alexey Bataev27041fa2017-12-05 15:22:49 +000013487 return nullptr;
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000013488 }
Samuel Antao90927002016-04-26 14:54:23 +000013489
Patrick Lystere13b1e32019-01-02 19:28:48 +000013490 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13491 Expr::EvalResult ResultR;
13492 Expr::EvalResult ResultL;
13493 if (CurE->getLength()->EvaluateAsInt(ResultR,
13494 SemaRef.getASTContext())) {
13495 if (!ResultR.Val.getInt().isOneValue()) {
13496 SemaRef.Diag(CurE->getLength()->getExprLoc(),
13497 diag::err_omp_invalid_map_this_expr);
13498 SemaRef.Diag(CurE->getLength()->getExprLoc(),
13499 diag::note_omp_invalid_length_on_this_ptr_mapping);
13500 }
13501 }
13502 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
13503 ResultL, SemaRef.getASTContext())) {
13504 if (!ResultL.Val.getInt().isNullValue()) {
13505 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
13506 diag::err_omp_invalid_map_this_expr);
13507 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
13508 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
13509 }
13510 }
13511 RelevantExpr = TE;
13512 }
13513
Samuel Antao90927002016-04-26 14:54:23 +000013514 // Record the component - we don't have any declaration associated.
Alexey Bataev27041fa2017-12-05 15:22:49 +000013515 CurComponents.emplace_back(CurE, nullptr);
13516 } else {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000013517 if (!NoDiagnose) {
13518 // If nothing else worked, this is not a valid map clause expression.
13519 SemaRef.Diag(
13520 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
13521 << ERange;
13522 }
Alexey Bataev27041fa2017-12-05 15:22:49 +000013523 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013524 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013525 }
13526
13527 return RelevantExpr;
13528}
13529
13530// Return true if expression E associated with value VD has conflicts with other
13531// map information.
Alexey Bataeve3727102018-04-18 15:57:46 +000013532static bool checkMapConflicts(
13533 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
Samuel Antao90927002016-04-26 14:54:23 +000013534 bool CurrentRegionOnly,
Samuel Antao661c0902016-05-26 17:39:58 +000013535 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
13536 OpenMPClauseKind CKind) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013537 assert(VD && E);
Samuel Antao5de996e2016-01-22 20:21:36 +000013538 SourceLocation ELoc = E->getExprLoc();
13539 SourceRange ERange = E->getSourceRange();
13540
13541 // In order to easily check the conflicts we need to match each component of
13542 // the expression under test with the components of the expressions that are
13543 // already in the stack.
13544
Samuel Antao5de996e2016-01-22 20:21:36 +000013545 assert(!CurComponents.empty() && "Map clause expression with no components!");
Samuel Antao90927002016-04-26 14:54:23 +000013546 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
Samuel Antao5de996e2016-01-22 20:21:36 +000013547 "Map clause expression with unexpected base!");
13548
13549 // Variables to help detecting enclosing problems in data environment nests.
13550 bool IsEnclosedByDataEnvironmentExpr = false;
Samuel Antao90927002016-04-26 14:54:23 +000013551 const Expr *EnclosingExpr = nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000013552
Samuel Antao90927002016-04-26 14:54:23 +000013553 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
13554 VD, CurrentRegionOnly,
Alexey Bataeve3727102018-04-18 15:57:46 +000013555 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
13556 ERange, CKind, &EnclosingExpr,
13557 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
13558 StackComponents,
13559 OpenMPClauseKind) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013560 assert(!StackComponents.empty() &&
13561 "Map clause expression with no components!");
Samuel Antao90927002016-04-26 14:54:23 +000013562 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
Samuel Antao5de996e2016-01-22 20:21:36 +000013563 "Map clause expression with unexpected base!");
Fangrui Song16fe49a2018-04-18 19:32:01 +000013564 (void)VD;
Samuel Antao5de996e2016-01-22 20:21:36 +000013565
Samuel Antao90927002016-04-26 14:54:23 +000013566 // The whole expression in the stack.
Alexey Bataeve3727102018-04-18 15:57:46 +000013567 const Expr *RE = StackComponents.front().getAssociatedExpression();
Samuel Antao90927002016-04-26 14:54:23 +000013568
Samuel Antao5de996e2016-01-22 20:21:36 +000013569 // Expressions must start from the same base. Here we detect at which
13570 // point both expressions diverge from each other and see if we can
13571 // detect if the memory referred to both expressions is contiguous and
13572 // do not overlap.
13573 auto CI = CurComponents.rbegin();
13574 auto CE = CurComponents.rend();
13575 auto SI = StackComponents.rbegin();
13576 auto SE = StackComponents.rend();
13577 for (; CI != CE && SI != SE; ++CI, ++SI) {
13578
13579 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
13580 // At most one list item can be an array item derived from a given
13581 // variable in map clauses of the same construct.
Samuel Antao90927002016-04-26 14:54:23 +000013582 if (CurrentRegionOnly &&
13583 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
13584 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
13585 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
13586 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
13587 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
Samuel Antao5de996e2016-01-22 20:21:36 +000013588 diag::err_omp_multiple_array_items_in_map_clause)
Samuel Antao90927002016-04-26 14:54:23 +000013589 << CI->getAssociatedExpression()->getSourceRange();
13590 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
13591 diag::note_used_here)
13592 << SI->getAssociatedExpression()->getSourceRange();
Samuel Antao5de996e2016-01-22 20:21:36 +000013593 return true;
13594 }
13595
13596 // Do both expressions have the same kind?
Samuel Antao90927002016-04-26 14:54:23 +000013597 if (CI->getAssociatedExpression()->getStmtClass() !=
13598 SI->getAssociatedExpression()->getStmtClass())
Samuel Antao5de996e2016-01-22 20:21:36 +000013599 break;
13600
13601 // Are we dealing with different variables/fields?
Samuel Antao90927002016-04-26 14:54:23 +000013602 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
Samuel Antao5de996e2016-01-22 20:21:36 +000013603 break;
13604 }
Kelvin Li9f645ae2016-07-18 22:49:16 +000013605 // Check if the extra components of the expressions in the enclosing
13606 // data environment are redundant for the current base declaration.
13607 // If they are, the maps completely overlap, which is legal.
13608 for (; SI != SE; ++SI) {
13609 QualType Type;
Alexey Bataeve3727102018-04-18 15:57:46 +000013610 if (const auto *ASE =
David Majnemer9d168222016-08-05 17:44:54 +000013611 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
Kelvin Li9f645ae2016-07-18 22:49:16 +000013612 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
Alexey Bataeve3727102018-04-18 15:57:46 +000013613 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
David Majnemer9d168222016-08-05 17:44:54 +000013614 SI->getAssociatedExpression())) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013615 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
Kelvin Li9f645ae2016-07-18 22:49:16 +000013616 Type =
13617 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
13618 }
13619 if (Type.isNull() || Type->isAnyPointerType() ||
Alexey Bataeve3727102018-04-18 15:57:46 +000013620 checkArrayExpressionDoesNotReferToWholeSize(
Kelvin Li9f645ae2016-07-18 22:49:16 +000013621 SemaRef, SI->getAssociatedExpression(), Type))
13622 break;
13623 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013624
13625 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
13626 // List items of map clauses in the same construct must not share
13627 // original storage.
13628 //
13629 // If the expressions are exactly the same or one is a subset of the
13630 // other, it means they are sharing storage.
13631 if (CI == CE && SI == SE) {
13632 if (CurrentRegionOnly) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013633 if (CKind == OMPC_map) {
Samuel Antao661c0902016-05-26 17:39:58 +000013634 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
Alexey Bataeve3727102018-04-18 15:57:46 +000013635 } else {
Samuel Antaoec172c62016-05-26 17:49:04 +000013636 assert(CKind == OMPC_to || CKind == OMPC_from);
Samuel Antao661c0902016-05-26 17:39:58 +000013637 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13638 << ERange;
13639 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013640 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13641 << RE->getSourceRange();
13642 return true;
Samuel Antao5de996e2016-01-22 20:21:36 +000013643 }
Alexey Bataeve3727102018-04-18 15:57:46 +000013644 // If we find the same expression in the enclosing data environment,
13645 // that is legal.
13646 IsEnclosedByDataEnvironmentExpr = true;
13647 return false;
Samuel Antao5de996e2016-01-22 20:21:36 +000013648 }
13649
Samuel Antao90927002016-04-26 14:54:23 +000013650 QualType DerivedType =
13651 std::prev(CI)->getAssociatedDeclaration()->getType();
13652 SourceLocation DerivedLoc =
13653 std::prev(CI)->getAssociatedExpression()->getExprLoc();
Samuel Antao5de996e2016-01-22 20:21:36 +000013654
13655 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13656 // If the type of a list item is a reference to a type T then the type
13657 // will be considered to be T for all purposes of this clause.
Samuel Antao90927002016-04-26 14:54:23 +000013658 DerivedType = DerivedType.getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000013659
13660 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
13661 // A variable for which the type is pointer and an array section
13662 // derived from that variable must not appear as list items of map
13663 // clauses of the same construct.
13664 //
13665 // Also, cover one of the cases in:
13666 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
13667 // If any part of the original storage of a list item has corresponding
13668 // storage in the device data environment, all of the original storage
13669 // must have corresponding storage in the device data environment.
13670 //
13671 if (DerivedType->isAnyPointerType()) {
13672 if (CI == CE || SI == SE) {
13673 SemaRef.Diag(
13674 DerivedLoc,
13675 diag::err_omp_pointer_mapped_along_with_derived_section)
13676 << DerivedLoc;
Alexey Bataev2819260b2018-02-27 17:42:00 +000013677 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13678 << RE->getSourceRange();
13679 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +000013680 }
13681 if (CI->getAssociatedExpression()->getStmtClass() !=
Alexey Bataev2819260b2018-02-27 17:42:00 +000013682 SI->getAssociatedExpression()->getStmtClass() ||
13683 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
13684 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
Samuel Antao5de996e2016-01-22 20:21:36 +000013685 assert(CI != CE && SI != SE);
Alexey Bataev2819260b2018-02-27 17:42:00 +000013686 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
Samuel Antao5de996e2016-01-22 20:21:36 +000013687 << DerivedLoc;
Alexey Bataev2819260b2018-02-27 17:42:00 +000013688 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13689 << RE->getSourceRange();
13690 return true;
Samuel Antao5de996e2016-01-22 20:21:36 +000013691 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013692 }
13693
13694 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
13695 // List items of map clauses in the same construct must not share
13696 // original storage.
13697 //
13698 // An expression is a subset of the other.
13699 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013700 if (CKind == OMPC_map) {
Alexey Bataeve82445f2018-09-20 13:54:02 +000013701 if (CI != CE || SI != SE) {
13702 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
13703 // a pointer.
13704 auto Begin =
13705 CI != CE ? CurComponents.begin() : StackComponents.begin();
13706 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
13707 auto It = Begin;
13708 while (It != End && !It->getAssociatedDeclaration())
13709 std::advance(It, 1);
13710 assert(It != End &&
13711 "Expected at least one component with the declaration.");
13712 if (It != Begin && It->getAssociatedDeclaration()
13713 ->getType()
13714 .getCanonicalType()
13715 ->isAnyPointerType()) {
13716 IsEnclosedByDataEnvironmentExpr = false;
13717 EnclosingExpr = nullptr;
13718 return false;
13719 }
13720 }
Samuel Antao661c0902016-05-26 17:39:58 +000013721 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
Alexey Bataeve3727102018-04-18 15:57:46 +000013722 } else {
Samuel Antaoec172c62016-05-26 17:49:04 +000013723 assert(CKind == OMPC_to || CKind == OMPC_from);
Samuel Antao661c0902016-05-26 17:39:58 +000013724 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13725 << ERange;
13726 }
Samuel Antao5de996e2016-01-22 20:21:36 +000013727 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
13728 << RE->getSourceRange();
13729 return true;
13730 }
13731
13732 // The current expression uses the same base as other expression in the
Samuel Antao90927002016-04-26 14:54:23 +000013733 // data environment but does not contain it completely.
Samuel Antao5de996e2016-01-22 20:21:36 +000013734 if (!CurrentRegionOnly && SI != SE)
13735 EnclosingExpr = RE;
13736
13737 // The current expression is a subset of the expression in the data
13738 // environment.
13739 IsEnclosedByDataEnvironmentExpr |=
13740 (!CurrentRegionOnly && CI != CE && SI == SE);
13741
13742 return false;
13743 });
13744
13745 if (CurrentRegionOnly)
13746 return FoundError;
13747
13748 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
13749 // If any part of the original storage of a list item has corresponding
13750 // storage in the device data environment, all of the original storage must
13751 // have corresponding storage in the device data environment.
13752 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
13753 // If a list item is an element of a structure, and a different element of
13754 // the structure has a corresponding list item in the device data environment
13755 // prior to a task encountering the construct associated with the map clause,
Samuel Antao90927002016-04-26 14:54:23 +000013756 // then the list item must also have a corresponding list item in the device
Samuel Antao5de996e2016-01-22 20:21:36 +000013757 // data environment prior to the task encountering the construct.
13758 //
13759 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
13760 SemaRef.Diag(ELoc,
13761 diag::err_omp_original_storage_is_shared_and_does_not_contain)
13762 << ERange;
13763 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
13764 << EnclosingExpr->getSourceRange();
13765 return true;
13766 }
13767
13768 return FoundError;
13769}
13770
Michael Kruse4304e9d2019-02-19 16:38:20 +000013771// Look up the user-defined mapper given the mapper name and mapped type, and
13772// build a reference to it.
Benjamin Kramerba2ea932019-03-28 17:18:42 +000013773static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
13774 CXXScopeSpec &MapperIdScopeSpec,
13775 const DeclarationNameInfo &MapperId,
13776 QualType Type,
13777 Expr *UnresolvedMapper) {
Michael Kruse4304e9d2019-02-19 16:38:20 +000013778 if (MapperIdScopeSpec.isInvalid())
13779 return ExprError();
13780 // Find all user-defined mappers with the given MapperId.
13781 SmallVector<UnresolvedSet<8>, 4> Lookups;
13782 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
13783 Lookup.suppressDiagnostics();
13784 if (S) {
13785 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
13786 NamedDecl *D = Lookup.getRepresentativeDecl();
13787 while (S && !S->isDeclScope(D))
13788 S = S->getParent();
13789 if (S)
13790 S = S->getParent();
13791 Lookups.emplace_back();
13792 Lookups.back().append(Lookup.begin(), Lookup.end());
13793 Lookup.clear();
13794 }
13795 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
13796 // Extract the user-defined mappers with the given MapperId.
13797 Lookups.push_back(UnresolvedSet<8>());
13798 for (NamedDecl *D : ULE->decls()) {
13799 auto *DMD = cast<OMPDeclareMapperDecl>(D);
13800 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
13801 Lookups.back().addDecl(DMD);
13802 }
13803 }
13804 // Defer the lookup for dependent types. The results will be passed through
13805 // UnresolvedMapper on instantiation.
13806 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
13807 Type->isInstantiationDependentType() ||
13808 Type->containsUnexpandedParameterPack() ||
13809 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
13810 return !D->isInvalidDecl() &&
13811 (D->getType()->isDependentType() ||
13812 D->getType()->isInstantiationDependentType() ||
13813 D->getType()->containsUnexpandedParameterPack());
13814 })) {
13815 UnresolvedSet<8> URS;
13816 for (const UnresolvedSet<8> &Set : Lookups) {
13817 if (Set.empty())
13818 continue;
13819 URS.append(Set.begin(), Set.end());
13820 }
13821 return UnresolvedLookupExpr::Create(
13822 SemaRef.Context, /*NamingClass=*/nullptr,
13823 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
13824 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
13825 }
13826 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
13827 // The type must be of struct, union or class type in C and C++
13828 if (!Type->isStructureOrClassType() && !Type->isUnionType())
13829 return ExprEmpty();
13830 SourceLocation Loc = MapperId.getLoc();
13831 // Perform argument dependent lookup.
13832 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
13833 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
13834 // Return the first user-defined mapper with the desired type.
13835 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13836 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
13837 if (!D->isInvalidDecl() &&
13838 SemaRef.Context.hasSameType(D->getType(), Type))
13839 return D;
13840 return nullptr;
13841 }))
13842 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
13843 // Find the first user-defined mapper with a type derived from the desired
13844 // type.
13845 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13846 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
13847 if (!D->isInvalidDecl() &&
13848 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
13849 !Type.isMoreQualifiedThan(D->getType()))
13850 return D;
13851 return nullptr;
13852 })) {
13853 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
13854 /*DetectVirtual=*/false);
13855 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
13856 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
13857 VD->getType().getUnqualifiedType()))) {
13858 if (SemaRef.CheckBaseClassAccess(
13859 Loc, VD->getType(), Type, Paths.front(),
13860 /*DiagID=*/0) != Sema::AR_inaccessible) {
13861 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
13862 }
13863 }
13864 }
13865 }
13866 // Report error if a mapper is specified, but cannot be found.
13867 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
13868 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
13869 << Type << MapperId.getName();
13870 return ExprError();
13871 }
13872 return ExprEmpty();
13873}
13874
Samuel Antao661c0902016-05-26 17:39:58 +000013875namespace {
13876// Utility struct that gathers all the related lists associated with a mappable
13877// expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000013878struct MappableVarListInfo {
Samuel Antao661c0902016-05-26 17:39:58 +000013879 // The list of expressions.
13880 ArrayRef<Expr *> VarList;
13881 // The list of processed expressions.
13882 SmallVector<Expr *, 16> ProcessedVarList;
13883 // The mappble components for each expression.
13884 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
13885 // The base declaration of the variable.
13886 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
Michael Kruse4304e9d2019-02-19 16:38:20 +000013887 // The reference to the user-defined mapper associated with every expression.
13888 SmallVector<Expr *, 16> UDMapperList;
Samuel Antao661c0902016-05-26 17:39:58 +000013889
13890 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
13891 // We have a list of components and base declarations for each entry in the
13892 // variable list.
13893 VarComponents.reserve(VarList.size());
13894 VarBaseDeclarations.reserve(VarList.size());
13895 }
13896};
13897}
13898
13899// Check the validity of the provided variable list for the provided clause kind
Michael Kruse4304e9d2019-02-19 16:38:20 +000013900// \a CKind. In the check process the valid expressions, mappable expression
13901// components, variables, and user-defined mappers are extracted and used to
13902// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
13903// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
13904// and \a MapperId are expected to be valid if the clause kind is 'map'.
13905static void checkMappableExpressionList(
13906 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
13907 MappableVarListInfo &MVLI, SourceLocation StartLoc,
Michael Kruse01f670d2019-02-22 22:29:42 +000013908 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
13909 ArrayRef<Expr *> UnresolvedMappers,
Michael Kruse4304e9d2019-02-19 16:38:20 +000013910 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
Michael Kruse01f670d2019-02-22 22:29:42 +000013911 bool IsMapTypeImplicit = false) {
Samuel Antaoec172c62016-05-26 17:49:04 +000013912 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
13913 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
Samuel Antao661c0902016-05-26 17:39:58 +000013914 "Unexpected clause kind with mappable expressions!");
Michael Kruse01f670d2019-02-22 22:29:42 +000013915
13916 // If the identifier of user-defined mapper is not specified, it is "default".
13917 // We do not change the actual name in this clause to distinguish whether a
13918 // mapper is specified explicitly, i.e., it is not explicitly specified when
13919 // MapperId.getName() is empty.
13920 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
13921 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
13922 MapperId.setName(DeclNames.getIdentifier(
13923 &SemaRef.getASTContext().Idents.get("default")));
13924 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000013925
13926 // Iterators to find the current unresolved mapper expression.
13927 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
13928 bool UpdateUMIt = false;
13929 Expr *UnresolvedMapper = nullptr;
Kelvin Li0bff7af2015-11-23 05:32:03 +000013930
Samuel Antao90927002016-04-26 14:54:23 +000013931 // Keep track of the mappable components and base declarations in this clause.
13932 // Each entry in the list is going to have a list of components associated. We
13933 // record each set of the components so that we can build the clause later on.
13934 // In the end we should have the same amount of declarations and component
13935 // lists.
Samuel Antao90927002016-04-26 14:54:23 +000013936
Alexey Bataeve3727102018-04-18 15:57:46 +000013937 for (Expr *RE : MVLI.VarList) {
Samuel Antaoec172c62016-05-26 17:49:04 +000013938 assert(RE && "Null expr in omp to/from/map clause");
Kelvin Li0bff7af2015-11-23 05:32:03 +000013939 SourceLocation ELoc = RE->getExprLoc();
13940
Michael Kruse4304e9d2019-02-19 16:38:20 +000013941 // Find the current unresolved mapper expression.
13942 if (UpdateUMIt && UMIt != UMEnd) {
13943 UMIt++;
13944 assert(
13945 UMIt != UMEnd &&
13946 "Expect the size of UnresolvedMappers to match with that of VarList");
13947 }
13948 UpdateUMIt = true;
13949 if (UMIt != UMEnd)
13950 UnresolvedMapper = *UMIt;
13951
Alexey Bataeve3727102018-04-18 15:57:46 +000013952 const Expr *VE = RE->IgnoreParenLValueCasts();
Kelvin Li0bff7af2015-11-23 05:32:03 +000013953
13954 if (VE->isValueDependent() || VE->isTypeDependent() ||
13955 VE->isInstantiationDependent() ||
13956 VE->containsUnexpandedParameterPack()) {
Michael Kruse0336c752019-02-25 20:34:15 +000013957 // Try to find the associated user-defined mapper.
13958 ExprResult ER = buildUserDefinedMapperRef(
13959 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
13960 VE->getType().getCanonicalType(), UnresolvedMapper);
13961 if (ER.isInvalid())
13962 continue;
13963 MVLI.UDMapperList.push_back(ER.get());
Samuel Antao5de996e2016-01-22 20:21:36 +000013964 // We can only analyze this information once the missing information is
13965 // resolved.
Samuel Antao661c0902016-05-26 17:39:58 +000013966 MVLI.ProcessedVarList.push_back(RE);
Kelvin Li0bff7af2015-11-23 05:32:03 +000013967 continue;
13968 }
13969
Alexey Bataeve3727102018-04-18 15:57:46 +000013970 Expr *SimpleExpr = RE->IgnoreParenCasts();
Kelvin Li0bff7af2015-11-23 05:32:03 +000013971
Samuel Antao5de996e2016-01-22 20:21:36 +000013972 if (!RE->IgnoreParenImpCasts()->isLValue()) {
Samuel Antao661c0902016-05-26 17:39:58 +000013973 SemaRef.Diag(ELoc,
13974 diag::err_omp_expected_named_var_member_or_array_expression)
Samuel Antao5de996e2016-01-22 20:21:36 +000013975 << RE->getSourceRange();
Kelvin Li0bff7af2015-11-23 05:32:03 +000013976 continue;
13977 }
13978
Samuel Antao90927002016-04-26 14:54:23 +000013979 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
13980 ValueDecl *CurDeclaration = nullptr;
13981
13982 // Obtain the array or member expression bases if required. Also, fill the
13983 // components array with all the components identified in the process.
Alexey Bataeve3727102018-04-18 15:57:46 +000013984 const Expr *BE = checkMapClauseExpressionBase(
13985 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
Samuel Antao5de996e2016-01-22 20:21:36 +000013986 if (!BE)
13987 continue;
13988
Samuel Antao90927002016-04-26 14:54:23 +000013989 assert(!CurComponents.empty() &&
13990 "Invalid mappable expression information.");
Kelvin Li0bff7af2015-11-23 05:32:03 +000013991
Patrick Lystere13b1e32019-01-02 19:28:48 +000013992 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
13993 // Add store "this" pointer to class in DSAStackTy for future checking
13994 DSAS->addMappedClassesQualTypes(TE->getType());
Michael Kruse0336c752019-02-25 20:34:15 +000013995 // Try to find the associated user-defined mapper.
13996 ExprResult ER = buildUserDefinedMapperRef(
13997 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
13998 VE->getType().getCanonicalType(), UnresolvedMapper);
13999 if (ER.isInvalid())
14000 continue;
14001 MVLI.UDMapperList.push_back(ER.get());
Patrick Lystere13b1e32019-01-02 19:28:48 +000014002 // Skip restriction checking for variable or field declarations
14003 MVLI.ProcessedVarList.push_back(RE);
14004 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14005 MVLI.VarComponents.back().append(CurComponents.begin(),
14006 CurComponents.end());
14007 MVLI.VarBaseDeclarations.push_back(nullptr);
14008 continue;
14009 }
14010
Samuel Antao90927002016-04-26 14:54:23 +000014011 // For the following checks, we rely on the base declaration which is
14012 // expected to be associated with the last component. The declaration is
14013 // expected to be a variable or a field (if 'this' is being mapped).
14014 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
14015 assert(CurDeclaration && "Null decl on map clause.");
14016 assert(
14017 CurDeclaration->isCanonicalDecl() &&
14018 "Expecting components to have associated only canonical declarations.");
14019
14020 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
Alexey Bataeve3727102018-04-18 15:57:46 +000014021 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
Samuel Antao5de996e2016-01-22 20:21:36 +000014022
14023 assert((VD || FD) && "Only variables or fields are expected here!");
NAKAMURA Takumi6dcb8142016-01-23 01:38:20 +000014024 (void)FD;
Samuel Antao5de996e2016-01-22 20:21:36 +000014025
14026 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
Samuel Antao661c0902016-05-26 17:39:58 +000014027 // threadprivate variables cannot appear in a map clause.
14028 // OpenMP 4.5 [2.10.5, target update Construct]
14029 // threadprivate variables cannot appear in a from clause.
14030 if (VD && DSAS->isThreadPrivate(VD)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014031 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
Samuel Antao661c0902016-05-26 17:39:58 +000014032 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
14033 << getOpenMPClauseName(CKind);
Alexey Bataeve3727102018-04-18 15:57:46 +000014034 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
Kelvin Li0bff7af2015-11-23 05:32:03 +000014035 continue;
14036 }
14037
Samuel Antao5de996e2016-01-22 20:21:36 +000014038 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
14039 // A list item cannot appear in both a map clause and a data-sharing
14040 // attribute clause on the same construct.
Kelvin Li0bff7af2015-11-23 05:32:03 +000014041
Samuel Antao5de996e2016-01-22 20:21:36 +000014042 // Check conflicts with other map clause expressions. We check the conflicts
14043 // with the current construct separately from the enclosing data
Samuel Antao661c0902016-05-26 17:39:58 +000014044 // environment, because the restrictions are different. We only have to
14045 // check conflicts across regions for the map clauses.
Alexey Bataeve3727102018-04-18 15:57:46 +000014046 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
Samuel Antao661c0902016-05-26 17:39:58 +000014047 /*CurrentRegionOnly=*/true, CurComponents, CKind))
Samuel Antao5de996e2016-01-22 20:21:36 +000014048 break;
Samuel Antao661c0902016-05-26 17:39:58 +000014049 if (CKind == OMPC_map &&
Alexey Bataeve3727102018-04-18 15:57:46 +000014050 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
Samuel Antao661c0902016-05-26 17:39:58 +000014051 /*CurrentRegionOnly=*/false, CurComponents, CKind))
Samuel Antao5de996e2016-01-22 20:21:36 +000014052 break;
Kelvin Li0bff7af2015-11-23 05:32:03 +000014053
Samuel Antao661c0902016-05-26 17:39:58 +000014054 // OpenMP 4.5 [2.10.5, target update Construct]
Samuel Antao5de996e2016-01-22 20:21:36 +000014055 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14056 // If the type of a list item is a reference to a type T then the type will
14057 // be considered to be T for all purposes of this clause.
Alexey Bataev354df2e2018-05-02 18:44:10 +000014058 auto I = llvm::find_if(
14059 CurComponents,
14060 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
14061 return MC.getAssociatedDeclaration();
14062 });
14063 assert(I != CurComponents.end() && "Null decl on map clause.");
14064 QualType Type =
14065 I->getAssociatedDeclaration()->getType().getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000014066
Samuel Antao661c0902016-05-26 17:39:58 +000014067 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
14068 // A list item in a to or from clause must have a mappable type.
Samuel Antao5de996e2016-01-22 20:21:36 +000014069 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
Kelvin Li0bff7af2015-11-23 05:32:03 +000014070 // A list item must have a mappable type.
Alexey Bataeve3727102018-04-18 15:57:46 +000014071 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
Samuel Antao661c0902016-05-26 17:39:58 +000014072 DSAS, Type))
Kelvin Li0bff7af2015-11-23 05:32:03 +000014073 continue;
14074
Samuel Antao661c0902016-05-26 17:39:58 +000014075 if (CKind == OMPC_map) {
14076 // target enter data
14077 // OpenMP [2.10.2, Restrictions, p. 99]
14078 // A map-type must be specified in all map clauses and must be either
14079 // to or alloc.
14080 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
14081 if (DKind == OMPD_target_enter_data &&
14082 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
14083 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
14084 << (IsMapTypeImplicit ? 1 : 0)
14085 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
14086 << getOpenMPDirectiveName(DKind);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000014087 continue;
14088 }
Samuel Antao661c0902016-05-26 17:39:58 +000014089
14090 // target exit_data
14091 // OpenMP [2.10.3, Restrictions, p. 102]
14092 // A map-type must be specified in all map clauses and must be either
14093 // from, release, or delete.
14094 if (DKind == OMPD_target_exit_data &&
14095 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
14096 MapType == OMPC_MAP_delete)) {
14097 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
14098 << (IsMapTypeImplicit ? 1 : 0)
14099 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
14100 << getOpenMPDirectiveName(DKind);
14101 continue;
14102 }
14103
14104 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14105 // A list item cannot appear in both a map clause and a data-sharing
14106 // attribute clause on the same construct
Alexey Bataeve3727102018-04-18 15:57:46 +000014107 if (VD && isOpenMPTargetExecutionDirective(DKind)) {
14108 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
Samuel Antao661c0902016-05-26 17:39:58 +000014109 if (isOpenMPPrivate(DVar.CKind)) {
Samuel Antao6890b092016-07-28 14:25:09 +000014110 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Samuel Antao661c0902016-05-26 17:39:58 +000014111 << getOpenMPClauseName(DVar.CKind)
Samuel Antao6890b092016-07-28 14:25:09 +000014112 << getOpenMPClauseName(OMPC_map)
Samuel Antao661c0902016-05-26 17:39:58 +000014113 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000014114 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
Samuel Antao661c0902016-05-26 17:39:58 +000014115 continue;
14116 }
14117 }
Michael Kruse01f670d2019-02-22 22:29:42 +000014118 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000014119
Michael Kruse01f670d2019-02-22 22:29:42 +000014120 // Try to find the associated user-defined mapper.
Michael Kruse0336c752019-02-25 20:34:15 +000014121 ExprResult ER = buildUserDefinedMapperRef(
14122 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
14123 Type.getCanonicalType(), UnresolvedMapper);
14124 if (ER.isInvalid())
14125 continue;
14126 MVLI.UDMapperList.push_back(ER.get());
Carlo Bertollib74bfc82016-03-18 21:43:32 +000014127
Samuel Antao90927002016-04-26 14:54:23 +000014128 // Save the current expression.
Samuel Antao661c0902016-05-26 17:39:58 +000014129 MVLI.ProcessedVarList.push_back(RE);
Samuel Antao90927002016-04-26 14:54:23 +000014130
14131 // Store the components in the stack so that they can be used to check
14132 // against other clauses later on.
Samuel Antao6890b092016-07-28 14:25:09 +000014133 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
14134 /*WhereFoundClauseKind=*/OMPC_map);
Samuel Antao90927002016-04-26 14:54:23 +000014135
14136 // Save the components and declaration to create the clause. For purposes of
14137 // the clause creation, any component list that has has base 'this' uses
Samuel Antao686c70c2016-05-26 17:30:50 +000014138 // null as base declaration.
Samuel Antao661c0902016-05-26 17:39:58 +000014139 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14140 MVLI.VarComponents.back().append(CurComponents.begin(),
14141 CurComponents.end());
14142 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
14143 : CurDeclaration);
Kelvin Li0bff7af2015-11-23 05:32:03 +000014144 }
Samuel Antao661c0902016-05-26 17:39:58 +000014145}
14146
Michael Kruse4304e9d2019-02-19 16:38:20 +000014147OMPClause *Sema::ActOnOpenMPMapClause(
14148 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
14149 ArrayRef<SourceLocation> MapTypeModifiersLoc,
14150 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
14151 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
14152 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
14153 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
14154 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
14155 OMPC_MAP_MODIFIER_unknown,
14156 OMPC_MAP_MODIFIER_unknown};
Kelvin Lief579432018-12-18 22:18:41 +000014157 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
14158
14159 // Process map-type-modifiers, flag errors for duplicate modifiers.
14160 unsigned Count = 0;
14161 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
14162 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
14163 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
14164 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
14165 continue;
14166 }
14167 assert(Count < OMPMapClause::NumberOfModifiers &&
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +000014168 "Modifiers exceed the allowed number of map type modifiers");
Kelvin Lief579432018-12-18 22:18:41 +000014169 Modifiers[Count] = MapTypeModifiers[I];
14170 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
14171 ++Count;
14172 }
14173
Michael Kruse4304e9d2019-02-19 16:38:20 +000014174 MappableVarListInfo MVLI(VarList);
14175 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
Michael Kruse01f670d2019-02-22 22:29:42 +000014176 MapperIdScopeSpec, MapperId, UnresolvedMappers,
14177 MapType, IsMapTypeImplicit);
Michael Kruse4304e9d2019-02-19 16:38:20 +000014178
Samuel Antao5de996e2016-01-22 20:21:36 +000014179 // We need to produce a map clause even if we don't have variables so that
14180 // other diagnostics related with non-existing map clauses are accurate.
Michael Kruse4304e9d2019-02-19 16:38:20 +000014181 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
14182 MVLI.VarBaseDeclarations, MVLI.VarComponents,
14183 MVLI.UDMapperList, Modifiers, ModifiersLoc,
14184 MapperIdScopeSpec.getWithLocInContext(Context),
14185 MapperId, MapType, IsMapTypeImplicit, MapLoc);
Kelvin Li0bff7af2015-11-23 05:32:03 +000014186}
Kelvin Li099bb8c2015-11-24 20:50:12 +000014187
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014188QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
14189 TypeResult ParsedType) {
14190 assert(ParsedType.isUsable());
14191
14192 QualType ReductionType = GetTypeFromParser(ParsedType.get());
14193 if (ReductionType.isNull())
14194 return QualType();
14195
14196 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
14197 // A type name in a declare reduction directive cannot be a function type, an
14198 // array type, a reference type, or a type qualified with const, volatile or
14199 // restrict.
14200 if (ReductionType.hasQualifiers()) {
14201 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
14202 return QualType();
14203 }
14204
14205 if (ReductionType->isFunctionType()) {
14206 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
14207 return QualType();
14208 }
14209 if (ReductionType->isReferenceType()) {
14210 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
14211 return QualType();
14212 }
14213 if (ReductionType->isArrayType()) {
14214 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
14215 return QualType();
14216 }
14217 return ReductionType;
14218}
14219
14220Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
14221 Scope *S, DeclContext *DC, DeclarationName Name,
14222 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
14223 AccessSpecifier AS, Decl *PrevDeclInScope) {
14224 SmallVector<Decl *, 8> Decls;
14225 Decls.reserve(ReductionTypes.size());
14226
14227 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
Richard Smithbecb92d2017-10-10 22:33:17 +000014228 forRedeclarationInCurContext());
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014229 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
14230 // A reduction-identifier may not be re-declared in the current scope for the
14231 // same type or for a type that is compatible according to the base language
14232 // rules.
14233 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
14234 OMPDeclareReductionDecl *PrevDRD = nullptr;
14235 bool InCompoundScope = true;
14236 if (S != nullptr) {
14237 // Find previous declaration with the same name not referenced in other
14238 // declarations.
14239 FunctionScopeInfo *ParentFn = getEnclosingFunction();
14240 InCompoundScope =
14241 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
14242 LookupName(Lookup, S);
14243 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
14244 /*AllowInlineNamespace=*/false);
14245 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
Alexey Bataeve3727102018-04-18 15:57:46 +000014246 LookupResult::Filter Filter = Lookup.makeFilter();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014247 while (Filter.hasNext()) {
14248 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
14249 if (InCompoundScope) {
14250 auto I = UsedAsPrevious.find(PrevDecl);
14251 if (I == UsedAsPrevious.end())
14252 UsedAsPrevious[PrevDecl] = false;
Alexey Bataeve3727102018-04-18 15:57:46 +000014253 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014254 UsedAsPrevious[D] = true;
14255 }
14256 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
14257 PrevDecl->getLocation();
14258 }
14259 Filter.done();
14260 if (InCompoundScope) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014261 for (const auto &PrevData : UsedAsPrevious) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014262 if (!PrevData.second) {
14263 PrevDRD = PrevData.first;
14264 break;
14265 }
14266 }
14267 }
14268 } else if (PrevDeclInScope != nullptr) {
14269 auto *PrevDRDInScope = PrevDRD =
14270 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
14271 do {
14272 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
14273 PrevDRDInScope->getLocation();
14274 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
14275 } while (PrevDRDInScope != nullptr);
14276 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014277 for (const auto &TyData : ReductionTypes) {
14278 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014279 bool Invalid = false;
14280 if (I != PreviousRedeclTypes.end()) {
14281 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
14282 << TyData.first;
14283 Diag(I->second, diag::note_previous_definition);
14284 Invalid = true;
14285 }
14286 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
14287 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
14288 Name, TyData.first, PrevDRD);
14289 DC->addDecl(DRD);
14290 DRD->setAccess(AS);
14291 Decls.push_back(DRD);
14292 if (Invalid)
14293 DRD->setInvalidDecl();
14294 else
14295 PrevDRD = DRD;
14296 }
14297
14298 return DeclGroupPtrTy::make(
14299 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
14300}
14301
14302void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
14303 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14304
14305 // Enter new function scope.
14306 PushFunctionScope();
Reid Kleckner87a31802018-03-12 21:43:02 +000014307 setFunctionHasBranchProtectedScope();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014308 getCurFunction()->setHasOMPDeclareReductionCombiner();
14309
14310 if (S != nullptr)
14311 PushDeclContext(S, DRD);
14312 else
14313 CurContext = DRD;
14314
Faisal Valid143a0c2017-04-01 21:30:49 +000014315 PushExpressionEvaluationContext(
14316 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014317
14318 QualType ReductionType = DRD->getType();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000014319 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
14320 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
14321 // uses semantics of argument handles by value, but it should be passed by
14322 // reference. C lang does not support references, so pass all parameters as
14323 // pointers.
14324 // Create 'T omp_in;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000014325 VarDecl *OmpInParm =
Alexey Bataeva839ddd2016-03-17 10:19:46 +000014326 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014327 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
14328 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
14329 // uses semantics of argument handles by value, but it should be passed by
14330 // reference. C lang does not support references, so pass all parameters as
14331 // pointers.
14332 // Create 'T omp_out;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000014333 VarDecl *OmpOutParm =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014334 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
14335 if (S != nullptr) {
14336 PushOnScopeChains(OmpInParm, S);
14337 PushOnScopeChains(OmpOutParm, S);
14338 } else {
14339 DRD->addDecl(OmpInParm);
14340 DRD->addDecl(OmpOutParm);
14341 }
Alexey Bataeve6aa4692018-09-13 16:54:05 +000014342 Expr *InE =
14343 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
14344 Expr *OutE =
14345 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
14346 DRD->setCombinerData(InE, OutE);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014347}
14348
14349void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
14350 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14351 DiscardCleanupsInEvaluationContext();
14352 PopExpressionEvaluationContext();
14353
14354 PopDeclContext();
14355 PopFunctionScopeInfo();
14356
14357 if (Combiner != nullptr)
14358 DRD->setCombiner(Combiner);
14359 else
14360 DRD->setInvalidDecl();
14361}
14362
Alexey Bataev070f43a2017-09-06 14:49:58 +000014363VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014364 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14365
14366 // Enter new function scope.
14367 PushFunctionScope();
Reid Kleckner87a31802018-03-12 21:43:02 +000014368 setFunctionHasBranchProtectedScope();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014369
14370 if (S != nullptr)
14371 PushDeclContext(S, DRD);
14372 else
14373 CurContext = DRD;
14374
Faisal Valid143a0c2017-04-01 21:30:49 +000014375 PushExpressionEvaluationContext(
14376 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014377
14378 QualType ReductionType = DRD->getType();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014379 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
14380 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
14381 // uses semantics of argument handles by value, but it should be passed by
14382 // reference. C lang does not support references, so pass all parameters as
14383 // pointers.
14384 // Create 'T omp_priv;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000014385 VarDecl *OmpPrivParm =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014386 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
Alexey Bataeva839ddd2016-03-17 10:19:46 +000014387 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
14388 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
14389 // uses semantics of argument handles by value, but it should be passed by
14390 // reference. C lang does not support references, so pass all parameters as
14391 // pointers.
14392 // Create 'T omp_orig;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000014393 VarDecl *OmpOrigParm =
Alexey Bataeva839ddd2016-03-17 10:19:46 +000014394 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014395 if (S != nullptr) {
14396 PushOnScopeChains(OmpPrivParm, S);
14397 PushOnScopeChains(OmpOrigParm, S);
14398 } else {
14399 DRD->addDecl(OmpPrivParm);
14400 DRD->addDecl(OmpOrigParm);
14401 }
Alexey Bataeve6aa4692018-09-13 16:54:05 +000014402 Expr *OrigE =
14403 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
14404 Expr *PrivE =
14405 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
14406 DRD->setInitializerData(OrigE, PrivE);
Alexey Bataev070f43a2017-09-06 14:49:58 +000014407 return OmpPrivParm;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014408}
14409
Alexey Bataev070f43a2017-09-06 14:49:58 +000014410void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
14411 VarDecl *OmpPrivParm) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014412 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14413 DiscardCleanupsInEvaluationContext();
14414 PopExpressionEvaluationContext();
14415
14416 PopDeclContext();
14417 PopFunctionScopeInfo();
14418
Alexey Bataev070f43a2017-09-06 14:49:58 +000014419 if (Initializer != nullptr) {
14420 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
14421 } else if (OmpPrivParm->hasInit()) {
14422 DRD->setInitializer(OmpPrivParm->getInit(),
14423 OmpPrivParm->isDirectInit()
14424 ? OMPDeclareReductionDecl::DirectInit
14425 : OMPDeclareReductionDecl::CopyInit);
14426 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014427 DRD->setInvalidDecl();
Alexey Bataev070f43a2017-09-06 14:49:58 +000014428 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014429}
14430
14431Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
14432 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014433 for (Decl *D : DeclReductions.get()) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014434 if (IsValid) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014435 if (S)
14436 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
14437 /*AddToContext=*/false);
14438 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014439 D->setInvalidDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +000014440 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000014441 }
14442 return DeclReductions;
14443}
14444
Michael Kruse251e1482019-02-01 20:25:04 +000014445TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
14446 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
14447 QualType T = TInfo->getType();
14448 if (D.isInvalidType())
14449 return true;
14450
14451 if (getLangOpts().CPlusPlus) {
14452 // Check that there are no default arguments (C++ only).
14453 CheckExtraCXXDefaultArguments(D);
14454 }
14455
14456 return CreateParsedType(T, TInfo);
14457}
14458
14459QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
14460 TypeResult ParsedType) {
14461 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
14462
14463 QualType MapperType = GetTypeFromParser(ParsedType.get());
14464 assert(!MapperType.isNull() && "Expect valid mapper type");
14465
14466 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
14467 // The type must be of struct, union or class type in C and C++
14468 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
14469 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
14470 return QualType();
14471 }
14472 return MapperType;
14473}
14474
14475OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
14476 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
14477 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
14478 Decl *PrevDeclInScope) {
14479 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
14480 forRedeclarationInCurContext());
14481 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
14482 // A mapper-identifier may not be redeclared in the current scope for the
14483 // same type or for a type that is compatible according to the base language
14484 // rules.
14485 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
14486 OMPDeclareMapperDecl *PrevDMD = nullptr;
14487 bool InCompoundScope = true;
14488 if (S != nullptr) {
14489 // Find previous declaration with the same name not referenced in other
14490 // declarations.
14491 FunctionScopeInfo *ParentFn = getEnclosingFunction();
14492 InCompoundScope =
14493 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
14494 LookupName(Lookup, S);
14495 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
14496 /*AllowInlineNamespace=*/false);
14497 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
14498 LookupResult::Filter Filter = Lookup.makeFilter();
14499 while (Filter.hasNext()) {
14500 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
14501 if (InCompoundScope) {
14502 auto I = UsedAsPrevious.find(PrevDecl);
14503 if (I == UsedAsPrevious.end())
14504 UsedAsPrevious[PrevDecl] = false;
14505 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
14506 UsedAsPrevious[D] = true;
14507 }
14508 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
14509 PrevDecl->getLocation();
14510 }
14511 Filter.done();
14512 if (InCompoundScope) {
14513 for (const auto &PrevData : UsedAsPrevious) {
14514 if (!PrevData.second) {
14515 PrevDMD = PrevData.first;
14516 break;
14517 }
14518 }
14519 }
14520 } else if (PrevDeclInScope) {
14521 auto *PrevDMDInScope = PrevDMD =
14522 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
14523 do {
14524 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
14525 PrevDMDInScope->getLocation();
14526 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
14527 } while (PrevDMDInScope != nullptr);
14528 }
14529 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
14530 bool Invalid = false;
14531 if (I != PreviousRedeclTypes.end()) {
14532 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
14533 << MapperType << Name;
14534 Diag(I->second, diag::note_previous_definition);
14535 Invalid = true;
14536 }
14537 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
14538 MapperType, VN, PrevDMD);
14539 DC->addDecl(DMD);
14540 DMD->setAccess(AS);
14541 if (Invalid)
14542 DMD->setInvalidDecl();
14543
14544 // Enter new function scope.
14545 PushFunctionScope();
14546 setFunctionHasBranchProtectedScope();
14547
14548 CurContext = DMD;
14549
14550 return DMD;
14551}
14552
14553void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
14554 Scope *S,
14555 QualType MapperType,
14556 SourceLocation StartLoc,
14557 DeclarationName VN) {
14558 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
14559 if (S)
14560 PushOnScopeChains(VD, S);
14561 else
14562 DMD->addDecl(VD);
14563 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
14564 DMD->setMapperVarRef(MapperVarRefExpr);
14565}
14566
14567Sema::DeclGroupPtrTy
14568Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
14569 ArrayRef<OMPClause *> ClauseList) {
14570 PopDeclContext();
14571 PopFunctionScopeInfo();
14572
14573 if (D) {
14574 if (S)
14575 PushOnScopeChains(D, S, /*AddToContext=*/false);
14576 D->CreateClauses(Context, ClauseList);
14577 }
14578
14579 return DeclGroupPtrTy::make(DeclGroupRef(D));
14580}
14581
David Majnemer9d168222016-08-05 17:44:54 +000014582OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
Kelvin Li099bb8c2015-11-24 20:50:12 +000014583 SourceLocation StartLoc,
14584 SourceLocation LParenLoc,
14585 SourceLocation EndLoc) {
14586 Expr *ValExpr = NumTeams;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000014587 Stmt *HelperValStmt = nullptr;
Kelvin Li099bb8c2015-11-24 20:50:12 +000014588
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014589 // OpenMP [teams Constrcut, Restrictions]
14590 // The num_teams expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000014591 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
Alexey Bataeva0569352015-12-01 10:17:31 +000014592 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014593 return nullptr;
Kelvin Li099bb8c2015-11-24 20:50:12 +000014594
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000014595 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000014596 OpenMPDirectiveKind CaptureRegion =
14597 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
14598 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000014599 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000014600 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000014601 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14602 HelperValStmt = buildPreInits(Context, Captures);
14603 }
14604
14605 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
14606 StartLoc, LParenLoc, EndLoc);
Kelvin Li099bb8c2015-11-24 20:50:12 +000014607}
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014608
14609OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
14610 SourceLocation StartLoc,
14611 SourceLocation LParenLoc,
14612 SourceLocation EndLoc) {
14613 Expr *ValExpr = ThreadLimit;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000014614 Stmt *HelperValStmt = nullptr;
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014615
14616 // OpenMP [teams Constrcut, Restrictions]
14617 // The thread_limit expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000014618 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
Alexey Bataeva0569352015-12-01 10:17:31 +000014619 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014620 return nullptr;
14621
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000014622 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000014623 OpenMPDirectiveKind CaptureRegion =
14624 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
14625 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000014626 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000014627 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000014628 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14629 HelperValStmt = buildPreInits(Context, Captures);
14630 }
14631
14632 return new (Context) OMPThreadLimitClause(
14633 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014634}
Alexey Bataeva0569352015-12-01 10:17:31 +000014635
14636OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
14637 SourceLocation StartLoc,
14638 SourceLocation LParenLoc,
14639 SourceLocation EndLoc) {
14640 Expr *ValExpr = Priority;
14641
14642 // OpenMP [2.9.1, task Constrcut]
14643 // The priority-value is a non-negative numerical scalar expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000014644 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
Alexey Bataeva0569352015-12-01 10:17:31 +000014645 /*StrictlyPositive=*/false))
14646 return nullptr;
14647
14648 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14649}
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000014650
14651OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
14652 SourceLocation StartLoc,
14653 SourceLocation LParenLoc,
14654 SourceLocation EndLoc) {
14655 Expr *ValExpr = Grainsize;
14656
14657 // OpenMP [2.9.2, taskloop Constrcut]
14658 // The parameter of the grainsize clause must be a positive integer
14659 // expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000014660 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000014661 /*StrictlyPositive=*/true))
14662 return nullptr;
14663
14664 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14665}
Alexey Bataev382967a2015-12-08 12:06:20 +000014666
14667OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
14668 SourceLocation StartLoc,
14669 SourceLocation LParenLoc,
14670 SourceLocation EndLoc) {
14671 Expr *ValExpr = NumTasks;
14672
14673 // OpenMP [2.9.2, taskloop Constrcut]
14674 // The parameter of the num_tasks clause must be a positive integer
14675 // expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000014676 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
Alexey Bataev382967a2015-12-08 12:06:20 +000014677 /*StrictlyPositive=*/true))
14678 return nullptr;
14679
14680 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
14681}
14682
Alexey Bataev28c75412015-12-15 08:19:24 +000014683OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
14684 SourceLocation LParenLoc,
14685 SourceLocation EndLoc) {
14686 // OpenMP [2.13.2, critical construct, Description]
14687 // ... where hint-expression is an integer constant expression that evaluates
14688 // to a valid lock hint.
14689 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
14690 if (HintExpr.isInvalid())
14691 return nullptr;
14692 return new (Context)
14693 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
14694}
14695
Carlo Bertollib4adf552016-01-15 18:50:31 +000014696OMPClause *Sema::ActOnOpenMPDistScheduleClause(
14697 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14698 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
14699 SourceLocation EndLoc) {
14700 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
14701 std::string Values;
14702 Values += "'";
14703 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
14704 Values += "'";
14705 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14706 << Values << getOpenMPClauseName(OMPC_dist_schedule);
14707 return nullptr;
14708 }
14709 Expr *ValExpr = ChunkSize;
Alexey Bataev3392d762016-02-16 11:18:12 +000014710 Stmt *HelperValStmt = nullptr;
Carlo Bertollib4adf552016-01-15 18:50:31 +000014711 if (ChunkSize) {
14712 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14713 !ChunkSize->isInstantiationDependent() &&
14714 !ChunkSize->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014715 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
Carlo Bertollib4adf552016-01-15 18:50:31 +000014716 ExprResult Val =
14717 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14718 if (Val.isInvalid())
14719 return nullptr;
14720
14721 ValExpr = Val.get();
14722
14723 // OpenMP [2.7.1, Restrictions]
14724 // chunk_size must be a loop invariant integer expression with a positive
14725 // value.
14726 llvm::APSInt Result;
14727 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
14728 if (Result.isSigned() && !Result.isStrictlyPositive()) {
14729 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14730 << "dist_schedule" << ChunkSize->getSourceRange();
14731 return nullptr;
14732 }
Alexey Bataev2ba67042017-11-28 21:11:44 +000014733 } else if (getOpenMPCaptureRegionForClause(
14734 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
14735 OMPD_unknown &&
Alexey Bataevb46cdea2016-06-15 11:20:48 +000014736 !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000014737 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000014738 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev5a3af132016-03-29 08:58:54 +000014739 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14740 HelperValStmt = buildPreInits(Context, Captures);
Carlo Bertollib4adf552016-01-15 18:50:31 +000014741 }
14742 }
14743 }
14744
14745 return new (Context)
14746 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
Alexey Bataev3392d762016-02-16 11:18:12 +000014747 Kind, ValExpr, HelperValStmt);
Carlo Bertollib4adf552016-01-15 18:50:31 +000014748}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000014749
14750OMPClause *Sema::ActOnOpenMPDefaultmapClause(
14751 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
14752 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
14753 SourceLocation KindLoc, SourceLocation EndLoc) {
14754 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
David Majnemer9d168222016-08-05 17:44:54 +000014755 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000014756 std::string Value;
14757 SourceLocation Loc;
14758 Value += "'";
14759 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
14760 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
David Majnemer9d168222016-08-05 17:44:54 +000014761 OMPC_DEFAULTMAP_MODIFIER_tofrom);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000014762 Loc = MLoc;
14763 } else {
14764 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
David Majnemer9d168222016-08-05 17:44:54 +000014765 OMPC_DEFAULTMAP_scalar);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000014766 Loc = KindLoc;
14767 }
14768 Value += "'";
14769 Diag(Loc, diag::err_omp_unexpected_clause_value)
14770 << Value << getOpenMPClauseName(OMPC_defaultmap);
14771 return nullptr;
14772 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +000014773 DSAStack->setDefaultDMAToFromScalar(StartLoc);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000014774
14775 return new (Context)
14776 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
14777}
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014778
14779bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
14780 DeclContext *CurLexicalContext = getCurLexicalContext();
14781 if (!CurLexicalContext->isFileContext() &&
14782 !CurLexicalContext->isExternCContext() &&
Alexey Bataev502ec492017-10-03 20:00:00 +000014783 !CurLexicalContext->isExternCXXContext() &&
14784 !isa<CXXRecordDecl>(CurLexicalContext) &&
14785 !isa<ClassTemplateDecl>(CurLexicalContext) &&
14786 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
14787 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014788 Diag(Loc, diag::err_omp_region_not_file_context);
14789 return false;
14790 }
Kelvin Libc38e632018-09-10 02:07:09 +000014791 ++DeclareTargetNestingLevel;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014792 return true;
14793}
14794
14795void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
Kelvin Libc38e632018-09-10 02:07:09 +000014796 assert(DeclareTargetNestingLevel > 0 &&
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014797 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
Kelvin Libc38e632018-09-10 02:07:09 +000014798 --DeclareTargetNestingLevel;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014799}
14800
David Majnemer9d168222016-08-05 17:44:54 +000014801void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
14802 CXXScopeSpec &ScopeSpec,
14803 const DeclarationNameInfo &Id,
14804 OMPDeclareTargetDeclAttr::MapTypeTy MT,
14805 NamedDeclSetType &SameDirectiveDecls) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014806 LookupResult Lookup(*this, Id, LookupOrdinaryName);
14807 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
14808
14809 if (Lookup.isAmbiguous())
14810 return;
14811 Lookup.suppressDiagnostics();
14812
14813 if (!Lookup.isSingleResult()) {
Bruno Ricci70ad3962019-03-25 17:08:51 +000014814 VarOrFuncDeclFilterCCC CCC(*this);
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014815 if (TypoCorrection Corrected =
Bruno Ricci70ad3962019-03-25 17:08:51 +000014816 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014817 CTK_ErrorRecovery)) {
14818 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
14819 << Id.getName());
14820 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
14821 return;
14822 }
14823
14824 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
14825 return;
14826 }
14827
14828 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
Alexey Bataev30a78212018-09-11 13:59:10 +000014829 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
14830 isa<FunctionTemplateDecl>(ND)) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014831 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
14832 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
Alexey Bataev30a78212018-09-11 13:59:10 +000014833 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
14834 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
14835 cast<ValueDecl>(ND));
14836 if (!Res) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014837 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014838 ND->addAttr(A);
14839 if (ASTMutationListener *ML = Context.getASTMutationListener())
14840 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
Kelvin Li1ce87c72017-12-12 20:08:12 +000014841 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
Alexey Bataev30a78212018-09-11 13:59:10 +000014842 } else if (*Res != MT) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014843 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
14844 << Id.getName();
14845 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014846 } else {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014847 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
Alexey Bataeve3727102018-04-18 15:57:46 +000014848 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +000014849}
14850
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014851static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
14852 Sema &SemaRef, Decl *D) {
Alexey Bataev30a78212018-09-11 13:59:10 +000014853 if (!D || !isa<VarDecl>(D))
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014854 return;
Alexey Bataev30a78212018-09-11 13:59:10 +000014855 auto *VD = cast<VarDecl>(D);
14856 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
14857 return;
14858 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
14859 SemaRef.Diag(SL, diag::note_used_here) << SR;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014860}
14861
14862static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
14863 Sema &SemaRef, DSAStackTy *Stack,
14864 ValueDecl *VD) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014865 return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
14866 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
14867 /*FullCheck=*/false);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014868}
14869
Kelvin Li1ce87c72017-12-12 20:08:12 +000014870void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
14871 SourceLocation IdLoc) {
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014872 if (!D || D->isInvalidDecl())
14873 return;
14874 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014875 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
Alexey Bataeve3727102018-04-18 15:57:46 +000014876 if (auto *VD = dyn_cast<VarDecl>(D)) {
Alexey Bataevc1943e72018-07-09 19:58:08 +000014877 // Only global variables can be marked as declare target.
Alexey Bataev30a78212018-09-11 13:59:10 +000014878 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
14879 !VD->isStaticDataMember())
Alexey Bataevc1943e72018-07-09 19:58:08 +000014880 return;
14881 // 2.10.6: threadprivate variable cannot appear in a declare target
14882 // directive.
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014883 if (DSAStack->isThreadPrivate(VD)) {
14884 Diag(SL, diag::err_omp_threadprivate_in_target);
Alexey Bataeve3727102018-04-18 15:57:46 +000014885 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014886 return;
14887 }
14888 }
Alexey Bataev97b72212018-08-14 18:31:20 +000014889 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
14890 D = FTD->getTemplatedDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +000014891 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
Alexey Bataev30a78212018-09-11 13:59:10 +000014892 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
14893 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
14894 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
Kelvin Li1ce87c72017-12-12 20:08:12 +000014895 assert(IdLoc.isValid() && "Source location is expected");
14896 Diag(IdLoc, diag::err_omp_function_in_link_clause);
14897 Diag(FD->getLocation(), diag::note_defined_here) << FD;
14898 return;
14899 }
14900 }
Alexey Bataev30a78212018-09-11 13:59:10 +000014901 if (auto *VD = dyn_cast<ValueDecl>(D)) {
14902 // Problem if any with var declared with incomplete type will be reported
14903 // as normal, so no need to check it here.
14904 if ((E || !VD->getType()->isIncompleteType()) &&
14905 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
14906 return;
14907 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
14908 // Checking declaration inside declare target region.
14909 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
14910 isa<FunctionTemplateDecl>(D)) {
14911 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
14912 Context, OMPDeclareTargetDeclAttr::MT_To);
14913 D->addAttr(A);
14914 if (ASTMutationListener *ML = Context.getASTMutationListener())
14915 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
14916 }
14917 return;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014918 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014919 }
Alexey Bataev30a78212018-09-11 13:59:10 +000014920 if (!E)
14921 return;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000014922 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
14923}
Samuel Antao661c0902016-05-26 17:39:58 +000014924
14925OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
Michael Kruse01f670d2019-02-22 22:29:42 +000014926 CXXScopeSpec &MapperIdScopeSpec,
14927 DeclarationNameInfo &MapperId,
14928 const OMPVarListLocTy &Locs,
14929 ArrayRef<Expr *> UnresolvedMappers) {
Samuel Antao661c0902016-05-26 17:39:58 +000014930 MappableVarListInfo MVLI(VarList);
Michael Kruse01f670d2019-02-22 22:29:42 +000014931 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
14932 MapperIdScopeSpec, MapperId, UnresolvedMappers);
Samuel Antao661c0902016-05-26 17:39:58 +000014933 if (MVLI.ProcessedVarList.empty())
14934 return nullptr;
14935
Michael Kruse01f670d2019-02-22 22:29:42 +000014936 return OMPToClause::Create(
14937 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
14938 MVLI.VarComponents, MVLI.UDMapperList,
14939 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
Samuel Antao661c0902016-05-26 17:39:58 +000014940}
Samuel Antaoec172c62016-05-26 17:49:04 +000014941
14942OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
Michael Kruse0336c752019-02-25 20:34:15 +000014943 CXXScopeSpec &MapperIdScopeSpec,
14944 DeclarationNameInfo &MapperId,
14945 const OMPVarListLocTy &Locs,
14946 ArrayRef<Expr *> UnresolvedMappers) {
Samuel Antaoec172c62016-05-26 17:49:04 +000014947 MappableVarListInfo MVLI(VarList);
Michael Kruse01f670d2019-02-22 22:29:42 +000014948 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
14949 MapperIdScopeSpec, MapperId, UnresolvedMappers);
Samuel Antaoec172c62016-05-26 17:49:04 +000014950 if (MVLI.ProcessedVarList.empty())
14951 return nullptr;
14952
Michael Kruse0336c752019-02-25 20:34:15 +000014953 return OMPFromClause::Create(
14954 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
14955 MVLI.VarComponents, MVLI.UDMapperList,
14956 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
Samuel Antaoec172c62016-05-26 17:49:04 +000014957}
Carlo Bertolli2404b172016-07-13 15:37:16 +000014958
14959OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
Michael Kruse4304e9d2019-02-19 16:38:20 +000014960 const OMPVarListLocTy &Locs) {
Samuel Antaocc10b852016-07-28 14:23:26 +000014961 MappableVarListInfo MVLI(VarList);
14962 SmallVector<Expr *, 8> PrivateCopies;
14963 SmallVector<Expr *, 8> Inits;
14964
Alexey Bataeve3727102018-04-18 15:57:46 +000014965 for (Expr *RefExpr : VarList) {
Carlo Bertolli2404b172016-07-13 15:37:16 +000014966 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
14967 SourceLocation ELoc;
14968 SourceRange ERange;
14969 Expr *SimpleRefExpr = RefExpr;
14970 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14971 if (Res.second) {
14972 // It will be analyzed later.
Samuel Antaocc10b852016-07-28 14:23:26 +000014973 MVLI.ProcessedVarList.push_back(RefExpr);
14974 PrivateCopies.push_back(nullptr);
14975 Inits.push_back(nullptr);
Carlo Bertolli2404b172016-07-13 15:37:16 +000014976 }
14977 ValueDecl *D = Res.first;
14978 if (!D)
14979 continue;
14980
14981 QualType Type = D->getType();
Samuel Antaocc10b852016-07-28 14:23:26 +000014982 Type = Type.getNonReferenceType().getUnqualifiedType();
14983
14984 auto *VD = dyn_cast<VarDecl>(D);
14985
14986 // Item should be a pointer or reference to pointer.
14987 if (!Type->isPointerType()) {
Carlo Bertolli2404b172016-07-13 15:37:16 +000014988 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
14989 << 0 << RefExpr->getSourceRange();
14990 continue;
14991 }
Samuel Antaocc10b852016-07-28 14:23:26 +000014992
14993 // Build the private variable and the expression that refers to it.
Alexey Bataev63cc8e92018-03-20 14:45:59 +000014994 auto VDPrivate =
14995 buildVarDecl(*this, ELoc, Type, D->getName(),
14996 D->hasAttrs() ? &D->getAttrs() : nullptr,
14997 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Samuel Antaocc10b852016-07-28 14:23:26 +000014998 if (VDPrivate->isInvalidDecl())
14999 continue;
15000
15001 CurContext->addDecl(VDPrivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000015002 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Samuel Antaocc10b852016-07-28 14:23:26 +000015003 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15004
15005 // Add temporary variable to initialize the private copy of the pointer.
Alexey Bataeve3727102018-04-18 15:57:46 +000015006 VarDecl *VDInit =
Samuel Antaocc10b852016-07-28 14:23:26 +000015007 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
Alexey Bataeve3727102018-04-18 15:57:46 +000015008 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
15009 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
Samuel Antaocc10b852016-07-28 14:23:26 +000015010 AddInitializerToDecl(VDPrivate,
15011 DefaultLvalueConversion(VDInitRefExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000015012 /*DirectInit=*/false);
Samuel Antaocc10b852016-07-28 14:23:26 +000015013
15014 // If required, build a capture to implement the privatization initialized
15015 // with the current list item value.
15016 DeclRefExpr *Ref = nullptr;
15017 if (!VD)
15018 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15019 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
15020 PrivateCopies.push_back(VDPrivateRefExpr);
15021 Inits.push_back(VDInitRefExpr);
15022
15023 // We need to add a data sharing attribute for this variable to make sure it
15024 // is correctly captured. A variable that shows up in a use_device_ptr has
15025 // similar properties of a first private variable.
15026 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
15027
15028 // Create a mappable component for the list item. List items in this clause
15029 // only need a component.
15030 MVLI.VarBaseDeclarations.push_back(D);
15031 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15032 MVLI.VarComponents.back().push_back(
15033 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
Carlo Bertolli2404b172016-07-13 15:37:16 +000015034 }
15035
Samuel Antaocc10b852016-07-28 14:23:26 +000015036 if (MVLI.ProcessedVarList.empty())
Carlo Bertolli2404b172016-07-13 15:37:16 +000015037 return nullptr;
15038
Samuel Antaocc10b852016-07-28 14:23:26 +000015039 return OMPUseDevicePtrClause::Create(
Michael Kruse4304e9d2019-02-19 16:38:20 +000015040 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
15041 MVLI.VarBaseDeclarations, MVLI.VarComponents);
Carlo Bertolli2404b172016-07-13 15:37:16 +000015042}
Carlo Bertolli70594e92016-07-13 17:16:49 +000015043
15044OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
Michael Kruse4304e9d2019-02-19 16:38:20 +000015045 const OMPVarListLocTy &Locs) {
Samuel Antao6890b092016-07-28 14:25:09 +000015046 MappableVarListInfo MVLI(VarList);
Alexey Bataeve3727102018-04-18 15:57:46 +000015047 for (Expr *RefExpr : VarList) {
Kelvin Li84376252016-12-14 15:39:58 +000015048 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
Carlo Bertolli70594e92016-07-13 17:16:49 +000015049 SourceLocation ELoc;
15050 SourceRange ERange;
15051 Expr *SimpleRefExpr = RefExpr;
15052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15053 if (Res.second) {
15054 // It will be analyzed later.
Samuel Antao6890b092016-07-28 14:25:09 +000015055 MVLI.ProcessedVarList.push_back(RefExpr);
Carlo Bertolli70594e92016-07-13 17:16:49 +000015056 }
15057 ValueDecl *D = Res.first;
15058 if (!D)
15059 continue;
15060
15061 QualType Type = D->getType();
15062 // item should be a pointer or array or reference to pointer or array
15063 if (!Type.getNonReferenceType()->isPointerType() &&
15064 !Type.getNonReferenceType()->isArrayType()) {
15065 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
15066 << 0 << RefExpr->getSourceRange();
15067 continue;
15068 }
Samuel Antao6890b092016-07-28 14:25:09 +000015069
15070 // Check if the declaration in the clause does not show up in any data
15071 // sharing attribute.
Alexey Bataeve3727102018-04-18 15:57:46 +000015072 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Samuel Antao6890b092016-07-28 14:25:09 +000015073 if (isOpenMPPrivate(DVar.CKind)) {
15074 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15075 << getOpenMPClauseName(DVar.CKind)
15076 << getOpenMPClauseName(OMPC_is_device_ptr)
15077 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000015078 reportOriginalDsa(*this, DSAStack, D, DVar);
Samuel Antao6890b092016-07-28 14:25:09 +000015079 continue;
15080 }
15081
Alexey Bataeve3727102018-04-18 15:57:46 +000015082 const Expr *ConflictExpr;
Samuel Antao6890b092016-07-28 14:25:09 +000015083 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000015084 D, /*CurrentRegionOnly=*/true,
Samuel Antao6890b092016-07-28 14:25:09 +000015085 [&ConflictExpr](
15086 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
15087 OpenMPClauseKind) -> bool {
15088 ConflictExpr = R.front().getAssociatedExpression();
15089 return true;
15090 })) {
15091 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
15092 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
15093 << ConflictExpr->getSourceRange();
15094 continue;
15095 }
15096
15097 // Store the components in the stack so that they can be used to check
15098 // against other clauses later on.
15099 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
15100 DSAStack->addMappableExpressionComponents(
15101 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
15102
15103 // Record the expression we've just processed.
15104 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
15105
15106 // Create a mappable component for the list item. List items in this clause
15107 // only need a component. We use a null declaration to signal fields in
15108 // 'this'.
15109 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
15110 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
15111 "Unexpected device pointer expression!");
15112 MVLI.VarBaseDeclarations.push_back(
15113 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
15114 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15115 MVLI.VarComponents.back().push_back(MC);
Carlo Bertolli70594e92016-07-13 17:16:49 +000015116 }
15117
Samuel Antao6890b092016-07-28 14:25:09 +000015118 if (MVLI.ProcessedVarList.empty())
Carlo Bertolli70594e92016-07-13 17:16:49 +000015119 return nullptr;
15120
Michael Kruse4304e9d2019-02-19 16:38:20 +000015121 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
15122 MVLI.VarBaseDeclarations,
15123 MVLI.VarComponents);
Carlo Bertolli70594e92016-07-13 17:16:49 +000015124}
Alexey Bataeve04483e2019-03-27 14:14:31 +000015125
15126OMPClause *Sema::ActOnOpenMPAllocateClause(
15127 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
15128 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15129 if (Allocator) {
15130 // OpenMP [2.11.4 allocate Clause, Description]
15131 // allocator is an expression of omp_allocator_handle_t type.
15132 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
15133 return nullptr;
15134
15135 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
15136 if (AllocatorRes.isInvalid())
15137 return nullptr;
15138 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
15139 DSAStack->getOMPAllocatorHandleT(),
15140 Sema::AA_Initializing,
15141 /*AllowExplicit=*/true);
15142 if (AllocatorRes.isInvalid())
15143 return nullptr;
15144 Allocator = AllocatorRes.get();
Alexey Bataev84c8bae2019-04-01 16:56:59 +000015145 } else {
15146 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
15147 // allocate clauses that appear on a target construct or on constructs in a
15148 // target region must specify an allocator expression unless a requires
15149 // directive with the dynamic_allocators clause is present in the same
15150 // compilation unit.
15151 if (LangOpts.OpenMPIsDevice &&
15152 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
15153 targetDiag(StartLoc, diag::err_expected_allocator_expression);
Alexey Bataeve04483e2019-03-27 14:14:31 +000015154 }
15155 // Analyze and build list of variables.
15156 SmallVector<Expr *, 8> Vars;
15157 for (Expr *RefExpr : VarList) {
15158 assert(RefExpr && "NULL expr in OpenMP private clause.");
15159 SourceLocation ELoc;
15160 SourceRange ERange;
15161 Expr *SimpleRefExpr = RefExpr;
15162 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15163 if (Res.second) {
15164 // It will be analyzed later.
15165 Vars.push_back(RefExpr);
15166 }
15167 ValueDecl *D = Res.first;
15168 if (!D)
15169 continue;
15170
15171 auto *VD = dyn_cast<VarDecl>(D);
15172 DeclRefExpr *Ref = nullptr;
15173 if (!VD && !CurContext->isDependentContext())
15174 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15175 Vars.push_back((VD || CurContext->isDependentContext())
15176 ? RefExpr->IgnoreParens()
15177 : Ref);
15178 }
15179
15180 if (Vars.empty())
15181 return nullptr;
15182
15183 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
15184 ColonLoc, EndLoc, Vars);
15185}