blob: 8b1fca89dee8cbadb3b0756605b760f2a044a6a2 [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;
Alexey Bataev05be1da2019-07-18 17:49:13 +0000142 bool HasMutipleLoops = false;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000143 const Decl *PossiblyLoopCounter = nullptr;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000144 bool NowaitRegion = false;
145 bool CancelRegion = false;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000146 bool LoopStart = false;
Richard Smith0621a8f2019-05-31 00:45:10 +0000147 bool BodyComplete = false;
Alexey Bataev13314bf2014-10-09 04:18:56 +0000148 SourceLocation InnerTeamsRegionLoc;
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000149 /// Reference to the taskgroup task_reduction reference expression.
150 Expr *TaskgroupReductionRef = nullptr;
Patrick Lystere13b1e32019-01-02 19:28:48 +0000151 llvm::DenseSet<QualType> MappedClassesQualTypes;
Alexey Bataeva495c642019-03-11 19:51:42 +0000152 /// List of globals marked as declare target link in this target region
153 /// (isOpenMPTargetExecutionDirective(Directive) == true).
154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
Alexey Bataeved09d242014-05-28 05:53:51 +0000155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Alexey Bataevbae9a792014-06-27 10:37:06 +0000156 Scope *CurScope, SourceLocation Loc)
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
158 ConstructLoc(Loc) {}
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000159 SharingMapTy() = default;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000160 };
161
Alexey Bataeve3727102018-04-18 15:57:46 +0000162 using StackTy = SmallVector<SharingMapTy, 4>;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000163
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000164 /// Stack of used declaration and their data-sharing attributes.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000165 DeclSAMapTy Threadprivates;
Alexey Bataev4b465392017-04-26 15:06:24 +0000166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000168 /// true, if check for DSA must be from parent directive, false, if
Alexey Bataev39f915b82015-05-08 10:41:21 +0000169 /// from current directive.
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000170 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
Alexey Bataev7ff55242014-06-19 09:13:45 +0000171 Sema &SemaRef;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000172 bool ForceCapturing = false;
Alexey Bataevd1caf932019-09-30 14:05:26 +0000173 /// true if all the variables in the target executable directives must be
Alexey Bataev60705422018-10-30 15:50:12 +0000174 /// captured by reference.
175 bool ForceCaptureByReferenceInTargetExecutable = false;
Alexey Bataev28c75412015-12-15 08:19:24 +0000176 CriticalsWithHintsTy Criticals;
Richard Smith0621a8f2019-05-31 00:45:10 +0000177 unsigned IgnoredStackElements = 0;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000178
Richard Smith375dec52019-05-30 23:21:14 +0000179 /// Iterators over the stack iterate in order from innermost to outermost
180 /// directive.
181 using const_iterator = StackTy::const_reverse_iterator;
182 const_iterator begin() const {
Richard Smith0621a8f2019-05-31 00:45:10 +0000183 return Stack.empty() ? const_iterator()
184 : Stack.back().first.rbegin() + IgnoredStackElements;
Richard Smith375dec52019-05-30 23:21:14 +0000185 }
186 const_iterator end() const {
187 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
188 }
189 using iterator = StackTy::reverse_iterator;
190 iterator begin() {
Richard Smith0621a8f2019-05-31 00:45:10 +0000191 return Stack.empty() ? iterator()
192 : Stack.back().first.rbegin() + IgnoredStackElements;
Richard Smith375dec52019-05-30 23:21:14 +0000193 }
194 iterator end() {
195 return Stack.empty() ? iterator() : Stack.back().first.rend();
196 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000197
Richard Smith375dec52019-05-30 23:21:14 +0000198 // Convenience operations to get at the elements of the stack.
Alexey Bataeved09d242014-05-28 05:53:51 +0000199
Alexey Bataev4b465392017-04-26 15:06:24 +0000200 bool isStackEmpty() const {
201 return Stack.empty() ||
202 Stack.back().second != CurrentNonCapturingFunctionScope ||
Richard Smith0621a8f2019-05-31 00:45:10 +0000203 Stack.back().first.size() <= IgnoredStackElements;
Alexey Bataev4b465392017-04-26 15:06:24 +0000204 }
Richard Smith375dec52019-05-30 23:21:14 +0000205 size_t getStackSize() const {
Richard Smith0621a8f2019-05-31 00:45:10 +0000206 return isStackEmpty() ? 0
207 : Stack.back().first.size() - IgnoredStackElements;
Richard Smith375dec52019-05-30 23:21:14 +0000208 }
209
210 SharingMapTy *getTopOfStackOrNull() {
Richard Smith0621a8f2019-05-31 00:45:10 +0000211 size_t Size = getStackSize();
212 if (Size == 0)
Richard Smith375dec52019-05-30 23:21:14 +0000213 return nullptr;
Richard Smith0621a8f2019-05-31 00:45:10 +0000214 return &Stack.back().first[Size - 1];
Richard Smith375dec52019-05-30 23:21:14 +0000215 }
216 const SharingMapTy *getTopOfStackOrNull() const {
217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
218 }
219 SharingMapTy &getTopOfStack() {
220 assert(!isStackEmpty() && "no current directive");
221 return *getTopOfStackOrNull();
222 }
223 const SharingMapTy &getTopOfStack() const {
224 return const_cast<DSAStackTy&>(*this).getTopOfStack();
225 }
226
227 SharingMapTy *getSecondOnStackOrNull() {
228 size_t Size = getStackSize();
229 if (Size <= 1)
230 return nullptr;
231 return &Stack.back().first[Size - 2];
232 }
233 const SharingMapTy *getSecondOnStackOrNull() const {
234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
235 }
236
237 /// Get the stack element at a certain level (previously returned by
238 /// \c getNestingLevel).
239 ///
240 /// Note that nesting levels count from outermost to innermost, and this is
241 /// the reverse of our iteration order where new inner levels are pushed at
242 /// the front of the stack.
243 SharingMapTy &getStackElemAtLevel(unsigned Level) {
244 assert(Level < getStackSize() && "no such stack element");
245 return Stack.back().first[Level];
246 }
247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
249 }
250
251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
252
253 /// Checks if the variable is a local for OpenMP region.
254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
Alexey Bataev4b465392017-04-26 15:06:24 +0000255
Kelvin Li1408f912018-09-26 04:28:39 +0000256 /// Vector of previously declared requires directives
257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
Alexey Bataev27ef9512019-03-20 20:14:22 +0000258 /// omp_allocator_handle_t type.
259 QualType OMPAllocatorHandleT;
260 /// Expression for the predefined allocators.
261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
262 nullptr};
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +0000263 /// Vector of previously encountered target directives
264 SmallVector<SourceLocation, 2> TargetLocations;
Kelvin Li1408f912018-09-26 04:28:39 +0000265
Alexey Bataev758e55e2013-09-06 18:03:48 +0000266public:
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000267 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
Alexey Bataev39f915b82015-05-08 10:41:21 +0000268
Alexey Bataev27ef9512019-03-20 20:14:22 +0000269 /// Sets omp_allocator_handle_t type.
270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
271 /// Gets omp_allocator_handle_t type.
272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
273 /// Sets the given default allocator.
274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
275 Expr *Allocator) {
276 OMPPredefinedAllocators[AllocatorKind] = Allocator;
277 }
278 /// Returns the specified default allocator.
279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
280 return OMPPredefinedAllocators[AllocatorKind];
281 }
282
Alexey Bataevaac108a2015-06-23 04:51:00 +0000283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
Alexey Bataev3f82cfc2017-12-13 15:28:44 +0000284 OpenMPClauseKind getClauseParsingMode() const {
285 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
286 return ClauseKindMode;
287 }
Alexey Bataevaac108a2015-06-23 04:51:00 +0000288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000289
Richard Smith0621a8f2019-05-31 00:45:10 +0000290 bool isBodyComplete() const {
291 const SharingMapTy *Top = getTopOfStackOrNull();
292 return Top && Top->BodyComplete;
293 }
294 void setBodyComplete() {
295 getTopOfStack().BodyComplete = true;
296 }
297
Samuel Antao9c75cfe2015-07-27 16:38:06 +0000298 bool isForceVarCapturing() const { return ForceCapturing; }
299 void setForceVarCapturing(bool V) { ForceCapturing = V; }
300
Alexey Bataev60705422018-10-30 15:50:12 +0000301 void setForceCaptureByReferenceInTargetExecutable(bool V) {
302 ForceCaptureByReferenceInTargetExecutable = V;
303 }
304 bool isForceCaptureByReferenceInTargetExecutable() const {
305 return ForceCaptureByReferenceInTargetExecutable;
306 }
307
Alexey Bataev758e55e2013-09-06 18:03:48 +0000308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
Alexey Bataevbae9a792014-06-27 10:37:06 +0000309 Scope *CurScope, SourceLocation Loc) {
Richard Smith0621a8f2019-05-31 00:45:10 +0000310 assert(!IgnoredStackElements &&
311 "cannot change stack while ignoring elements");
Alexey Bataev4b465392017-04-26 15:06:24 +0000312 if (Stack.empty() ||
313 Stack.back().second != CurrentNonCapturingFunctionScope)
314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
316 Stack.back().first.back().DefaultAttrLoc = Loc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000317 }
318
319 void pop() {
Richard Smith0621a8f2019-05-31 00:45:10 +0000320 assert(!IgnoredStackElements &&
321 "cannot change stack while ignoring elements");
Alexey Bataev4b465392017-04-26 15:06:24 +0000322 assert(!Stack.back().first.empty() &&
323 "Data-sharing attributes stack is empty!");
324 Stack.back().first.pop_back();
325 }
326
Richard Smith0621a8f2019-05-31 00:45:10 +0000327 /// RAII object to temporarily leave the scope of a directive when we want to
328 /// logically operate in its parent.
329 class ParentDirectiveScope {
330 DSAStackTy &Self;
331 bool Active;
332 public:
333 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
334 : Self(Self), Active(false) {
335 if (Activate)
336 enable();
337 }
338 ~ParentDirectiveScope() { disable(); }
339 void disable() {
340 if (Active) {
341 --Self.IgnoredStackElements;
342 Active = false;
343 }
344 }
345 void enable() {
346 if (!Active) {
347 ++Self.IgnoredStackElements;
348 Active = true;
349 }
350 }
351 };
352
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000353 /// Marks that we're started loop parsing.
354 void loopInit() {
355 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
356 "Expected loop-based directive.");
Richard Smith375dec52019-05-30 23:21:14 +0000357 getTopOfStack().LoopStart = true;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000358 }
359 /// Start capturing of the variables in the loop context.
360 void loopStart() {
361 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
362 "Expected loop-based directive.");
Richard Smith375dec52019-05-30 23:21:14 +0000363 getTopOfStack().LoopStart = false;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000364 }
365 /// true, if variables are captured, false otherwise.
366 bool isLoopStarted() const {
367 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
368 "Expected loop-based directive.");
Richard Smith375dec52019-05-30 23:21:14 +0000369 return !getTopOfStack().LoopStart;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000370 }
371 /// Marks (or clears) declaration as possibly loop counter.
372 void resetPossibleLoopCounter(const Decl *D = nullptr) {
Richard Smith375dec52019-05-30 23:21:14 +0000373 getTopOfStack().PossiblyLoopCounter =
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000374 D ? D->getCanonicalDecl() : D;
375 }
376 /// Gets the possible loop counter decl.
377 const Decl *getPossiblyLoopCunter() const {
Richard Smith375dec52019-05-30 23:21:14 +0000378 return getTopOfStack().PossiblyLoopCounter;
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000379 }
Alexey Bataev4b465392017-04-26 15:06:24 +0000380 /// Start new OpenMP region stack in new non-capturing function.
381 void pushFunction() {
Richard Smith0621a8f2019-05-31 00:45:10 +0000382 assert(!IgnoredStackElements &&
383 "cannot change stack while ignoring elements");
Alexey Bataev4b465392017-04-26 15:06:24 +0000384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
385 assert(!isa<CapturingScopeInfo>(CurFnScope));
386 CurrentNonCapturingFunctionScope = CurFnScope;
387 }
388 /// Pop region stack for non-capturing function.
389 void popFunction(const FunctionScopeInfo *OldFSI) {
Richard Smith0621a8f2019-05-31 00:45:10 +0000390 assert(!IgnoredStackElements &&
391 "cannot change stack while ignoring elements");
Alexey Bataev4b465392017-04-26 15:06:24 +0000392 if (!Stack.empty() && Stack.back().second == OldFSI) {
393 assert(Stack.back().first.empty());
394 Stack.pop_back();
395 }
396 CurrentNonCapturingFunctionScope = nullptr;
397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
398 if (!isa<CapturingScopeInfo>(FSI)) {
399 CurrentNonCapturingFunctionScope = FSI;
400 break;
401 }
402 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000403 }
404
Alexey Bataeve3727102018-04-18 15:57:46 +0000405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
Alexey Bataev43a919f2018-04-13 17:48:43 +0000406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
Alexey Bataev28c75412015-12-15 08:19:24 +0000407 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000408 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
Alexey Bataev28c75412015-12-15 08:19:24 +0000409 getCriticalWithHint(const DeclarationNameInfo &Name) const {
410 auto I = Criticals.find(Name.getAsString());
411 if (I != Criticals.end())
412 return I->second;
413 return std::make_pair(nullptr, llvm::APSInt());
414 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000415 /// If 'aligned' declaration for given variable \a D was not seen yet,
Alp Toker15e62a32014-06-06 12:02:07 +0000416 /// add it and return NULL; otherwise return previous occurrence's expression
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000417 /// for diagnostics.
Alexey Bataeve3727102018-04-18 15:57:46 +0000418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
Alexander Musmanf0d76e72014-05-29 14:36:25 +0000419
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000420 /// Register specified variable as loop control variable.
Alexey Bataeve3727102018-04-18 15:57:46 +0000421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000422 /// Check if the specified variable is a loop control variable for
Alexey Bataev9c821032015-04-30 04:23:23 +0000423 /// current region.
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000424 /// \return The index of the loop control variable in the list of associated
425 /// for-loops (from outer to inner).
Alexey Bataeve3727102018-04-18 15:57:46 +0000426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000427 /// Check if the specified variable is a loop control variable for
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000428 /// parent region.
429 /// \return The index of the loop control variable in the list of associated
430 /// for-loops (from outer to inner).
Alexey Bataeve3727102018-04-18 15:57:46 +0000431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000432 /// Get the loop control variable for the I-th loop (or nullptr) in
Alexey Bataeva636c7f2015-12-23 10:27:45 +0000433 /// parent directive.
Alexey Bataeve3727102018-04-18 15:57:46 +0000434 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
Alexey Bataev9c821032015-04-30 04:23:23 +0000435
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000436 /// Adds explicit data sharing attribute to the specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
Alexey Bataev90c228f2016-02-08 09:29:13 +0000438 DeclRefExpr *PrivateCopy = nullptr);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000439
Alexey Bataevfa312f32017-07-21 18:48:21 +0000440 /// Adds additional information for the reduction items with the reduction id
441 /// represented as an operator.
Alexey Bataeve3727102018-04-18 15:57:46 +0000442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000443 BinaryOperatorKind BOK);
Alexey Bataevfa312f32017-07-21 18:48:21 +0000444 /// Adds additional information for the reduction items with the reduction id
445 /// represented as reduction identifier.
Alexey Bataeve3727102018-04-18 15:57:46 +0000446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000447 const Expr *ReductionRef);
Alexey Bataevfa312f32017-07-21 18:48:21 +0000448 /// Returns the location and reduction operation from the innermost parent
449 /// region for the given \p D.
Alexey Bataeve3727102018-04-18 15:57:46 +0000450 const DSAVarData
451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
452 BinaryOperatorKind &BOK,
453 Expr *&TaskgroupDescriptor) const;
Alexey Bataevfa312f32017-07-21 18:48:21 +0000454 /// Returns the location and reduction operation from the innermost parent
455 /// region for the given \p D.
Alexey Bataeve3727102018-04-18 15:57:46 +0000456 const DSAVarData
457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
458 const Expr *&ReductionRef,
459 Expr *&TaskgroupDescriptor) const;
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000460 /// Return reduction reference expression for the current taskgroup.
461 Expr *getTaskgroupReductionRef() const {
Richard Smith375dec52019-05-30 23:21:14 +0000462 assert(getTopOfStack().Directive == OMPD_taskgroup &&
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000463 "taskgroup reference expression requested for non taskgroup "
464 "directive.");
Richard Smith375dec52019-05-30 23:21:14 +0000465 return getTopOfStack().TaskgroupReductionRef;
Alexey Bataev3b1b8952017-07-25 15:53:26 +0000466 }
Alexey Bataev88202be2017-07-27 13:20:36 +0000467 /// Checks if the given \p VD declaration is actually a taskgroup reduction
468 /// descriptor variable at the \p Level of OpenMP regions.
Alexey Bataeve3727102018-04-18 15:57:46 +0000469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
Richard Smith375dec52019-05-30 23:21:14 +0000470 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
Alexey Bataev88202be2017-07-27 13:20:36 +0000472 ->getDecl() == VD;
473 }
Alexey Bataevfa312f32017-07-21 18:48:21 +0000474
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000475 /// Returns data sharing attributes from top of the stack for the
Alexey Bataev758e55e2013-09-06 18:03:48 +0000476 /// specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000478 /// Returns data-sharing attributes for the specified declaration.
Alexey Bataeve3727102018-04-18 15:57:46 +0000479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000480 /// Checks if the specified variables has data-sharing attributes which
Alexey Bataevf29276e2014-06-18 04:14:57 +0000481 /// match specified \a CPred predicate in any directive which matches \a DPred
482 /// predicate.
Alexey Bataeve3727102018-04-18 15:57:46 +0000483 const DSAVarData
484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
486 bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000487 /// Checks if the specified variables has data-sharing attributes which
Alexey Bataevf29276e2014-06-18 04:14:57 +0000488 /// match specified \a CPred predicate in any innermost directive which
489 /// matches \a DPred predicate.
Alexey Bataeve3727102018-04-18 15:57:46 +0000490 const DSAVarData
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000491 hasInnermostDSA(ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000494 bool FromParent) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000495 /// Checks if the specified variables has explicit data-sharing
Alexey Bataevaac108a2015-06-23 04:51:00 +0000496 /// attributes which match specified \a CPred predicate at the specified
497 /// OpenMP region.
Alexey Bataeve3727102018-04-18 15:57:46 +0000498 bool hasExplicitDSA(const ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000500 unsigned Level, bool NotLastprivate = false) const;
Samuel Antao4be30e92015-10-02 17:14:03 +0000501
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000502 /// Returns true if the directive at level \Level matches in the
Samuel Antao4be30e92015-10-02 17:14:03 +0000503 /// specified \a DPred predicate.
504 bool hasExplicitDirective(
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000506 unsigned Level) const;
Samuel Antao4be30e92015-10-02 17:14:03 +0000507
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000508 /// Finds a directive which matches specified \a DPred predicate.
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000509 bool hasDirective(
510 const llvm::function_ref<bool(
511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
512 DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +0000513 bool FromParent) const;
Alexey Bataevd5af8e42013-10-01 05:32:34 +0000514
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000515 /// Returns currently analyzed directive.
Alexey Bataev758e55e2013-09-06 18:03:48 +0000516 OpenMPDirectiveKind getCurrentDirective() const {
Richard Smith375dec52019-05-30 23:21:14 +0000517 const SharingMapTy *Top = getTopOfStackOrNull();
518 return Top ? Top->Directive : OMPD_unknown;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000519 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000520 /// Returns directive kind at specified level.
Alexey Bataevdfa430f2017-12-08 15:03:50 +0000521 OpenMPDirectiveKind getDirective(unsigned Level) const {
522 assert(!isStackEmpty() && "No directive at specified level.");
Richard Smith375dec52019-05-30 23:21:14 +0000523 return getStackElemAtLevel(Level).Directive;
Alexey Bataevdfa430f2017-12-08 15:03:50 +0000524 }
Joel E. Denny7d5bc552019-08-22 03:34:30 +0000525 /// Returns the capture region at the specified level.
526 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
527 unsigned OpenMPCaptureLevel) const {
528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
530 return CaptureRegions[OpenMPCaptureLevel];
531 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000532 /// Returns parent directive.
Alexey Bataev549210e2014-06-24 04:39:47 +0000533 OpenMPDirectiveKind getParentDirective() const {
Richard Smith375dec52019-05-30 23:21:14 +0000534 const SharingMapTy *Parent = getSecondOnStackOrNull();
535 return Parent ? Parent->Directive : OMPD_unknown;
Alexey Bataev549210e2014-06-24 04:39:47 +0000536 }
Alexey Bataev6ab5bb12018-10-29 15:01:58 +0000537
Kelvin Li1408f912018-09-26 04:28:39 +0000538 /// Add requires decl to internal vector
539 void addRequiresDecl(OMPRequiresDecl *RD) {
540 RequiresDecls.push_back(RD);
541 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000542
Alexey Bataev318f431b2019-03-22 15:25:12 +0000543 /// Checks if the defined 'requires' directive has specified type of clause.
544 template <typename ClauseType>
545 bool hasRequiresDeclWithClause() {
546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
548 return isa<ClauseType>(C);
549 });
550 });
551 }
552
Kelvin Li1408f912018-09-26 04:28:39 +0000553 /// Checks for a duplicate clause amongst previously declared requires
554 /// directives
555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
556 bool IsDuplicate = false;
557 for (OMPClause *CNew : ClauseList) {
558 for (const OMPRequiresDecl *D : RequiresDecls) {
559 for (const OMPClause *CPrev : D->clauselists()) {
560 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
561 SemaRef.Diag(CNew->getBeginLoc(),
562 diag::err_omp_requires_clause_redeclaration)
563 << getOpenMPClauseName(CNew->getClauseKind());
564 SemaRef.Diag(CPrev->getBeginLoc(),
565 diag::note_omp_requires_previous_clause)
566 << getOpenMPClauseName(CPrev->getClauseKind());
567 IsDuplicate = true;
568 }
569 }
570 }
571 }
572 return IsDuplicate;
573 }
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +0000574
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +0000575 /// Add location of previously encountered target to internal vector
576 void addTargetDirLocation(SourceLocation LocStart) {
577 TargetLocations.push_back(LocStart);
578 }
579
580 // Return previously encountered target region locations.
581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
582 return TargetLocations;
583 }
584
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000585 /// Set default data sharing attribute to none.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000586 void setDefaultDSANone(SourceLocation Loc) {
Richard Smith375dec52019-05-30 23:21:14 +0000587 getTopOfStack().DefaultAttr = DSA_none;
588 getTopOfStack().DefaultAttrLoc = Loc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000589 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000590 /// Set default data sharing attribute to shared.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000591 void setDefaultDSAShared(SourceLocation Loc) {
Richard Smith375dec52019-05-30 23:21:14 +0000592 getTopOfStack().DefaultAttr = DSA_shared;
593 getTopOfStack().DefaultAttrLoc = Loc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000594 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000595 /// Set default data mapping attribute to 'tofrom:scalar'.
596 void setDefaultDMAToFromScalar(SourceLocation Loc) {
Richard Smith375dec52019-05-30 23:21:14 +0000597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar;
598 getTopOfStack().DefaultMapAttrLoc = Loc;
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000599 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000600
601 DefaultDataSharingAttributes getDefaultDSA() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000602 return isStackEmpty() ? DSA_unspecified
Richard Smith375dec52019-05-30 23:21:14 +0000603 : getTopOfStack().DefaultAttr;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000604 }
Alexey Bataevbae9a792014-06-27 10:37:06 +0000605 SourceLocation getDefaultDSALocation() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000606 return isStackEmpty() ? SourceLocation()
Richard Smith375dec52019-05-30 23:21:14 +0000607 : getTopOfStack().DefaultAttrLoc;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000608 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000609 DefaultMapAttributes getDefaultDMA() const {
610 return isStackEmpty() ? DMA_unspecified
Richard Smith375dec52019-05-30 23:21:14 +0000611 : getTopOfStack().DefaultMapAttr;
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000612 }
613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
Richard Smith375dec52019-05-30 23:21:14 +0000614 return getStackElemAtLevel(Level).DefaultMapAttr;
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000615 }
616 SourceLocation getDefaultDMALocation() const {
617 return isStackEmpty() ? SourceLocation()
Richard Smith375dec52019-05-30 23:21:14 +0000618 : getTopOfStack().DefaultMapAttrLoc;
Alexey Bataev2fd0cb22017-10-05 17:51:39 +0000619 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000620
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000621 /// Checks if the specified variable is a threadprivate.
Alexey Bataevd48bcd82014-03-31 03:36:38 +0000622 bool isThreadPrivate(VarDecl *D) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000623 const DSAVarData DVar = getTopDSA(D, false);
Alexey Bataevf29276e2014-06-18 04:14:57 +0000624 return isOpenMPThreadPrivate(DVar.CKind);
Alexey Bataevd48bcd82014-03-31 03:36:38 +0000625 }
626
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000627 /// Marks current region as ordered (it has an 'ordered' clause).
Alexey Bataevf138fda2018-08-13 19:04:24 +0000628 void setOrderedRegion(bool IsOrdered, const Expr *Param,
629 OMPOrderedClause *Clause) {
Alexey Bataevf138fda2018-08-13 19:04:24 +0000630 if (IsOrdered)
Richard Smith375dec52019-05-30 23:21:14 +0000631 getTopOfStack().OrderedRegion.emplace(Param, Clause);
Alexey Bataevf138fda2018-08-13 19:04:24 +0000632 else
Richard Smith375dec52019-05-30 23:21:14 +0000633 getTopOfStack().OrderedRegion.reset();
Alexey Bataevf138fda2018-08-13 19:04:24 +0000634 }
635 /// Returns true, if region is ordered (has associated 'ordered' clause),
636 /// false - otherwise.
637 bool isOrderedRegion() const {
Richard Smith375dec52019-05-30 23:21:14 +0000638 if (const SharingMapTy *Top = getTopOfStackOrNull())
639 return Top->OrderedRegion.hasValue();
640 return false;
Alexey Bataevf138fda2018-08-13 19:04:24 +0000641 }
642 /// Returns optional parameter for the ordered region.
643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
Richard Smith375dec52019-05-30 23:21:14 +0000644 if (const SharingMapTy *Top = getTopOfStackOrNull())
645 if (Top->OrderedRegion.hasValue())
646 return Top->OrderedRegion.getValue();
647 return std::make_pair(nullptr, nullptr);
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000648 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000649 /// Returns true, if parent region is ordered (has associated
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000650 /// 'ordered' clause), false - otherwise.
651 bool isParentOrderedRegion() const {
Richard Smith375dec52019-05-30 23:21:14 +0000652 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
653 return Parent->OrderedRegion.hasValue();
654 return false;
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000655 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000656 /// Returns optional parameter for the ordered region.
Alexey Bataevf138fda2018-08-13 19:04:24 +0000657 std::pair<const Expr *, OMPOrderedClause *>
658 getParentOrderedRegionParam() const {
Richard Smith375dec52019-05-30 23:21:14 +0000659 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
660 if (Parent->OrderedRegion.hasValue())
661 return Parent->OrderedRegion.getValue();
662 return std::make_pair(nullptr, nullptr);
Alexey Bataev346265e2015-09-25 10:37:12 +0000663 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000664 /// Marks current region as nowait (it has a 'nowait' clause).
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000665 void setNowaitRegion(bool IsNowait = true) {
Richard Smith375dec52019-05-30 23:21:14 +0000666 getTopOfStack().NowaitRegion = IsNowait;
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000667 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000668 /// Returns true, if parent region is nowait (has associated
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000669 /// 'nowait' clause), false - otherwise.
670 bool isParentNowaitRegion() const {
Richard Smith375dec52019-05-30 23:21:14 +0000671 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
672 return Parent->NowaitRegion;
673 return false;
Alexey Bataev6d4ed052015-07-01 06:57:41 +0000674 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000675 /// Marks parent region as cancel region.
Alexey Bataev25e5b442015-09-15 12:52:43 +0000676 void setParentCancelRegion(bool Cancel = true) {
Richard Smith375dec52019-05-30 23:21:14 +0000677 if (SharingMapTy *Parent = getSecondOnStackOrNull())
678 Parent->CancelRegion |= Cancel;
Alexey Bataev25e5b442015-09-15 12:52:43 +0000679 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000680 /// Return true if current region has inner cancel construct.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000681 bool isCancelRegion() const {
Richard Smith375dec52019-05-30 23:21:14 +0000682 const SharingMapTy *Top = getTopOfStackOrNull();
683 return Top ? Top->CancelRegion : false;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000684 }
Alexey Bataev9fb6e642014-07-22 06:45:04 +0000685
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000686 /// Set collapse value for the region.
Alexey Bataev4b465392017-04-26 15:06:24 +0000687 void setAssociatedLoops(unsigned Val) {
Richard Smith375dec52019-05-30 23:21:14 +0000688 getTopOfStack().AssociatedLoops = Val;
Alexey Bataev05be1da2019-07-18 17:49:13 +0000689 if (Val > 1)
690 getTopOfStack().HasMutipleLoops = true;
Alexey Bataev4b465392017-04-26 15:06:24 +0000691 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000692 /// Return collapse value for region.
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000693 unsigned getAssociatedLoops() const {
Richard Smith375dec52019-05-30 23:21:14 +0000694 const SharingMapTy *Top = getTopOfStackOrNull();
695 return Top ? Top->AssociatedLoops : 0;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000696 }
Alexey Bataev05be1da2019-07-18 17:49:13 +0000697 /// Returns true if the construct is associated with multiple loops.
698 bool hasMutipleLoops() const {
699 const SharingMapTy *Top = getTopOfStackOrNull();
700 return Top ? Top->HasMutipleLoops : false;
701 }
Alexey Bataev9c821032015-04-30 04:23:23 +0000702
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000703 /// Marks current target region as one with closely nested teams
Alexey Bataev13314bf2014-10-09 04:18:56 +0000704 /// region.
705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
Richard Smith375dec52019-05-30 23:21:14 +0000706 if (SharingMapTy *Parent = getSecondOnStackOrNull())
707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
Alexey Bataev13314bf2014-10-09 04:18:56 +0000708 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000709 /// Returns true, if current region has closely nested teams region.
Alexey Bataev13314bf2014-10-09 04:18:56 +0000710 bool hasInnerTeamsRegion() const {
711 return getInnerTeamsRegionLoc().isValid();
712 }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000713 /// Returns location of the nested teams region (if any).
Alexey Bataev13314bf2014-10-09 04:18:56 +0000714 SourceLocation getInnerTeamsRegionLoc() const {
Richard Smith375dec52019-05-30 23:21:14 +0000715 const SharingMapTy *Top = getTopOfStackOrNull();
716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
Alexey Bataev13314bf2014-10-09 04:18:56 +0000717 }
718
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000719 Scope *getCurScope() const {
Richard Smith375dec52019-05-30 23:21:14 +0000720 const SharingMapTy *Top = getTopOfStackOrNull();
721 return Top ? Top->CurScope : nullptr;
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000722 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000723 SourceLocation getConstructLoc() const {
Richard Smith375dec52019-05-30 23:21:14 +0000724 const SharingMapTy *Top = getTopOfStackOrNull();
725 return Top ? Top->ConstructLoc : SourceLocation();
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000726 }
Kelvin Li0bff7af2015-11-23 05:32:03 +0000727
Samuel Antao4c8035b2016-12-12 18:00:20 +0000728 /// Do the check specified in \a Check to all component lists and return true
729 /// if any issue is found.
Samuel Antao90927002016-04-26 14:54:23 +0000730 bool checkMappableExprComponentListsForDecl(
Alexey Bataeve3727102018-04-18 15:57:46 +0000731 const ValueDecl *VD, bool CurrentRegionOnly,
Samuel Antao6890b092016-07-28 14:25:09 +0000732 const llvm::function_ref<
733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000734 OpenMPClauseKind)>
Alexey Bataeve3727102018-04-18 15:57:46 +0000735 Check) const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000736 if (isStackEmpty())
737 return false;
Richard Smith375dec52019-05-30 23:21:14 +0000738 auto SI = begin();
739 auto SE = end();
Samuel Antao5de996e2016-01-22 20:21:36 +0000740
741 if (SI == SE)
742 return false;
743
Alexey Bataeve3727102018-04-18 15:57:46 +0000744 if (CurrentRegionOnly)
Samuel Antao5de996e2016-01-22 20:21:36 +0000745 SE = std::next(SI);
Alexey Bataeve3727102018-04-18 15:57:46 +0000746 else
747 std::advance(SI, 1);
Samuel Antao5de996e2016-01-22 20:21:36 +0000748
749 for (; SI != SE; ++SI) {
Samuel Antao90927002016-04-26 14:54:23 +0000750 auto MI = SI->MappedExprComponents.find(VD);
751 if (MI != SI->MappedExprComponents.end())
Alexey Bataeve3727102018-04-18 15:57:46 +0000752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
753 MI->second.Components)
Samuel Antao6890b092016-07-28 14:25:09 +0000754 if (Check(L, MI->second.Kind))
Samuel Antao5de996e2016-01-22 20:21:36 +0000755 return true;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000756 }
Samuel Antao5de996e2016-01-22 20:21:36 +0000757 return false;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000758 }
759
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000760 /// Do the check specified in \a Check to all component lists at a given level
761 /// and return true if any issue is found.
762 bool checkMappableExprComponentListsForDeclAtLevel(
Alexey Bataeve3727102018-04-18 15:57:46 +0000763 const ValueDecl *VD, unsigned Level,
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000764 const llvm::function_ref<
765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
Alexey Bataev97d18bf2018-04-11 19:21:00 +0000766 OpenMPClauseKind)>
Alexey Bataeve3727102018-04-18 15:57:46 +0000767 Check) const {
Richard Smith375dec52019-05-30 23:21:14 +0000768 if (getStackSize() <= Level)
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000769 return false;
770
Richard Smith375dec52019-05-30 23:21:14 +0000771 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
772 auto MI = StackElem.MappedExprComponents.find(VD);
773 if (MI != StackElem.MappedExprComponents.end())
Alexey Bataeve3727102018-04-18 15:57:46 +0000774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
775 MI->second.Components)
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +0000776 if (Check(L, MI->second.Kind))
777 return true;
778 return false;
779 }
780
Samuel Antao4c8035b2016-12-12 18:00:20 +0000781 /// Create a new mappable expression component list associated with a given
782 /// declaration and initialize it with the provided list of components.
Samuel Antao90927002016-04-26 14:54:23 +0000783 void addMappableExpressionComponents(
Alexey Bataeve3727102018-04-18 15:57:46 +0000784 const ValueDecl *VD,
Samuel Antao6890b092016-07-28 14:25:09 +0000785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
786 OpenMPClauseKind WhereFoundClauseKind) {
Richard Smith375dec52019-05-30 23:21:14 +0000787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
Samuel Antao90927002016-04-26 14:54:23 +0000788 // Create new entry and append the new components there.
Samuel Antao6890b092016-07-28 14:25:09 +0000789 MEC.Components.resize(MEC.Components.size() + 1);
790 MEC.Components.back().append(Components.begin(), Components.end());
791 MEC.Kind = WhereFoundClauseKind;
Kelvin Li0bff7af2015-11-23 05:32:03 +0000792 }
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000793
794 unsigned getNestingLevel() const {
Alexey Bataev4b465392017-04-26 15:06:24 +0000795 assert(!isStackEmpty());
Richard Smith375dec52019-05-30 23:21:14 +0000796 return getStackSize() - 1;
Alexey Bataev7ace49d2016-05-17 08:55:33 +0000797 }
Alexey Bataeve3727102018-04-18 15:57:46 +0000798 void addDoacrossDependClause(OMPDependClause *C,
799 const OperatorOffsetTy &OpsOffs) {
Richard Smith375dec52019-05-30 23:21:14 +0000800 SharingMapTy *Parent = getSecondOnStackOrNull();
801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
802 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
Alexey Bataev8b427062016-05-25 12:36:08 +0000803 }
804 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
805 getDoacrossDependClauses() const {
Richard Smith375dec52019-05-30 23:21:14 +0000806 const SharingMapTy &StackElem = getTopOfStack();
Alexey Bataev4b465392017-04-26 15:06:24 +0000807 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
Alexey Bataev8b427062016-05-25 12:36:08 +0000809 return llvm::make_range(Ref.begin(), Ref.end());
810 }
Alexey Bataev4b465392017-04-26 15:06:24 +0000811 return llvm::make_range(StackElem.DoacrossDepends.end(),
812 StackElem.DoacrossDepends.end());
Alexey Bataev8b427062016-05-25 12:36:08 +0000813 }
Patrick Lystere13b1e32019-01-02 19:28:48 +0000814
815 // Store types of classes which have been explicitly mapped
816 void addMappedClassesQualTypes(QualType QT) {
Richard Smith375dec52019-05-30 23:21:14 +0000817 SharingMapTy &StackElem = getTopOfStack();
Patrick Lystere13b1e32019-01-02 19:28:48 +0000818 StackElem.MappedClassesQualTypes.insert(QT);
819 }
820
821 // Return set of mapped classes types
822 bool isClassPreviouslyMapped(QualType QT) const {
Richard Smith375dec52019-05-30 23:21:14 +0000823 const SharingMapTy &StackElem = getTopOfStack();
Patrick Lystere13b1e32019-01-02 19:28:48 +0000824 return StackElem.MappedClassesQualTypes.count(QT) != 0;
825 }
826
Alexey Bataeva495c642019-03-11 19:51:42 +0000827 /// Adds global declare target to the parent target region.
828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
831 "Expected declare target link global.");
Richard Smith375dec52019-05-30 23:21:14 +0000832 for (auto &Elem : *this) {
833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
834 Elem.DeclareTargetLinkVarDecls.push_back(E);
835 return;
836 }
Alexey Bataeva495c642019-03-11 19:51:42 +0000837 }
838 }
839
840 /// Returns the list of globals with declare target link if current directive
841 /// is target.
842 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
844 "Expected target executable directive.");
Richard Smith375dec52019-05-30 23:21:14 +0000845 return getTopOfStack().DeclareTargetLinkVarDecls;
Alexey Bataeva495c642019-03-11 19:51:42 +0000846 }
Alexey Bataev758e55e2013-09-06 18:03:48 +0000847};
Alexey Bataev7e6803e2019-01-09 15:58:05 +0000848
849bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
851}
852
853bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
Alexey Bataev412254a2019-05-09 18:44:53 +0000854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
855 DKind == OMPD_unknown;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000856}
Alexey Bataeve3727102018-04-18 15:57:46 +0000857
Alexey Bataeved09d242014-05-28 05:53:51 +0000858} // namespace
Alexey Bataev758e55e2013-09-06 18:03:48 +0000859
Alexey Bataeve3727102018-04-18 15:57:46 +0000860static const Expr *getExprAsWritten(const Expr *E) {
Bill Wendling7c44da22018-10-31 03:48:47 +0000861 if (const auto *FE = dyn_cast<FullExpr>(E))
862 E = FE->getSubExpr();
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000863
Alexey Bataeve3727102018-04-18 15:57:46 +0000864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000865 E = MTE->GetTemporaryExpr();
866
Alexey Bataeve3727102018-04-18 15:57:46 +0000867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000868 E = Binder->getSubExpr();
869
Alexey Bataeve3727102018-04-18 15:57:46 +0000870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000871 E = ICE->getSubExprAsWritten();
872 return E->IgnoreParens();
873}
874
Alexey Bataeve3727102018-04-18 15:57:46 +0000875static Expr *getExprAsWritten(Expr *E) {
876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
877}
878
879static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev4d4624c2017-07-20 16:47:47 +0000882 D = ME->getMemberDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +0000883 const auto *VD = dyn_cast<VarDecl>(D);
884 const auto *FD = dyn_cast<FieldDecl>(D);
David Majnemer9d168222016-08-05 17:44:54 +0000885 if (VD != nullptr) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000886 VD = VD->getCanonicalDecl();
887 D = VD;
888 } else {
889 assert(FD);
890 FD = FD->getCanonicalDecl();
891 D = FD;
892 }
893 return D;
894}
895
Alexey Bataeve3727102018-04-18 15:57:46 +0000896static ValueDecl *getCanonicalDecl(ValueDecl *D) {
897 return const_cast<ValueDecl *>(
898 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
899}
900
Richard Smith375dec52019-05-30 23:21:14 +0000901DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
Alexey Bataeve3727102018-04-18 15:57:46 +0000902 ValueDecl *D) const {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000903 D = getCanonicalDecl(D);
904 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataeve3727102018-04-18 15:57:46 +0000905 const auto *FD = dyn_cast<FieldDecl>(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +0000906 DSAVarData DVar;
Richard Smith375dec52019-05-30 23:21:14 +0000907 if (Iter == end()) {
Alexey Bataev750a58b2014-03-18 12:19:12 +0000908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
909 // in a region but not in construct]
910 // File-scope or namespace-scope variables referenced in called routines
911 // in the region are shared unless they appear in a threadprivate
912 // directive.
Alexey Bataeve3727102018-04-18 15:57:46 +0000913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
Alexey Bataev750a58b2014-03-18 12:19:12 +0000914 DVar.CKind = OMPC_shared;
915
916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
917 // in a region but not in construct]
918 // Variables with static storage duration that are declared in called
919 // routines in the region are shared.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000920 if (VD && VD->hasGlobalStorage())
921 DVar.CKind = OMPC_shared;
922
923 // Non-static data members are shared by default.
924 if (FD)
Alexey Bataev750a58b2014-03-18 12:19:12 +0000925 DVar.CKind = OMPC_shared;
926
Alexey Bataev758e55e2013-09-06 18:03:48 +0000927 return DVar;
928 }
Alexey Bataevec3da872014-01-31 05:15:34 +0000929
Alexey Bataevec3da872014-01-31 05:15:34 +0000930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
931 // in a Construct, C/C++, predetermined, p.1]
932 // Variables with automatic storage duration that are declared in a scope
933 // inside the construct are private.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +0000934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
Alexey Bataevf29276e2014-06-18 04:14:57 +0000936 DVar.CKind = OMPC_private;
937 return DVar;
Alexey Bataevec3da872014-01-31 05:15:34 +0000938 }
939
Alexey Bataeveffbdf12017-07-21 17:24:30 +0000940 DVar.DKind = Iter->Directive;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000941 // Explicitly specified attributes and local variables with predetermined
942 // attributes.
943 if (Iter->SharingMap.count(D)) {
Alexey Bataeve3727102018-04-18 15:57:46 +0000944 const DSAInfo &Data = Iter->SharingMap.lookup(D);
945 DVar.RefExpr = Data.RefExpr.getPointer();
946 DVar.PrivateCopy = Data.PrivateCopy;
947 DVar.CKind = Data.Attributes;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +0000948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000949 return DVar;
950 }
951
952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
953 // in a Construct, C/C++, implicitly determined, p.1]
954 // In a parallel or task construct, the data-sharing attributes of these
955 // variables are determined by the default clause, if present.
956 switch (Iter->DefaultAttr) {
957 case DSA_shared:
958 DVar.CKind = OMPC_shared;
Alexey Bataevbae9a792014-06-27 10:37:06 +0000959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000960 return DVar;
961 case DSA_none:
962 return DVar;
963 case DSA_unspecified:
964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
965 // in a Construct, implicitly determined, p.2]
966 // In a parallel construct, if no default clause is present, these
967 // variables are shared.
Alexey Bataevbae9a792014-06-27 10:37:06 +0000968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
Alexey Bataev5bbcead2019-10-14 17:17:41 +0000969 if ((isOpenMPParallelDirective(DVar.DKind) &&
970 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
Alexey Bataev13314bf2014-10-09 04:18:56 +0000971 isOpenMPTeamsDirective(DVar.DKind)) {
Alexey Bataev758e55e2013-09-06 18:03:48 +0000972 DVar.CKind = OMPC_shared;
973 return DVar;
974 }
975
976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
977 // in a Construct, implicitly determined, p.4]
978 // In a task construct, if no default clause is present, a variable that in
979 // the enclosing context is determined to be shared by all implicit tasks
980 // bound to the current team is shared.
Alexey Bataev35aaee62016-04-13 13:36:48 +0000981 if (isOpenMPTaskingDirective(DVar.DKind)) {
Alexey Bataev758e55e2013-09-06 18:03:48 +0000982 DSAVarData DVarTemp;
Richard Smith375dec52019-05-30 23:21:14 +0000983 const_iterator I = Iter, E = end();
Alexey Bataevccaddfb2017-04-26 14:24:21 +0000984 do {
985 ++I;
Alexey Bataeved09d242014-05-28 05:53:51 +0000986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
Alexey Bataev35aaee62016-04-13 13:36:48 +0000987 // Referenced in a Construct, implicitly determined, p.6]
Alexey Bataev758e55e2013-09-06 18:03:48 +0000988 // In a task construct, if no default clause is present, a variable
989 // whose data-sharing attribute is not determined by the rules above is
990 // firstprivate.
991 DVarTemp = getDSA(I, D);
992 if (DVarTemp.CKind != OMPC_shared) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +0000993 DVar.RefExpr = nullptr;
Alexey Bataevd5af8e42013-10-01 05:32:34 +0000994 DVar.CKind = OMPC_firstprivate;
Alexey Bataev758e55e2013-09-06 18:03:48 +0000995 return DVar;
996 }
Alexey Bataev7e6803e2019-01-09 15:58:05 +0000997 } while (I != E && !isImplicitTaskingRegion(I->Directive));
Alexey Bataev758e55e2013-09-06 18:03:48 +0000998 DVar.CKind =
Alexey Bataeved09d242014-05-28 05:53:51 +0000999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001000 return DVar;
1001 }
1002 }
1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1004 // in a Construct, implicitly determined, p.3]
1005 // For constructs other than task, if no default clause is present, these
1006 // variables inherit their data-sharing attributes from the enclosing
1007 // context.
Dmitry Polukhindc78bc822016-04-01 09:52:30 +00001008 return getDSA(++Iter, D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001009}
1010
Alexey Bataeve3727102018-04-18 15:57:46 +00001011const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1012 const Expr *NewDE) {
Alexey Bataev4b465392017-04-26 15:06:24 +00001013 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001014 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001015 SharingMapTy &StackElem = getTopOfStack();
Alexey Bataev4b465392017-04-26 15:06:24 +00001016 auto It = StackElem.AlignedMap.find(D);
1017 if (It == StackElem.AlignedMap.end()) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
Alexey Bataev4b465392017-04-26 15:06:24 +00001019 StackElem.AlignedMap[D] = NewDE;
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001020 return nullptr;
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001021 }
Alexey Bataeve3727102018-04-18 15:57:46 +00001022 assert(It->second && "Unexpected nullptr expr in the aligned map");
1023 return It->second;
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001024}
1025
Alexey Bataeve3727102018-04-18 15:57:46 +00001026void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
Alexey Bataev4b465392017-04-26 15:06:24 +00001027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001028 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001029 SharingMapTy &StackElem = getTopOfStack();
Alexey Bataeve3727102018-04-18 15:57:46 +00001030 StackElem.LCVMap.try_emplace(
1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
Alexey Bataev9c821032015-04-30 04:23:23 +00001032}
1033
Alexey Bataeve3727102018-04-18 15:57:46 +00001034const DSAStackTy::LCDeclInfo
1035DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001037 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001038 const SharingMapTy &StackElem = getTopOfStack();
Alexey Bataev4b465392017-04-26 15:06:24 +00001039 auto It = StackElem.LCVMap.find(D);
1040 if (It != StackElem.LCVMap.end())
1041 return It->second;
1042 return {0, nullptr};
Alexey Bataeva636c7f2015-12-23 10:27:45 +00001043}
1044
Alexey Bataeve3727102018-04-18 15:57:46 +00001045const DSAStackTy::LCDeclInfo
1046DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
Richard Smith375dec52019-05-30 23:21:14 +00001047 const SharingMapTy *Parent = getSecondOnStackOrNull();
1048 assert(Parent && "Data-sharing attributes stack is empty");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001049 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001050 auto It = Parent->LCVMap.find(D);
1051 if (It != Parent->LCVMap.end())
Alexey Bataev4b465392017-04-26 15:06:24 +00001052 return It->second;
1053 return {0, nullptr};
Alexey Bataeva636c7f2015-12-23 10:27:45 +00001054}
1055
Alexey Bataeve3727102018-04-18 15:57:46 +00001056const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
Richard Smith375dec52019-05-30 23:21:14 +00001057 const SharingMapTy *Parent = getSecondOnStackOrNull();
1058 assert(Parent && "Data-sharing attributes stack is empty");
1059 if (Parent->LCVMap.size() < I)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00001060 return nullptr;
Richard Smith375dec52019-05-30 23:21:14 +00001061 for (const auto &Pair : Parent->LCVMap)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00001062 if (Pair.second.first == I)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00001063 return Pair.first;
Alexey Bataeva636c7f2015-12-23 10:27:45 +00001064 return nullptr;
Alexey Bataev9c821032015-04-30 04:23:23 +00001065}
1066
Alexey Bataeve3727102018-04-18 15:57:46 +00001067void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
Alexey Bataev90c228f2016-02-08 09:29:13 +00001068 DeclRefExpr *PrivateCopy) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001069 D = getCanonicalDecl(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001070 if (A == OMPC_threadprivate) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001071 DSAInfo &Data = Threadprivates[D];
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001072 Data.Attributes = A;
1073 Data.RefExpr.setPointer(E);
1074 Data.PrivateCopy = nullptr;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001075 } else {
Richard Smith375dec52019-05-30 23:21:14 +00001076 DSAInfo &Data = getTopOfStack().SharingMap[D];
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1080 (isLoopControlVariable(D).first && A == OMPC_private));
1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1082 Data.RefExpr.setInt(/*IntVal=*/true);
1083 return;
1084 }
1085 const bool IsLastprivate =
1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1087 Data.Attributes = A;
1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1089 Data.PrivateCopy = PrivateCopy;
1090 if (PrivateCopy) {
Richard Smith375dec52019-05-30 23:21:14 +00001091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001092 Data.Attributes = A;
1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1094 Data.PrivateCopy = nullptr;
1095 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001096 }
1097}
1098
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00001099/// Build a variable declaration for OpenMP loop iteration variable.
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001100static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001101 StringRef Name, const AttrVec *Attrs = nullptr,
1102 DeclRefExpr *OrigRef = nullptr) {
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001103 DeclContext *DC = SemaRef.CurContext;
1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
Alexey Bataeve3727102018-04-18 15:57:46 +00001106 auto *Decl =
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1108 if (Attrs) {
1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1110 I != E; ++I)
1111 Decl->addAttr(*I);
1112 }
1113 Decl->setImplicit();
Alexey Bataev63cc8e92018-03-20 14:45:59 +00001114 if (OrigRef) {
1115 Decl->addAttr(
1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1117 }
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001118 return Decl;
1119}
1120
1121static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1122 SourceLocation Loc,
1123 bool RefersToCapture = false) {
1124 D->setReferenced();
1125 D->markUsed(S.Context);
1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1127 SourceLocation(), D, RefersToCapture, Loc, Ty,
1128 VK_LValue);
1129}
1130
Alexey Bataeve3727102018-04-18 15:57:46 +00001131void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001132 BinaryOperatorKind BOK) {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001133 D = getCanonicalDecl(D);
1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataevfa312f32017-07-21 18:48:21 +00001135 assert(
Richard Smith375dec52019-05-30 23:21:14 +00001136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001137 "Additional reduction info may be specified only for reduction items.");
Richard Smith375dec52019-05-30 23:21:14 +00001138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
Alexey Bataevfa312f32017-07-21 18:48:21 +00001139 assert(ReductionData.ReductionRange.isInvalid() &&
Richard Smith375dec52019-05-30 23:21:14 +00001140 getTopOfStack().Directive == OMPD_taskgroup &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001141 "Additional reduction info may be specified only once for reduction "
1142 "items.");
1143 ReductionData.set(BOK, SR);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001144 Expr *&TaskgroupReductionRef =
Richard Smith375dec52019-05-30 23:21:14 +00001145 getTopOfStack().TaskgroupReductionRef;
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001146 if (!TaskgroupReductionRef) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1148 SemaRef.Context.VoidPtrTy, ".task_red.");
Alexey Bataevd070a582017-10-25 15:54:04 +00001149 TaskgroupReductionRef =
1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001151 }
Alexey Bataevfa312f32017-07-21 18:48:21 +00001152}
1153
Alexey Bataeve3727102018-04-18 15:57:46 +00001154void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001155 const Expr *ReductionRef) {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001156 D = getCanonicalDecl(D);
1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
Alexey Bataevfa312f32017-07-21 18:48:21 +00001158 assert(
Richard Smith375dec52019-05-30 23:21:14 +00001159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001160 "Additional reduction info may be specified only for reduction items.");
Richard Smith375dec52019-05-30 23:21:14 +00001161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
Alexey Bataevfa312f32017-07-21 18:48:21 +00001162 assert(ReductionData.ReductionRange.isInvalid() &&
Richard Smith375dec52019-05-30 23:21:14 +00001163 getTopOfStack().Directive == OMPD_taskgroup &&
Alexey Bataevfa312f32017-07-21 18:48:21 +00001164 "Additional reduction info may be specified only once for reduction "
1165 "items.");
1166 ReductionData.set(ReductionRef, SR);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001167 Expr *&TaskgroupReductionRef =
Richard Smith375dec52019-05-30 23:21:14 +00001168 getTopOfStack().TaskgroupReductionRef;
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001169 if (!TaskgroupReductionRef) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1171 SemaRef.Context.VoidPtrTy, ".task_red.");
Alexey Bataevd070a582017-10-25 15:54:04 +00001172 TaskgroupReductionRef =
1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
Alexey Bataev3b1b8952017-07-25 15:53:26 +00001174 }
Alexey Bataevfa312f32017-07-21 18:48:21 +00001175}
1176
Alexey Bataeve3727102018-04-18 15:57:46 +00001177const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1179 Expr *&TaskgroupDescriptor) const {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001180 D = getCanonicalDecl(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
Richard Smith375dec52019-05-30 23:21:14 +00001182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001183 const DSAInfo &Data = I->SharingMap.lookup(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
Alexey Bataevfa312f32017-07-21 18:48:21 +00001185 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +00001186 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001187 if (!ReductionData.ReductionOp ||
1188 ReductionData.ReductionOp.is<const Expr *>())
Alexey Bataevf189cb72017-07-24 14:52:13 +00001189 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001190 SR = ReductionData.ReductionRange;
Alexey Bataevf87fa882017-07-21 19:26:22 +00001191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
Alexey Bataev88202be2017-07-27 13:20:36 +00001192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1193 "expression for the descriptor is not "
1194 "set.");
1195 TaskgroupDescriptor = I->TaskgroupReductionRef;
Alexey Bataevf189cb72017-07-24 14:52:13 +00001196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1197 Data.PrivateCopy, I->DefaultAttrLoc);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001198 }
Alexey Bataevf189cb72017-07-24 14:52:13 +00001199 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001200}
1201
Alexey Bataeve3727102018-04-18 15:57:46 +00001202const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1204 Expr *&TaskgroupDescriptor) const {
Alexey Bataevfa312f32017-07-21 18:48:21 +00001205 D = getCanonicalDecl(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
Richard Smith375dec52019-05-30 23:21:14 +00001207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001208 const DSAInfo &Data = I->SharingMap.lookup(D);
Alexey Bataevf189cb72017-07-24 14:52:13 +00001209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
Alexey Bataevfa312f32017-07-21 18:48:21 +00001210 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +00001211 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001212 if (!ReductionData.ReductionOp ||
1213 !ReductionData.ReductionOp.is<const Expr *>())
Alexey Bataevf189cb72017-07-24 14:52:13 +00001214 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001215 SR = ReductionData.ReductionRange;
1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
Alexey Bataev88202be2017-07-27 13:20:36 +00001217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1218 "expression for the descriptor is not "
1219 "set.");
1220 TaskgroupDescriptor = I->TaskgroupReductionRef;
Alexey Bataevf189cb72017-07-24 14:52:13 +00001221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1222 Data.PrivateCopy, I->DefaultAttrLoc);
Alexey Bataevfa312f32017-07-21 18:48:21 +00001223 }
Alexey Bataevf189cb72017-07-24 14:52:13 +00001224 return DSAVarData();
Alexey Bataevfa312f32017-07-21 18:48:21 +00001225}
1226
Richard Smith375dec52019-05-30 23:21:14 +00001227bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
Alexey Bataev6ddfe1a2015-04-16 13:49:42 +00001228 D = D->getCanonicalDecl();
Richard Smith375dec52019-05-30 23:21:14 +00001229 for (const_iterator E = end(); I != E; ++I) {
1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1231 isOpenMPTargetExecutionDirective(I->Directive)) {
1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1233 Scope *CurScope = getCurScope();
1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1235 CurScope = CurScope->getParent();
1236 return CurScope != TopScope;
1237 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001238 }
Alexey Bataevec3da872014-01-31 05:15:34 +00001239 return false;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001240}
1241
Joel E. Dennyd2649292019-01-04 22:11:56 +00001242static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1243 bool AcceptIfMutable = true,
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001244 bool *IsClassType = nullptr) {
1245 ASTContext &Context = SemaRef.getASTContext();
Joel E. Dennyd2649292019-01-04 22:11:56 +00001246 Type = Type.getNonReferenceType().getCanonicalType();
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001247 bool IsConstant = Type.isConstant(Context);
1248 Type = Context.getBaseElementType(Type);
Joel E. Dennyd2649292019-01-04 22:11:56 +00001249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1250 ? Type->getAsCXXRecordDecl()
1251 : nullptr;
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1254 RD = CTD->getTemplatedDecl();
1255 if (IsClassType)
1256 *IsClassType = RD;
1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1258 RD->hasDefinition() && RD->hasMutableFields());
1259}
1260
Joel E. Dennyd2649292019-01-04 22:11:56 +00001261static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1262 QualType Type, OpenMPClauseKind CKind,
1263 SourceLocation ELoc,
1264 bool AcceptIfMutable = true,
1265 bool ListItemNotVar = false) {
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001266 ASTContext &Context = SemaRef.getASTContext();
1267 bool IsClassType;
Joel E. Dennyd2649292019-01-04 22:11:56 +00001268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1269 unsigned Diag = ListItemNotVar
1270 ? diag::err_omp_const_list_item
1271 : IsClassType ? diag::err_omp_const_not_mutable_variable
1272 : diag::err_omp_const_variable;
1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1274 if (!ListItemNotVar && D) {
1275 const VarDecl *VD = dyn_cast<VarDecl>(D);
1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1277 VarDecl::DeclarationOnly;
1278 SemaRef.Diag(D->getLocation(),
1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1280 << D;
1281 }
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001282 return true;
1283 }
1284 return false;
1285}
1286
Alexey Bataeve3727102018-04-18 15:57:46 +00001287const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1288 bool FromParent) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001289 D = getCanonicalDecl(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001290 DSAVarData DVar;
1291
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001292 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001293 auto TI = Threadprivates.find(D);
1294 if (TI != Threadprivates.end()) {
1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
Alexey Bataev758e55e2013-09-06 18:03:48 +00001296 DVar.CKind = OMPC_threadprivate;
1297 return DVar;
Alexey Bataeve3727102018-04-18 15:57:46 +00001298 }
1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
Alexey Bataev817d7f32017-11-14 21:01:01 +00001300 DVar.RefExpr = buildDeclRefExpr(
1301 SemaRef, VD, D->getType().getNonReferenceType(),
1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1303 DVar.CKind = OMPC_threadprivate;
1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
Alexey Bataev852525d2018-03-02 17:17:12 +00001305 return DVar;
1306 }
1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1308 // in a Construct, C/C++, predetermined, p.1]
1309 // Variables appearing in threadprivate directives are threadprivate.
1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1312 SemaRef.getLangOpts().OpenMPUseTLS &&
1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1314 (VD && VD->getStorageClass() == SC_Register &&
1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1316 DVar.RefExpr = buildDeclRefExpr(
1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1318 DVar.CKind = OMPC_threadprivate;
1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1320 return DVar;
1321 }
1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1324 !isLoopControlVariable(D).first) {
Richard Smith375dec52019-05-30 23:21:14 +00001325 const_iterator IterTarget =
1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1327 return isOpenMPTargetExecutionDirective(Data.Directive);
1328 });
1329 if (IterTarget != end()) {
1330 const_iterator ParentIterTarget = IterTarget + 1;
1331 for (const_iterator Iter = begin();
1332 Iter != ParentIterTarget; ++Iter) {
Alexey Bataev852525d2018-03-02 17:17:12 +00001333 if (isOpenMPLocal(VD, Iter)) {
1334 DVar.RefExpr =
1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1336 D->getLocation());
1337 DVar.CKind = OMPC_threadprivate;
1338 return DVar;
1339 }
Alexey Bataev852525d2018-03-02 17:17:12 +00001340 }
Richard Smith375dec52019-05-30 23:21:14 +00001341 if (!isClauseParsingMode() || IterTarget != begin()) {
Alexey Bataev852525d2018-03-02 17:17:12 +00001342 auto DSAIter = IterTarget->SharingMap.find(D);
1343 if (DSAIter != IterTarget->SharingMap.end() &&
1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1346 DVar.CKind = OMPC_threadprivate;
1347 return DVar;
Alexey Bataeve3727102018-04-18 15:57:46 +00001348 }
Richard Smith375dec52019-05-30 23:21:14 +00001349 const_iterator End = end();
Alexey Bataeve3727102018-04-18 15:57:46 +00001350 if (!SemaRef.isOpenMPCapturedByRef(
Joel E. Denny7d5bc552019-08-22 03:34:30 +00001351 D, std::distance(ParentIterTarget, End),
1352 /*OpenMPCaptureLevel=*/0)) {
Alexey Bataev852525d2018-03-02 17:17:12 +00001353 DVar.RefExpr =
1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1355 IterTarget->ConstructLoc);
1356 DVar.CKind = OMPC_threadprivate;
1357 return DVar;
1358 }
1359 }
1360 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001361 }
1362
Alexey Bataev4b465392017-04-26 15:06:24 +00001363 if (isStackEmpty())
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001364 // Not in OpenMP execution region and top scope was already checked.
1365 return DVar;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00001366
Alexey Bataev758e55e2013-09-06 18:03:48 +00001367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
Alexey Bataevdffa93a2015-12-10 08:20:58 +00001368 // in a Construct, C/C++, predetermined, p.4]
1369 // Static data members are shared.
1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1371 // in a Construct, C/C++, predetermined, p.7]
1372 // Variables with static storage duration that are declared in a scope
1373 // inside the construct are shared.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001374 if (VD && VD->isStaticDataMember()) {
Alexey Bataev73f9d9aa2019-06-28 16:16:00 +00001375 // Check for explicitly specified attributes.
1376 const_iterator I = begin();
1377 const_iterator EndI = end();
1378 if (FromParent && I != EndI)
1379 ++I;
1380 auto It = I->SharingMap.find(D);
1381 if (It != I->SharingMap.end()) {
1382 const DSAInfo &Data = It->getSecond();
1383 DVar.RefExpr = Data.RefExpr.getPointer();
1384 DVar.PrivateCopy = Data.PrivateCopy;
1385 DVar.CKind = Data.Attributes;
1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1387 DVar.DKind = I->Directive;
Alexey Bataevec3da872014-01-31 05:15:34 +00001388 return DVar;
Alexey Bataev73f9d9aa2019-06-28 16:16:00 +00001389 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001390
Alexey Bataevdffa93a2015-12-10 08:20:58 +00001391 DVar.CKind = OMPC_shared;
1392 return DVar;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001393 }
1394
Alexey Bataev73f9d9aa2019-06-28 16:16:00 +00001395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001396 // The predetermined shared attribute for const-qualified types having no
1397 // mutable members was removed after OpenMP 3.1.
1398 if (SemaRef.LangOpts.OpenMP <= 31) {
1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1400 // in a Construct, C/C++, predetermined, p.6]
1401 // Variables with const qualified type having no mutable member are
1402 // shared.
Joel E. Dennyd2649292019-01-04 22:11:56 +00001403 if (isConstNotMutableType(SemaRef, D->getType())) {
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001404 // Variables with const-qualified type having no mutable member may be
1405 // listed in a firstprivate clause, even if they are static data members.
1406 DSAVarData DVarTemp = hasInnermostDSA(
1407 D,
1408 [](OpenMPClauseKind C) {
1409 return C == OMPC_firstprivate || C == OMPC_shared;
1410 },
1411 MatchesAlways, FromParent);
1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1413 return DVarTemp;
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001414
Joel E. Dennye6234d1422019-01-04 22:11:31 +00001415 DVar.CKind = OMPC_shared;
1416 return DVar;
1417 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00001418 }
1419
Alexey Bataev758e55e2013-09-06 18:03:48 +00001420 // Explicitly specified attributes and local variables with predetermined
1421 // attributes.
Richard Smith375dec52019-05-30 23:21:14 +00001422 const_iterator I = begin();
1423 const_iterator EndI = end();
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001424 if (FromParent && I != EndI)
Richard Smith375dec52019-05-30 23:21:14 +00001425 ++I;
Alexey Bataeve3727102018-04-18 15:57:46 +00001426 auto It = I->SharingMap.find(D);
1427 if (It != I->SharingMap.end()) {
1428 const DSAInfo &Data = It->getSecond();
1429 DVar.RefExpr = Data.RefExpr.getPointer();
1430 DVar.PrivateCopy = Data.PrivateCopy;
1431 DVar.CKind = Data.Attributes;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001432 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
Alexey Bataev4d4624c2017-07-20 16:47:47 +00001433 DVar.DKind = I->Directive;
Alexey Bataev758e55e2013-09-06 18:03:48 +00001434 }
1435
1436 return DVar;
1437}
1438
Alexey Bataeve3727102018-04-18 15:57:46 +00001439const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1440 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001441 if (isStackEmpty()) {
Richard Smith375dec52019-05-30 23:21:14 +00001442 const_iterator I;
Alexey Bataev4b465392017-04-26 15:06:24 +00001443 return getDSA(I, D);
1444 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001445 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001446 const_iterator StartI = begin();
1447 const_iterator EndI = end();
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001448 if (FromParent && StartI != EndI)
Richard Smith375dec52019-05-30 23:21:14 +00001449 ++StartI;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001450 return getDSA(StartI, D);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001451}
1452
Alexey Bataeve3727102018-04-18 15:57:46 +00001453const DSAStackTy::DSAVarData
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001454DSAStackTy::hasDSA(ValueDecl *D,
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001457 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001458 if (isStackEmpty())
1459 return {};
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001460 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001461 const_iterator I = begin();
1462 const_iterator EndI = end();
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001463 if (FromParent && I != EndI)
Richard Smith375dec52019-05-30 23:21:14 +00001464 ++I;
1465 for (; I != EndI; ++I) {
1466 if (!DPred(I->Directive) &&
1467 !isImplicitOrExplicitTaskingRegion(I->Directive))
Alexey Bataeved09d242014-05-28 05:53:51 +00001468 continue;
Richard Smith375dec52019-05-30 23:21:14 +00001469 const_iterator NewI = I;
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001470 DSAVarData DVar = getDSA(NewI, D);
1471 if (I == NewI && CPred(DVar.CKind))
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001472 return DVar;
Alexey Bataev60859c02017-04-27 15:10:33 +00001473 }
Alexey Bataevccaddfb2017-04-26 14:24:21 +00001474 return {};
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001475}
1476
Alexey Bataeve3727102018-04-18 15:57:46 +00001477const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001480 bool FromParent) const {
Alexey Bataev4b465392017-04-26 15:06:24 +00001481 if (isStackEmpty())
1482 return {};
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001483 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001484 const_iterator StartI = begin();
1485 const_iterator EndI = end();
Alexey Bataeve3978122016-07-19 05:06:39 +00001486 if (FromParent && StartI != EndI)
Richard Smith375dec52019-05-30 23:21:14 +00001487 ++StartI;
Alexey Bataeve3978122016-07-19 05:06:39 +00001488 if (StartI == EndI || !DPred(StartI->Directive))
Alexey Bataev4b465392017-04-26 15:06:24 +00001489 return {};
Richard Smith375dec52019-05-30 23:21:14 +00001490 const_iterator NewI = StartI;
Alexey Bataeveffbdf12017-07-21 17:24:30 +00001491 DSAVarData DVar = getDSA(NewI, D);
1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
Alexey Bataevc5e02582014-06-16 07:08:35 +00001493}
1494
Alexey Bataevaac108a2015-06-23 04:51:00 +00001495bool DSAStackTy::hasExplicitDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00001496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1497 unsigned Level, bool NotLastprivate) const {
Richard Smith375dec52019-05-30 23:21:14 +00001498 if (getStackSize() <= Level)
Alexey Bataev4b465392017-04-26 15:06:24 +00001499 return false;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001500 D = getCanonicalDecl(D);
Richard Smith375dec52019-05-30 23:21:14 +00001501 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1502 auto I = StackElem.SharingMap.find(D);
1503 if (I != StackElem.SharingMap.end() &&
1504 I->getSecond().RefExpr.getPointer() &&
1505 CPred(I->getSecond().Attributes) &&
1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
Alexey Bataev92b33652018-11-21 19:41:10 +00001507 return true;
1508 // Check predetermined rules for the loop control variables.
Richard Smith375dec52019-05-30 23:21:14 +00001509 auto LI = StackElem.LCVMap.find(D);
1510 if (LI != StackElem.LCVMap.end())
Alexey Bataev92b33652018-11-21 19:41:10 +00001511 return CPred(OMPC_private);
1512 return false;
Alexey Bataevaac108a2015-06-23 04:51:00 +00001513}
1514
Samuel Antao4be30e92015-10-02 17:14:03 +00001515bool DSAStackTy::hasExplicitDirective(
Alexey Bataeve3727102018-04-18 15:57:46 +00001516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1517 unsigned Level) const {
Richard Smith375dec52019-05-30 23:21:14 +00001518 if (getStackSize() <= Level)
Alexey Bataev4b465392017-04-26 15:06:24 +00001519 return false;
Richard Smith375dec52019-05-30 23:21:14 +00001520 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1521 return DPred(StackElem.Directive);
Samuel Antao4be30e92015-10-02 17:14:03 +00001522}
1523
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001524bool DSAStackTy::hasDirective(
1525 const llvm::function_ref<bool(OpenMPDirectiveKind,
1526 const DeclarationNameInfo &, SourceLocation)>
Alexey Bataev97d18bf2018-04-11 19:21:00 +00001527 DPred,
Alexey Bataeve3727102018-04-18 15:57:46 +00001528 bool FromParent) const {
Samuel Antaof0d79752016-05-27 15:21:27 +00001529 // We look only in the enclosing region.
Richard Smith375dec52019-05-30 23:21:14 +00001530 size_t Skip = FromParent ? 2 : 1;
1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1532 I != E; ++I) {
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1534 return true;
1535 }
1536 return false;
1537}
1538
Alexey Bataev758e55e2013-09-06 18:03:48 +00001539void Sema::InitDataSharingAttributesStack() {
1540 VarDataSharingAttributesStack = new DSAStackTy(*this);
1541}
1542
1543#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1544
Alexey Bataev4b465392017-04-26 15:06:24 +00001545void Sema::pushOpenMPFunctionRegion() {
1546 DSAStack->pushFunction();
1547}
1548
1549void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1550 DSAStack->popFunction(OldFSI);
1551}
1552
Alexey Bataevc416e642019-02-08 18:02:25 +00001553static bool isOpenMPDeviceDelayedContext(Sema &S) {
1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1555 "Expected OpenMP device compilation.");
1556 return !S.isInOpenMPTargetExecutionDirective() &&
1557 !S.isInOpenMPDeclareTargetContext();
1558}
1559
Alexey Bataev729e2422019-08-23 16:11:14 +00001560namespace {
1561/// Status of the function emission on the host/device.
1562enum class FunctionEmissionStatus {
1563 Emitted,
1564 Discarded,
1565 Unknown,
1566};
1567} // anonymous namespace
1568
Alexey Bataevc416e642019-02-08 18:02:25 +00001569Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1570 unsigned DiagID) {
1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1572 "Expected OpenMP device compilation.");
Yaxun Liu229c78d2019-10-09 23:54:10 +00001573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
Alexey Bataev729e2422019-08-23 16:11:14 +00001574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1575 switch (FES) {
1576 case FunctionEmissionStatus::Emitted:
1577 Kind = DeviceDiagBuilder::K_Immediate;
1578 break;
1579 case FunctionEmissionStatus::Unknown:
1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred
1581 : DeviceDiagBuilder::K_Immediate;
1582 break;
Yaxun Liu229c78d2019-10-09 23:54:10 +00001583 case FunctionEmissionStatus::TemplateDiscarded:
1584 case FunctionEmissionStatus::OMPDiscarded:
Alexey Bataev729e2422019-08-23 16:11:14 +00001585 Kind = DeviceDiagBuilder::K_Nop;
1586 break;
Yaxun Liu229c78d2019-10-09 23:54:10 +00001587 case FunctionEmissionStatus::CUDADiscarded:
1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1589 break;
Alexey Bataev729e2422019-08-23 16:11:14 +00001590 }
1591
1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1593}
1594
Alexey Bataev729e2422019-08-23 16:11:14 +00001595Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1596 unsigned DiagID) {
1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1598 "Expected OpenMP host compilation.");
Yaxun Liu229c78d2019-10-09 23:54:10 +00001599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
Alexey Bataev729e2422019-08-23 16:11:14 +00001600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1601 switch (FES) {
1602 case FunctionEmissionStatus::Emitted:
1603 Kind = DeviceDiagBuilder::K_Immediate;
1604 break;
1605 case FunctionEmissionStatus::Unknown:
1606 Kind = DeviceDiagBuilder::K_Deferred;
1607 break;
Yaxun Liu229c78d2019-10-09 23:54:10 +00001608 case FunctionEmissionStatus::TemplateDiscarded:
1609 case FunctionEmissionStatus::OMPDiscarded:
1610 case FunctionEmissionStatus::CUDADiscarded:
Alexey Bataev729e2422019-08-23 16:11:14 +00001611 Kind = DeviceDiagBuilder::K_Nop;
1612 break;
1613 }
1614
1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
Alexey Bataevc416e642019-02-08 18:02:25 +00001616}
1617
Alexey Bataev9fd495b2019-08-20 19:50:13 +00001618void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
1619 bool CheckForDelayedContext) {
Alexey Bataevc416e642019-02-08 18:02:25 +00001620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1621 "Expected OpenMP device compilation.");
1622 assert(Callee && "Callee may not be null.");
Alexey Bataev729e2422019-08-23 16:11:14 +00001623 Callee = Callee->getMostRecentDecl();
Alexey Bataevc416e642019-02-08 18:02:25 +00001624 FunctionDecl *Caller = getCurFunctionDecl();
1625
Alexey Bataev729e2422019-08-23 16:11:14 +00001626 // host only function are not available on the device.
Yaxun Liu229c78d2019-10-09 23:54:10 +00001627 if (Caller) {
1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&
1631 CalleeS != FunctionEmissionStatus::CUDADiscarded &&
1632 "CUDADiscarded unexpected in OpenMP device function check");
1633 if ((CallerS == FunctionEmissionStatus::Emitted ||
1634 (!isOpenMPDeviceDelayedContext(*this) &&
1635 CallerS == FunctionEmissionStatus::Unknown)) &&
1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
1638 OMPC_device_type, OMPC_DEVICE_TYPE_host);
1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1641 diag::note_omp_marked_device_type_here)
1642 << HostDevTy;
1643 return;
1644 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001645 }
Alexey Bataevc416e642019-02-08 18:02:25 +00001646 // If the caller is known-emitted, mark the callee as known-emitted.
1647 // Otherwise, mark the call in our call graph so we can traverse it later.
Alexey Bataev9fd495b2019-08-20 19:50:13 +00001648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
1649 (!Caller && !CheckForDelayedContext) ||
Yaxun Liu229c78d2019-10-09 23:54:10 +00001650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
Alexey Bataev9fd495b2019-08-20 19:50:13 +00001651 markKnownEmitted(*this, Caller, Callee, Loc,
1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
Alexey Bataev729e2422019-08-23 16:11:14 +00001653 return CheckForDelayedContext &&
Yaxun Liu229c78d2019-10-09 23:54:10 +00001654 S.getEmissionStatus(FD) ==
Alexey Bataev729e2422019-08-23 16:11:14 +00001655 FunctionEmissionStatus::Emitted;
Alexey Bataev9fd495b2019-08-20 19:50:13 +00001656 });
Alexey Bataevc416e642019-02-08 18:02:25 +00001657 else if (Caller)
1658 DeviceCallGraph[Caller].insert({Callee, Loc});
1659}
1660
Alexey Bataev729e2422019-08-23 16:11:14 +00001661void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
1662 bool CheckCaller) {
1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1664 "Expected OpenMP host compilation.");
1665 assert(Callee && "Callee may not be null.");
1666 Callee = Callee->getMostRecentDecl();
1667 FunctionDecl *Caller = getCurFunctionDecl();
1668
1669 // device only function are not available on the host.
Yaxun Liu229c78d2019-10-09 23:54:10 +00001670 if (Caller) {
1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1673 assert(
1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&
1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&
1676 "CUDADiscarded unexpected in OpenMP host function check");
1677 if (CallerS == FunctionEmissionStatus::Emitted &&
1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1683 diag::note_omp_marked_device_type_here)
1684 << NoHostDevTy;
1685 return;
1686 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001687 }
1688 // If the caller is known-emitted, mark the callee as known-emitted.
1689 // Otherwise, mark the call in our call graph so we can traverse it later.
Yaxun Liu229c78d2019-10-09 23:54:10 +00001690 if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1691 if ((!CheckCaller && !Caller) ||
1692 (Caller &&
1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1694 markKnownEmitted(
1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) {
1696 return CheckCaller &&
1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted;
1698 });
1699 else if (Caller)
1700 DeviceCallGraph[Caller].insert({Callee, Loc});
1701 }
Alexey Bataev729e2422019-08-23 16:11:14 +00001702}
1703
Alexey Bataev123ad192019-02-27 20:29:45 +00001704void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1706 "OpenMP device compilation mode is expected.");
1707 QualType Ty = E->getType();
1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
Alexey Bataev8557d1a2019-06-18 18:39:26 +00001709 ((Ty->isFloat128Type() ||
1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
1711 !Context.getTargetInfo().hasFloat128Type()) ||
Alexey Bataev123ad192019-02-27 20:29:45 +00001712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1713 !Context.getTargetInfo().hasInt128Type()))
Alexey Bataev62892592019-07-08 19:21:54 +00001714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type)
1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange();
Alexey Bataev123ad192019-02-27 20:29:45 +00001717}
1718
Joel E. Denny7d5bc552019-08-22 03:34:30 +00001719bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1720 unsigned OpenMPCaptureLevel) const {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001721 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1722
Alexey Bataeve3727102018-04-18 15:57:46 +00001723 ASTContext &Ctx = getASTContext();
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001724 bool IsByRef = true;
1725
1726 // Find the directive that is associated with the provided scope.
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00001727 D = cast<ValueDecl>(D->getCanonicalDecl());
Alexey Bataeve3727102018-04-18 15:57:46 +00001728 QualType Ty = D->getType();
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001729
Joel E. Denny7d5bc552019-08-22 03:34:30 +00001730 bool IsVariableUsedInMapClause = false;
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001732 // This table summarizes how a given variable should be passed to the device
1733 // given its type and the clauses where it appears. This table is based on
1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1736 //
1737 // =========================================================================
1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1739 // | |(tofrom:scalar)| | pvt | | | |
1740 // =========================================================================
1741 // | scl | | | | - | | bycopy|
1742 // | scl | | - | x | - | - | bycopy|
1743 // | scl | | x | - | - | - | null |
1744 // | scl | x | | | - | | byref |
1745 // | scl | x | - | x | - | - | bycopy|
1746 // | scl | x | x | - | - | - | null |
1747 // | scl | | - | - | - | x | byref |
1748 // | scl | x | - | - | - | x | byref |
1749 //
1750 // | agg | n.a. | | | - | | byref |
1751 // | agg | n.a. | - | x | - | - | byref |
1752 // | agg | n.a. | x | - | - | - | null |
1753 // | agg | n.a. | - | - | - | x | byref |
1754 // | agg | n.a. | - | - | - | x[] | byref |
1755 //
1756 // | ptr | n.a. | | | - | | bycopy|
1757 // | ptr | n.a. | - | x | - | - | bycopy|
1758 // | ptr | n.a. | x | - | - | - | null |
1759 // | ptr | n.a. | - | - | - | x | byref |
1760 // | ptr | n.a. | - | - | - | x[] | bycopy|
1761 // | ptr | n.a. | - | - | x | | bycopy|
1762 // | ptr | n.a. | - | - | x | x | bycopy|
1763 // | ptr | n.a. | - | - | x | x[] | bycopy|
1764 // =========================================================================
1765 // Legend:
1766 // scl - scalar
1767 // ptr - pointer
1768 // agg - aggregate
1769 // x - applies
1770 // - - invalid in this combination
1771 // [] - mapped with an array section
1772 // byref - should be mapped by reference
1773 // byval - should be mapped by value
1774 // null - initialize a local variable to null on the device
1775 //
1776 // Observations:
1777 // - All scalar declarations that show up in a map clause have to be passed
1778 // by reference, because they may have been mapped in the enclosing data
1779 // environment.
1780 // - If the scalar value does not fit the size of uintptr, it has to be
1781 // passed by reference, regardless the result in the table above.
1782 // - For pointers mapped by value that have either an implicit map or an
1783 // array section, the runtime library may pass the NULL value to the
1784 // device instead of the value passed to it by the compiler.
1785
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001786 if (Ty->isReferenceType())
1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
Samuel Antao86ace552016-04-27 22:40:57 +00001788
1789 // Locate map clauses and see if the variable being captured is referred to
1790 // in any of those clauses. Here we only care about variables, not fields,
1791 // because fields are part of aggregates.
Samuel Antao86ace552016-04-27 22:40:57 +00001792 bool IsVariableAssociatedWithSection = false;
1793
Jonas Hahnfeldf7c4d7b2017-07-01 10:40:50 +00001794 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
Alexey Bataeve3727102018-04-18 15:57:46 +00001795 D, Level,
1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1797 OMPClauseMappableExprCommon::MappableExprComponentListRef
Samuel Antao6890b092016-07-28 14:25:09 +00001798 MapExprComponents,
1799 OpenMPClauseKind WhereFoundClauseKind) {
1800 // Only the map clause information influences how a variable is
1801 // captured. E.g. is_device_ptr does not require changing the default
Samuel Antao4c8035b2016-12-12 18:00:20 +00001802 // behavior.
Samuel Antao6890b092016-07-28 14:25:09 +00001803 if (WhereFoundClauseKind != OMPC_map)
1804 return false;
Samuel Antao86ace552016-04-27 22:40:57 +00001805
1806 auto EI = MapExprComponents.rbegin();
1807 auto EE = MapExprComponents.rend();
1808
1809 assert(EI != EE && "Invalid map expression!");
1810
1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1813
1814 ++EI;
1815 if (EI == EE)
1816 return false;
1817
1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1820 isa<MemberExpr>(EI->getAssociatedExpression())) {
1821 IsVariableAssociatedWithSection = true;
1822 // There is nothing more we need to know about this variable.
1823 return true;
1824 }
1825
1826 // Keep looking for more map info.
1827 return false;
1828 });
1829
1830 if (IsVariableUsedInMapClause) {
1831 // If variable is identified in a map clause it is always captured by
1832 // reference except if it is a pointer that is dereferenced somehow.
1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1834 } else {
Alexey Bataev3f96fe62017-12-13 17:31:39 +00001835 // By default, all the data that has a scalar type is mapped by copy
1836 // (except for reduction variables).
1837 IsByRef =
Alexey Bataev60705422018-10-30 15:50:12 +00001838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1839 !Ty->isAnyPointerType()) ||
Alexey Bataev3f96fe62017-12-13 17:31:39 +00001840 !Ty->isScalarType() ||
1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1842 DSAStack->hasExplicitDSA(
1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
Samuel Antao86ace552016-04-27 22:40:57 +00001844 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001845 }
1846
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00001848 IsByRef =
Joel E. Denny7d5bc552019-08-22 03:34:30 +00001849 ((IsVariableUsedInMapClause &&
1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1851 OMPD_target) ||
1852 !DSAStack->hasExplicitDSA(
1853 D,
1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1855 Level, /*NotLastprivate=*/true)) &&
Alexey Bataev8e769ee2017-12-22 21:01:52 +00001856 // If the variable is artificial and must be captured by value - try to
1857 // capture by value.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00001858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001860 }
1861
Samuel Antao86ace552016-04-27 22:40:57 +00001862 // When passing data by copy, we need to make sure it fits the uintptr size
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001863 // and alignment, because the runtime library only deals with uintptr types.
1864 // If it does not fit the uintptr size, we need to pass the data by reference
1865 // instead.
1866 if (!IsByRef &&
1867 (Ctx.getTypeSizeInChars(Ty) >
1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001870 IsByRef = true;
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001871 }
Samuel Antao4af1b7b2015-12-02 17:44:43 +00001872
1873 return IsByRef;
1874}
1875
Alexey Bataev7ace49d2016-05-17 08:55:33 +00001876unsigned Sema::getOpenMPNestingLevel() const {
1877 assert(getLangOpts().OpenMP);
1878 return DSAStack->getNestingLevel();
1879}
1880
Jonas Hahnfeld87d44262017-11-18 21:00:46 +00001881bool Sema::isInOpenMPTargetExecutionDirective() const {
1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1883 !DSAStack->isClauseParsingMode()) ||
1884 DSAStack->hasDirective(
1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1886 SourceLocation) -> bool {
1887 return isOpenMPTargetExecutionDirective(K);
1888 },
1889 false);
1890}
1891
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001892VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
1893 unsigned StopAt) {
Alexey Bataevf841bd92014-12-16 07:00:22 +00001894 assert(LangOpts.OpenMP && "OpenMP is not allowed");
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001895 D = getCanonicalDecl(D);
Samuel Antao4be30e92015-10-02 17:14:03 +00001896
Alexey Bataev7c860692019-10-25 16:35:32 -04001897 auto *VD = dyn_cast<VarDecl>(D);
1898 // Do not capture constexpr variables.
1899 if (VD && VD->isConstexpr())
1900 return nullptr;
1901
Richard Smith0621a8f2019-05-31 00:45:10 +00001902 // If we want to determine whether the variable should be captured from the
1903 // perspective of the current capturing scope, and we've already left all the
1904 // capturing scopes of the top directive on the stack, check from the
1905 // perspective of its parent directive (if any) instead.
1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
1908
Samuel Antao4be30e92015-10-02 17:14:03 +00001909 // If we are attempting to capture a global variable in a directive with
1910 // 'target' we return true so that this global is also mapped to the device.
1911 //
Richard Smith0621a8f2019-05-31 00:45:10 +00001912 if (VD && !VD->hasLocalStorage() &&
1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1914 if (isInOpenMPDeclareTargetContext()) {
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001915 // Try to mark variable as declare target if it is used in capturing
1916 // regions.
Alexey Bataev217ff1e2019-08-16 20:15:02 +00001917 if (LangOpts.OpenMP <= 45 &&
1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
Alexey Bataev92327c52018-03-26 16:40:55 +00001920 return nullptr;
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001921 } else if (isInOpenMPTargetExecutionDirective()) {
1922 // If the declaration is enclosed in a 'declare target' directive,
1923 // then it should not be captured.
1924 //
Alexey Bataev97b72212018-08-14 18:31:20 +00001925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
Alexey Bataevbf8fe712018-08-07 16:14:36 +00001926 return nullptr;
1927 return VD;
1928 }
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00001929 }
Samuel Antao4be30e92015-10-02 17:14:03 +00001930
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001931 if (CheckScopeInfo) {
1932 bool OpenMPFound = false;
1933 for (unsigned I = StopAt + 1; I > 0; --I) {
1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
1935 if(!isa<CapturingScopeInfo>(FSI))
1936 return nullptr;
1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
1938 if (RSI->CapRegionKind == CR_OpenMP) {
1939 OpenMPFound = true;
1940 break;
1941 }
1942 }
1943 if (!OpenMPFound)
1944 return nullptr;
1945 }
1946
Alexey Bataev48977c32015-08-04 08:10:48 +00001947 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1948 (!DSAStack->isClauseParsingMode() ||
1949 DSAStack->getParentDirective() != OMPD_unknown)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00001950 auto &&Info = DSAStack->isLoopControlVariable(D);
1951 if (Info.first ||
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001952 (VD && VD->hasLocalStorage() &&
Alexey Bataev7e6803e2019-01-09 15:58:05 +00001953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00001954 (VD && DSAStack->isForceVarCapturing()))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00001955 return VD ? VD : Info.second;
Alexey Bataeve3727102018-04-18 15:57:46 +00001956 DSAStackTy::DSAVarData DVarPrivate =
1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
Alexey Bataevf841bd92014-12-16 07:00:22 +00001958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
Alexey Bataev90c228f2016-02-08 09:29:13 +00001959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
Alexey Bataeve0eb66b2019-06-21 15:08:30 +00001960 // Threadprivate variables must not be captured.
1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind))
1962 return nullptr;
1963 // The variable is not private or it is the variable in the directive with
1964 // default(none) clause and not used in any clause.
Alexey Bataeve3727102018-04-18 15:57:46 +00001965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1966 [](OpenMPDirectiveKind) { return true; },
1967 DSAStack->isClauseParsingMode());
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00001968 if (DVarPrivate.CKind != OMPC_unknown ||
1969 (VD && DSAStack->getDefaultDSA() == DSA_none))
Alexey Bataev90c228f2016-02-08 09:29:13 +00001970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
Alexey Bataevf841bd92014-12-16 07:00:22 +00001971 }
Alexey Bataev90c228f2016-02-08 09:29:13 +00001972 return nullptr;
Alexey Bataevf841bd92014-12-16 07:00:22 +00001973}
1974
Alexey Bataevdfa430f2017-12-08 15:03:50 +00001975void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1976 unsigned Level) const {
1977 SmallVector<OpenMPDirectiveKind, 4> Regions;
1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1979 FunctionScopesIndex -= Regions.size();
1980}
1981
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00001982void Sema::startOpenMPLoop() {
1983 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1985 DSAStack->loopInit();
1986}
1987
Alexey Bataevbef93a92019-10-07 18:54:57 +00001988void Sema::startOpenMPCXXRangeFor() {
1989 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1991 DSAStack->resetPossibleLoopCounter();
1992 DSAStack->loopStart();
1993 }
1994}
1995
Alexey Bataeve3727102018-04-18 15:57:46 +00001996bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
Alexey Bataevaac108a2015-06-23 04:51:00 +00001997 assert(LangOpts.OpenMP && "OpenMP is not allowed");
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00001998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1999 if (DSAStack->getAssociatedLoops() > 0 &&
2000 !DSAStack->isLoopStarted()) {
2001 DSAStack->resetPossibleLoopCounter(D);
2002 DSAStack->loopStart();
2003 return true;
2004 }
2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2006 DSAStack->isLoopControlVariable(D).first) &&
2007 !DSAStack->hasExplicitDSA(
2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2010 return true;
2011 }
Alexey Bataev0c99d192019-07-18 19:40:24 +00002012 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2014 DSAStack->isForceVarCapturing() &&
2015 !DSAStack->hasExplicitDSA(
2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2017 return true;
2018 }
Alexey Bataevaac108a2015-06-23 04:51:00 +00002019 return DSAStack->hasExplicitDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00002020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
Alexey Bataev3f82cfc2017-12-13 15:28:44 +00002021 (DSAStack->isClauseParsingMode() &&
2022 DSAStack->getClauseParsingMode() == OMPC_private) ||
Alexey Bataev88202be2017-07-27 13:20:36 +00002023 // Consider taskgroup reduction descriptor variable a private to avoid
2024 // possible capture in the region.
2025 (DSAStack->hasExplicitDirective(
2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
2027 Level) &&
2028 DSAStack->isTaskgroupReductionRef(D, Level));
Alexey Bataevaac108a2015-06-23 04:51:00 +00002029}
2030
Alexey Bataeve3727102018-04-18 15:57:46 +00002031void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2032 unsigned Level) {
Alexey Bataev3b8d5582017-08-08 18:04:06 +00002033 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2034 D = getCanonicalDecl(D);
2035 OpenMPClauseKind OMPC = OMPC_unknown;
2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2037 const unsigned NewLevel = I - 1;
2038 if (DSAStack->hasExplicitDSA(D,
2039 [&OMPC](const OpenMPClauseKind K) {
2040 if (isOpenMPPrivate(K)) {
2041 OMPC = K;
2042 return true;
2043 }
2044 return false;
2045 },
2046 NewLevel))
2047 break;
2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2049 D, NewLevel,
2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2051 OpenMPClauseKind) { return true; })) {
2052 OMPC = OMPC_map;
2053 break;
2054 }
2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2056 NewLevel)) {
Alexey Bataev63cc8e92018-03-20 14:45:59 +00002057 OMPC = OMPC_map;
2058 if (D->getType()->isScalarType() &&
2059 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
2060 DefaultMapAttributes::DMA_tofrom_scalar)
2061 OMPC = OMPC_firstprivate;
Alexey Bataev3b8d5582017-08-08 18:04:06 +00002062 break;
2063 }
2064 }
2065 if (OMPC != OMPC_unknown)
2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2067}
2068
Alexey Bataeve3727102018-04-18 15:57:46 +00002069bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
2070 unsigned Level) const {
Samuel Antao4be30e92015-10-02 17:14:03 +00002071 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2072 // Return true if the current level is no longer enclosed in a target region.
2073
Alexey Bataeve3727102018-04-18 15:57:46 +00002074 const auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002075 return VD && !VD->hasLocalStorage() &&
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00002076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2077 Level);
Samuel Antao4be30e92015-10-02 17:14:03 +00002078}
2079
Alexey Bataeved09d242014-05-28 05:53:51 +00002080void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002081
Alexey Bataev729e2422019-08-23 16:11:14 +00002082void Sema::finalizeOpenMPDelayedAnalysis() {
2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2084 // Diagnose implicit declare target functions and their callees.
2085 for (const auto &CallerCallees : DeviceCallGraph) {
2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2087 OMPDeclareTargetDeclAttr::getDeviceType(
2088 CallerCallees.getFirst()->getMostRecentDecl());
2089 // Ignore host functions during device analyzis.
2090 if (LangOpts.OpenMPIsDevice && DevTy &&
2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2092 continue;
2093 // Ignore nohost functions during host analyzis.
2094 if (!LangOpts.OpenMPIsDevice && DevTy &&
2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2096 continue;
2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation>
2098 &Callee : CallerCallees.getSecond()) {
2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl();
2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2101 OMPDeclareTargetDeclAttr::getDeviceType(FD);
2102 if (LangOpts.OpenMPIsDevice && DevTy &&
2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2104 // Diagnose host function called during device codegen.
2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
2106 OMPC_device_type, OMPC_DEVICE_TYPE_host);
2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2108 << HostDevTy << 0;
2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2110 diag::note_omp_marked_device_type_here)
2111 << HostDevTy;
2112 continue;
2113 }
2114 if (!LangOpts.OpenMPIsDevice && DevTy &&
2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2116 // Diagnose nohost function called during host codegen.
2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2120 << NoHostDevTy << 1;
2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2122 diag::note_omp_marked_device_type_here)
2123 << NoHostDevTy;
2124 continue;
2125 }
2126 }
2127 }
2128}
2129
Alexey Bataev758e55e2013-09-06 18:03:48 +00002130void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2131 const DeclarationNameInfo &DirName,
Alexey Bataevbae9a792014-06-27 10:37:06 +00002132 Scope *CurScope, SourceLocation Loc) {
2133 DSAStack->push(DKind, DirName, CurScope, Loc);
Faisal Valid143a0c2017-04-01 21:30:49 +00002134 PushExpressionEvaluationContext(
2135 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002136}
2137
Alexey Bataevaac108a2015-06-23 04:51:00 +00002138void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2139 DSAStack->setClauseParsingMode(K);
Alexey Bataev39f915b82015-05-08 10:41:21 +00002140}
2141
Alexey Bataevaac108a2015-06-23 04:51:00 +00002142void Sema::EndOpenMPClause() {
2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
Alexey Bataev39f915b82015-05-08 10:41:21 +00002144}
2145
Alexey Bataeve106f252019-04-01 14:25:31 +00002146static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2147 ArrayRef<OMPClause *> Clauses);
2148
Alexey Bataev758e55e2013-09-06 18:03:48 +00002149void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
Alexey Bataevf29276e2014-06-18 04:14:57 +00002150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2151 // A variable of class type (or array thereof) that appears in a lastprivate
2152 // clause requires an accessible, unambiguous default constructor for the
2153 // class type, unless the list item is also specified in a firstprivate
2154 // clause.
Alexey Bataeve3727102018-04-18 15:57:46 +00002155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2156 for (OMPClause *C : D->clauses()) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2158 SmallVector<Expr *, 8> PrivateCopies;
Alexey Bataeve3727102018-04-18 15:57:46 +00002159 for (Expr *DE : Clause->varlists()) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002160 if (DE->isValueDependent() || DE->isTypeDependent()) {
2161 PrivateCopies.push_back(nullptr);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002162 continue;
Alexey Bataev38e89532015-04-16 04:54:05 +00002163 }
Alexey Bataev74caaf22016-02-20 04:09:36 +00002164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
Alexey Bataeve3727102018-04-18 15:57:46 +00002165 auto *VD = cast<VarDecl>(DRE->getDecl());
Alexey Bataev005248a2016-02-25 05:25:57 +00002166 QualType Type = VD->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +00002167 const DSAStackTy::DSAVarData DVar =
2168 DSAStack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002169 if (DVar.CKind == OMPC_lastprivate) {
Alexey Bataev38e89532015-04-16 04:54:05 +00002170 // Generate helper private variable and initialize it with the
2171 // default value. The address of the original variable is replaced
2172 // by the address of the new private variable in CodeGen. This new
2173 // variable is not added to IdResolver, so the code in the OpenMP
2174 // region uses original variable for proper diagnostics.
Alexey Bataeve3727102018-04-18 15:57:46 +00002175 VarDecl *VDPrivate = buildVarDecl(
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +00002176 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
Alexey Bataev63cc8e92018-03-20 14:45:59 +00002177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
Richard Smith3beb7c62017-01-12 02:27:38 +00002178 ActOnUninitializedDecl(VDPrivate);
Alexey Bataeve106f252019-04-01 14:25:31 +00002179 if (VDPrivate->isInvalidDecl()) {
2180 PrivateCopies.push_back(nullptr);
Alexey Bataev38e89532015-04-16 04:54:05 +00002181 continue;
Alexey Bataeve106f252019-04-01 14:25:31 +00002182 }
Alexey Bataev39f915b82015-05-08 10:41:21 +00002183 PrivateCopies.push_back(buildDeclRefExpr(
2184 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
Alexey Bataev38e89532015-04-16 04:54:05 +00002185 } else {
2186 // The variable is also a firstprivate, so initialization sequence
2187 // for private copy is generated already.
2188 PrivateCopies.push_back(nullptr);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002189 }
2190 }
Alexey Bataeve106f252019-04-01 14:25:31 +00002191 Clause->setPrivateCopies(PrivateCopies);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002192 }
2193 }
Alexey Bataeve106f252019-04-01 14:25:31 +00002194 // Check allocate clauses.
2195 if (!CurContext->isDependentContext())
2196 checkAllocateClauses(*this, DSAStack, D->clauses());
Alexey Bataevf29276e2014-06-18 04:14:57 +00002197 }
2198
Alexey Bataev758e55e2013-09-06 18:03:48 +00002199 DSAStack->pop();
2200 DiscardCleanupsInEvaluationContext();
2201 PopExpressionEvaluationContext();
2202}
2203
Alexey Bataev5dff95c2016-04-22 03:56:56 +00002204static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2205 Expr *NumIterations, Sema &SemaRef,
2206 Scope *S, DSAStackTy *Stack);
Alexander Musman3276a272015-03-21 10:12:56 +00002207
Alexey Bataeva769e072013-03-22 06:34:35 +00002208namespace {
2209
Alexey Bataeve3727102018-04-18 15:57:46 +00002210class VarDeclFilterCCC final : public CorrectionCandidateCallback {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002211private:
Alexey Bataev7ff55242014-06-19 09:13:45 +00002212 Sema &SemaRef;
Alexey Bataeved09d242014-05-28 05:53:51 +00002213
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002214public:
Alexey Bataev7ff55242014-06-19 09:13:45 +00002215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
Craig Toppere14c0f82014-03-12 04:55:44 +00002216 bool ValidateCandidate(const TypoCorrection &Candidate) override {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002217 NamedDecl *ND = Candidate.getCorrectionDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +00002218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002219 return VD->hasGlobalStorage() &&
Alexey Bataev7ff55242014-06-19 09:13:45 +00002220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2221 SemaRef.getCurScope());
Alexey Bataeva769e072013-03-22 06:34:35 +00002222 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002223 return false;
Alexey Bataeva769e072013-03-22 06:34:35 +00002224 }
Bruno Ricci70ad3962019-03-25 17:08:51 +00002225
2226 std::unique_ptr<CorrectionCandidateCallback> clone() override {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00002227 return std::make_unique<VarDeclFilterCCC>(*this);
Bruno Ricci70ad3962019-03-25 17:08:51 +00002228 }
2229
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002230};
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002231
Alexey Bataeve3727102018-04-18 15:57:46 +00002232class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002233private:
2234 Sema &SemaRef;
2235
2236public:
2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2238 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2239 NamedDecl *ND = Candidate.getCorrectionDecl();
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2241 isa<FunctionDecl>(ND))) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2243 SemaRef.getCurScope());
2244 }
2245 return false;
2246 }
Bruno Ricci70ad3962019-03-25 17:08:51 +00002247
2248 std::unique_ptr<CorrectionCandidateCallback> clone() override {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00002249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
Bruno Ricci70ad3962019-03-25 17:08:51 +00002250 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +00002251};
2252
Alexey Bataeved09d242014-05-28 05:53:51 +00002253} // namespace
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002254
2255ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2256 CXXScopeSpec &ScopeSpec,
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002257 const DeclarationNameInfo &Id,
2258 OpenMPDirectiveKind Kind) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002259 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2261
2262 if (Lookup.isAmbiguous())
2263 return ExprError();
2264
2265 VarDecl *VD;
2266 if (!Lookup.isSingleResult()) {
Bruno Ricci70ad3962019-03-25 17:08:51 +00002267 VarDeclFilterCCC CCC(*this);
2268 if (TypoCorrection Corrected =
2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2270 CTK_ErrorRecovery)) {
Richard Smithf9b15102013-08-17 00:46:16 +00002271 diagnoseTypo(Corrected,
Alexander Musmancb7f9c42014-05-15 13:04:49 +00002272 PDiag(Lookup.empty()
2273 ? diag::err_undeclared_var_use_suggest
2274 : diag::err_omp_expected_var_arg_suggest)
2275 << Id.getName());
Richard Smithf9b15102013-08-17 00:46:16 +00002276 VD = Corrected.getCorrectionDeclAs<VarDecl>();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002277 } else {
Richard Smithf9b15102013-08-17 00:46:16 +00002278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2279 : diag::err_omp_expected_var_arg)
2280 << Id.getName();
2281 return ExprError();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002282 }
Alexey Bataeve3727102018-04-18 15:57:46 +00002283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2286 return ExprError();
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002287 }
2288 Lookup.suppressDiagnostics();
2289
2290 // OpenMP [2.9.2, Syntax, C/C++]
2291 // Variables must be file-scope, namespace-scope, or static block-scope.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002293 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
Alexey Bataeved09d242014-05-28 05:53:51 +00002295 bool IsDecl =
2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002297 Diag(VD->getLocation(),
Alexey Bataeved09d242014-05-28 05:53:51 +00002298 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2299 << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002300 return ExprError();
2301 }
2302
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002303 VarDecl *CanonicalVD = VD->getCanonicalDecl();
George Burgess IV00f70bd2018-03-01 05:43:23 +00002304 NamedDecl *ND = CanonicalVD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002305 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2306 // A threadprivate directive for file-scope variables must appear outside
2307 // any definition or declaration.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002308 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2309 !getCurLexicalContext()->isTranslationUnit()) {
2310 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002311 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002312 bool IsDecl =
2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2314 Diag(VD->getLocation(),
2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2316 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002317 return ExprError();
2318 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002319 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2320 // A threadprivate directive for static class member variables must appear
2321 // in the class definition, in the same scope in which the member
2322 // variables are declared.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002323 if (CanonicalVD->isStaticDataMember() &&
2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2325 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002326 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002327 bool IsDecl =
2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2329 Diag(VD->getLocation(),
2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2331 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002332 return ExprError();
2333 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002334 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2335 // A threadprivate directive for namespace-scope variables must appear
2336 // outside any definition or declaration other than the namespace
2337 // definition itself.
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002338 if (CanonicalVD->getDeclContext()->isNamespace() &&
2339 (!getCurLexicalContext()->isFileContext() ||
2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2341 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002342 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002343 bool IsDecl =
2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2345 Diag(VD->getLocation(),
2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2347 << VD;
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002348 return ExprError();
2349 }
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002350 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2351 // A threadprivate directive for static block-scope variables must appear
2352 // in the scope of the variable and not in a nested scope.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002353 if (CanonicalVD->isLocalVarDecl() && CurScope &&
Alexey Bataev7d2960b2013-09-26 03:24:06 +00002354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002355 Diag(Id.getLoc(), diag::err_omp_var_scope)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002356 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataeved09d242014-05-28 05:53:51 +00002357 bool IsDecl =
2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2359 Diag(VD->getLocation(),
2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2361 << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002362 return ExprError();
2363 }
2364
2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2366 // A threadprivate directive must lexically precede all references to any
2367 // of the variables in its list.
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002368 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2369 !DSAStack->isThreadPrivate(VD)) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002370 Diag(Id.getLoc(), diag::err_omp_var_used)
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002371 << getOpenMPDirectiveName(Kind) << VD;
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002372 return ExprError();
2373 }
2374
2375 QualType ExprType = VD->getType().getNonReferenceType();
Alexey Bataev376b4a42016-02-09 09:41:09 +00002376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2377 SourceLocation(), VD,
2378 /*RefersToEnclosingVariableOrCapture=*/false,
2379 Id.getLoc(), ExprType, VK_LValue);
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002380}
2381
Alexey Bataeved09d242014-05-28 05:53:51 +00002382Sema::DeclGroupPtrTy
2383Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2384 ArrayRef<Expr *> VarList) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002386 CurContext->addDecl(D);
2387 return DeclGroupPtrTy::make(DeclGroupRef(D));
2388 }
David Blaikie0403cb12016-01-15 23:43:25 +00002389 return nullptr;
Alexey Bataeva769e072013-03-22 06:34:35 +00002390}
2391
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002392namespace {
Alexey Bataeve3727102018-04-18 15:57:46 +00002393class LocalVarRefChecker final
2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002395 Sema &SemaRef;
2396
2397public:
2398 bool VisitDeclRefExpr(const DeclRefExpr *E) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002400 if (VD->hasLocalStorage()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002401 SemaRef.Diag(E->getBeginLoc(),
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002402 diag::err_omp_local_var_in_threadprivate_init)
2403 << E->getSourceRange();
2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2405 << VD << VD->getSourceRange();
2406 return true;
2407 }
2408 }
2409 return false;
2410 }
2411 bool VisitStmt(const Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00002412 for (const Stmt *Child : S->children()) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002413 if (Child && Visit(Child))
2414 return true;
2415 }
2416 return false;
2417 }
Alexey Bataev23b69422014-06-18 07:08:49 +00002418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002419};
2420} // namespace
2421
Alexey Bataeved09d242014-05-28 05:53:51 +00002422OMPThreadPrivateDecl *
2423Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002424 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +00002425 for (Expr *RefExpr : VarList) {
2426 auto *DE = cast<DeclRefExpr>(RefExpr);
2427 auto *VD = cast<VarDecl>(DE->getDecl());
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002428 SourceLocation ILoc = DE->getExprLoc();
Alexey Bataeva769e072013-03-22 06:34:35 +00002429
Alexey Bataev376b4a42016-02-09 09:41:09 +00002430 // Mark variable as used.
2431 VD->setReferenced();
2432 VD->markUsed(Context);
2433
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002434 QualType QType = VD->getType();
2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2436 // It will be analyzed later.
2437 Vars.push_back(DE);
2438 continue;
2439 }
2440
Alexey Bataeva769e072013-03-22 06:34:35 +00002441 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2442 // A threadprivate variable must not have an incomplete type.
2443 if (RequireCompleteType(ILoc, VD->getType(),
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002444 diag::err_omp_threadprivate_incomplete_type)) {
Alexey Bataeva769e072013-03-22 06:34:35 +00002445 continue;
2446 }
2447
2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2449 // A threadprivate variable must not have a reference type.
2450 if (VD->getType()->isReferenceType()) {
2451 Diag(ILoc, diag::err_omp_ref_type_arg)
Alexey Bataeved09d242014-05-28 05:53:51 +00002452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2453 bool IsDecl =
2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2455 Diag(VD->getLocation(),
2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2457 << VD;
Alexey Bataeva769e072013-03-22 06:34:35 +00002458 continue;
2459 }
2460
Samuel Antaof8b50122015-07-13 22:54:53 +00002461 // Check if this is a TLS variable. If TLS is not being supported, produce
2462 // the corresponding diagnostic.
2463 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2465 getLangOpts().OpenMPUseTLS &&
2466 getASTContext().getTargetInfo().isTLSSupported())) ||
Alexey Bataev1a8b3f12015-05-06 06:34:55 +00002467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2468 !VD->isLocalVarDecl())) {
Alexey Bataev26a39242015-01-13 03:35:30 +00002469 Diag(ILoc, diag::err_omp_var_thread_local)
2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
Alexey Bataeved09d242014-05-28 05:53:51 +00002471 bool IsDecl =
2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2473 Diag(VD->getLocation(),
2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2475 << VD;
Alexey Bataeva769e072013-03-22 06:34:35 +00002476 continue;
2477 }
2478
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002479 // Check if initial value of threadprivate variable reference variable with
2480 // local storage (it is not supported by runtime).
Alexey Bataeve3727102018-04-18 15:57:46 +00002481 if (const Expr *Init = VD->getAnyInitializer()) {
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002482 LocalVarRefChecker Checker(*this);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002483 if (Checker.Visit(Init))
2484 continue;
Alexey Bataev18b92ee2014-05-28 07:40:25 +00002485 }
2486
Alexey Bataeved09d242014-05-28 05:53:51 +00002487 Vars.push_back(RefExpr);
Alexey Bataevd178ad42014-03-07 08:03:37 +00002488 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
Alexey Bataev97720002014-11-11 04:05:39 +00002489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2490 Context, SourceRange(Loc, Loc)));
Alexey Bataeve3727102018-04-18 15:57:46 +00002491 if (ASTMutationListener *ML = Context.getASTMutationListener())
Alexey Bataev97720002014-11-11 04:05:39 +00002492 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
Alexey Bataeva769e072013-03-22 06:34:35 +00002493 }
Alexander Musmancb7f9c42014-05-15 13:04:49 +00002494 OMPThreadPrivateDecl *D = nullptr;
Alexey Bataevec3da872014-01-31 05:15:34 +00002495 if (!Vars.empty()) {
2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2497 Vars);
2498 D->setAccess(AS_public);
2499 }
2500 return D;
Alexey Bataeva769e072013-03-22 06:34:35 +00002501}
Alexey Bataev6f6f3b42013-05-13 04:18:18 +00002502
Alexey Bataev27ef9512019-03-20 20:14:22 +00002503static OMPAllocateDeclAttr::AllocatorTypeTy
2504getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2505 if (!Allocator)
2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2508 Allocator->isInstantiationDependent() ||
Alexey Bataev441510e2019-03-21 19:05:07 +00002509 Allocator->containsUnexpandedParameterPack())
Alexey Bataev27ef9512019-03-20 20:14:22 +00002510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
Alexey Bataev27ef9512019-03-20 20:14:22 +00002511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
Alexey Bataeve106f252019-04-01 14:25:31 +00002512 const Expr *AE = Allocator->IgnoreParenImpCasts();
Alexey Bataev27ef9512019-03-20 20:14:22 +00002513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
Alexey Bataeve106f252019-04-01 14:25:31 +00002516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
Alexey Bataev441510e2019-03-21 19:05:07 +00002517 llvm::FoldingSetNodeID AEId, DAEId;
2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2520 if (AEId == DAEId) {
Alexey Bataev27ef9512019-03-20 20:14:22 +00002521 AllocatorKindRes = AllocatorKind;
2522 break;
2523 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002524 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002525 return AllocatorKindRes;
2526}
2527
Alexey Bataeve106f252019-04-01 14:25:31 +00002528static bool checkPreviousOMPAllocateAttribute(
2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2531 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2532 return false;
2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2534 Expr *PrevAllocator = A->getAllocator();
2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2536 getAllocatorKind(S, Stack, PrevAllocator);
2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2538 if (AllocatorsMatch &&
2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2540 Allocator && PrevAllocator) {
2541 const Expr *AE = Allocator->IgnoreParenImpCasts();
2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2543 llvm::FoldingSetNodeID AEId, PAEId;
2544 AE->Profile(AEId, S.Context, /*Canonical=*/true);
2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2546 AllocatorsMatch = AEId == PAEId;
2547 }
2548 if (!AllocatorsMatch) {
2549 SmallString<256> AllocatorBuffer;
2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2551 if (Allocator)
2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2553 SmallString<256> PrevAllocatorBuffer;
2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2555 if (PrevAllocator)
2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2557 S.getPrintingPolicy());
2558
2559 SourceLocation AllocatorLoc =
2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2561 SourceRange AllocatorRange =
2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2563 SourceLocation PrevAllocatorLoc =
2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2565 SourceRange PrevAllocatorRange =
2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2568 << (Allocator ? 1 : 0) << AllocatorStream.str()
2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2570 << AllocatorRange;
2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2572 << PrevAllocatorRange;
2573 return true;
2574 }
2575 return false;
2576}
2577
2578static void
2579applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2581 Expr *Allocator, SourceRange SR) {
2582 if (VD->hasAttr<OMPAllocateDeclAttr>())
2583 return;
2584 if (Allocator &&
2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2586 Allocator->isInstantiationDependent() ||
2587 Allocator->containsUnexpandedParameterPack()))
2588 return;
2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2590 Allocator, SR);
2591 VD->addAttr(A);
2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
2593 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2594}
2595
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002596Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2597 SourceLocation Loc, ArrayRef<Expr *> VarList,
2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2599 assert(Clauses.size() <= 1 && "Expected at most one clause.");
2600 Expr *Allocator = nullptr;
Alexey Bataev2213dd62019-03-22 14:41:39 +00002601 if (Clauses.empty()) {
Alexey Bataevf4936072019-03-22 15:32:02 +00002602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2603 // allocate directives that appear in a target region must specify an
2604 // allocator clause unless a requires directive with the dynamic_allocators
2605 // clause is present in the same compilation unit.
Alexey Bataev318f431b2019-03-22 15:25:12 +00002606 if (LangOpts.OpenMPIsDevice &&
2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
Alexey Bataev2213dd62019-03-22 14:41:39 +00002608 targetDiag(Loc, diag::err_expected_allocator_clause);
2609 } else {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
Alexey Bataev2213dd62019-03-22 14:41:39 +00002611 }
Alexey Bataev27ef9512019-03-20 20:14:22 +00002612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2613 getAllocatorKind(*this, DSAStack, Allocator);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002614 SmallVector<Expr *, 8> Vars;
2615 for (Expr *RefExpr : VarList) {
2616 auto *DE = cast<DeclRefExpr>(RefExpr);
2617 auto *VD = cast<VarDecl>(DE->getDecl());
2618
2619 // Check if this is a TLS variable or global register.
2620 if (VD->getTLSKind() != VarDecl::TLS_None ||
2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2623 !VD->isLocalVarDecl()))
2624 continue;
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002625
Alexey Bataev282555a2019-03-19 20:33:44 +00002626 // If the used several times in the allocate directive, the same allocator
2627 // must be used.
Alexey Bataeve106f252019-04-01 14:25:31 +00002628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
2629 AllocatorKind, Allocator))
2630 continue;
Alexey Bataev282555a2019-03-19 20:33:44 +00002631
Alexey Bataevd2fc9652019-03-19 18:39:11 +00002632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2633 // If a list item has a static storage type, the allocator expression in the
2634 // allocator clause must be a constant expression that evaluates to one of
2635 // the predefined memory allocator values.
2636 if (Allocator && VD->hasGlobalStorage()) {
Alexey Bataev441510e2019-03-21 19:05:07 +00002637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
Alexey Bataevd2fc9652019-03-19 18:39:11 +00002638 Diag(Allocator->getExprLoc(),
2639 diag::err_omp_expected_predefined_allocator)
2640 << Allocator->getSourceRange();
2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2642 VarDecl::DeclarationOnly;
2643 Diag(VD->getLocation(),
2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2645 << VD;
2646 continue;
2647 }
2648 }
2649
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002650 Vars.push_back(RefExpr);
Alexey Bataeve106f252019-04-01 14:25:31 +00002651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2652 DE->getSourceRange());
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002653 }
2654 if (Vars.empty())
2655 return nullptr;
2656 if (!Owner)
2657 Owner = getCurLexicalContext();
Alexey Bataeve106f252019-04-01 14:25:31 +00002658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
Alexey Bataev25ed0c02019-03-07 17:54:44 +00002659 D->setAccess(AS_public);
2660 Owner->addDecl(D);
2661 return DeclGroupPtrTy::make(DeclGroupRef(D));
2662}
2663
2664Sema::DeclGroupPtrTy
Kelvin Li1408f912018-09-26 04:28:39 +00002665Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2666 ArrayRef<OMPClause *> ClauseList) {
2667 OMPRequiresDecl *D = nullptr;
2668 if (!CurContext->isFileContext()) {
2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2670 } else {
2671 D = CheckOMPRequiresDecl(Loc, ClauseList);
2672 if (D) {
2673 CurContext->addDecl(D);
2674 DSAStack->addRequiresDecl(D);
2675 }
2676 }
2677 return DeclGroupPtrTy::make(DeclGroupRef(D));
2678}
2679
2680OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2681 ArrayRef<OMPClause *> ClauseList) {
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +00002682 /// For target specific clauses, the requires directive cannot be
2683 /// specified after the handling of any of the target regions in the
2684 /// current compilation unit.
2685 ArrayRef<SourceLocation> TargetLocations =
2686 DSAStack->getEncounteredTargetLocs();
2687 if (!TargetLocations.empty()) {
2688 for (const OMPClause *CNew : ClauseList) {
2689 // Check if any of the requires clauses affect target regions.
2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2691 isa<OMPUnifiedAddressClause>(CNew) ||
2692 isa<OMPReverseOffloadClause>(CNew) ||
2693 isa<OMPDynamicAllocatorsClause>(CNew)) {
2694 Diag(Loc, diag::err_omp_target_before_requires)
2695 << getOpenMPClauseName(CNew->getClauseKind());
2696 for (SourceLocation TargetLoc : TargetLocations) {
2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2698 }
2699 }
2700 }
2701 }
2702
Kelvin Li1408f912018-09-26 04:28:39 +00002703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2705 ClauseList);
2706 return nullptr;
2707}
2708
Alexey Bataeve3727102018-04-18 15:57:46 +00002709static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2710 const ValueDecl *D,
2711 const DSAStackTy::DSAVarData &DVar,
Alexey Bataev7ff55242014-06-19 09:13:45 +00002712 bool IsLoopIterVar = false) {
2713 if (DVar.RefExpr) {
2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2715 << getOpenMPClauseName(DVar.CKind);
2716 return;
2717 }
2718 enum {
2719 PDSA_StaticMemberShared,
2720 PDSA_StaticLocalVarShared,
2721 PDSA_LoopIterVarPrivate,
2722 PDSA_LoopIterVarLinear,
2723 PDSA_LoopIterVarLastprivate,
2724 PDSA_ConstVarShared,
2725 PDSA_GlobalVarShared,
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002726 PDSA_TaskVarFirstprivate,
Alexey Bataevbae9a792014-06-27 10:37:06 +00002727 PDSA_LocalVarPrivate,
2728 PDSA_Implicit
2729 } Reason = PDSA_Implicit;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002730 bool ReportHint = false;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002731 auto ReportLoc = D->getLocation();
2732 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev7ff55242014-06-19 09:13:45 +00002733 if (IsLoopIterVar) {
2734 if (DVar.CKind == OMPC_private)
2735 Reason = PDSA_LoopIterVarPrivate;
2736 else if (DVar.CKind == OMPC_lastprivate)
2737 Reason = PDSA_LoopIterVarLastprivate;
2738 else
2739 Reason = PDSA_LoopIterVarLinear;
Alexey Bataev35aaee62016-04-13 13:36:48 +00002740 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2741 DVar.CKind == OMPC_firstprivate) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002742 Reason = PDSA_TaskVarFirstprivate;
2743 ReportLoc = DVar.ImplicitDSALoc;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002744 } else if (VD && VD->isStaticLocal())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002745 Reason = PDSA_StaticLocalVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002746 else if (VD && VD->isStaticDataMember())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002747 Reason = PDSA_StaticMemberShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002748 else if (VD && VD->isFileVarDecl())
Alexey Bataev7ff55242014-06-19 09:13:45 +00002749 Reason = PDSA_GlobalVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002750 else if (D->getType().isConstant(SemaRef.getASTContext()))
Alexey Bataev7ff55242014-06-19 09:13:45 +00002751 Reason = PDSA_ConstVarShared;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
Alexey Bataev7ff55242014-06-19 09:13:45 +00002753 ReportHint = true;
2754 Reason = PDSA_LocalVarPrivate;
2755 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002756 if (Reason != PDSA_Implicit) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
Alexey Bataevbae9a792014-06-27 10:37:06 +00002758 << Reason << ReportHint
2759 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2760 } else if (DVar.ImplicitDSALoc.isValid()) {
2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2762 << getOpenMPClauseName(DVar.CKind);
2763 }
Alexey Bataev7ff55242014-06-19 09:13:45 +00002764}
2765
Alexey Bataev758e55e2013-09-06 18:03:48 +00002766namespace {
Alexey Bataeve3727102018-04-18 15:57:46 +00002767class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
Alexey Bataev758e55e2013-09-06 18:03:48 +00002768 DSAStackTy *Stack;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002769 Sema &SemaRef;
Alexey Bataeve3727102018-04-18 15:57:46 +00002770 bool ErrorFound = false;
2771 CapturedStmt *CS = nullptr;
2772 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2773 llvm::SmallVector<Expr *, 4> ImplicitMap;
2774 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2775 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
Alexey Bataeved09d242014-05-28 05:53:51 +00002776
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00002777 void VisitSubCaptures(OMPExecutableDirective *S) {
2778 // Check implicitly captured variables.
2779 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2780 return;
Alexey Bataev1242d8f2019-06-28 20:45:14 +00002781 visitSubCaptures(S->getInnermostCapturedStmt());
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00002782 }
2783
Alexey Bataev758e55e2013-09-06 18:03:48 +00002784public:
2785 void VisitDeclRefExpr(DeclRefExpr *E) {
Alexey Bataev07b79c22016-04-29 09:56:11 +00002786 if (E->isTypeDependent() || E->isValueDependent() ||
2787 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2788 return;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002789 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
Alexey Bataev412254a2019-05-09 18:44:53 +00002790 // Check the datasharing rules for the expressions in the clauses.
2791 if (!CS) {
2792 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2793 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2794 Visit(CED->getInit());
2795 return;
2796 }
Alexey Bataev1242d8f2019-06-28 20:45:14 +00002797 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2798 // Do not analyze internal variables and do not enclose them into
2799 // implicit clauses.
2800 return;
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00002801 VD = VD->getCanonicalDecl();
Alexey Bataev758e55e2013-09-06 18:03:48 +00002802 // Skip internally declared variables.
Alexey Bataev412254a2019-05-09 18:44:53 +00002803 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
Alexey Bataeved09d242014-05-28 05:53:51 +00002804 return;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002805
Alexey Bataeve3727102018-04-18 15:57:46 +00002806 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002807 // Check if the variable has explicit DSA set and stop analysis if it so.
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00002808 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
David Majnemer9d168222016-08-05 17:44:54 +00002809 return;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002810
Alexey Bataevafe50572017-10-06 17:00:28 +00002811 // Skip internally declared static variables.
Alexey Bataev92327c52018-03-26 16:40:55 +00002812 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002813 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataev412254a2019-05-09 18:44:53 +00002814 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
Gheorghe-Teodor Bercea5254f0a2019-06-14 17:58:26 +00002815 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
2816 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
Alexey Bataevafe50572017-10-06 17:00:28 +00002817 return;
2818
Alexey Bataeve3727102018-04-18 15:57:46 +00002819 SourceLocation ELoc = E->getExprLoc();
2820 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
Alexey Bataev758e55e2013-09-06 18:03:48 +00002821 // The default(none) clause requires that each variable that is referenced
2822 // in the construct, and does not have a predetermined data-sharing
2823 // attribute, must have its data-sharing attribute explicitly determined
2824 // by being listed in a data-sharing attribute clause.
2825 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
Alexey Bataev7e6803e2019-01-09 15:58:05 +00002826 isImplicitOrExplicitTaskingRegion(DKind) &&
Alexey Bataev4acb8592014-07-07 13:01:15 +00002827 VarsWithInheritedDSA.count(VD) == 0) {
2828 VarsWithInheritedDSA[VD] = E;
Alexey Bataev758e55e2013-09-06 18:03:48 +00002829 return;
2830 }
2831
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002832 if (isOpenMPTargetExecutionDirective(DKind) &&
2833 !Stack->isLoopControlVariable(VD).first) {
2834 if (!Stack->checkMappableExprComponentListsForDecl(
2835 VD, /*CurrentRegionOnly=*/true,
2836 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2837 StackComponents,
2838 OpenMPClauseKind) {
2839 // Variable is used if it has been marked as an array, array
2840 // section or the variable iself.
2841 return StackComponents.size() == 1 ||
2842 std::all_of(
2843 std::next(StackComponents.rbegin()),
2844 StackComponents.rend(),
2845 [](const OMPClauseMappableExprCommon::
2846 MappableComponent &MC) {
2847 return MC.getAssociatedDeclaration() ==
2848 nullptr &&
2849 (isa<OMPArraySectionExpr>(
2850 MC.getAssociatedExpression()) ||
2851 isa<ArraySubscriptExpr>(
2852 MC.getAssociatedExpression()));
2853 });
2854 })) {
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002855 bool IsFirstprivate = false;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002856 // By default lambdas are captured as firstprivates.
2857 if (const auto *RD =
2858 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002859 IsFirstprivate = RD->isLambda();
2860 IsFirstprivate =
2861 IsFirstprivate ||
2862 (VD->getType().getNonReferenceType()->isScalarType() &&
Alexey Bataev92327c52018-03-26 16:40:55 +00002863 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
Alexey Bataev2fd0cb22017-10-05 17:51:39 +00002864 if (IsFirstprivate)
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002865 ImplicitFirstprivate.emplace_back(E);
2866 else
2867 ImplicitMap.emplace_back(E);
2868 return;
2869 }
2870 }
2871
Alexey Bataev758e55e2013-09-06 18:03:48 +00002872 // OpenMP [2.9.3.6, Restrictions, p.2]
2873 // A list item that appears in a reduction clause of the innermost
2874 // enclosing worksharing or parallel construct may not be accessed in an
2875 // explicit task.
Alexey Bataev7ace49d2016-05-17 08:55:33 +00002876 DVar = Stack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00002877 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2878 [](OpenMPDirectiveKind K) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +00002879 return isOpenMPParallelDirective(K) ||
2880 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2881 },
Alexey Bataeveffbdf12017-07-21 17:24:30 +00002882 /*FromParent=*/true);
Alexey Bataev35aaee62016-04-13 13:36:48 +00002883 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
Alexey Bataevc5e02582014-06-16 07:08:35 +00002884 ErrorFound = true;
Alexey Bataev7ff55242014-06-19 09:13:45 +00002885 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
Alexey Bataeve3727102018-04-18 15:57:46 +00002886 reportOriginalDsa(SemaRef, Stack, VD, DVar);
Alexey Bataevc5e02582014-06-16 07:08:35 +00002887 return;
2888 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002889
2890 // Define implicit data-sharing attributes for task.
Alexey Bataeve3727102018-04-18 15:57:46 +00002891 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
Alexey Bataev35aaee62016-04-13 13:36:48 +00002892 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
Alexey Bataeva495c642019-03-11 19:51:42 +00002893 !Stack->isLoopControlVariable(VD).first) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002894 ImplicitFirstprivate.push_back(E);
Alexey Bataeva495c642019-03-11 19:51:42 +00002895 return;
2896 }
2897
2898 // Store implicitly used globals with declare target link for parent
2899 // target.
2900 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
2901 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2902 Stack->addToParentTargetRegionLinkGlobals(E);
2903 return;
2904 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00002905 }
2906 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002907 void VisitMemberExpr(MemberExpr *E) {
Alexey Bataev07b79c22016-04-29 09:56:11 +00002908 if (E->isTypeDependent() || E->isValueDependent() ||
2909 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2910 return;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002911 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002912 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
Patrick Lystere13b1e32019-01-02 19:28:48 +00002913 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002914 if (!FD)
2915 return;
Alexey Bataeve3727102018-04-18 15:57:46 +00002916 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002917 // Check if the variable has explicit DSA set and stop analysis if it
2918 // so.
2919 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2920 return;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002921
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002922 if (isOpenMPTargetExecutionDirective(DKind) &&
2923 !Stack->isLoopControlVariable(FD).first &&
2924 !Stack->checkMappableExprComponentListsForDecl(
2925 FD, /*CurrentRegionOnly=*/true,
2926 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2927 StackComponents,
2928 OpenMPClauseKind) {
2929 return isa<CXXThisExpr>(
2930 cast<MemberExpr>(
2931 StackComponents.back().getAssociatedExpression())
2932 ->getBase()
2933 ->IgnoreParens());
2934 })) {
2935 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2936 // A bit-field cannot appear in a map clause.
2937 //
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002938 if (FD->isBitField())
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002939 return;
Patrick Lystere13b1e32019-01-02 19:28:48 +00002940
2941 // Check to see if the member expression is referencing a class that
2942 // has already been explicitly mapped
2943 if (Stack->isClassPreviouslyMapped(TE->getType()))
2944 return;
2945
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002946 ImplicitMap.emplace_back(E);
2947 return;
2948 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00002949
Alexey Bataeve3727102018-04-18 15:57:46 +00002950 SourceLocation ELoc = E->getExprLoc();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002951 // OpenMP [2.9.3.6, Restrictions, p.2]
2952 // A list item that appears in a reduction clause of the innermost
2953 // enclosing worksharing or parallel construct may not be accessed in
2954 // an explicit task.
2955 DVar = Stack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +00002956 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2957 [](OpenMPDirectiveKind K) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002958 return isOpenMPParallelDirective(K) ||
2959 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2960 },
2961 /*FromParent=*/true);
2962 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2963 ErrorFound = true;
2964 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
Alexey Bataeve3727102018-04-18 15:57:46 +00002965 reportOriginalDsa(SemaRef, Stack, FD, DVar);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002966 return;
2967 }
2968
2969 // Define implicit data-sharing attributes for task.
Alexey Bataeve3727102018-04-18 15:57:46 +00002970 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002971 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
Alexey Bataevb40e05202018-10-24 18:53:12 +00002972 !Stack->isLoopControlVariable(FD).first) {
2973 // Check if there is a captured expression for the current field in the
2974 // region. Do not mark it as firstprivate unless there is no captured
2975 // expression.
2976 // TODO: try to make it firstprivate.
2977 if (DVar.CKind != OMPC_unknown)
2978 ImplicitFirstprivate.push_back(E);
2979 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002980 return;
2981 }
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002982 if (isOpenMPTargetExecutionDirective(DKind)) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002983 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
Alexey Bataeve3727102018-04-18 15:57:46 +00002984 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
Alexey Bataevb7a9b742017-12-05 19:20:09 +00002985 /*NoDiagnose=*/true))
Alexey Bataev27041fa2017-12-05 15:22:49 +00002986 return;
Alexey Bataeve3727102018-04-18 15:57:46 +00002987 const auto *VD = cast<ValueDecl>(
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002988 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2989 if (!Stack->checkMappableExprComponentListsForDecl(
2990 VD, /*CurrentRegionOnly=*/true,
2991 [&CurComponents](
2992 OMPClauseMappableExprCommon::MappableExprComponentListRef
2993 StackComponents,
2994 OpenMPClauseKind) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002995 auto CCI = CurComponents.rbegin();
Alexey Bataev5ec38932017-09-26 16:19:04 +00002996 auto CCE = CurComponents.rend();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00002997 for (const auto &SC : llvm::reverse(StackComponents)) {
2998 // Do both expressions have the same kind?
2999 if (CCI->getAssociatedExpression()->getStmtClass() !=
3000 SC.getAssociatedExpression()->getStmtClass())
3001 if (!(isa<OMPArraySectionExpr>(
3002 SC.getAssociatedExpression()) &&
3003 isa<ArraySubscriptExpr>(
3004 CCI->getAssociatedExpression())))
3005 return false;
3006
Alexey Bataeve3727102018-04-18 15:57:46 +00003007 const Decl *CCD = CCI->getAssociatedDeclaration();
3008 const Decl *SCD = SC.getAssociatedDeclaration();
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003009 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3010 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3011 if (SCD != CCD)
3012 return false;
3013 std::advance(CCI, 1);
Alexey Bataev5ec38932017-09-26 16:19:04 +00003014 if (CCI == CCE)
3015 break;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003016 }
3017 return true;
3018 })) {
3019 Visit(E->getBase());
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00003020 }
Alexey Bataeve3727102018-04-18 15:57:46 +00003021 } else {
Alexey Bataev7fcacd82016-11-28 15:55:15 +00003022 Visit(E->getBase());
Alexey Bataeve3727102018-04-18 15:57:46 +00003023 }
Alexey Bataev48c0bfb2016-01-20 09:07:54 +00003024 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00003025 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003026 for (OMPClause *C : S->clauses()) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003027 // Skip analysis of arguments of implicitly defined firstprivate clause
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003028 // for task|target directives.
3029 // Skip analysis of arguments of implicitly defined map clause for target
3030 // directives.
3031 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3032 C->isImplicit())) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003033 for (Stmt *CC : C->children()) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003034 if (CC)
3035 Visit(CC);
3036 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003037 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003038 }
Alexey Bataevf07946e2018-10-29 20:17:42 +00003039 // Check implicitly captured variables.
3040 VisitSubCaptures(S);
Alexey Bataev758e55e2013-09-06 18:03:48 +00003041 }
3042 void VisitStmt(Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003043 for (Stmt *C : S->children()) {
Alexey Bataev8fc7b5f2018-10-25 15:35:27 +00003044 if (C) {
Joel E. Denny0fdf5a92018-12-19 15:59:47 +00003045 // Check implicitly captured variables in the task-based directives to
3046 // check if they must be firstprivatized.
3047 Visit(C);
Alexey Bataev8fc7b5f2018-10-25 15:35:27 +00003048 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003049 }
Alexey Bataeved09d242014-05-28 05:53:51 +00003050 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00003051
Alexey Bataev1242d8f2019-06-28 20:45:14 +00003052 void visitSubCaptures(CapturedStmt *S) {
3053 for (const CapturedStmt::Capture &Cap : S->captures()) {
3054 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3055 continue;
3056 VarDecl *VD = Cap.getCapturedVar();
3057 // Do not try to map the variable if it or its sub-component was mapped
3058 // already.
3059 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3060 Stack->checkMappableExprComponentListsForDecl(
3061 VD, /*CurrentRegionOnly=*/true,
3062 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3063 OpenMPClauseKind) { return true; }))
3064 continue;
3065 DeclRefExpr *DRE = buildDeclRefExpr(
3066 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3067 Cap.getLocation(), /*RefersToCapture=*/true);
3068 Visit(DRE);
3069 }
3070 }
Alexey Bataeve3727102018-04-18 15:57:46 +00003071 bool isErrorFound() const { return ErrorFound; }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00003072 ArrayRef<Expr *> getImplicitFirstprivate() const {
3073 return ImplicitFirstprivate;
3074 }
3075 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
Alexey Bataeve3727102018-04-18 15:57:46 +00003076 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
Alexey Bataev4acb8592014-07-07 13:01:15 +00003077 return VarsWithInheritedDSA;
3078 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00003079
Alexey Bataev7ff55242014-06-19 09:13:45 +00003080 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
Alexey Bataeva495c642019-03-11 19:51:42 +00003081 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3082 // Process declare target link variables for the target directives.
3083 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3084 for (DeclRefExpr *E : Stack->getLinkGlobals())
3085 Visit(E);
3086 }
3087 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00003088};
Alexey Bataeved09d242014-05-28 05:53:51 +00003089} // namespace
Alexey Bataev758e55e2013-09-06 18:03:48 +00003090
Alexey Bataevbae9a792014-06-27 10:37:06 +00003091void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
Alexey Bataev9959db52014-05-06 10:08:46 +00003092 switch (DKind) {
Kelvin Li70a12c52016-07-13 21:51:49 +00003093 case OMPD_parallel:
3094 case OMPD_parallel_for:
3095 case OMPD_parallel_for_simd:
3096 case OMPD_parallel_sections:
Carlo Bertolliba1487b2017-10-04 14:12:09 +00003097 case OMPD_teams:
Alexey Bataev999277a2017-12-06 14:31:09 +00003098 case OMPD_teams_distribute:
3099 case OMPD_teams_distribute_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003100 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Alexey Bataev2377fe92015-09-10 08:12:02 +00003101 QualType KmpInt32PtrTy =
3102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
Alexey Bataevdf9b1592014-06-25 04:09:13 +00003103 Sema::CapturedParamNameType Params[] = {
Alexey Bataevf29276e2014-06-18 04:14:57 +00003104 std::make_pair(".global_tid.", KmpInt32PtrTy),
3105 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3106 std::make_pair(StringRef(), QualType()) // __context with shared vars
Alexey Bataev9959db52014-05-06 10:08:46 +00003107 };
Alexey Bataevbae9a792014-06-27 10:37:06 +00003108 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3109 Params);
Alexey Bataev9959db52014-05-06 10:08:46 +00003110 break;
3111 }
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003112 case OMPD_target_teams:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00003113 case OMPD_target_parallel:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00003114 case OMPD_target_parallel_for:
Alexey Bataevdfa430f2017-12-08 15:03:50 +00003115 case OMPD_target_parallel_for_simd:
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00003116 case OMPD_target_teams_distribute:
3117 case OMPD_target_teams_distribute_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003118 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3119 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3120 QualType KmpInt32PtrTy =
3121 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3122 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00003123 FunctionProtoType::ExtProtoInfo EPI;
3124 EPI.Variadic = true;
3125 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3126 Sema::CapturedParamNameType Params[] = {
3127 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003128 std::make_pair(".part_id.", KmpInt32PtrTy),
3129 std::make_pair(".privates.", VoidPtrTy),
3130 std::make_pair(
3131 ".copy_fn.",
3132 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00003133 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3134 std::make_pair(StringRef(), QualType()) // __context with shared vars
3135 };
3136 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003137 Params, /*OpenMPCaptureLevel=*/0);
Alexey Bataev0c869ef2018-01-16 15:57:07 +00003138 // Mark this captured region as inlined, because we don't use outlined
3139 // function directly.
3140 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3141 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003142 Context, {}, AttributeCommonInfo::AS_Keyword,
3143 AlwaysInlineAttr::Keyword_forceinline));
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003144 Sema::CapturedParamNameType ParamsTarget[] = {
3145 std::make_pair(StringRef(), QualType()) // __context with shared vars
3146 };
3147 // Start a captured region for 'target' with no implicit parameters.
3148 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003149 ParamsTarget, /*OpenMPCaptureLevel=*/1);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003150 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003151 std::make_pair(".global_tid.", KmpInt32PtrTy),
3152 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3153 std::make_pair(StringRef(), QualType()) // __context with shared vars
3154 };
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00003155 // Start a captured region for 'teams' or 'parallel'. Both regions have
3156 // the same implicit parameters.
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003157 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003158 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003159 break;
3160 }
Alexey Bataev8451efa2018-01-15 19:06:12 +00003161 case OMPD_target:
3162 case OMPD_target_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003163 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3164 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3165 QualType KmpInt32PtrTy =
3166 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3167 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00003168 FunctionProtoType::ExtProtoInfo EPI;
3169 EPI.Variadic = true;
3170 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3171 Sema::CapturedParamNameType Params[] = {
3172 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003173 std::make_pair(".part_id.", KmpInt32PtrTy),
3174 std::make_pair(".privates.", VoidPtrTy),
3175 std::make_pair(
3176 ".copy_fn.",
3177 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00003178 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3179 std::make_pair(StringRef(), QualType()) // __context with shared vars
3180 };
3181 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003182 Params, /*OpenMPCaptureLevel=*/0);
Alexey Bataev8451efa2018-01-15 19:06:12 +00003183 // Mark this captured region as inlined, because we don't use outlined
3184 // function directly.
3185 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3186 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003187 Context, {}, AttributeCommonInfo::AS_Keyword,
3188 AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev8451efa2018-01-15 19:06:12 +00003189 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003190 std::make_pair(StringRef(), QualType()),
3191 /*OpenMPCaptureLevel=*/1);
Alexey Bataev8451efa2018-01-15 19:06:12 +00003192 break;
3193 }
Kelvin Li70a12c52016-07-13 21:51:49 +00003194 case OMPD_simd:
3195 case OMPD_for:
3196 case OMPD_for_simd:
3197 case OMPD_sections:
3198 case OMPD_section:
3199 case OMPD_single:
3200 case OMPD_master:
3201 case OMPD_critical:
Kelvin Lia579b912016-07-14 02:54:56 +00003202 case OMPD_taskgroup:
3203 case OMPD_distribute:
Alexey Bataev46506272017-12-05 17:41:34 +00003204 case OMPD_distribute_simd:
Kelvin Li70a12c52016-07-13 21:51:49 +00003205 case OMPD_ordered:
3206 case OMPD_atomic:
Alexey Bataev8451efa2018-01-15 19:06:12 +00003207 case OMPD_target_data: {
Alexey Bataevdf9b1592014-06-25 04:09:13 +00003208 Sema::CapturedParamNameType Params[] = {
Alexey Bataevf29276e2014-06-18 04:14:57 +00003209 std::make_pair(StringRef(), QualType()) // __context with shared vars
3210 };
Alexey Bataevbae9a792014-06-27 10:37:06 +00003211 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3212 Params);
Alexey Bataevf29276e2014-06-18 04:14:57 +00003213 break;
3214 }
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003215 case OMPD_task: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003216 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3217 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3218 QualType KmpInt32PtrTy =
3219 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3220 QualType Args[] = {VoidPtrTy};
Alexey Bataev3ae88e22015-05-22 08:56:35 +00003221 FunctionProtoType::ExtProtoInfo EPI;
3222 EPI.Variadic = true;
3223 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003224 Sema::CapturedParamNameType Params[] = {
Alexey Bataev62b63b12015-03-10 07:28:44 +00003225 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003226 std::make_pair(".part_id.", KmpInt32PtrTy),
3227 std::make_pair(".privates.", VoidPtrTy),
3228 std::make_pair(
3229 ".copy_fn.",
3230 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev48591dd2016-04-20 04:01:36 +00003231 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003232 std::make_pair(StringRef(), QualType()) // __context with shared vars
3233 };
3234 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3235 Params);
Alexey Bataev62b63b12015-03-10 07:28:44 +00003236 // Mark this captured region as inlined, because we don't use outlined
3237 // function directly.
3238 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3239 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003240 Context, {}, AttributeCommonInfo::AS_Keyword,
3241 AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00003242 break;
3243 }
Alexey Bataev1e73ef32016-04-28 12:14:51 +00003244 case OMPD_taskloop:
Alexey Bataev60e51c42019-10-10 20:13:02 +00003245 case OMPD_taskloop_simd:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00003246 case OMPD_master_taskloop:
3247 case OMPD_master_taskloop_simd: {
Alexey Bataev7292c292016-04-25 12:22:29 +00003248 QualType KmpInt32Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003249 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3250 .withConst();
Alexey Bataev7292c292016-04-25 12:22:29 +00003251 QualType KmpUInt64Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003252 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3253 .withConst();
Alexey Bataev7292c292016-04-25 12:22:29 +00003254 QualType KmpInt64Ty =
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003255 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3256 .withConst();
3257 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3258 QualType KmpInt32PtrTy =
3259 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3260 QualType Args[] = {VoidPtrTy};
Alexey Bataev7292c292016-04-25 12:22:29 +00003261 FunctionProtoType::ExtProtoInfo EPI;
3262 EPI.Variadic = true;
3263 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
Alexey Bataev49f6e782015-12-01 04:18:41 +00003264 Sema::CapturedParamNameType Params[] = {
Alexey Bataev7292c292016-04-25 12:22:29 +00003265 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003266 std::make_pair(".part_id.", KmpInt32PtrTy),
3267 std::make_pair(".privates.", VoidPtrTy),
Alexey Bataev7292c292016-04-25 12:22:29 +00003268 std::make_pair(
3269 ".copy_fn.",
3270 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3271 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3272 std::make_pair(".lb.", KmpUInt64Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003273 std::make_pair(".ub.", KmpUInt64Ty),
3274 std::make_pair(".st.", KmpInt64Ty),
Alexey Bataev7292c292016-04-25 12:22:29 +00003275 std::make_pair(".liter.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003276 std::make_pair(".reductions.", VoidPtrTy),
Alexey Bataev49f6e782015-12-01 04:18:41 +00003277 std::make_pair(StringRef(), QualType()) // __context with shared vars
3278 };
3279 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3280 Params);
Alexey Bataev7292c292016-04-25 12:22:29 +00003281 // Mark this captured region as inlined, because we don't use outlined
3282 // function directly.
3283 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3284 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003285 Context, {}, AttributeCommonInfo::AS_Keyword,
3286 AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev49f6e782015-12-01 04:18:41 +00003287 break;
3288 }
Alexey Bataev5bbcead2019-10-14 17:17:41 +00003289 case OMPD_parallel_master_taskloop: {
3290 QualType KmpInt32Ty =
3291 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3292 .withConst();
3293 QualType KmpUInt64Ty =
3294 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3295 .withConst();
3296 QualType KmpInt64Ty =
3297 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3298 .withConst();
3299 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3300 QualType KmpInt32PtrTy =
3301 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3302 Sema::CapturedParamNameType ParamsParallel[] = {
3303 std::make_pair(".global_tid.", KmpInt32PtrTy),
3304 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3305 std::make_pair(StringRef(), QualType()) // __context with shared vars
3306 };
3307 // Start a captured region for 'parallel'.
3308 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3309 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3310 QualType Args[] = {VoidPtrTy};
3311 FunctionProtoType::ExtProtoInfo EPI;
3312 EPI.Variadic = true;
3313 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3314 Sema::CapturedParamNameType Params[] = {
3315 std::make_pair(".global_tid.", KmpInt32Ty),
3316 std::make_pair(".part_id.", KmpInt32PtrTy),
3317 std::make_pair(".privates.", VoidPtrTy),
3318 std::make_pair(
3319 ".copy_fn.",
3320 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3321 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3322 std::make_pair(".lb.", KmpUInt64Ty),
3323 std::make_pair(".ub.", KmpUInt64Ty),
3324 std::make_pair(".st.", KmpInt64Ty),
3325 std::make_pair(".liter.", KmpInt32Ty),
3326 std::make_pair(".reductions.", VoidPtrTy),
3327 std::make_pair(StringRef(), QualType()) // __context with shared vars
3328 };
3329 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3330 Params, /*OpenMPCaptureLevel=*/2);
3331 // Mark this captured region as inlined, because we don't use outlined
3332 // function directly.
3333 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3334 AlwaysInlineAttr::CreateImplicit(
3335 Context, {}, AttributeCommonInfo::AS_Keyword,
3336 AlwaysInlineAttr::Keyword_forceinline));
3337 break;
3338 }
Kelvin Li4a39add2016-07-05 05:00:15 +00003339 case OMPD_distribute_parallel_for_simd:
Alexey Bataev647dd842018-01-15 20:59:40 +00003340 case OMPD_distribute_parallel_for: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003341 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli9925f152016-06-27 14:55:37 +00003342 QualType KmpInt32PtrTy =
3343 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3344 Sema::CapturedParamNameType Params[] = {
3345 std::make_pair(".global_tid.", KmpInt32PtrTy),
3346 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003347 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3348 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli9925f152016-06-27 14:55:37 +00003349 std::make_pair(StringRef(), QualType()) // __context with shared vars
3350 };
3351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3352 Params);
3353 break;
3354 }
Alexey Bataev647dd842018-01-15 20:59:40 +00003355 case OMPD_target_teams_distribute_parallel_for:
3356 case OMPD_target_teams_distribute_parallel_for_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli52978c32018-01-03 21:12:44 +00003358 QualType KmpInt32PtrTy =
3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003360 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
Carlo Bertolli52978c32018-01-03 21:12:44 +00003361
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003362 QualType Args[] = {VoidPtrTy};
Alexey Bataev8451efa2018-01-15 19:06:12 +00003363 FunctionProtoType::ExtProtoInfo EPI;
3364 EPI.Variadic = true;
3365 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3366 Sema::CapturedParamNameType Params[] = {
3367 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003368 std::make_pair(".part_id.", KmpInt32PtrTy),
3369 std::make_pair(".privates.", VoidPtrTy),
3370 std::make_pair(
3371 ".copy_fn.",
3372 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev8451efa2018-01-15 19:06:12 +00003373 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3374 std::make_pair(StringRef(), QualType()) // __context with shared vars
3375 };
3376 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003377 Params, /*OpenMPCaptureLevel=*/0);
Alexey Bataev9f9fb0b2018-01-16 19:02:33 +00003378 // Mark this captured region as inlined, because we don't use outlined
3379 // function directly.
3380 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3381 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003382 Context, {}, AttributeCommonInfo::AS_Keyword,
3383 AlwaysInlineAttr::Keyword_forceinline));
Carlo Bertolli52978c32018-01-03 21:12:44 +00003384 Sema::CapturedParamNameType ParamsTarget[] = {
3385 std::make_pair(StringRef(), QualType()) // __context with shared vars
3386 };
3387 // Start a captured region for 'target' with no implicit parameters.
3388 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003389 ParamsTarget, /*OpenMPCaptureLevel=*/1);
Carlo Bertolli52978c32018-01-03 21:12:44 +00003390
3391 Sema::CapturedParamNameType ParamsTeams[] = {
3392 std::make_pair(".global_tid.", KmpInt32PtrTy),
3393 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3394 std::make_pair(StringRef(), QualType()) // __context with shared vars
3395 };
3396 // Start a captured region for 'target' with no implicit parameters.
3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003398 ParamsTeams, /*OpenMPCaptureLevel=*/2);
Carlo Bertolli52978c32018-01-03 21:12:44 +00003399
3400 Sema::CapturedParamNameType ParamsParallel[] = {
3401 std::make_pair(".global_tid.", KmpInt32PtrTy),
3402 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003403 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3404 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli52978c32018-01-03 21:12:44 +00003405 std::make_pair(StringRef(), QualType()) // __context with shared vars
3406 };
3407 // Start a captured region for 'teams' or 'parallel'. Both regions have
3408 // the same implicit parameters.
3409 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003410 ParamsParallel, /*OpenMPCaptureLevel=*/3);
Carlo Bertolli52978c32018-01-03 21:12:44 +00003411 break;
3412 }
3413
Alexey Bataev46506272017-12-05 17:41:34 +00003414 case OMPD_teams_distribute_parallel_for:
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00003415 case OMPD_teams_distribute_parallel_for_simd: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003416 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
Carlo Bertolli62fae152017-11-20 20:46:39 +00003417 QualType KmpInt32PtrTy =
3418 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3419
3420 Sema::CapturedParamNameType ParamsTeams[] = {
3421 std::make_pair(".global_tid.", KmpInt32PtrTy),
3422 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3423 std::make_pair(StringRef(), QualType()) // __context with shared vars
3424 };
3425 // Start a captured region for 'target' with no implicit parameters.
3426 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003427 ParamsTeams, /*OpenMPCaptureLevel=*/0);
Carlo Bertolli62fae152017-11-20 20:46:39 +00003428
3429 Sema::CapturedParamNameType ParamsParallel[] = {
3430 std::make_pair(".global_tid.", KmpInt32PtrTy),
3431 std::make_pair(".bound_tid.", KmpInt32PtrTy),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003432 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3433 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
Carlo Bertolli62fae152017-11-20 20:46:39 +00003434 std::make_pair(StringRef(), QualType()) // __context with shared vars
3435 };
3436 // Start a captured region for 'teams' or 'parallel'. Both regions have
3437 // the same implicit parameters.
3438 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
Joel E. Denny7d5bc552019-08-22 03:34:30 +00003439 ParamsParallel, /*OpenMPCaptureLevel=*/1);
Carlo Bertolli62fae152017-11-20 20:46:39 +00003440 break;
3441 }
Alexey Bataev7828b252017-11-21 17:08:48 +00003442 case OMPD_target_update:
3443 case OMPD_target_enter_data:
3444 case OMPD_target_exit_data: {
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003445 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3446 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3447 QualType KmpInt32PtrTy =
3448 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3449 QualType Args[] = {VoidPtrTy};
Alexey Bataev7828b252017-11-21 17:08:48 +00003450 FunctionProtoType::ExtProtoInfo EPI;
3451 EPI.Variadic = true;
3452 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3453 Sema::CapturedParamNameType Params[] = {
3454 std::make_pair(".global_tid.", KmpInt32Ty),
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003455 std::make_pair(".part_id.", KmpInt32PtrTy),
3456 std::make_pair(".privates.", VoidPtrTy),
3457 std::make_pair(
3458 ".copy_fn.",
3459 Context.getPointerType(CopyFnType).withConst().withRestrict()),
Alexey Bataev7828b252017-11-21 17:08:48 +00003460 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3461 std::make_pair(StringRef(), QualType()) // __context with shared vars
3462 };
3463 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3464 Params);
3465 // Mark this captured region as inlined, because we don't use outlined
3466 // function directly.
3467 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3468 AlwaysInlineAttr::CreateImplicit(
Erich Keane6a24e802019-09-13 17:39:31 +00003469 Context, {}, AttributeCommonInfo::AS_Keyword,
3470 AlwaysInlineAttr::Keyword_forceinline));
Alexey Bataev7828b252017-11-21 17:08:48 +00003471 break;
3472 }
Alexey Bataev9959db52014-05-06 10:08:46 +00003473 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00003474 case OMPD_allocate:
Alexey Bataevee9af452014-11-21 11:33:46 +00003475 case OMPD_taskyield:
3476 case OMPD_barrier:
3477 case OMPD_taskwait:
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003478 case OMPD_cancellation_point:
Alexey Bataev80909872015-07-02 11:25:17 +00003479 case OMPD_cancel:
Alexey Bataevee9af452014-11-21 11:33:46 +00003480 case OMPD_flush:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00003481 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00003482 case OMPD_declare_mapper:
Alexey Bataev587e1de2016-03-30 10:43:55 +00003483 case OMPD_declare_simd:
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00003484 case OMPD_declare_target:
3485 case OMPD_end_declare_target:
Kelvin Li1408f912018-09-26 04:28:39 +00003486 case OMPD_requires:
Alexey Bataevd158cf62019-09-13 20:18:17 +00003487 case OMPD_declare_variant:
Alexey Bataev9959db52014-05-06 10:08:46 +00003488 llvm_unreachable("OpenMP Directive is not allowed");
3489 case OMPD_unknown:
Alexey Bataev9959db52014-05-06 10:08:46 +00003490 llvm_unreachable("Unknown OpenMP directive");
3491 }
3492}
3493
Alexey Bataev0e100032019-10-14 16:44:01 +00003494int Sema::getNumberOfConstructScopes(unsigned Level) const {
3495 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
3496}
3497
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003498int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3499 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3500 getOpenMPCaptureRegions(CaptureRegions, DKind);
3501 return CaptureRegions.size();
3502}
3503
Alexey Bataev3392d762016-02-16 11:18:12 +00003504static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
Alexey Bataev5a3af132016-03-29 08:58:54 +00003505 Expr *CaptureExpr, bool WithInit,
3506 bool AsExpression) {
Alexey Bataev2bbf7212016-03-03 03:52:24 +00003507 assert(CaptureExpr);
Alexey Bataev4244be22016-02-11 05:35:55 +00003508 ASTContext &C = S.getASTContext();
Alexey Bataev5a3af132016-03-29 08:58:54 +00003509 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
Alexey Bataev4244be22016-02-11 05:35:55 +00003510 QualType Ty = Init->getType();
3511 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003512 if (S.getLangOpts().CPlusPlus) {
Alexey Bataev4244be22016-02-11 05:35:55 +00003513 Ty = C.getLValueReferenceType(Ty);
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003514 } else {
Alexey Bataev4244be22016-02-11 05:35:55 +00003515 Ty = C.getPointerType(Ty);
3516 ExprResult Res =
3517 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3518 if (!Res.isUsable())
3519 return nullptr;
3520 Init = Res.get();
3521 }
Alexey Bataev61205072016-03-02 04:57:40 +00003522 WithInit = true;
Alexey Bataev4244be22016-02-11 05:35:55 +00003523 }
Alexey Bataeva7206b92016-12-20 16:51:02 +00003524 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003525 CaptureExpr->getBeginLoc());
Alexey Bataev2bbf7212016-03-03 03:52:24 +00003526 if (!WithInit)
Alexey Bataeve3727102018-04-18 15:57:46 +00003527 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
Alexey Bataev4244be22016-02-11 05:35:55 +00003528 S.CurContext->addHiddenDecl(CED);
Richard Smith3beb7c62017-01-12 02:27:38 +00003529 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
Alexey Bataev3392d762016-02-16 11:18:12 +00003530 return CED;
3531}
3532
Alexey Bataev61205072016-03-02 04:57:40 +00003533static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3534 bool WithInit) {
Alexey Bataevb7a34b62016-02-25 03:59:29 +00003535 OMPCapturedExprDecl *CD;
Alexey Bataeve3727102018-04-18 15:57:46 +00003536 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
Alexey Bataevb7a34b62016-02-25 03:59:29 +00003537 CD = cast<OMPCapturedExprDecl>(VD);
Alexey Bataeve3727102018-04-18 15:57:46 +00003538 else
Alexey Bataev5a3af132016-03-29 08:58:54 +00003539 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3540 /*AsExpression=*/false);
Alexey Bataev3392d762016-02-16 11:18:12 +00003541 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
Alexey Bataev1efd1662016-03-29 10:59:56 +00003542 CaptureExpr->getExprLoc());
Alexey Bataev3392d762016-02-16 11:18:12 +00003543}
3544
Alexey Bataev5a3af132016-03-29 08:58:54 +00003545static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003546 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
Alexey Bataev5a3af132016-03-29 08:58:54 +00003547 if (!Ref) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003548 OMPCapturedExprDecl *CD = buildCaptureDecl(
3549 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3550 /*WithInit=*/true, /*AsExpression=*/true);
Alexey Bataev5a3af132016-03-29 08:58:54 +00003551 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3552 CaptureExpr->getExprLoc());
3553 }
3554 ExprResult Res = Ref;
3555 if (!S.getLangOpts().CPlusPlus &&
3556 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003557 Ref->getType()->isPointerType()) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00003558 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
Alexey Bataev8e769ee2017-12-22 21:01:52 +00003559 if (!Res.isUsable())
3560 return ExprError();
3561 }
3562 return S.DefaultLvalueConversion(Res.get());
Alexey Bataev4244be22016-02-11 05:35:55 +00003563}
3564
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003565namespace {
3566// OpenMP directives parsed in this section are represented as a
3567// CapturedStatement with an associated statement. If a syntax error
3568// is detected during the parsing of the associated statement, the
3569// compiler must abort processing and close the CapturedStatement.
3570//
3571// Combined directives such as 'target parallel' have more than one
3572// nested CapturedStatements. This RAII ensures that we unwind out
3573// of all the nested CapturedStatements when an error is found.
3574class CaptureRegionUnwinderRAII {
3575private:
3576 Sema &S;
3577 bool &ErrorFound;
Alexey Bataeve3727102018-04-18 15:57:46 +00003578 OpenMPDirectiveKind DKind = OMPD_unknown;
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003579
3580public:
3581 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3582 OpenMPDirectiveKind DKind)
3583 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3584 ~CaptureRegionUnwinderRAII() {
3585 if (ErrorFound) {
3586 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3587 while (--ThisCaptureLevel >= 0)
3588 S.ActOnCapturedRegionError();
3589 }
3590 }
3591};
3592} // namespace
3593
Alexey Bataevb600ae32019-07-01 17:46:52 +00003594void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
3595 // Capture variables captured by reference in lambdas for target-based
3596 // directives.
3597 if (!CurContext->isDependentContext() &&
3598 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
3599 isOpenMPTargetDataManagementDirective(
3600 DSAStack->getCurrentDirective()))) {
3601 QualType Type = V->getType();
3602 if (const auto *RD = Type.getCanonicalType()
3603 .getNonReferenceType()
3604 ->getAsCXXRecordDecl()) {
3605 bool SavedForceCaptureByReferenceInTargetExecutable =
3606 DSAStack->isForceCaptureByReferenceInTargetExecutable();
3607 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3608 /*V=*/true);
3609 if (RD->isLambda()) {
3610 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3611 FieldDecl *ThisCapture;
3612 RD->getCaptureFields(Captures, ThisCapture);
3613 for (const LambdaCapture &LC : RD->captures()) {
3614 if (LC.getCaptureKind() == LCK_ByRef) {
3615 VarDecl *VD = LC.getCapturedVar();
3616 DeclContext *VDC = VD->getDeclContext();
3617 if (!VDC->Encloses(CurContext))
3618 continue;
3619 MarkVariableReferenced(LC.getLocation(), VD);
3620 } else if (LC.getCaptureKind() == LCK_This) {
3621 QualType ThisTy = getCurrentThisType();
3622 if (!ThisTy.isNull() &&
3623 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
3624 CheckCXXThisCapture(LC.getLocation());
3625 }
3626 }
3627 }
3628 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3629 SavedForceCaptureByReferenceInTargetExecutable);
3630 }
3631 }
3632}
3633
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003634StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3635 ArrayRef<OMPClause *> Clauses) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003636 bool ErrorFound = false;
3637 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3638 *this, ErrorFound, DSAStack->getCurrentDirective());
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003639 if (!S.isUsable()) {
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003640 ErrorFound = true;
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003641 return StmtError();
3642 }
Alexey Bataev993d2802015-12-28 06:23:08 +00003643
Alexey Bataev2ba67042017-11-28 21:11:44 +00003644 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3645 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
Alexey Bataev993d2802015-12-28 06:23:08 +00003646 OMPOrderedClause *OC = nullptr;
Alexey Bataev6402bca2015-12-28 07:25:51 +00003647 OMPScheduleClause *SC = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +00003648 SmallVector<const OMPLinearClause *, 4> LCs;
3649 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
Alexey Bataev040d5402015-05-12 08:35:28 +00003650 // This is required for proper codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00003651 for (OMPClause *Clause : Clauses) {
Alexey Bataev88202be2017-07-27 13:20:36 +00003652 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
3653 Clause->getClauseKind() == OMPC_in_reduction) {
3654 // Capture taskgroup task_reduction descriptors inside the tasking regions
3655 // with the corresponding in_reduction items.
3656 auto *IRC = cast<OMPInReductionClause>(Clause);
Alexey Bataeve3727102018-04-18 15:57:46 +00003657 for (Expr *E : IRC->taskgroup_descriptors())
Alexey Bataev88202be2017-07-27 13:20:36 +00003658 if (E)
3659 MarkDeclarationsReferencedInExpr(E);
3660 }
Alexey Bataev16dc7b62015-05-20 03:46:04 +00003661 if (isOpenMPPrivate(Clause->getClauseKind()) ||
Samuel Antao9c75cfe2015-07-27 16:38:06 +00003662 Clause->getClauseKind() == OMPC_copyprivate ||
3663 (getLangOpts().OpenMPUseTLS &&
3664 getASTContext().getTargetInfo().isTLSSupported() &&
3665 Clause->getClauseKind() == OMPC_copyin)) {
3666 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
Alexey Bataev040d5402015-05-12 08:35:28 +00003667 // Mark all variables in private list clauses as used in inner region.
Alexey Bataeve3727102018-04-18 15:57:46 +00003668 for (Stmt *VarRef : Clause->children()) {
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003669 if (auto *E = cast_or_null<Expr>(VarRef)) {
Alexey Bataev8bf6b3e2015-04-02 13:07:08 +00003670 MarkDeclarationsReferencedInExpr(E);
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003671 }
3672 }
Samuel Antao9c75cfe2015-07-27 16:38:06 +00003673 DSAStack->setForceVarCapturing(/*V=*/false);
Alexey Bataev2ba67042017-11-28 21:11:44 +00003674 } else if (CaptureRegions.size() > 1 ||
3675 CaptureRegions.back() != OMPD_unknown) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003676 if (auto *C = OMPClauseWithPreInit::get(Clause))
3677 PICs.push_back(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00003678 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003679 if (Expr *E = C->getPostUpdateExpr())
Alexey Bataev005248a2016-02-25 05:25:57 +00003680 MarkDeclarationsReferencedInExpr(E);
3681 }
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003682 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003683 if (Clause->getClauseKind() == OMPC_schedule)
3684 SC = cast<OMPScheduleClause>(Clause);
3685 else if (Clause->getClauseKind() == OMPC_ordered)
Alexey Bataev993d2802015-12-28 06:23:08 +00003686 OC = cast<OMPOrderedClause>(Clause);
3687 else if (Clause->getClauseKind() == OMPC_linear)
3688 LCs.push_back(cast<OMPLinearClause>(Clause));
3689 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003690 // OpenMP, 2.7.1 Loop Construct, Restrictions
3691 // The nonmonotonic modifier cannot be specified if an ordered clause is
3692 // specified.
3693 if (SC &&
3694 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3695 SC->getSecondScheduleModifier() ==
3696 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3697 OC) {
3698 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3699 ? SC->getFirstScheduleModifierLoc()
3700 : SC->getSecondScheduleModifierLoc(),
3701 diag::err_omp_schedule_nonmonotonic_ordered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00003702 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
Alexey Bataev6402bca2015-12-28 07:25:51 +00003703 ErrorFound = true;
3704 }
Alexey Bataev993d2802015-12-28 06:23:08 +00003705 if (!LCs.empty() && OC && OC->getNumForLoops()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003706 for (const OMPLinearClause *C : LCs) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003707 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00003708 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
Alexey Bataev993d2802015-12-28 06:23:08 +00003709 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003710 ErrorFound = true;
3711 }
Alexey Bataev113438c2015-12-30 12:06:23 +00003712 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
3713 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
3714 OC->getNumForLoops()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00003715 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
Alexey Bataev113438c2015-12-30 12:06:23 +00003716 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3717 ErrorFound = true;
3718 }
Alexey Bataev6402bca2015-12-28 07:25:51 +00003719 if (ErrorFound) {
Alexey Bataev993d2802015-12-28 06:23:08 +00003720 return StmtError();
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003721 }
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003722 StmtResult SR = S;
Richard Smith0621a8f2019-05-31 00:45:10 +00003723 unsigned CompletedRegions = 0;
Alexey Bataev2ba67042017-11-28 21:11:44 +00003724 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003725 // Mark all variables in private list clauses as used in inner region.
3726 // Required for proper codegen of combined directives.
3727 // TODO: add processing for other clauses.
Alexey Bataev2ba67042017-11-28 21:11:44 +00003728 if (ThisCaptureRegion != OMPD_unknown) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003729 for (const clang::OMPClauseWithPreInit *C : PICs) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003730 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3731 // Find the particular capture region for the clause if the
3732 // directive is a combined one with multiple capture regions.
3733 // If the directive is not a combined one, the capture region
3734 // associated with the clause is OMPD_unknown and is generated
3735 // only once.
3736 if (CaptureRegion == ThisCaptureRegion ||
3737 CaptureRegion == OMPD_unknown) {
3738 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003739 for (Decl *D : DS->decls())
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003740 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3741 }
3742 }
3743 }
3744 }
Richard Smith0621a8f2019-05-31 00:45:10 +00003745 if (++CompletedRegions == CaptureRegions.size())
3746 DSAStack->setBodyComplete();
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003747 SR = ActOnCapturedRegionEnd(SR.get());
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00003748 }
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00003749 return SR;
Alexey Bataeva8d4a5432015-04-02 07:48:16 +00003750}
3751
Jonas Hahnfeld64a9e3c2017-02-22 06:49:10 +00003752static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3753 OpenMPDirectiveKind CancelRegion,
3754 SourceLocation StartLoc) {
3755 // CancelRegion is only needed for cancel and cancellation_point.
3756 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3757 return false;
3758
3759 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3760 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3761 return false;
3762
3763 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3764 << getOpenMPDirectiveName(CancelRegion);
3765 return true;
3766}
3767
Alexey Bataeve3727102018-04-18 15:57:46 +00003768static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003769 OpenMPDirectiveKind CurrentRegion,
3770 const DeclarationNameInfo &CurrentName,
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003771 OpenMPDirectiveKind CancelRegion,
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003772 SourceLocation StartLoc) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003773 if (Stack->getCurScope()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00003774 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3775 OpenMPDirectiveKind OffendingRegion = ParentRegion;
Alexey Bataev549210e2014-06-24 04:39:47 +00003776 bool NestingProhibited = false;
3777 bool CloseNesting = true;
David Majnemer9d168222016-08-05 17:44:54 +00003778 bool OrphanSeen = false;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003779 enum {
3780 NoRecommend,
3781 ShouldBeInParallelRegion,
Alexey Bataev13314bf2014-10-09 04:18:56 +00003782 ShouldBeInOrderedRegion,
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003783 ShouldBeInTargetRegion,
3784 ShouldBeInTeamsRegion
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003785 } Recommend = NoRecommend;
Kelvin Lifd8b5742016-07-01 14:30:25 +00003786 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003787 // OpenMP [2.16, Nesting of Regions]
3788 // OpenMP constructs may not be nested inside a simd region.
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003789 // OpenMP [2.8.1,simd Construct, Restrictions]
Kelvin Lifd8b5742016-07-01 14:30:25 +00003790 // An ordered construct with the simd clause is the only OpenMP
3791 // construct that can appear in the simd region.
David Majnemer9d168222016-08-05 17:44:54 +00003792 // Allowing a SIMD construct nested in another SIMD construct is an
Kelvin Lifd8b5742016-07-01 14:30:25 +00003793 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3794 // message.
3795 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3796 ? diag::err_omp_prohibited_region_simd
3797 : diag::warn_omp_nesting_simd);
3798 return CurrentRegion != OMPD_simd;
Alexey Bataev549210e2014-06-24 04:39:47 +00003799 }
Alexey Bataev0162e452014-07-22 10:10:35 +00003800 if (ParentRegion == OMPD_atomic) {
3801 // OpenMP [2.16, Nesting of Regions]
3802 // OpenMP constructs may not be nested inside an atomic region.
3803 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3804 return true;
3805 }
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003806 if (CurrentRegion == OMPD_section) {
3807 // OpenMP [2.7.2, sections Construct, Restrictions]
3808 // Orphaned section directives are prohibited. That is, the section
3809 // directives must appear within the sections construct and must not be
3810 // encountered elsewhere in the sections region.
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00003811 if (ParentRegion != OMPD_sections &&
3812 ParentRegion != OMPD_parallel_sections) {
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003813 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3814 << (ParentRegion != OMPD_unknown)
3815 << getOpenMPDirectiveName(ParentRegion);
3816 return true;
3817 }
3818 return false;
3819 }
Alexey Bataev185e88d2019-01-08 15:53:42 +00003820 // Allow some constructs (except teams and cancellation constructs) to be
3821 // orphaned (they could be used in functions, called from OpenMP regions
3822 // with the required preconditions).
Kelvin Libf594a52016-12-17 05:48:59 +00003823 if (ParentRegion == OMPD_unknown &&
Alexey Bataev185e88d2019-01-08 15:53:42 +00003824 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3825 CurrentRegion != OMPD_cancellation_point &&
3826 CurrentRegion != OMPD_cancel)
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003827 return false;
Alexey Bataev80909872015-07-02 11:25:17 +00003828 if (CurrentRegion == OMPD_cancellation_point ||
3829 CurrentRegion == OMPD_cancel) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003830 // OpenMP [2.16, Nesting of Regions]
3831 // A cancellation point construct for which construct-type-clause is
3832 // taskgroup must be nested inside a task construct. A cancellation
3833 // point construct for which construct-type-clause is not taskgroup must
3834 // be closely nested inside an OpenMP construct that matches the type
3835 // specified in construct-type-clause.
Alexey Bataev80909872015-07-02 11:25:17 +00003836 // A cancel construct for which construct-type-clause is taskgroup must be
3837 // nested inside a task construct. A cancel construct for which
3838 // construct-type-clause is not taskgroup must be closely nested inside an
3839 // OpenMP construct that matches the type specified in
3840 // construct-type-clause.
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003841 NestingProhibited =
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00003842 !((CancelRegion == OMPD_parallel &&
3843 (ParentRegion == OMPD_parallel ||
3844 ParentRegion == OMPD_target_parallel)) ||
Alexey Bataev25e5b442015-09-15 12:52:43 +00003845 (CancelRegion == OMPD_for &&
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00003846 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00003847 ParentRegion == OMPD_target_parallel_for ||
3848 ParentRegion == OMPD_distribute_parallel_for ||
Alexey Bataev16e79882017-11-22 21:12:03 +00003849 ParentRegion == OMPD_teams_distribute_parallel_for ||
3850 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003851 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3852 (CancelRegion == OMPD_sections &&
Alexey Bataev25e5b442015-09-15 12:52:43 +00003853 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3854 ParentRegion == OMPD_parallel_sections)));
Alexey Bataev185e88d2019-01-08 15:53:42 +00003855 OrphanSeen = ParentRegion == OMPD_unknown;
Alexey Bataev6d4ed052015-07-01 06:57:41 +00003856 } else if (CurrentRegion == OMPD_master) {
Alexander Musman80c22892014-07-17 08:54:58 +00003857 // OpenMP [2.16, Nesting of Regions]
3858 // A master region may not be closely nested inside a worksharing,
Alexey Bataev0162e452014-07-22 10:10:35 +00003859 // atomic, or explicit task region.
Alexander Musman80c22892014-07-17 08:54:58 +00003860 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
Alexey Bataev35aaee62016-04-13 13:36:48 +00003861 isOpenMPTaskingDirective(ParentRegion);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003862 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3863 // OpenMP [2.16, Nesting of Regions]
3864 // A critical region may not be nested (closely or otherwise) inside a
3865 // critical region with the same name. Note that this restriction is not
3866 // sufficient to prevent deadlock.
3867 SourceLocation PreviousCriticalLoc;
David Majnemer9d168222016-08-05 17:44:54 +00003868 bool DeadLock = Stack->hasDirective(
3869 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3870 const DeclarationNameInfo &DNI,
Alexey Bataeve3727102018-04-18 15:57:46 +00003871 SourceLocation Loc) {
David Majnemer9d168222016-08-05 17:44:54 +00003872 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3873 PreviousCriticalLoc = Loc;
3874 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003875 }
3876 return false;
David Majnemer9d168222016-08-05 17:44:54 +00003877 },
3878 false /* skip top directive */);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00003879 if (DeadLock) {
3880 SemaRef.Diag(StartLoc,
3881 diag::err_omp_prohibited_region_critical_same_name)
3882 << CurrentName.getName();
3883 if (PreviousCriticalLoc.isValid())
3884 SemaRef.Diag(PreviousCriticalLoc,
3885 diag::note_omp_previous_critical_region);
3886 return true;
3887 }
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00003888 } else if (CurrentRegion == OMPD_barrier) {
3889 // OpenMP [2.16, Nesting of Regions]
3890 // A barrier region may not be closely nested inside a worksharing,
Alexey Bataev0162e452014-07-22 10:10:35 +00003891 // explicit task, critical, ordered, atomic, or master region.
Alexey Bataev35aaee62016-04-13 13:36:48 +00003892 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3893 isOpenMPTaskingDirective(ParentRegion) ||
3894 ParentRegion == OMPD_master ||
3895 ParentRegion == OMPD_critical ||
3896 ParentRegion == OMPD_ordered;
Alexander Musman80c22892014-07-17 08:54:58 +00003897 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
Kelvin Li579e41c2016-11-30 23:51:03 +00003898 !isOpenMPParallelDirective(CurrentRegion) &&
3899 !isOpenMPTeamsDirective(CurrentRegion)) {
Alexey Bataev549210e2014-06-24 04:39:47 +00003900 // OpenMP [2.16, Nesting of Regions]
3901 // A worksharing region may not be closely nested inside a worksharing,
3902 // explicit task, critical, ordered, atomic, or master region.
Alexey Bataev35aaee62016-04-13 13:36:48 +00003903 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3904 isOpenMPTaskingDirective(ParentRegion) ||
3905 ParentRegion == OMPD_master ||
3906 ParentRegion == OMPD_critical ||
3907 ParentRegion == OMPD_ordered;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003908 Recommend = ShouldBeInParallelRegion;
3909 } else if (CurrentRegion == OMPD_ordered) {
3910 // OpenMP [2.16, Nesting of Regions]
3911 // An ordered region may not be closely nested inside a critical,
Alexey Bataev0162e452014-07-22 10:10:35 +00003912 // atomic, or explicit task region.
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003913 // An ordered region must be closely nested inside a loop region (or
3914 // parallel loop region) with an ordered clause.
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003915 // OpenMP [2.8.1,simd Construct, Restrictions]
3916 // An ordered construct with the simd clause is the only OpenMP construct
3917 // that can appear in the simd region.
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003918 NestingProhibited = ParentRegion == OMPD_critical ||
Alexey Bataev35aaee62016-04-13 13:36:48 +00003919 isOpenMPTaskingDirective(ParentRegion) ||
Alexey Bataevd14d1e62015-09-28 06:39:35 +00003920 !(isOpenMPSimdDirective(ParentRegion) ||
3921 Stack->isParentOrderedRegion());
Alexey Bataev9fb6e642014-07-22 06:45:04 +00003922 Recommend = ShouldBeInOrderedRegion;
Kelvin Libf594a52016-12-17 05:48:59 +00003923 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00003924 // OpenMP [2.16, Nesting of Regions]
3925 // If specified, a teams construct must be contained within a target
3926 // construct.
Alexey Bataev7a54d762019-09-10 20:19:58 +00003927 NestingProhibited =
3928 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
3929 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
3930 ParentRegion != OMPD_target);
Kelvin Li2b51f722016-07-26 04:32:50 +00003931 OrphanSeen = ParentRegion == OMPD_unknown;
Alexey Bataev13314bf2014-10-09 04:18:56 +00003932 Recommend = ShouldBeInTargetRegion;
Alexey Bataev13314bf2014-10-09 04:18:56 +00003933 }
Kelvin Libf594a52016-12-17 05:48:59 +00003934 if (!NestingProhibited &&
3935 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3936 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3937 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00003938 // OpenMP [2.16, Nesting of Regions]
3939 // distribute, parallel, parallel sections, parallel workshare, and the
3940 // parallel loop and parallel loop SIMD constructs are the only OpenMP
3941 // constructs that can be closely nested in the teams region.
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003942 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3943 !isOpenMPDistributeDirective(CurrentRegion);
Alexey Bataev13314bf2014-10-09 04:18:56 +00003944 Recommend = ShouldBeInParallelRegion;
Alexey Bataev549210e2014-06-24 04:39:47 +00003945 }
David Majnemer9d168222016-08-05 17:44:54 +00003946 if (!NestingProhibited &&
Kelvin Li02532872016-08-05 14:37:37 +00003947 isOpenMPNestingDistributeDirective(CurrentRegion)) {
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003948 // OpenMP 4.5 [2.17 Nesting of Regions]
3949 // The region associated with the distribute construct must be strictly
3950 // nested inside a teams region
Kelvin Libf594a52016-12-17 05:48:59 +00003951 NestingProhibited =
3952 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003953 Recommend = ShouldBeInTeamsRegion;
3954 }
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003955 if (!NestingProhibited &&
3956 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3957 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3958 // OpenMP 4.5 [2.17 Nesting of Regions]
3959 // If a target, target update, target data, target enter data, or
3960 // target exit data construct is encountered during execution of a
3961 // target region, the behavior is unspecified.
3962 NestingProhibited = Stack->hasDirective(
Alexey Bataev7ace49d2016-05-17 08:55:33 +00003963 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
Alexey Bataeve3727102018-04-18 15:57:46 +00003964 SourceLocation) {
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003965 if (isOpenMPTargetExecutionDirective(K)) {
3966 OffendingRegion = K;
3967 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00003968 }
3969 return false;
Arpith Chacko Jacob3d58f262016-02-02 04:00:47 +00003970 },
3971 false /* don't skip top directive */);
3972 CloseNesting = false;
3973 }
Alexey Bataev549210e2014-06-24 04:39:47 +00003974 if (NestingProhibited) {
Kelvin Li2b51f722016-07-26 04:32:50 +00003975 if (OrphanSeen) {
3976 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3977 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3978 } else {
3979 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3980 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3981 << Recommend << getOpenMPDirectiveName(CurrentRegion);
3982 }
Alexey Bataev549210e2014-06-24 04:39:47 +00003983 return true;
3984 }
3985 }
3986 return false;
3987}
3988
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003989static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
3990 ArrayRef<OMPClause *> Clauses,
3991 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3992 bool ErrorFound = false;
3993 unsigned NamedModifiersNumber = 0;
3994 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
3995 OMPD_unknown + 1);
Alexey Bataevecb156a2015-09-15 17:23:56 +00003996 SmallVector<SourceLocation, 4> NameModifierLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +00003997 for (const OMPClause *C : Clauses) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00003998 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3999 // At most one if clause without a directive-name-modifier can appear on
4000 // the directive.
4001 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4002 if (FoundNameModifiers[CurNM]) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004003 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004004 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4005 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4006 ErrorFound = true;
Alexey Bataevecb156a2015-09-15 17:23:56 +00004007 } else if (CurNM != OMPD_unknown) {
4008 NameModifierLoc.push_back(IC->getNameModifierLoc());
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004009 ++NamedModifiersNumber;
Alexey Bataevecb156a2015-09-15 17:23:56 +00004010 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004011 FoundNameModifiers[CurNM] = IC;
4012 if (CurNM == OMPD_unknown)
4013 continue;
4014 // Check if the specified name modifier is allowed for the current
4015 // directive.
4016 // At most one if clause with the particular directive-name-modifier can
4017 // appear on the directive.
4018 bool MatchFound = false;
4019 for (auto NM : AllowedNameModifiers) {
4020 if (CurNM == NM) {
4021 MatchFound = true;
4022 break;
4023 }
4024 }
4025 if (!MatchFound) {
4026 S.Diag(IC->getNameModifierLoc(),
4027 diag::err_omp_wrong_if_directive_name_modifier)
4028 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4029 ErrorFound = true;
4030 }
4031 }
4032 }
4033 // If any if clause on the directive includes a directive-name-modifier then
4034 // all if clauses on the directive must include a directive-name-modifier.
4035 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4036 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004037 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004038 diag::err_omp_no_more_if_clause);
4039 } else {
4040 std::string Values;
4041 std::string Sep(", ");
4042 unsigned AllowedCnt = 0;
4043 unsigned TotalAllowedNum =
4044 AllowedNameModifiers.size() - NamedModifiersNumber;
4045 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4046 ++Cnt) {
4047 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4048 if (!FoundNameModifiers[NM]) {
4049 Values += "'";
4050 Values += getOpenMPDirectiveName(NM);
4051 Values += "'";
4052 if (AllowedCnt + 2 == TotalAllowedNum)
4053 Values += " or ";
4054 else if (AllowedCnt + 1 != TotalAllowedNum)
4055 Values += Sep;
4056 ++AllowedCnt;
4057 }
4058 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004059 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004060 diag::err_omp_unnamed_if_clause)
4061 << (TotalAllowedNum > 1) << Values;
4062 }
Alexey Bataeve3727102018-04-18 15:57:46 +00004063 for (SourceLocation Loc : NameModifierLoc) {
Alexey Bataevecb156a2015-09-15 17:23:56 +00004064 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4065 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004066 ErrorFound = true;
4067 }
4068 return ErrorFound;
4069}
4070
Alexey Bataeve106f252019-04-01 14:25:31 +00004071static std::pair<ValueDecl *, bool>
4072getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
4073 SourceRange &ERange, bool AllowArraySection = false) {
4074 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4075 RefExpr->containsUnexpandedParameterPack())
4076 return std::make_pair(nullptr, true);
4077
4078 // OpenMP [3.1, C/C++]
4079 // A list item is a variable name.
4080 // OpenMP [2.9.3.3, Restrictions, p.1]
4081 // A variable that is part of another variable (as an array or
4082 // structure element) cannot appear in a private clause.
4083 RefExpr = RefExpr->IgnoreParens();
4084 enum {
4085 NoArrayExpr = -1,
4086 ArraySubscript = 0,
4087 OMPArraySection = 1
4088 } IsArrayExpr = NoArrayExpr;
4089 if (AllowArraySection) {
4090 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4091 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4092 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4093 Base = TempASE->getBase()->IgnoreParenImpCasts();
4094 RefExpr = Base;
4095 IsArrayExpr = ArraySubscript;
4096 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4097 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4098 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4099 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4100 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4101 Base = TempASE->getBase()->IgnoreParenImpCasts();
4102 RefExpr = Base;
4103 IsArrayExpr = OMPArraySection;
4104 }
4105 }
4106 ELoc = RefExpr->getExprLoc();
4107 ERange = RefExpr->getSourceRange();
4108 RefExpr = RefExpr->IgnoreParenImpCasts();
4109 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4110 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4111 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4112 (S.getCurrentThisType().isNull() || !ME ||
4113 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4114 !isa<FieldDecl>(ME->getMemberDecl()))) {
4115 if (IsArrayExpr != NoArrayExpr) {
4116 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4117 << ERange;
4118 } else {
4119 S.Diag(ELoc,
4120 AllowArraySection
4121 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4122 : diag::err_omp_expected_var_name_member_expr)
4123 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4124 }
4125 return std::make_pair(nullptr, false);
4126 }
4127 return std::make_pair(
4128 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4129}
4130
4131static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
Alexey Bataev471171c2019-03-28 19:15:36 +00004132 ArrayRef<OMPClause *> Clauses) {
4133 assert(!S.CurContext->isDependentContext() &&
4134 "Expected non-dependent context.");
Alexey Bataev471171c2019-03-28 19:15:36 +00004135 auto AllocateRange =
4136 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
Alexey Bataeve106f252019-04-01 14:25:31 +00004137 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4138 DeclToCopy;
4139 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4140 return isOpenMPPrivate(C->getClauseKind());
4141 });
4142 for (OMPClause *Cl : PrivateRange) {
4143 MutableArrayRef<Expr *>::iterator I, It, Et;
4144 if (Cl->getClauseKind() == OMPC_private) {
4145 auto *PC = cast<OMPPrivateClause>(Cl);
4146 I = PC->private_copies().begin();
4147 It = PC->varlist_begin();
4148 Et = PC->varlist_end();
4149 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4150 auto *PC = cast<OMPFirstprivateClause>(Cl);
4151 I = PC->private_copies().begin();
4152 It = PC->varlist_begin();
4153 Et = PC->varlist_end();
4154 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4155 auto *PC = cast<OMPLastprivateClause>(Cl);
4156 I = PC->private_copies().begin();
4157 It = PC->varlist_begin();
4158 Et = PC->varlist_end();
4159 } else if (Cl->getClauseKind() == OMPC_linear) {
4160 auto *PC = cast<OMPLinearClause>(Cl);
4161 I = PC->privates().begin();
4162 It = PC->varlist_begin();
4163 Et = PC->varlist_end();
4164 } else if (Cl->getClauseKind() == OMPC_reduction) {
4165 auto *PC = cast<OMPReductionClause>(Cl);
4166 I = PC->privates().begin();
4167 It = PC->varlist_begin();
4168 Et = PC->varlist_end();
4169 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4170 auto *PC = cast<OMPTaskReductionClause>(Cl);
4171 I = PC->privates().begin();
4172 It = PC->varlist_begin();
4173 Et = PC->varlist_end();
4174 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4175 auto *PC = cast<OMPInReductionClause>(Cl);
4176 I = PC->privates().begin();
4177 It = PC->varlist_begin();
4178 Et = PC->varlist_end();
4179 } else {
4180 llvm_unreachable("Expected private clause.");
4181 }
4182 for (Expr *E : llvm::make_range(It, Et)) {
4183 if (!*I) {
4184 ++I;
4185 continue;
4186 }
4187 SourceLocation ELoc;
4188 SourceRange ERange;
4189 Expr *SimpleRefExpr = E;
4190 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4191 /*AllowArraySection=*/true);
4192 DeclToCopy.try_emplace(Res.first,
4193 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4194 ++I;
4195 }
4196 }
Alexey Bataev471171c2019-03-28 19:15:36 +00004197 for (OMPClause *C : AllocateRange) {
4198 auto *AC = cast<OMPAllocateClause>(C);
4199 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4200 getAllocatorKind(S, Stack, AC->getAllocator());
4201 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4202 // For task, taskloop or target directives, allocation requests to memory
4203 // allocators with the trait access set to thread result in unspecified
4204 // behavior.
4205 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4206 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4207 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4208 S.Diag(AC->getAllocator()->getExprLoc(),
4209 diag::warn_omp_allocate_thread_on_task_target_directive)
4210 << getOpenMPDirectiveName(Stack->getCurrentDirective());
Alexey Bataeve106f252019-04-01 14:25:31 +00004211 }
4212 for (Expr *E : AC->varlists()) {
4213 SourceLocation ELoc;
4214 SourceRange ERange;
4215 Expr *SimpleRefExpr = E;
4216 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4217 ValueDecl *VD = Res.first;
4218 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4219 if (!isOpenMPPrivate(Data.CKind)) {
4220 S.Diag(E->getExprLoc(),
4221 diag::err_omp_expected_private_copy_for_allocate);
4222 continue;
4223 }
4224 VarDecl *PrivateVD = DeclToCopy[VD];
4225 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4226 AllocatorKind, AC->getAllocator()))
4227 continue;
4228 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4229 E->getSourceRange());
Alexey Bataev471171c2019-03-28 19:15:36 +00004230 }
4231 }
Alexey Bataev471171c2019-03-28 19:15:36 +00004232}
4233
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004234StmtResult Sema::ActOnOpenMPExecutableDirective(
4235 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4236 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4237 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004238 StmtResult Res = StmtError();
Jonas Hahnfeld64a9e3c2017-02-22 06:49:10 +00004239 // First check CancelRegion which is then used in checkNestingOfRegions.
4240 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4241 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004242 StartLoc))
Alexey Bataev549210e2014-06-24 04:39:47 +00004243 return StmtError();
Alexey Bataev758e55e2013-09-06 18:03:48 +00004244
Alexey Bataevd5af8e42013-10-01 05:32:34 +00004245 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
Alexey Bataeve3727102018-04-18 15:57:46 +00004246 VarsWithInheritedDSAType VarsWithInheritedDSA;
Alexey Bataevd5af8e42013-10-01 05:32:34 +00004247 bool ErrorFound = false;
Alexey Bataev6125da92014-07-21 11:26:11 +00004248 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
Alexey Bataev0dce2ea2017-09-21 14:06:59 +00004249 if (AStmt && !CurContext->isDependentContext()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00004250 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4251
4252 // Check default data sharing attributes for referenced variables.
4253 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
Arpith Chacko Jacob1f46b702017-01-23 15:38:49 +00004254 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4255 Stmt *S = AStmt;
4256 while (--ThisCaptureLevel >= 0)
4257 S = cast<CapturedStmt>(S)->getCapturedStmt();
4258 DSAChecker.Visit(S);
Alexey Bataev1242d8f2019-06-28 20:45:14 +00004259 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4260 !isOpenMPTaskingDirective(Kind)) {
4261 // Visit subcaptures to generate implicit clauses for captured vars.
4262 auto *CS = cast<CapturedStmt>(AStmt);
4263 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4264 getOpenMPCaptureRegions(CaptureRegions, Kind);
4265 // Ignore outer tasking regions for target directives.
4266 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4267 CS = cast<CapturedStmt>(CS->getCapturedStmt());
4268 DSAChecker.visitSubCaptures(CS);
4269 }
Alexey Bataev68446b72014-07-18 07:47:19 +00004270 if (DSAChecker.isErrorFound())
4271 return StmtError();
4272 // Generate list of implicitly defined firstprivate variables.
4273 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
Alexey Bataev68446b72014-07-18 07:47:19 +00004274
Alexey Bataev88202be2017-07-27 13:20:36 +00004275 SmallVector<Expr *, 4> ImplicitFirstprivates(
4276 DSAChecker.getImplicitFirstprivate().begin(),
4277 DSAChecker.getImplicitFirstprivate().end());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004278 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
4279 DSAChecker.getImplicitMap().end());
Alexey Bataev88202be2017-07-27 13:20:36 +00004280 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
Alexey Bataeve3727102018-04-18 15:57:46 +00004281 for (OMPClause *C : Clauses) {
Alexey Bataev88202be2017-07-27 13:20:36 +00004282 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
Alexey Bataeve3727102018-04-18 15:57:46 +00004283 for (Expr *E : IRC->taskgroup_descriptors())
Alexey Bataev88202be2017-07-27 13:20:36 +00004284 if (E)
4285 ImplicitFirstprivates.emplace_back(E);
4286 }
4287 }
4288 if (!ImplicitFirstprivates.empty()) {
Alexey Bataev68446b72014-07-18 07:47:19 +00004289 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
Alexey Bataev88202be2017-07-27 13:20:36 +00004290 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
4291 SourceLocation())) {
Alexey Bataev68446b72014-07-18 07:47:19 +00004292 ClausesWithImplicit.push_back(Implicit);
4293 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
Alexey Bataev88202be2017-07-27 13:20:36 +00004294 ImplicitFirstprivates.size();
Alexey Bataeve3727102018-04-18 15:57:46 +00004295 } else {
Alexey Bataev68446b72014-07-18 07:47:19 +00004296 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00004297 }
Alexey Bataev68446b72014-07-18 07:47:19 +00004298 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004299 if (!ImplicitMaps.empty()) {
Michael Kruse4304e9d2019-02-19 16:38:20 +00004300 CXXScopeSpec MapperIdScopeSpec;
4301 DeclarationNameInfo MapperId;
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004302 if (OMPClause *Implicit = ActOnOpenMPMapClause(
Michael Kruse4304e9d2019-02-19 16:38:20 +00004303 llvm::None, llvm::None, MapperIdScopeSpec, MapperId,
4304 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(),
4305 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004306 ClausesWithImplicit.emplace_back(Implicit);
4307 ErrorFound |=
4308 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
Alexey Bataeve3727102018-04-18 15:57:46 +00004309 } else {
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004310 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00004311 }
Alexey Bataevf47c4b42017-09-26 13:47:31 +00004312 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00004313 }
Alexey Bataev758e55e2013-09-06 18:03:48 +00004314
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004315 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004316 switch (Kind) {
4317 case OMPD_parallel:
Alexey Bataeved09d242014-05-28 05:53:51 +00004318 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4319 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004320 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004321 break;
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004322 case OMPD_simd:
Alexey Bataev4acb8592014-07-07 13:01:15 +00004323 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4324 VarsWithInheritedDSA);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004325 break;
Alexey Bataevf29276e2014-06-18 04:14:57 +00004326 case OMPD_for:
Alexey Bataev4acb8592014-07-07 13:01:15 +00004327 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4328 VarsWithInheritedDSA);
Alexey Bataevf29276e2014-06-18 04:14:57 +00004329 break;
Alexander Musmanf82886e2014-09-18 05:12:34 +00004330 case OMPD_for_simd:
4331 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4332 EndLoc, VarsWithInheritedDSA);
4333 break;
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004334 case OMPD_sections:
4335 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4336 EndLoc);
4337 break;
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004338 case OMPD_section:
4339 assert(ClausesWithImplicit.empty() &&
Alexander Musman80c22892014-07-17 08:54:58 +00004340 "No clauses are allowed for 'omp section' directive");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004341 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4342 break;
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004343 case OMPD_single:
4344 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4345 EndLoc);
4346 break;
Alexander Musman80c22892014-07-17 08:54:58 +00004347 case OMPD_master:
4348 assert(ClausesWithImplicit.empty() &&
4349 "No clauses are allowed for 'omp master' directive");
4350 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4351 break;
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004352 case OMPD_critical:
Alexey Bataev28c75412015-12-15 08:19:24 +00004353 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4354 StartLoc, EndLoc);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004355 break;
Alexey Bataev4acb8592014-07-07 13:01:15 +00004356 case OMPD_parallel_for:
4357 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4358 EndLoc, VarsWithInheritedDSA);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004359 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev4acb8592014-07-07 13:01:15 +00004360 break;
Alexander Musmane4e893b2014-09-23 09:33:00 +00004361 case OMPD_parallel_for_simd:
4362 Res = ActOnOpenMPParallelForSimdDirective(
4363 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004364 AllowedNameModifiers.push_back(OMPD_parallel);
Alexander Musmane4e893b2014-09-23 09:33:00 +00004365 break;
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004366 case OMPD_parallel_sections:
4367 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4368 StartLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004369 AllowedNameModifiers.push_back(OMPD_parallel);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004370 break;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004371 case OMPD_task:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004372 Res =
4373 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004374 AllowedNameModifiers.push_back(OMPD_task);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004375 break;
Alexey Bataev68446b72014-07-18 07:47:19 +00004376 case OMPD_taskyield:
4377 assert(ClausesWithImplicit.empty() &&
4378 "No clauses are allowed for 'omp taskyield' directive");
4379 assert(AStmt == nullptr &&
4380 "No associated statement allowed for 'omp taskyield' directive");
4381 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4382 break;
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004383 case OMPD_barrier:
4384 assert(ClausesWithImplicit.empty() &&
4385 "No clauses are allowed for 'omp barrier' directive");
4386 assert(AStmt == nullptr &&
4387 "No associated statement allowed for 'omp barrier' directive");
4388 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4389 break;
Alexey Bataev2df347a2014-07-18 10:17:07 +00004390 case OMPD_taskwait:
4391 assert(ClausesWithImplicit.empty() &&
4392 "No clauses are allowed for 'omp taskwait' directive");
4393 assert(AStmt == nullptr &&
4394 "No associated statement allowed for 'omp taskwait' directive");
4395 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4396 break;
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004397 case OMPD_taskgroup:
Alexey Bataev169d96a2017-07-18 20:17:46 +00004398 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4399 EndLoc);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004400 break;
Alexey Bataev6125da92014-07-21 11:26:11 +00004401 case OMPD_flush:
4402 assert(AStmt == nullptr &&
4403 "No associated statement allowed for 'omp flush' directive");
4404 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4405 break;
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004406 case OMPD_ordered:
Alexey Bataev346265e2015-09-25 10:37:12 +00004407 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4408 EndLoc);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004409 break;
Alexey Bataev0162e452014-07-22 10:10:35 +00004410 case OMPD_atomic:
4411 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4412 EndLoc);
4413 break;
Alexey Bataev13314bf2014-10-09 04:18:56 +00004414 case OMPD_teams:
4415 Res =
4416 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4417 break;
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004418 case OMPD_target:
4419 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4420 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004421 AllowedNameModifiers.push_back(OMPD_target);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004422 break;
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004423 case OMPD_target_parallel:
4424 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4425 StartLoc, EndLoc);
4426 AllowedNameModifiers.push_back(OMPD_target);
4427 AllowedNameModifiers.push_back(OMPD_parallel);
4428 break;
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004429 case OMPD_target_parallel_for:
4430 Res = ActOnOpenMPTargetParallelForDirective(
4431 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4432 AllowedNameModifiers.push_back(OMPD_target);
4433 AllowedNameModifiers.push_back(OMPD_parallel);
4434 break;
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004435 case OMPD_cancellation_point:
4436 assert(ClausesWithImplicit.empty() &&
4437 "No clauses are allowed for 'omp cancellation point' directive");
4438 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
4439 "cancellation point' directive");
4440 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4441 break;
Alexey Bataev80909872015-07-02 11:25:17 +00004442 case OMPD_cancel:
Alexey Bataev80909872015-07-02 11:25:17 +00004443 assert(AStmt == nullptr &&
4444 "No associated statement allowed for 'omp cancel' directive");
Alexey Bataev87933c72015-09-18 08:07:34 +00004445 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4446 CancelRegion);
4447 AllowedNameModifiers.push_back(OMPD_cancel);
Alexey Bataev80909872015-07-02 11:25:17 +00004448 break;
Michael Wong65f367f2015-07-21 13:44:28 +00004449 case OMPD_target_data:
4450 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4451 EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004452 AllowedNameModifiers.push_back(OMPD_target_data);
Michael Wong65f367f2015-07-21 13:44:28 +00004453 break;
Samuel Antaodf67fc42016-01-19 19:15:56 +00004454 case OMPD_target_enter_data:
4455 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00004456 EndLoc, AStmt);
Samuel Antaodf67fc42016-01-19 19:15:56 +00004457 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4458 break;
Samuel Antao72590762016-01-19 20:04:50 +00004459 case OMPD_target_exit_data:
4460 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00004461 EndLoc, AStmt);
Samuel Antao72590762016-01-19 20:04:50 +00004462 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4463 break;
Alexey Bataev49f6e782015-12-01 04:18:41 +00004464 case OMPD_taskloop:
4465 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4466 EndLoc, VarsWithInheritedDSA);
4467 AllowedNameModifiers.push_back(OMPD_taskloop);
4468 break;
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004469 case OMPD_taskloop_simd:
4470 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4471 EndLoc, VarsWithInheritedDSA);
4472 AllowedNameModifiers.push_back(OMPD_taskloop);
4473 break;
Alexey Bataev60e51c42019-10-10 20:13:02 +00004474 case OMPD_master_taskloop:
4475 Res = ActOnOpenMPMasterTaskLoopDirective(
4476 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4477 AllowedNameModifiers.push_back(OMPD_taskloop);
4478 break;
Alexey Bataevb8552ab2019-10-18 16:47:35 +00004479 case OMPD_master_taskloop_simd:
4480 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4482 AllowedNameModifiers.push_back(OMPD_taskloop);
4483 break;
Alexey Bataev5bbcead2019-10-14 17:17:41 +00004484 case OMPD_parallel_master_taskloop:
4485 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4486 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4487 AllowedNameModifiers.push_back(OMPD_taskloop);
4488 AllowedNameModifiers.push_back(OMPD_parallel);
4489 break;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004490 case OMPD_distribute:
4491 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4492 EndLoc, VarsWithInheritedDSA);
4493 break;
Samuel Antao686c70c2016-05-26 17:30:50 +00004494 case OMPD_target_update:
Alexey Bataev7828b252017-11-21 17:08:48 +00004495 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4496 EndLoc, AStmt);
Samuel Antao686c70c2016-05-26 17:30:50 +00004497 AllowedNameModifiers.push_back(OMPD_target_update);
4498 break;
Carlo Bertolli9925f152016-06-27 14:55:37 +00004499 case OMPD_distribute_parallel_for:
4500 Res = ActOnOpenMPDistributeParallelForDirective(
4501 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4502 AllowedNameModifiers.push_back(OMPD_parallel);
4503 break;
Kelvin Li4a39add2016-07-05 05:00:15 +00004504 case OMPD_distribute_parallel_for_simd:
4505 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4506 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4507 AllowedNameModifiers.push_back(OMPD_parallel);
4508 break;
Kelvin Li787f3fc2016-07-06 04:45:38 +00004509 case OMPD_distribute_simd:
4510 Res = ActOnOpenMPDistributeSimdDirective(
4511 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4512 break;
Kelvin Lia579b912016-07-14 02:54:56 +00004513 case OMPD_target_parallel_for_simd:
4514 Res = ActOnOpenMPTargetParallelForSimdDirective(
4515 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4516 AllowedNameModifiers.push_back(OMPD_target);
4517 AllowedNameModifiers.push_back(OMPD_parallel);
4518 break;
Kelvin Li986330c2016-07-20 22:57:10 +00004519 case OMPD_target_simd:
4520 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4521 EndLoc, VarsWithInheritedDSA);
4522 AllowedNameModifiers.push_back(OMPD_target);
4523 break;
Kelvin Li02532872016-08-05 14:37:37 +00004524 case OMPD_teams_distribute:
David Majnemer9d168222016-08-05 17:44:54 +00004525 Res = ActOnOpenMPTeamsDistributeDirective(
4526 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
Kelvin Li02532872016-08-05 14:37:37 +00004527 break;
Kelvin Li4e325f72016-10-25 12:50:55 +00004528 case OMPD_teams_distribute_simd:
4529 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4531 break;
Kelvin Li579e41c2016-11-30 23:51:03 +00004532 case OMPD_teams_distribute_parallel_for_simd:
4533 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4535 AllowedNameModifiers.push_back(OMPD_parallel);
4536 break;
Kelvin Li7ade93f2016-12-09 03:24:30 +00004537 case OMPD_teams_distribute_parallel_for:
4538 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4539 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4540 AllowedNameModifiers.push_back(OMPD_parallel);
4541 break;
Kelvin Libf594a52016-12-17 05:48:59 +00004542 case OMPD_target_teams:
4543 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4544 EndLoc);
4545 AllowedNameModifiers.push_back(OMPD_target);
4546 break;
Kelvin Li83c451e2016-12-25 04:52:54 +00004547 case OMPD_target_teams_distribute:
4548 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4549 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4550 AllowedNameModifiers.push_back(OMPD_target);
4551 break;
Kelvin Li80e8f562016-12-29 22:16:30 +00004552 case OMPD_target_teams_distribute_parallel_for:
4553 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4554 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4555 AllowedNameModifiers.push_back(OMPD_target);
4556 AllowedNameModifiers.push_back(OMPD_parallel);
4557 break;
Kelvin Li1851df52017-01-03 05:23:48 +00004558 case OMPD_target_teams_distribute_parallel_for_simd:
4559 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4560 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4561 AllowedNameModifiers.push_back(OMPD_target);
4562 AllowedNameModifiers.push_back(OMPD_parallel);
4563 break;
Kelvin Lida681182017-01-10 18:08:18 +00004564 case OMPD_target_teams_distribute_simd:
4565 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4566 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4567 AllowedNameModifiers.push_back(OMPD_target);
4568 break;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +00004569 case OMPD_declare_target:
4570 case OMPD_end_declare_target:
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004571 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00004572 case OMPD_allocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00004573 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00004574 case OMPD_declare_mapper:
Alexey Bataev587e1de2016-03-30 10:43:55 +00004575 case OMPD_declare_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00004576 case OMPD_requires:
Alexey Bataevd158cf62019-09-13 20:18:17 +00004577 case OMPD_declare_variant:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004578 llvm_unreachable("OpenMP Directive is not allowed");
4579 case OMPD_unknown:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004580 llvm_unreachable("Unknown OpenMP directive");
4581 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00004582
Roman Lebedevb5700602019-03-20 16:32:36 +00004583 ErrorFound = Res.isInvalid() || ErrorFound;
4584
Alexey Bataev412254a2019-05-09 18:44:53 +00004585 // Check variables in the clauses if default(none) was specified.
4586 if (DSAStack->getDefaultDSA() == DSA_none) {
4587 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
4588 for (OMPClause *C : Clauses) {
4589 switch (C->getClauseKind()) {
4590 case OMPC_num_threads:
4591 case OMPC_dist_schedule:
4592 // Do not analyse if no parent teams directive.
4593 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()))
4594 break;
4595 continue;
4596 case OMPC_if:
4597 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) &&
4598 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4599 break;
4600 continue;
4601 case OMPC_schedule:
4602 break;
Alexey Bataevb9c55e22019-10-14 19:29:52 +00004603 case OMPC_grainsize:
Alexey Bataevd88c7de2019-10-14 20:44:34 +00004604 case OMPC_num_tasks:
Alexey Bataev3a842ec2019-10-15 19:37:05 +00004605 case OMPC_final:
Alexey Bataev31ba4762019-10-16 18:09:37 +00004606 case OMPC_priority:
Alexey Bataev3a842ec2019-10-15 19:37:05 +00004607 // Do not analyze if no parent parallel directive.
4608 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective()))
4609 break;
4610 continue;
Alexey Bataev412254a2019-05-09 18:44:53 +00004611 case OMPC_ordered:
4612 case OMPC_device:
4613 case OMPC_num_teams:
4614 case OMPC_thread_limit:
Alexey Bataev412254a2019-05-09 18:44:53 +00004615 case OMPC_hint:
4616 case OMPC_collapse:
4617 case OMPC_safelen:
4618 case OMPC_simdlen:
Alexey Bataev412254a2019-05-09 18:44:53 +00004619 case OMPC_default:
4620 case OMPC_proc_bind:
4621 case OMPC_private:
4622 case OMPC_firstprivate:
4623 case OMPC_lastprivate:
4624 case OMPC_shared:
4625 case OMPC_reduction:
4626 case OMPC_task_reduction:
4627 case OMPC_in_reduction:
4628 case OMPC_linear:
4629 case OMPC_aligned:
4630 case OMPC_copyin:
4631 case OMPC_copyprivate:
4632 case OMPC_nowait:
4633 case OMPC_untied:
4634 case OMPC_mergeable:
4635 case OMPC_allocate:
4636 case OMPC_read:
4637 case OMPC_write:
4638 case OMPC_update:
4639 case OMPC_capture:
4640 case OMPC_seq_cst:
4641 case OMPC_depend:
4642 case OMPC_threads:
4643 case OMPC_simd:
4644 case OMPC_map:
4645 case OMPC_nogroup:
4646 case OMPC_defaultmap:
4647 case OMPC_to:
4648 case OMPC_from:
4649 case OMPC_use_device_ptr:
4650 case OMPC_is_device_ptr:
4651 continue;
4652 case OMPC_allocator:
4653 case OMPC_flush:
4654 case OMPC_threadprivate:
4655 case OMPC_uniform:
4656 case OMPC_unknown:
4657 case OMPC_unified_address:
4658 case OMPC_unified_shared_memory:
4659 case OMPC_reverse_offload:
4660 case OMPC_dynamic_allocators:
4661 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +00004662 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +00004663 case OMPC_match:
Alexey Bataev412254a2019-05-09 18:44:53 +00004664 llvm_unreachable("Unexpected clause");
4665 }
4666 for (Stmt *CC : C->children()) {
4667 if (CC)
4668 DSAChecker.Visit(CC);
4669 }
4670 }
4671 for (auto &P : DSAChecker.getVarsWithInheritedDSA())
4672 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
4673 }
Alexey Bataeve3727102018-04-18 15:57:46 +00004674 for (const auto &P : VarsWithInheritedDSA) {
Alexey Bataev1242d8f2019-06-28 20:45:14 +00004675 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
4676 continue;
4677 ErrorFound = true;
Alexey Bataev4acb8592014-07-07 13:01:15 +00004678 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4679 << P.first << P.second->getSourceRange();
Alexey Bataev41ebe0c2019-05-09 18:14:57 +00004680 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
Alexey Bataev4acb8592014-07-07 13:01:15 +00004681 }
Alexey Bataev6b8046a2015-09-03 07:23:48 +00004682
4683 if (!AllowedNameModifiers.empty())
4684 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4685 ErrorFound;
Alexey Bataev4acb8592014-07-07 13:01:15 +00004686
Alexey Bataeved09d242014-05-28 05:53:51 +00004687 if (ErrorFound)
4688 return StmtError();
Roman Lebedevb5700602019-03-20 16:32:36 +00004689
4690 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
4691 Res.getAs<OMPExecutableDirective>()
4692 ->getStructuredBlock()
4693 ->setIsOMPStructuredBlock(true);
4694 }
4695
Gheorghe-Teodor Bercea411a6242019-04-18 19:53:43 +00004696 if (!CurContext->isDependentContext() &&
4697 isOpenMPTargetExecutionDirective(Kind) &&
4698 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
4699 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
4700 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
4701 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
4702 // Register target to DSA Stack.
4703 DSAStack->addTargetDirLocation(StartLoc);
4704 }
4705
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004706 return Res;
4707}
4708
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004709Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
4710 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
Alexey Bataevd93d3762016-04-12 09:35:56 +00004711 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
Alexey Bataevecba70f2016-04-12 11:02:11 +00004712 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
4713 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004714 assert(Aligneds.size() == Alignments.size());
Alexey Bataevecba70f2016-04-12 11:02:11 +00004715 assert(Linears.size() == LinModifiers.size());
4716 assert(Linears.size() == Steps.size());
Alexey Bataev587e1de2016-03-30 10:43:55 +00004717 if (!DG || DG.get().isNull())
4718 return DeclGroupPtrTy();
4719
Alexey Bataevd158cf62019-09-13 20:18:17 +00004720 const int SimdId = 0;
Alexey Bataev587e1de2016-03-30 10:43:55 +00004721 if (!DG.get().isSingleDecl()) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00004722 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
4723 << SimdId;
Alexey Bataev587e1de2016-03-30 10:43:55 +00004724 return DG;
4725 }
Alexey Bataeve3727102018-04-18 15:57:46 +00004726 Decl *ADecl = DG.get().getSingleDecl();
Alexey Bataev587e1de2016-03-30 10:43:55 +00004727 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4728 ADecl = FTD->getTemplatedDecl();
4729
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004730 auto *FD = dyn_cast<FunctionDecl>(ADecl);
4731 if (!FD) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00004732 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
Alexey Bataev587e1de2016-03-30 10:43:55 +00004733 return DeclGroupPtrTy();
4734 }
4735
Alexey Bataev2af33e32016-04-07 12:45:37 +00004736 // OpenMP [2.8.2, declare simd construct, Description]
4737 // The parameter of the simdlen clause must be a constant positive integer
4738 // expression.
4739 ExprResult SL;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004740 if (Simdlen)
Alexey Bataev2af33e32016-04-07 12:45:37 +00004741 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004742 // OpenMP [2.8.2, declare simd construct, Description]
4743 // The special this pointer can be used as if was one of the arguments to the
4744 // function in any of the linear, aligned, or uniform clauses.
4745 // The uniform clause declares one or more arguments to have an invariant
4746 // value for all concurrent invocations of the function in the execution of a
4747 // single SIMD loop.
Alexey Bataeve3727102018-04-18 15:57:46 +00004748 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
4749 const Expr *UniformedLinearThis = nullptr;
4750 for (const Expr *E : Uniforms) {
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004751 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004752 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4753 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004754 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4755 FD->getParamDecl(PVD->getFunctionScopeIndex())
Alexey Bataevecba70f2016-04-12 11:02:11 +00004756 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
Alexey Bataev43a919f2018-04-13 17:48:43 +00004757 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004758 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004759 }
4760 if (isa<CXXThisExpr>(E)) {
4761 UniformedLinearThis = E;
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004762 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004763 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004764 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4765 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
Alexey Bataev2af33e32016-04-07 12:45:37 +00004766 }
Alexey Bataevd93d3762016-04-12 09:35:56 +00004767 // OpenMP [2.8.2, declare simd construct, Description]
4768 // The aligned clause declares that the object to which each list item points
4769 // is aligned to the number of bytes expressed in the optional parameter of
4770 // the aligned clause.
4771 // The special this pointer can be used as if was one of the arguments to the
4772 // function in any of the linear, aligned, or uniform clauses.
4773 // The type of list items appearing in the aligned clause must be array,
4774 // pointer, reference to array, or reference to pointer.
Alexey Bataeve3727102018-04-18 15:57:46 +00004775 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
4776 const Expr *AlignedThis = nullptr;
4777 for (const Expr *E : Aligneds) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004778 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004779 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4780 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4781 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevd93d3762016-04-12 09:35:56 +00004782 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4783 FD->getParamDecl(PVD->getFunctionScopeIndex())
4784 ->getCanonicalDecl() == CanonPVD) {
4785 // OpenMP [2.8.1, simd construct, Restrictions]
4786 // A list-item cannot appear in more than one aligned clause.
4787 if (AlignedArgs.count(CanonPVD) > 0) {
4788 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4789 << 1 << E->getSourceRange();
4790 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
4791 diag::note_omp_explicit_dsa)
4792 << getOpenMPClauseName(OMPC_aligned);
4793 continue;
4794 }
4795 AlignedArgs[CanonPVD] = E;
4796 QualType QTy = PVD->getType()
4797 .getNonReferenceType()
4798 .getUnqualifiedType()
4799 .getCanonicalType();
4800 const Type *Ty = QTy.getTypePtrOrNull();
4801 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
4802 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
4803 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
4804 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
4805 }
4806 continue;
4807 }
4808 }
4809 if (isa<CXXThisExpr>(E)) {
4810 if (AlignedThis) {
4811 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
4812 << 2 << E->getSourceRange();
4813 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
4814 << getOpenMPClauseName(OMPC_aligned);
4815 }
4816 AlignedThis = E;
4817 continue;
4818 }
4819 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4820 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4821 }
4822 // The optional parameter of the aligned clause, alignment, must be a constant
4823 // positive integer expression. If no optional parameter is specified,
4824 // implementation-defined default alignments for SIMD instructions on the
4825 // target platforms are assumed.
Alexey Bataeve3727102018-04-18 15:57:46 +00004826 SmallVector<const Expr *, 4> NewAligns;
4827 for (Expr *E : Alignments) {
Alexey Bataevd93d3762016-04-12 09:35:56 +00004828 ExprResult Align;
4829 if (E)
4830 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
4831 NewAligns.push_back(Align.get());
4832 }
Alexey Bataevecba70f2016-04-12 11:02:11 +00004833 // OpenMP [2.8.2, declare simd construct, Description]
4834 // The linear clause declares one or more list items to be private to a SIMD
4835 // lane and to have a linear relationship with respect to the iteration space
4836 // of a loop.
4837 // The special this pointer can be used as if was one of the arguments to the
4838 // function in any of the linear, aligned, or uniform clauses.
4839 // When a linear-step expression is specified in a linear clause it must be
4840 // either a constant integer expression or an integer-typed parameter that is
4841 // specified in a uniform clause on the directive.
Alexey Bataeve3727102018-04-18 15:57:46 +00004842 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
Alexey Bataevecba70f2016-04-12 11:02:11 +00004843 const bool IsUniformedThis = UniformedLinearThis != nullptr;
4844 auto MI = LinModifiers.begin();
Alexey Bataeve3727102018-04-18 15:57:46 +00004845 for (const Expr *E : Linears) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004846 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
4847 ++MI;
4848 E = E->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00004849 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
4850 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4851 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevecba70f2016-04-12 11:02:11 +00004852 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4853 FD->getParamDecl(PVD->getFunctionScopeIndex())
4854 ->getCanonicalDecl() == CanonPVD) {
4855 // OpenMP [2.15.3.7, linear Clause, Restrictions]
4856 // A list-item cannot appear in more than one linear clause.
4857 if (LinearArgs.count(CanonPVD) > 0) {
4858 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4859 << getOpenMPClauseName(OMPC_linear)
4860 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
4861 Diag(LinearArgs[CanonPVD]->getExprLoc(),
4862 diag::note_omp_explicit_dsa)
4863 << getOpenMPClauseName(OMPC_linear);
4864 continue;
4865 }
4866 // Each argument can appear in at most one uniform or linear clause.
4867 if (UniformedArgs.count(CanonPVD) > 0) {
4868 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4869 << getOpenMPClauseName(OMPC_linear)
4870 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
4871 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
4872 diag::note_omp_explicit_dsa)
4873 << getOpenMPClauseName(OMPC_uniform);
4874 continue;
4875 }
4876 LinearArgs[CanonPVD] = E;
4877 if (E->isValueDependent() || E->isTypeDependent() ||
4878 E->isInstantiationDependent() ||
4879 E->containsUnexpandedParameterPack())
4880 continue;
4881 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
4882 PVD->getOriginalType());
4883 continue;
4884 }
4885 }
4886 if (isa<CXXThisExpr>(E)) {
4887 if (UniformedLinearThis) {
4888 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
4889 << getOpenMPClauseName(OMPC_linear)
4890 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
4891 << E->getSourceRange();
4892 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
4893 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
4894 : OMPC_linear);
4895 continue;
4896 }
4897 UniformedLinearThis = E;
4898 if (E->isValueDependent() || E->isTypeDependent() ||
4899 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
4900 continue;
4901 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
4902 E->getType());
4903 continue;
4904 }
4905 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
4906 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4907 }
4908 Expr *Step = nullptr;
4909 Expr *NewStep = nullptr;
4910 SmallVector<Expr *, 4> NewSteps;
Alexey Bataeve3727102018-04-18 15:57:46 +00004911 for (Expr *E : Steps) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004912 // Skip the same step expression, it was checked already.
4913 if (Step == E || !E) {
4914 NewSteps.push_back(E ? NewStep : nullptr);
4915 continue;
4916 }
4917 Step = E;
Alexey Bataeve3727102018-04-18 15:57:46 +00004918 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
4919 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4920 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
Alexey Bataevecba70f2016-04-12 11:02:11 +00004921 if (UniformedArgs.count(CanonPVD) == 0) {
4922 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
4923 << Step->getSourceRange();
4924 } else if (E->isValueDependent() || E->isTypeDependent() ||
4925 E->isInstantiationDependent() ||
4926 E->containsUnexpandedParameterPack() ||
Alexey Bataeve3727102018-04-18 15:57:46 +00004927 CanonPVD->getType()->hasIntegerRepresentation()) {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004928 NewSteps.push_back(Step);
Alexey Bataeve3727102018-04-18 15:57:46 +00004929 } else {
Alexey Bataevecba70f2016-04-12 11:02:11 +00004930 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
4931 << Step->getSourceRange();
4932 }
4933 continue;
4934 }
4935 NewStep = Step;
4936 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
4937 !Step->isInstantiationDependent() &&
4938 !Step->containsUnexpandedParameterPack()) {
4939 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
4940 .get();
4941 if (NewStep)
4942 NewStep = VerifyIntegerConstantExpression(NewStep).get();
4943 }
4944 NewSteps.push_back(NewStep);
4945 }
Alexey Bataeve48a5fc2016-04-12 05:28:34 +00004946 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
4947 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
Alexey Bataevd93d3762016-04-12 09:35:56 +00004948 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
Alexey Bataevecba70f2016-04-12 11:02:11 +00004949 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
4950 const_cast<Expr **>(Linears.data()), Linears.size(),
4951 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
4952 NewSteps.data(), NewSteps.size(), SR);
Alexey Bataev587e1de2016-03-30 10:43:55 +00004953 ADecl->addAttr(NewAttr);
Alexey Bataeva0063072019-09-16 17:06:31 +00004954 return DG;
Alexey Bataev587e1de2016-03-30 10:43:55 +00004955}
4956
Alexey Bataev0736f7f2019-09-18 16:24:31 +00004957Optional<std::pair<FunctionDecl *, Expr *>>
4958Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
4959 Expr *VariantRef, SourceRange SR) {
Alexey Bataevd158cf62019-09-13 20:18:17 +00004960 if (!DG || DG.get().isNull())
Alexey Bataev0736f7f2019-09-18 16:24:31 +00004961 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00004962
4963 const int VariantId = 1;
4964 // Must be applied only to single decl.
4965 if (!DG.get().isSingleDecl()) {
4966 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
4967 << VariantId << SR;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00004968 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00004969 }
4970 Decl *ADecl = DG.get().getSingleDecl();
4971 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4972 ADecl = FTD->getTemplatedDecl();
4973
4974 // Decl must be a function.
4975 auto *FD = dyn_cast<FunctionDecl>(ADecl);
4976 if (!FD) {
4977 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
4978 << VariantId << SR;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00004979 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00004980 }
4981
4982 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
4983 return FD->hasAttrs() &&
4984 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
4985 FD->hasAttr<TargetAttr>());
4986 };
4987 // OpenMP is not compatible with CPU-specific attributes.
4988 if (HasMultiVersionAttributes(FD)) {
4989 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
4990 << SR;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00004991 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00004992 }
4993
4994 // Allow #pragma omp declare variant only if the function is not used.
Alexey Bataev12026142019-09-26 20:04:15 +00004995 if (FD->isUsed(false))
4996 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
Alexey Bataevd158cf62019-09-13 20:18:17 +00004997 << FD->getLocation();
Alexey Bataev12026142019-09-26 20:04:15 +00004998
4999 // Check if the function was emitted already.
Alexey Bataev218bea92019-09-30 18:24:35 +00005000 const FunctionDecl *Definition;
5001 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5002 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
Alexey Bataev12026142019-09-26 20:04:15 +00005003 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
5004 << FD->getLocation();
Alexey Bataevd158cf62019-09-13 20:18:17 +00005005
5006 // The VariantRef must point to function.
5007 if (!VariantRef) {
5008 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005009 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005010 }
5011
5012 // Do not check templates, wait until instantiation.
5013 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() ||
5014 VariantRef->containsUnexpandedParameterPack() ||
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005015 VariantRef->isInstantiationDependent() || FD->isDependentContext())
5016 return std::make_pair(FD, VariantRef);
Alexey Bataevd158cf62019-09-13 20:18:17 +00005017
5018 // Convert VariantRef expression to the type of the original function to
5019 // resolve possible conflicts.
5020 ExprResult VariantRefCast;
5021 if (LangOpts.CPlusPlus) {
5022 QualType FnPtrType;
5023 auto *Method = dyn_cast<CXXMethodDecl>(FD);
5024 if (Method && !Method->isStatic()) {
5025 const Type *ClassType =
5026 Context.getTypeDeclType(Method->getParent()).getTypePtr();
5027 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
5028 ExprResult ER;
5029 {
5030 // Build adrr_of unary op to correctly handle type checks for member
5031 // functions.
5032 Sema::TentativeAnalysisScope Trap(*this);
5033 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
5034 VariantRef);
5035 }
5036 if (!ER.isUsable()) {
5037 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5038 << VariantId << VariantRef->getSourceRange();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005039 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005040 }
5041 VariantRef = ER.get();
5042 } else {
5043 FnPtrType = Context.getPointerType(FD->getType());
5044 }
5045 ImplicitConversionSequence ICS =
5046 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
5047 /*SuppressUserConversions=*/false,
5048 /*AllowExplicit=*/false,
5049 /*InOverloadResolution=*/false,
5050 /*CStyle=*/false,
5051 /*AllowObjCWritebackConversion=*/false);
5052 if (ICS.isFailure()) {
5053 Diag(VariantRef->getExprLoc(),
5054 diag::err_omp_declare_variant_incompat_types)
5055 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005056 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005057 }
5058 VariantRefCast = PerformImplicitConversion(
5059 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
5060 if (!VariantRefCast.isUsable())
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005061 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005062 // Drop previously built artificial addr_of unary op for member functions.
5063 if (Method && !Method->isStatic()) {
5064 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
5065 if (auto *UO = dyn_cast<UnaryOperator>(
5066 PossibleAddrOfVariantRef->IgnoreImplicit()))
5067 VariantRefCast = UO->getSubExpr();
5068 }
5069 } else {
5070 VariantRefCast = VariantRef;
5071 }
5072
5073 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
5074 if (!ER.isUsable() ||
5075 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5076 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5077 << VariantId << VariantRef->getSourceRange();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005078 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005079 }
5080
5081 // The VariantRef must point to function.
5082 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
5083 if (!DRE) {
5084 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5085 << VariantId << VariantRef->getSourceRange();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005086 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005087 }
5088 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5089 if (!NewFD) {
5090 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5091 << VariantId << VariantRef->getSourceRange();
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005092 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005093 }
5094
Alexey Bataevbf5d4292019-09-17 17:36:49 +00005095 // Check if variant function is not marked with declare variant directive.
5096 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5097 Diag(VariantRef->getExprLoc(),
5098 diag::warn_omp_declare_variant_marked_as_declare_variant)
5099 << VariantRef->getSourceRange();
5100 SourceRange SR =
5101 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5102 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005103 return None;
Alexey Bataevbf5d4292019-09-17 17:36:49 +00005104 }
5105
Alexey Bataevd158cf62019-09-13 20:18:17 +00005106 enum DoesntSupport {
5107 VirtFuncs = 1,
5108 Constructors = 3,
5109 Destructors = 4,
5110 DeletedFuncs = 5,
5111 DefaultedFuncs = 6,
5112 ConstexprFuncs = 7,
5113 ConstevalFuncs = 8,
5114 };
5115 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5116 if (CXXFD->isVirtual()) {
5117 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5118 << VirtFuncs;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005119 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005120 }
5121
5122 if (isa<CXXConstructorDecl>(FD)) {
5123 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5124 << Constructors;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005125 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005126 }
5127
5128 if (isa<CXXDestructorDecl>(FD)) {
5129 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5130 << Destructors;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005131 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005132 }
5133 }
5134
5135 if (FD->isDeleted()) {
5136 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5137 << DeletedFuncs;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005138 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005139 }
5140
5141 if (FD->isDefaulted()) {
5142 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5143 << DefaultedFuncs;
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005144 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005145 }
5146
5147 if (FD->isConstexpr()) {
5148 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5149 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005150 return None;
Alexey Bataevd158cf62019-09-13 20:18:17 +00005151 }
5152
5153 // Check general compatibility.
5154 if (areMultiversionVariantFunctionsCompatible(
5155 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto),
5156 PartialDiagnosticAt(
5157 SR.getBegin(),
5158 PDiag(diag::note_omp_declare_variant_specified_here) << SR),
5159 PartialDiagnosticAt(
5160 VariantRef->getExprLoc(),
5161 PDiag(diag::err_omp_declare_variant_doesnt_support)),
5162 PartialDiagnosticAt(VariantRef->getExprLoc(),
5163 PDiag(diag::err_omp_declare_variant_diff)
5164 << FD->getLocation()),
Alexey Bataev6b06ead2019-10-08 14:56:20 +00005165 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
5166 /*CLinkageMayDiffer=*/true))
Alexey Bataev0736f7f2019-09-18 16:24:31 +00005167 return None;
5168 return std::make_pair(FD, cast<Expr>(DRE));
5169}
Alexey Bataevd158cf62019-09-13 20:18:17 +00005170
Alexey Bataev9ff34742019-09-25 19:43:37 +00005171void Sema::ActOnOpenMPDeclareVariantDirective(
5172 FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
5173 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
5174 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown ||
5175 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown)
5176 return;
Alexey Bataeva15a1412019-10-02 18:19:02 +00005177 Expr *Score = nullptr;
5178 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown;
5179 if (Data.CtxScore.isUsable()) {
5180 ST = OMPDeclareVariantAttr::ScoreSpecified;
5181 Score = Data.CtxScore.get();
5182 if (!Score->isTypeDependent() && !Score->isValueDependent() &&
5183 !Score->isInstantiationDependent() &&
5184 !Score->containsUnexpandedParameterPack()) {
5185 llvm::APSInt Result;
5186 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result);
5187 if (ICE.isInvalid())
5188 return;
5189 }
5190 }
Alexey Bataev9ff34742019-09-25 19:43:37 +00005191 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
Alexey Bataev303657a2019-10-08 19:44:16 +00005192 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx,
5193 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR);
Alexey Bataevbf5d4292019-09-17 17:36:49 +00005194 FD->addAttr(NewAttr);
Alexey Bataevd158cf62019-09-13 20:18:17 +00005195}
5196
Alexey Bataevbf5d4292019-09-17 17:36:49 +00005197void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
5198 FunctionDecl *Func,
5199 bool MightBeOdrUse) {
5200 assert(LangOpts.OpenMP && "Expected OpenMP mode.");
5201
5202 if (!Func->isDependentContext() && Func->hasAttrs()) {
5203 for (OMPDeclareVariantAttr *A :
5204 Func->specific_attrs<OMPDeclareVariantAttr>()) {
5205 // TODO: add checks for active OpenMP context where possible.
5206 Expr *VariantRef = A->getVariantFuncRef();
5207 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts());
5208 auto *F = cast<FunctionDecl>(DRE->getDecl());
5209 if (!F->isDefined() && F->isTemplateInstantiation())
5210 InstantiateFunctionDefinition(Loc, F->getFirstDecl());
5211 MarkFunctionReferenced(Loc, F, MightBeOdrUse);
5212 }
5213 }
5214}
5215
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005216StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
5217 Stmt *AStmt,
5218 SourceLocation StartLoc,
5219 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00005220 if (!AStmt)
5221 return StmtError();
5222
Alexey Bataeve3727102018-04-18 15:57:46 +00005223 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev9959db52014-05-06 10:08:46 +00005224 // 1.2.2 OpenMP Language Terminology
5225 // Structured block - An executable statement with a single entry at the
5226 // top and a single exit at the bottom.
5227 // The point of exit cannot be a branch out of the structured block.
5228 // longjmp() and throw() must not violate the entry/exit criteria.
5229 CS->getCapturedDecl()->setNothrow();
5230
Reid Kleckner87a31802018-03-12 21:43:02 +00005231 setFunctionHasBranchProtectedScope();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005232
Alexey Bataev25e5b442015-09-15 12:52:43 +00005233 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5234 DSAStack->isCancelRegion());
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005235}
5236
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005237namespace {
Alexey Bataevf8be4762019-08-14 19:30:06 +00005238/// Iteration space of a single for loop.
5239struct LoopIterationSpace final {
5240 /// True if the condition operator is the strict compare operator (<, > or
5241 /// !=).
5242 bool IsStrictCompare = false;
5243 /// Condition of the loop.
5244 Expr *PreCond = nullptr;
5245 /// This expression calculates the number of iterations in the loop.
5246 /// It is always possible to calculate it before starting the loop.
5247 Expr *NumIterations = nullptr;
5248 /// The loop counter variable.
5249 Expr *CounterVar = nullptr;
5250 /// Private loop counter variable.
5251 Expr *PrivateCounterVar = nullptr;
5252 /// This is initializer for the initial value of #CounterVar.
5253 Expr *CounterInit = nullptr;
5254 /// This is step for the #CounterVar used to generate its update:
5255 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
5256 Expr *CounterStep = nullptr;
5257 /// Should step be subtracted?
5258 bool Subtract = false;
5259 /// Source range of the loop init.
5260 SourceRange InitSrcRange;
5261 /// Source range of the loop condition.
5262 SourceRange CondSrcRange;
5263 /// Source range of the loop increment.
5264 SourceRange IncSrcRange;
5265 /// Minimum value that can have the loop control variable. Used to support
5266 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
5267 /// since only such variables can be used in non-loop invariant expressions.
5268 Expr *MinValue = nullptr;
5269 /// Maximum value that can have the loop control variable. Used to support
5270 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
5271 /// since only such variables can be used in non-loop invariant expressions.
5272 Expr *MaxValue = nullptr;
5273 /// true, if the lower bound depends on the outer loop control var.
5274 bool IsNonRectangularLB = false;
5275 /// true, if the upper bound depends on the outer loop control var.
5276 bool IsNonRectangularUB = false;
5277 /// Index of the loop this loop depends on and forms non-rectangular loop
5278 /// nest.
5279 unsigned LoopDependentIdx = 0;
5280 /// Final condition for the non-rectangular loop nest support. It is used to
5281 /// check that the number of iterations for this particular counter must be
5282 /// finished.
5283 Expr *FinalCondition = nullptr;
5284};
5285
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005286/// Helper class for checking canonical form of the OpenMP loops and
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005287/// extracting iteration space of each loop in the loop nest, that will be used
5288/// for IR generation.
5289class OpenMPIterationSpaceChecker {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005290 /// Reference to Sema.
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005291 Sema &SemaRef;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005292 /// Data-sharing stack.
5293 DSAStackTy &Stack;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005294 /// A location for diagnostics (when there is no some better location).
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005295 SourceLocation DefaultLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005296 /// A location for diagnostics (when increment is not compatible).
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005297 SourceLocation ConditionLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005298 /// A source location for referring to loop init later.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005299 SourceRange InitSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005300 /// A source location for referring to condition later.
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005301 SourceRange ConditionSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005302 /// A source location for referring to increment later.
Alexander Musmana5f070a2014-10-01 06:03:56 +00005303 SourceRange IncrementSrcRange;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005304 /// Loop variable.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005305 ValueDecl *LCDecl = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005306 /// Reference to loop variable.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005307 Expr *LCRef = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005308 /// Lower bound (initializer for the var).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005309 Expr *LB = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005310 /// Upper bound.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005311 Expr *UB = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005312 /// Loop step (increment).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005313 Expr *Step = nullptr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005314 /// This flag is true when condition is one of:
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005315 /// Var < UB
5316 /// Var <= UB
5317 /// UB > Var
5318 /// UB >= Var
Kelvin Liefbe4af2018-11-21 19:10:48 +00005319 /// This will have no value when the condition is !=
5320 llvm::Optional<bool> TestIsLessOp;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005321 /// This flag is true when condition is strict ( < or > ).
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005322 bool TestIsStrictOp = false;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005323 /// This flag is true when step is subtracted on each iteration.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005324 bool SubtractStep = false;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005325 /// The outer loop counter this loop depends on (if any).
5326 const ValueDecl *DepDecl = nullptr;
5327 /// Contains number of loop (starts from 1) on which loop counter init
5328 /// expression of this loop depends on.
5329 Optional<unsigned> InitDependOnLC;
5330 /// Contains number of loop (starts from 1) on which loop counter condition
5331 /// expression of this loop depends on.
5332 Optional<unsigned> CondDependOnLC;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005333 /// Checks if the provide statement depends on the loop counter.
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005334 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
Alexey Bataevf8be4762019-08-14 19:30:06 +00005335 /// Original condition required for checking of the exit condition for
5336 /// non-rectangular loop.
5337 Expr *Condition = nullptr;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005338
5339public:
Alexey Bataev622af1d2019-04-24 19:58:30 +00005340 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
5341 SourceLocation DefaultLoc)
5342 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
5343 ConditionLoc(DefaultLoc) {}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005344 /// Check init-expr for canonical loop form and save loop counter
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005345 /// variable - #Var and its initialization value - #LB.
Alexey Bataeve3727102018-04-18 15:57:46 +00005346 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005347 /// Check test-expr for canonical form, save upper-bound (#UB), flags
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005348 /// for less/greater and for strict/non-strict comparison.
Alexey Bataeve3727102018-04-18 15:57:46 +00005349 bool checkAndSetCond(Expr *S);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005350 /// Check incr-expr for canonical loop form and return true if it
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005351 /// does not conform, otherwise save loop step (#Step).
Alexey Bataeve3727102018-04-18 15:57:46 +00005352 bool checkAndSetInc(Expr *S);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005353 /// Return the loop counter variable.
Alexey Bataeve3727102018-04-18 15:57:46 +00005354 ValueDecl *getLoopDecl() const { return LCDecl; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005355 /// Return the reference expression to loop counter variable.
Alexey Bataeve3727102018-04-18 15:57:46 +00005356 Expr *getLoopDeclRefExpr() const { return LCRef; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005357 /// Source range of the loop init.
Alexey Bataeve3727102018-04-18 15:57:46 +00005358 SourceRange getInitSrcRange() const { return InitSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005359 /// Source range of the loop condition.
Alexey Bataeve3727102018-04-18 15:57:46 +00005360 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005361 /// Source range of the loop increment.
Alexey Bataeve3727102018-04-18 15:57:46 +00005362 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005363 /// True if the step should be subtracted.
Alexey Bataeve3727102018-04-18 15:57:46 +00005364 bool shouldSubtractStep() const { return SubtractStep; }
Alexey Bataev316ccf62019-01-29 18:51:58 +00005365 /// True, if the compare operator is strict (<, > or !=).
5366 bool isStrictTestOp() const { return TestIsStrictOp; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005367 /// Build the expression to calculate the number of iterations.
Alexey Bataeve3727102018-04-18 15:57:46 +00005368 Expr *buildNumIterations(
Alexey Bataevf8be4762019-08-14 19:30:06 +00005369 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
Alexey Bataeve3727102018-04-18 15:57:46 +00005370 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005371 /// Build the precondition expression for the loops.
Alexey Bataeve3727102018-04-18 15:57:46 +00005372 Expr *
5373 buildPreCond(Scope *S, Expr *Cond,
5374 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005375 /// Build reference expression to the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005376 DeclRefExpr *
5377 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5378 DSAStackTy &DSA) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005379 /// Build reference expression to the private counter be used for
Alexey Bataeva8899172015-08-06 12:30:57 +00005380 /// codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005381 Expr *buildPrivateCounterVar() const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005382 /// Build initialization of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005383 Expr *buildCounterInit() const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005384 /// Build step of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00005385 Expr *buildCounterStep() const;
Alexey Bataevf138fda2018-08-13 19:04:24 +00005386 /// Build loop data with counter value for depend clauses in ordered
5387 /// directives.
5388 Expr *
5389 buildOrderedLoopData(Scope *S, Expr *Counter,
5390 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5391 SourceLocation Loc, Expr *Inc = nullptr,
5392 OverloadedOperatorKind OOK = OO_Amp);
Alexey Bataevf8be4762019-08-14 19:30:06 +00005393 /// Builds the minimum value for the loop counter.
5394 std::pair<Expr *, Expr *> buildMinMaxValues(
5395 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5396 /// Builds final condition for the non-rectangular loops.
5397 Expr *buildFinalCondition(Scope *S) const;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005398 /// Return true if any expression is dependent.
Alexey Bataeve3727102018-04-18 15:57:46 +00005399 bool dependent() const;
Alexey Bataevf8be4762019-08-14 19:30:06 +00005400 /// Returns true if the initializer forms non-rectangular loop.
5401 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
5402 /// Returns true if the condition forms non-rectangular loop.
5403 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
5404 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
5405 unsigned getLoopDependentIdx() const {
5406 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
5407 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005408
5409private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005410 /// Check the right-hand side of an assignment in the increment
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005411 /// expression.
Alexey Bataeve3727102018-04-18 15:57:46 +00005412 bool checkAndSetIncRHS(Expr *RHS);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005413 /// Helper to set loop counter variable and its initializer.
Alexey Bataev622af1d2019-04-24 19:58:30 +00005414 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
5415 bool EmitDiags);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005416 /// Helper to set upper bound.
Kelvin Liefbe4af2018-11-21 19:10:48 +00005417 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
5418 SourceRange SR, SourceLocation SL);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005419 /// Helper to set loop increment.
Alexey Bataeve3727102018-04-18 15:57:46 +00005420 bool setStep(Expr *NewStep, bool Subtract);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005421};
5422
Alexey Bataeve3727102018-04-18 15:57:46 +00005423bool OpenMPIterationSpaceChecker::dependent() const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005424 if (!LCDecl) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005425 assert(!LB && !UB && !Step);
5426 return false;
5427 }
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005428 return LCDecl->getType()->isDependentType() ||
5429 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
5430 (Step && Step->isValueDependent());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005431}
5432
Alexey Bataeve3727102018-04-18 15:57:46 +00005433bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005434 Expr *NewLCRefExpr,
Alexey Bataev622af1d2019-04-24 19:58:30 +00005435 Expr *NewLB, bool EmitDiags) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005436 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005437 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
Alexey Bataevcaf09b02014-07-25 06:27:47 +00005438 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005439 if (!NewLCDecl || !NewLB)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005440 return true;
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005441 LCDecl = getCanonicalDecl(NewLCDecl);
5442 LCRef = NewLCRefExpr;
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005443 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
5444 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
Alexey Bataev0d08a7f2015-07-16 04:19:43 +00005445 if ((Ctor->isCopyOrMoveConstructor() ||
5446 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5447 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005448 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005449 LB = NewLB;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005450 if (EmitDiags)
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005451 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005452 return false;
5453}
5454
Alexey Bataev316ccf62019-01-29 18:51:58 +00005455bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
5456 llvm::Optional<bool> LessOp,
Kelvin Liefbe4af2018-11-21 19:10:48 +00005457 bool StrictOp, SourceRange SR,
5458 SourceLocation SL) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005459 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005460 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
5461 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005462 if (!NewUB)
5463 return true;
5464 UB = NewUB;
Kelvin Liefbe4af2018-11-21 19:10:48 +00005465 if (LessOp)
5466 TestIsLessOp = LessOp;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005467 TestIsStrictOp = StrictOp;
5468 ConditionSrcRange = SR;
5469 ConditionLoc = SL;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005470 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005471 return false;
5472}
5473
Alexey Bataeve3727102018-04-18 15:57:46 +00005474bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005475 // State consistency checking to ensure correct usage.
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005476 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005477 if (!NewStep)
5478 return true;
5479 if (!NewStep->isValueDependent()) {
5480 // Check that the step is integer expression.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005481 SourceLocation StepLoc = NewStep->getBeginLoc();
Alexey Bataev5372fb82017-08-31 23:06:52 +00005482 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
5483 StepLoc, getExprAsWritten(NewStep));
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005484 if (Val.isInvalid())
5485 return true;
5486 NewStep = Val.get();
5487
5488 // OpenMP [2.6, Canonical Loop Form, Restrictions]
5489 // If test-expr is of form var relational-op b and relational-op is < or
5490 // <= then incr-expr must cause var to increase on each iteration of the
5491 // loop. If test-expr is of form var relational-op b and relational-op is
5492 // > or >= then incr-expr must cause var to decrease on each iteration of
5493 // the loop.
5494 // If test-expr is of form b relational-op var and relational-op is < or
5495 // <= then incr-expr must cause var to decrease on each iteration of the
5496 // loop. If test-expr is of form b relational-op var and relational-op is
5497 // > or >= then incr-expr must cause var to increase on each iteration of
5498 // the loop.
5499 llvm::APSInt Result;
5500 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
5501 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
5502 bool IsConstNeg =
5503 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
Alexander Musmana5f070a2014-10-01 06:03:56 +00005504 bool IsConstPos =
5505 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005506 bool IsConstZero = IsConstant && !Result.getBoolValue();
Kelvin Liefbe4af2018-11-21 19:10:48 +00005507
5508 // != with increment is treated as <; != with decrement is treated as >
5509 if (!TestIsLessOp.hasValue())
5510 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005511 if (UB && (IsConstZero ||
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00005512 (TestIsLessOp.getValue() ?
Kelvin Liefbe4af2018-11-21 19:10:48 +00005513 (IsConstNeg || (IsUnsigned && Subtract)) :
5514 (IsConstPos || (IsUnsigned && !Subtract))))) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005515 SemaRef.Diag(NewStep->getExprLoc(),
5516 diag::err_omp_loop_incr_not_compatible)
Kelvin Liefbe4af2018-11-21 19:10:48 +00005517 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005518 SemaRef.Diag(ConditionLoc,
5519 diag::note_omp_loop_cond_requres_compatible_incr)
Kelvin Liefbe4af2018-11-21 19:10:48 +00005520 << TestIsLessOp.getValue() << ConditionSrcRange;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005521 return true;
5522 }
Kelvin Liefbe4af2018-11-21 19:10:48 +00005523 if (TestIsLessOp.getValue() == Subtract) {
David Majnemer9d168222016-08-05 17:44:54 +00005524 NewStep =
5525 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
5526 .get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00005527 Subtract = !Subtract;
5528 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005529 }
5530
5531 Step = NewStep;
5532 SubtractStep = Subtract;
5533 return false;
5534}
5535
Alexey Bataev622af1d2019-04-24 19:58:30 +00005536namespace {
5537/// Checker for the non-rectangular loops. Checks if the initializer or
5538/// condition expression references loop counter variable.
5539class LoopCounterRefChecker final
5540 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
5541 Sema &SemaRef;
5542 DSAStackTy &Stack;
5543 const ValueDecl *CurLCDecl = nullptr;
Alexey Bataev2f9ef332019-04-25 16:21:13 +00005544 const ValueDecl *DepDecl = nullptr;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005545 const ValueDecl *PrevDepDecl = nullptr;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005546 bool IsInitializer = true;
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005547 unsigned BaseLoopId = 0;
5548 bool checkDecl(const Expr *E, const ValueDecl *VD) {
5549 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
5550 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
5551 << (IsInitializer ? 0 : 1);
5552 return false;
5553 }
5554 const auto &&Data = Stack.isLoopControlVariable(VD);
5555 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
5556 // The type of the loop iterator on which we depend may not have a random
5557 // access iterator type.
5558 if (Data.first && VD->getType()->isRecordType()) {
5559 SmallString<128> Name;
5560 llvm::raw_svector_ostream OS(Name);
5561 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5562 /*Qualified=*/true);
5563 SemaRef.Diag(E->getExprLoc(),
5564 diag::err_omp_wrong_dependency_iterator_type)
5565 << OS.str();
5566 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
5567 return false;
5568 }
5569 if (Data.first &&
5570 (DepDecl || (PrevDepDecl &&
5571 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
5572 if (!DepDecl && PrevDepDecl)
5573 DepDecl = PrevDepDecl;
5574 SmallString<128> Name;
5575 llvm::raw_svector_ostream OS(Name);
5576 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5577 /*Qualified=*/true);
5578 SemaRef.Diag(E->getExprLoc(),
5579 diag::err_omp_invariant_or_linear_dependency)
5580 << OS.str();
5581 return false;
5582 }
5583 if (Data.first) {
5584 DepDecl = VD;
5585 BaseLoopId = Data.first;
5586 }
5587 return Data.first;
5588 }
Alexey Bataev622af1d2019-04-24 19:58:30 +00005589
5590public:
5591 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5592 const ValueDecl *VD = E->getDecl();
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005593 if (isa<VarDecl>(VD))
5594 return checkDecl(E, VD);
Alexey Bataev622af1d2019-04-24 19:58:30 +00005595 return false;
5596 }
5597 bool VisitMemberExpr(const MemberExpr *E) {
5598 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
5599 const ValueDecl *VD = E->getMemberDecl();
Mike Rice552c2c02019-07-17 15:18:45 +00005600 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
5601 return checkDecl(E, VD);
Alexey Bataev622af1d2019-04-24 19:58:30 +00005602 }
5603 return false;
5604 }
5605 bool VisitStmt(const Stmt *S) {
Alexey Bataevf8be4762019-08-14 19:30:06 +00005606 bool Res = false;
Alexey Bataev2f9ef332019-04-25 16:21:13 +00005607 for (const Stmt *Child : S->children())
Alexey Bataevf8be4762019-08-14 19:30:06 +00005608 Res = (Child && Visit(Child)) || Res;
Alexey Bataev2f9ef332019-04-25 16:21:13 +00005609 return Res;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005610 }
5611 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005612 const ValueDecl *CurLCDecl, bool IsInitializer,
5613 const ValueDecl *PrevDepDecl = nullptr)
Alexey Bataev622af1d2019-04-24 19:58:30 +00005614 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005615 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
5616 unsigned getBaseLoopId() const {
5617 assert(CurLCDecl && "Expected loop dependency.");
5618 return BaseLoopId;
5619 }
5620 const ValueDecl *getDepDecl() const {
5621 assert(CurLCDecl && "Expected loop dependency.");
5622 return DepDecl;
5623 }
Alexey Bataev622af1d2019-04-24 19:58:30 +00005624};
5625} // namespace
5626
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005627Optional<unsigned>
5628OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
5629 bool IsInitializer) {
Alexey Bataev622af1d2019-04-24 19:58:30 +00005630 // Check for the non-rectangular loops.
Alexey Bataev5ddc6d12019-04-26 19:28:37 +00005631 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
5632 DepDecl);
5633 if (LoopStmtChecker.Visit(S)) {
5634 DepDecl = LoopStmtChecker.getDepDecl();
5635 return LoopStmtChecker.getBaseLoopId();
5636 }
5637 return llvm::None;
Alexey Bataev622af1d2019-04-24 19:58:30 +00005638}
5639
Alexey Bataeve3727102018-04-18 15:57:46 +00005640bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005641 // Check init-expr for canonical loop form and save loop counter
5642 // variable - #Var and its initialization value - #LB.
5643 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
5644 // var = lb
5645 // integer-type var = lb
5646 // random-access-iterator-type var = lb
5647 // pointer-type var = lb
5648 //
5649 if (!S) {
Alexey Bataev9c821032015-04-30 04:23:23 +00005650 if (EmitDiags) {
5651 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
5652 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005653 return true;
5654 }
Tim Shen4a05bb82016-06-21 20:29:17 +00005655 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5656 if (!ExprTemp->cleanupsHaveSideEffects())
5657 S = ExprTemp->getSubExpr();
5658
Alexander Musmana5f070a2014-10-01 06:03:56 +00005659 InitSrcRange = S->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005660 if (Expr *E = dyn_cast<Expr>(S))
5661 S = E->IgnoreParens();
David Majnemer9d168222016-08-05 17:44:54 +00005662 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005663 if (BO->getOpcode() == BO_Assign) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005664 Expr *LHS = BO->getLHS()->IgnoreParens();
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005665 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
5666 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5667 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev622af1d2019-04-24 19:58:30 +00005668 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5669 EmitDiags);
5670 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005671 }
5672 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
5673 if (ME->isArrow() &&
5674 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
Alexey Bataev622af1d2019-04-24 19:58:30 +00005675 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5676 EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005677 }
5678 }
David Majnemer9d168222016-08-05 17:44:54 +00005679 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005680 if (DS->isSingleDecl()) {
David Majnemer9d168222016-08-05 17:44:54 +00005681 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
Alexey Bataeva8899172015-08-06 12:30:57 +00005682 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005683 // Accept non-canonical init form here but emit ext. warning.
Alexey Bataev9c821032015-04-30 04:23:23 +00005684 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005685 SemaRef.Diag(S->getBeginLoc(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005686 diag::ext_omp_loop_not_canonical_init)
5687 << S->getSourceRange();
Alexey Bataevf138fda2018-08-13 19:04:24 +00005688 return setLCDeclAndLB(
5689 Var,
5690 buildDeclRefExpr(SemaRef, Var,
5691 Var->getType().getNonReferenceType(),
5692 DS->getBeginLoc()),
Alexey Bataev622af1d2019-04-24 19:58:30 +00005693 Var->getInit(), EmitDiags);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005694 }
5695 }
5696 }
David Majnemer9d168222016-08-05 17:44:54 +00005697 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005698 if (CE->getOperator() == OO_Equal) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005699 Expr *LHS = CE->getArg(0);
David Majnemer9d168222016-08-05 17:44:54 +00005700 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005701 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5702 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
Alexey Bataev622af1d2019-04-24 19:58:30 +00005703 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5704 EmitDiags);
5705 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005706 }
5707 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
5708 if (ME->isArrow() &&
5709 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
Alexey Bataev622af1d2019-04-24 19:58:30 +00005710 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5711 EmitDiags);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005712 }
5713 }
5714 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005715
Alexey Bataeve3727102018-04-18 15:57:46 +00005716 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005717 return false;
Alexey Bataev9c821032015-04-30 04:23:23 +00005718 if (EmitDiags) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005719 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
Alexey Bataev9c821032015-04-30 04:23:23 +00005720 << S->getSourceRange();
5721 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005722 return true;
5723}
5724
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005725/// Ignore parenthesizes, implicit casts, copy constructor and return the
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005726/// variable (which may be the loop variable) if possible.
Alexey Bataeve3727102018-04-18 15:57:46 +00005727static const ValueDecl *getInitLCDecl(const Expr *E) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005728 if (!E)
Craig Topper4b566922014-06-09 02:04:02 +00005729 return nullptr;
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005730 E = getExprAsWritten(E);
Alexey Bataeve3727102018-04-18 15:57:46 +00005731 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005732 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
Alexey Bataev0d08a7f2015-07-16 04:19:43 +00005733 if ((Ctor->isCopyOrMoveConstructor() ||
5734 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5735 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005736 E = CE->getArg(0)->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00005737 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
5738 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005739 return getCanonicalDecl(VD);
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005740 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005741 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005742 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5743 return getCanonicalDecl(ME->getMemberDecl());
5744 return nullptr;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005745}
5746
Alexey Bataeve3727102018-04-18 15:57:46 +00005747bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005748 // Check test-expr for canonical form, save upper-bound UB, flags for
5749 // less/greater and for strict/non-strict comparison.
Alexey Bataev1be63402019-09-11 15:44:06 +00005750 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005751 // var relational-op b
5752 // b relational-op var
5753 //
Alexey Bataev1be63402019-09-11 15:44:06 +00005754 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005755 if (!S) {
Alexey Bataev1be63402019-09-11 15:44:06 +00005756 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
5757 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005758 return true;
5759 }
Alexey Bataevf8be4762019-08-14 19:30:06 +00005760 Condition = S;
Alexey Bataev3bed68c2015-07-15 12:14:07 +00005761 S = getExprAsWritten(S);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005762 SourceLocation CondLoc = S->getBeginLoc();
David Majnemer9d168222016-08-05 17:44:54 +00005763 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005764 if (BO->isRelationalOp()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005765 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5766 return setUB(BO->getRHS(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005767 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
5768 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5769 BO->getSourceRange(), BO->getOperatorLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +00005770 if (getInitLCDecl(BO->getRHS()) == LCDecl)
5771 return setUB(BO->getLHS(),
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005772 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
5773 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5774 BO->getSourceRange(), BO->getOperatorLoc());
Alexey Bataev1be63402019-09-11 15:44:06 +00005775 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
5776 return setUB(
5777 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
5778 /*LessOp=*/llvm::None,
5779 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
David Majnemer9d168222016-08-05 17:44:54 +00005780 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005781 if (CE->getNumArgs() == 2) {
5782 auto Op = CE->getOperator();
5783 switch (Op) {
5784 case OO_Greater:
5785 case OO_GreaterEqual:
5786 case OO_Less:
5787 case OO_LessEqual:
Alexey Bataeve3727102018-04-18 15:57:46 +00005788 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5789 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005790 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5791 CE->getOperatorLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +00005792 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
5793 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005794 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5795 CE->getOperatorLoc());
5796 break;
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00005797 case OO_ExclaimEqual:
Alexey Bataev1be63402019-09-11 15:44:06 +00005798 if (IneqCondIsCanonical)
5799 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
5800 : CE->getArg(0),
5801 /*LessOp=*/llvm::None,
5802 /*StrictOp=*/true, CE->getSourceRange(),
5803 CE->getOperatorLoc());
Kelvin Liefbe4af2018-11-21 19:10:48 +00005804 break;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005805 default:
5806 break;
5807 }
5808 }
5809 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005810 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005811 return false;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005812 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
Alexey Bataev1be63402019-09-11 15:44:06 +00005813 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005814 return true;
5815}
5816
Alexey Bataeve3727102018-04-18 15:57:46 +00005817bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005818 // RHS of canonical loop form increment can be:
5819 // var + incr
5820 // incr + var
5821 // var - incr
5822 //
5823 RHS = RHS->IgnoreParenImpCasts();
David Majnemer9d168222016-08-05 17:44:54 +00005824 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005825 if (BO->isAdditiveOp()) {
5826 bool IsAdd = BO->getOpcode() == BO_Add;
Alexey Bataeve3727102018-04-18 15:57:46 +00005827 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5828 return setStep(BO->getRHS(), !IsAdd);
5829 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
5830 return setStep(BO->getLHS(), /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005831 }
David Majnemer9d168222016-08-05 17:44:54 +00005832 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005833 bool IsAdd = CE->getOperator() == OO_Plus;
5834 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
Alexey Bataeve3727102018-04-18 15:57:46 +00005835 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5836 return setStep(CE->getArg(1), !IsAdd);
5837 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
5838 return setStep(CE->getArg(0), /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005839 }
5840 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005841 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005842 return false;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005843 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005844 << RHS->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005845 return true;
5846}
5847
Alexey Bataeve3727102018-04-18 15:57:46 +00005848bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005849 // Check incr-expr for canonical loop form and return true if it
5850 // does not conform.
5851 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
5852 // ++var
5853 // var++
5854 // --var
5855 // var--
5856 // var += incr
5857 // var -= incr
5858 // var = var + incr
5859 // var = incr + var
5860 // var = var - incr
5861 //
5862 if (!S) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005863 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005864 return true;
5865 }
Tim Shen4a05bb82016-06-21 20:29:17 +00005866 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5867 if (!ExprTemp->cleanupsHaveSideEffects())
5868 S = ExprTemp->getSubExpr();
5869
Alexander Musmana5f070a2014-10-01 06:03:56 +00005870 IncrementSrcRange = S->getSourceRange();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005871 S = S->IgnoreParens();
David Majnemer9d168222016-08-05 17:44:54 +00005872 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005873 if (UO->isIncrementDecrementOp() &&
Alexey Bataeve3727102018-04-18 15:57:46 +00005874 getInitLCDecl(UO->getSubExpr()) == LCDecl)
5875 return setStep(SemaRef
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005876 .ActOnIntegerConstant(UO->getBeginLoc(),
David Majnemer9d168222016-08-05 17:44:54 +00005877 (UO->isDecrementOp() ? -1 : 1))
5878 .get(),
Alexey Bataeve3727102018-04-18 15:57:46 +00005879 /*Subtract=*/false);
David Majnemer9d168222016-08-05 17:44:54 +00005880 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005881 switch (BO->getOpcode()) {
5882 case BO_AddAssign:
5883 case BO_SubAssign:
Alexey Bataeve3727102018-04-18 15:57:46 +00005884 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5885 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005886 break;
5887 case BO_Assign:
Alexey Bataeve3727102018-04-18 15:57:46 +00005888 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5889 return checkAndSetIncRHS(BO->getRHS());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005890 break;
5891 default:
5892 break;
5893 }
David Majnemer9d168222016-08-05 17:44:54 +00005894 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005895 switch (CE->getOperator()) {
5896 case OO_PlusPlus:
5897 case OO_MinusMinus:
Alexey Bataeve3727102018-04-18 15:57:46 +00005898 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5899 return setStep(SemaRef
David Majnemer9d168222016-08-05 17:44:54 +00005900 .ActOnIntegerConstant(
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005901 CE->getBeginLoc(),
David Majnemer9d168222016-08-05 17:44:54 +00005902 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
5903 .get(),
Alexey Bataeve3727102018-04-18 15:57:46 +00005904 /*Subtract=*/false);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005905 break;
5906 case OO_PlusEqual:
5907 case OO_MinusEqual:
Alexey Bataeve3727102018-04-18 15:57:46 +00005908 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5909 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005910 break;
5911 case OO_Equal:
Alexey Bataeve3727102018-04-18 15:57:46 +00005912 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5913 return checkAndSetIncRHS(CE->getArg(1));
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005914 break;
5915 default:
5916 break;
5917 }
5918 }
Alexey Bataeve3727102018-04-18 15:57:46 +00005919 if (dependent() || SemaRef.CurContext->isDependentContext())
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005920 return false;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005921 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00005922 << S->getSourceRange() << LCDecl;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00005923 return true;
5924}
Alexander Musmana5f070a2014-10-01 06:03:56 +00005925
Alexey Bataev5a3af132016-03-29 08:58:54 +00005926static ExprResult
5927tryBuildCapture(Sema &SemaRef, Expr *Capture,
Alexey Bataeve3727102018-04-18 15:57:46 +00005928 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataevbe8b8b52016-07-07 11:04:06 +00005929 if (SemaRef.CurContext->isDependentContext())
5930 return ExprResult(Capture);
Alexey Bataev5a3af132016-03-29 08:58:54 +00005931 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
5932 return SemaRef.PerformImplicitConversion(
5933 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
5934 /*AllowExplicit=*/true);
5935 auto I = Captures.find(Capture);
5936 if (I != Captures.end())
5937 return buildCapture(SemaRef, Capture, I->second);
5938 DeclRefExpr *Ref = nullptr;
5939 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
5940 Captures[Capture] = Ref;
5941 return Res;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005942}
5943
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005944/// Build the expression to calculate the number of iterations.
Alexey Bataeve3727102018-04-18 15:57:46 +00005945Expr *OpenMPIterationSpaceChecker::buildNumIterations(
Alexey Bataevf8be4762019-08-14 19:30:06 +00005946 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
Alexey Bataeve3727102018-04-18 15:57:46 +00005947 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
Alexander Musmana5f070a2014-10-01 06:03:56 +00005948 ExprResult Diff;
Alexey Bataeve3727102018-04-18 15:57:46 +00005949 QualType VarType = LCDecl->getType().getNonReferenceType();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00005950 if (VarType->isIntegerType() || VarType->isPointerType() ||
Alexander Musmana5f070a2014-10-01 06:03:56 +00005951 SemaRef.getLangOpts().CPlusPlus) {
Alexey Bataevf8be4762019-08-14 19:30:06 +00005952 Expr *LBVal = LB;
5953 Expr *UBVal = UB;
5954 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
5955 // max(LB(MinVal), LB(MaxVal))
5956 if (InitDependOnLC) {
5957 const LoopIterationSpace &IS =
5958 ResultIterSpaces[ResultIterSpaces.size() - 1 -
5959 InitDependOnLC.getValueOr(
5960 CondDependOnLC.getValueOr(0))];
5961 if (!IS.MinValue || !IS.MaxValue)
5962 return nullptr;
5963 // OuterVar = Min
5964 ExprResult MinValue =
5965 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
5966 if (!MinValue.isUsable())
5967 return nullptr;
5968
5969 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
5970 IS.CounterVar, MinValue.get());
5971 if (!LBMinVal.isUsable())
5972 return nullptr;
5973 // OuterVar = Min, LBVal
5974 LBMinVal =
5975 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
5976 if (!LBMinVal.isUsable())
5977 return nullptr;
5978 // (OuterVar = Min, LBVal)
5979 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
5980 if (!LBMinVal.isUsable())
5981 return nullptr;
5982
5983 // OuterVar = Max
5984 ExprResult MaxValue =
5985 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
5986 if (!MaxValue.isUsable())
5987 return nullptr;
5988
5989 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
5990 IS.CounterVar, MaxValue.get());
5991 if (!LBMaxVal.isUsable())
5992 return nullptr;
5993 // OuterVar = Max, LBVal
5994 LBMaxVal =
5995 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
5996 if (!LBMaxVal.isUsable())
5997 return nullptr;
5998 // (OuterVar = Max, LBVal)
5999 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
6000 if (!LBMaxVal.isUsable())
6001 return nullptr;
6002
6003 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
6004 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
6005 if (!LBMin || !LBMax)
6006 return nullptr;
6007 // LB(MinVal) < LB(MaxVal)
6008 ExprResult MinLessMaxRes =
6009 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
6010 if (!MinLessMaxRes.isUsable())
6011 return nullptr;
6012 Expr *MinLessMax =
6013 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
6014 if (!MinLessMax)
6015 return nullptr;
6016 if (TestIsLessOp.getValue()) {
6017 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
6018 // LB(MaxVal))
6019 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6020 MinLessMax, LBMin, LBMax);
6021 if (!MinLB.isUsable())
6022 return nullptr;
6023 LBVal = MinLB.get();
6024 } else {
6025 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
6026 // LB(MaxVal))
6027 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6028 MinLessMax, LBMax, LBMin);
6029 if (!MaxLB.isUsable())
6030 return nullptr;
6031 LBVal = MaxLB.get();
6032 }
6033 }
6034 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
6035 // min(UB(MinVal), UB(MaxVal))
6036 if (CondDependOnLC) {
6037 const LoopIterationSpace &IS =
6038 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6039 InitDependOnLC.getValueOr(
6040 CondDependOnLC.getValueOr(0))];
6041 if (!IS.MinValue || !IS.MaxValue)
6042 return nullptr;
6043 // OuterVar = Min
6044 ExprResult MinValue =
6045 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6046 if (!MinValue.isUsable())
6047 return nullptr;
6048
6049 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6050 IS.CounterVar, MinValue.get());
6051 if (!UBMinVal.isUsable())
6052 return nullptr;
6053 // OuterVar = Min, UBVal
6054 UBMinVal =
6055 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
6056 if (!UBMinVal.isUsable())
6057 return nullptr;
6058 // (OuterVar = Min, UBVal)
6059 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
6060 if (!UBMinVal.isUsable())
6061 return nullptr;
6062
6063 // OuterVar = Max
6064 ExprResult MaxValue =
6065 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6066 if (!MaxValue.isUsable())
6067 return nullptr;
6068
6069 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6070 IS.CounterVar, MaxValue.get());
6071 if (!UBMaxVal.isUsable())
6072 return nullptr;
6073 // OuterVar = Max, UBVal
6074 UBMaxVal =
6075 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
6076 if (!UBMaxVal.isUsable())
6077 return nullptr;
6078 // (OuterVar = Max, UBVal)
6079 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
6080 if (!UBMaxVal.isUsable())
6081 return nullptr;
6082
6083 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
6084 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
6085 if (!UBMin || !UBMax)
6086 return nullptr;
6087 // UB(MinVal) > UB(MaxVal)
6088 ExprResult MinGreaterMaxRes =
6089 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
6090 if (!MinGreaterMaxRes.isUsable())
6091 return nullptr;
6092 Expr *MinGreaterMax =
6093 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
6094 if (!MinGreaterMax)
6095 return nullptr;
6096 if (TestIsLessOp.getValue()) {
6097 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
6098 // UB(MaxVal))
6099 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
6100 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
6101 if (!MaxUB.isUsable())
6102 return nullptr;
6103 UBVal = MaxUB.get();
6104 } else {
6105 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
6106 // UB(MaxVal))
6107 ExprResult MinUB = SemaRef.ActOnConditionalOp(
6108 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
6109 if (!MinUB.isUsable())
6110 return nullptr;
6111 UBVal = MinUB.get();
6112 }
6113 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006114 // Upper - Lower
Alexey Bataevf8be4762019-08-14 19:30:06 +00006115 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
6116 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
Alexey Bataev5a3af132016-03-29 08:58:54 +00006117 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
6118 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006119 if (!Upper || !Lower)
6120 return nullptr;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006121
6122 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6123
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006124 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00006125 // BuildBinOp already emitted error, this one is to point user to upper
6126 // and lower bound, and to tell what is passed to 'operator-'.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006127 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
Alexander Musmana5f070a2014-10-01 06:03:56 +00006128 << Upper->getSourceRange() << Lower->getSourceRange();
6129 return nullptr;
6130 }
6131 }
6132
6133 if (!Diff.isUsable())
6134 return nullptr;
6135
6136 // Upper - Lower [- 1]
6137 if (TestIsStrictOp)
6138 Diff = SemaRef.BuildBinOp(
6139 S, DefaultLoc, BO_Sub, Diff.get(),
6140 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6141 if (!Diff.isUsable())
6142 return nullptr;
6143
6144 // Upper - Lower [- 1] + Step
Alexey Bataeve3727102018-04-18 15:57:46 +00006145 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00006146 if (!NewStep.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006147 return nullptr;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006148 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00006149 if (!Diff.isUsable())
6150 return nullptr;
6151
6152 // Parentheses (for dumping/debugging purposes only).
6153 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6154 if (!Diff.isUsable())
6155 return nullptr;
6156
6157 // (Upper - Lower [- 1] + Step) / Step
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006158 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00006159 if (!Diff.isUsable())
6160 return nullptr;
6161
Alexander Musman174b3ca2014-10-06 11:16:29 +00006162 // OpenMP runtime requires 32-bit or 64-bit loop variables.
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006163 QualType Type = Diff.get()->getType();
Alexey Bataeve3727102018-04-18 15:57:46 +00006164 ASTContext &C = SemaRef.Context;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006165 bool UseVarType = VarType->hasIntegerRepresentation() &&
6166 C.getTypeSize(Type) > C.getTypeSize(VarType);
6167 if (!Type->isIntegerType() || UseVarType) {
6168 unsigned NewSize =
6169 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
6170 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
6171 : Type->hasSignedIntegerRepresentation();
6172 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
Alexey Bataev11481f52016-02-17 10:29:05 +00006173 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
6174 Diff = SemaRef.PerformImplicitConversion(
6175 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
6176 if (!Diff.isUsable())
6177 return nullptr;
6178 }
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006179 }
Alexander Musman174b3ca2014-10-06 11:16:29 +00006180 if (LimitedType) {
Alexander Musman174b3ca2014-10-06 11:16:29 +00006181 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
6182 if (NewSize != C.getTypeSize(Type)) {
6183 if (NewSize < C.getTypeSize(Type)) {
6184 assert(NewSize == 64 && "incorrect loop var size");
6185 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
6186 << InitSrcRange << ConditionSrcRange;
6187 }
6188 QualType NewType = C.getIntTypeForBitwidth(
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006189 NewSize, Type->hasSignedIntegerRepresentation() ||
6190 C.getTypeSize(Type) < NewSize);
Alexey Bataev11481f52016-02-17 10:29:05 +00006191 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
6192 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
6193 Sema::AA_Converting, true);
6194 if (!Diff.isUsable())
6195 return nullptr;
6196 }
Alexander Musman174b3ca2014-10-06 11:16:29 +00006197 }
6198 }
6199
Alexander Musmana5f070a2014-10-01 06:03:56 +00006200 return Diff.get();
6201}
6202
Alexey Bataevf8be4762019-08-14 19:30:06 +00006203std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
6204 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6205 // Do not build for iterators, they cannot be used in non-rectangular loop
6206 // nests.
6207 if (LCDecl->getType()->isRecordType())
6208 return std::make_pair(nullptr, nullptr);
6209 // If we subtract, the min is in the condition, otherwise the min is in the
6210 // init value.
6211 Expr *MinExpr = nullptr;
6212 Expr *MaxExpr = nullptr;
6213 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
6214 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
6215 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
6216 : CondDependOnLC.hasValue();
6217 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
6218 : InitDependOnLC.hasValue();
6219 Expr *Lower =
6220 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
6221 Expr *Upper =
6222 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
6223 if (!Upper || !Lower)
6224 return std::make_pair(nullptr, nullptr);
6225
6226 if (TestIsLessOp.getValue())
6227 MinExpr = Lower;
6228 else
6229 MaxExpr = Upper;
6230
6231 // Build minimum/maximum value based on number of iterations.
6232 ExprResult Diff;
6233 QualType VarType = LCDecl->getType().getNonReferenceType();
6234
6235 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6236 if (!Diff.isUsable())
6237 return std::make_pair(nullptr, nullptr);
6238
6239 // Upper - Lower [- 1]
6240 if (TestIsStrictOp)
6241 Diff = SemaRef.BuildBinOp(
6242 S, DefaultLoc, BO_Sub, Diff.get(),
6243 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6244 if (!Diff.isUsable())
6245 return std::make_pair(nullptr, nullptr);
6246
6247 // Upper - Lower [- 1] + Step
6248 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6249 if (!NewStep.isUsable())
6250 return std::make_pair(nullptr, nullptr);
6251
6252 // Parentheses (for dumping/debugging purposes only).
6253 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6254 if (!Diff.isUsable())
6255 return std::make_pair(nullptr, nullptr);
6256
6257 // (Upper - Lower [- 1]) / Step
6258 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6259 if (!Diff.isUsable())
6260 return std::make_pair(nullptr, nullptr);
6261
6262 // ((Upper - Lower [- 1]) / Step) * Step
6263 // Parentheses (for dumping/debugging purposes only).
6264 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6265 if (!Diff.isUsable())
6266 return std::make_pair(nullptr, nullptr);
6267
6268 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
6269 if (!Diff.isUsable())
6270 return std::make_pair(nullptr, nullptr);
6271
6272 // Convert to the original type or ptrdiff_t, if original type is pointer.
6273 if (!VarType->isAnyPointerType() &&
6274 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) {
6275 Diff = SemaRef.PerformImplicitConversion(
6276 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true);
6277 } else if (VarType->isAnyPointerType() &&
6278 !SemaRef.Context.hasSameType(
6279 Diff.get()->getType(),
6280 SemaRef.Context.getUnsignedPointerDiffType())) {
6281 Diff = SemaRef.PerformImplicitConversion(
6282 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
6283 Sema::AA_Converting, /*AllowExplicit=*/true);
6284 }
6285 if (!Diff.isUsable())
6286 return std::make_pair(nullptr, nullptr);
6287
6288 // Parentheses (for dumping/debugging purposes only).
6289 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6290 if (!Diff.isUsable())
6291 return std::make_pair(nullptr, nullptr);
6292
6293 if (TestIsLessOp.getValue()) {
6294 // MinExpr = Lower;
6295 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
6296 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get());
6297 if (!Diff.isUsable())
6298 return std::make_pair(nullptr, nullptr);
6299 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6300 if (!Diff.isUsable())
6301 return std::make_pair(nullptr, nullptr);
6302 MaxExpr = Diff.get();
6303 } else {
6304 // MaxExpr = Upper;
6305 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
6306 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
6307 if (!Diff.isUsable())
6308 return std::make_pair(nullptr, nullptr);
6309 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6310 if (!Diff.isUsable())
6311 return std::make_pair(nullptr, nullptr);
6312 MinExpr = Diff.get();
6313 }
6314
6315 return std::make_pair(MinExpr, MaxExpr);
6316}
6317
6318Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
6319 if (InitDependOnLC || CondDependOnLC)
6320 return Condition;
6321 return nullptr;
6322}
6323
Alexey Bataeve3727102018-04-18 15:57:46 +00006324Expr *OpenMPIterationSpaceChecker::buildPreCond(
Alexey Bataev5a3af132016-03-29 08:58:54 +00006325 Scope *S, Expr *Cond,
Alexey Bataeve3727102018-04-18 15:57:46 +00006326 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
Alexey Bataev658ad4d2019-10-01 16:19:10 +00006327 // Do not build a precondition when the condition/initialization is dependent
6328 // to prevent pessimistic early loop exit.
6329 // TODO: this can be improved by calculating min/max values but not sure that
6330 // it will be very effective.
6331 if (CondDependOnLC || InitDependOnLC)
6332 return SemaRef.PerformImplicitConversion(
6333 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
6334 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6335 /*AllowExplicit=*/true).get();
6336
Alexey Bataev62dbb972015-04-22 11:59:37 +00006337 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
Richard Smith2e3ed4a2019-08-16 19:53:22 +00006338 Sema::TentativeAnalysisScope Trap(SemaRef);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006339
Alexey Bataev658ad4d2019-10-01 16:19:10 +00006340 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
6341 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00006342 if (!NewLB.isUsable() || !NewUB.isUsable())
6343 return nullptr;
6344
Alexey Bataeve3727102018-04-18 15:57:46 +00006345 ExprResult CondExpr =
6346 SemaRef.BuildBinOp(S, DefaultLoc,
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00006347 TestIsLessOp.getValue() ?
Kelvin Liefbe4af2018-11-21 19:10:48 +00006348 (TestIsStrictOp ? BO_LT : BO_LE) :
6349 (TestIsStrictOp ? BO_GT : BO_GE),
Alexey Bataeve3727102018-04-18 15:57:46 +00006350 NewLB.get(), NewUB.get());
Alexey Bataev3bed68c2015-07-15 12:14:07 +00006351 if (CondExpr.isUsable()) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00006352 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
6353 SemaRef.Context.BoolTy))
Alexey Bataev11481f52016-02-17 10:29:05 +00006354 CondExpr = SemaRef.PerformImplicitConversion(
6355 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6356 /*AllowExplicit=*/true);
Alexey Bataev3bed68c2015-07-15 12:14:07 +00006357 }
Richard Smith2e3ed4a2019-08-16 19:53:22 +00006358
Sergi Mateo Bellidof3e00fe2019-02-01 08:39:01 +00006359 // Otherwise use original loop condition and evaluate it in runtime.
Alexey Bataev62dbb972015-04-22 11:59:37 +00006360 return CondExpr.isUsable() ? CondExpr.get() : Cond;
6361}
6362
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006363/// Build reference expression to the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006364DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
Alexey Bataevf138fda2018-08-13 19:04:24 +00006365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6366 DSAStackTy &DSA) const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006367 auto *VD = dyn_cast<VarDecl>(LCDecl);
6368 if (!VD) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006369 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
6370 DeclRefExpr *Ref = buildDeclRefExpr(
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006371 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
Alexey Bataeve3727102018-04-18 15:57:46 +00006372 const DSAStackTy::DSAVarData Data =
6373 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
Alexey Bataev5dff95c2016-04-22 03:56:56 +00006374 // If the loop control decl is explicitly marked as private, do not mark it
6375 // as captured again.
6376 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
6377 Captures.insert(std::make_pair(LCRef, Ref));
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006378 return Ref;
6379 }
Alexey Bataev0d8fcdf2019-03-14 20:36:00 +00006380 return cast<DeclRefExpr>(LCRef);
Alexey Bataeva8899172015-08-06 12:30:57 +00006381}
6382
Alexey Bataeve3727102018-04-18 15:57:46 +00006383Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006384 if (LCDecl && !LCDecl->isInvalidDecl()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006385 QualType Type = LCDecl->getType().getNonReferenceType();
6386 VarDecl *PrivateVar = buildVarDecl(
Alexey Bataev63cc8e92018-03-20 14:45:59 +00006387 SemaRef, DefaultLoc, Type, LCDecl->getName(),
6388 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
6389 isa<VarDecl>(LCDecl)
6390 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
6391 : nullptr);
Alexey Bataeva8899172015-08-06 12:30:57 +00006392 if (PrivateVar->isInvalidDecl())
6393 return nullptr;
6394 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
6395 }
6396 return nullptr;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006397}
6398
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006399/// Build initialization of the counter to be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006400Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006401
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006402/// Build step of the counter be used for codegen.
Alexey Bataeve3727102018-04-18 15:57:46 +00006403Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006404
Alexey Bataevf138fda2018-08-13 19:04:24 +00006405Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
6406 Scope *S, Expr *Counter,
6407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
6408 Expr *Inc, OverloadedOperatorKind OOK) {
6409 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
6410 if (!Cnt)
6411 return nullptr;
6412 if (Inc) {
6413 assert((OOK == OO_Plus || OOK == OO_Minus) &&
6414 "Expected only + or - operations for depend clauses.");
6415 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
6416 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
6417 if (!Cnt)
6418 return nullptr;
6419 }
6420 ExprResult Diff;
6421 QualType VarType = LCDecl->getType().getNonReferenceType();
6422 if (VarType->isIntegerType() || VarType->isPointerType() ||
6423 SemaRef.getLangOpts().CPlusPlus) {
6424 // Upper - Lower
Alexey Bataev316ccf62019-01-29 18:51:58 +00006425 Expr *Upper = TestIsLessOp.getValue()
6426 ? Cnt
6427 : tryBuildCapture(SemaRef, UB, Captures).get();
6428 Expr *Lower = TestIsLessOp.getValue()
6429 ? tryBuildCapture(SemaRef, LB, Captures).get()
6430 : Cnt;
Alexey Bataevf138fda2018-08-13 19:04:24 +00006431 if (!Upper || !Lower)
6432 return nullptr;
6433
6434 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6435
6436 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6437 // BuildBinOp already emitted error, this one is to point user to upper
6438 // and lower bound, and to tell what is passed to 'operator-'.
6439 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6440 << Upper->getSourceRange() << Lower->getSourceRange();
6441 return nullptr;
6442 }
6443 }
6444
6445 if (!Diff.isUsable())
6446 return nullptr;
6447
6448 // Parentheses (for dumping/debugging purposes only).
6449 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6450 if (!Diff.isUsable())
6451 return nullptr;
6452
6453 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6454 if (!NewStep.isUsable())
6455 return nullptr;
6456 // (Upper - Lower) / Step
6457 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6458 if (!Diff.isUsable())
6459 return nullptr;
6460
6461 return Diff.get();
6462}
Alexey Bataev23b69422014-06-18 07:08:49 +00006463} // namespace
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006464
Alexey Bataev9c821032015-04-30 04:23:23 +00006465void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
6466 assert(getLangOpts().OpenMP && "OpenMP is not active.");
6467 assert(Init && "Expected loop in canonical form.");
Alexey Bataeva636c7f2015-12-23 10:27:45 +00006468 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
6469 if (AssociatedLoops > 0 &&
Alexey Bataev9c821032015-04-30 04:23:23 +00006470 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
Alexey Bataevce901812018-12-19 18:16:37 +00006471 DSAStack->loopStart();
Alexey Bataev622af1d2019-04-24 19:58:30 +00006472 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
Alexey Bataeve3727102018-04-18 15:57:46 +00006473 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
6474 if (ValueDecl *D = ISC.getLoopDecl()) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006475 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev05be1da2019-07-18 17:49:13 +00006476 DeclRefExpr *PrivateRef = nullptr;
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006477 if (!VD) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006478 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006479 VD = Private;
Alexey Bataeve3727102018-04-18 15:57:46 +00006480 } else {
Alexey Bataev05be1da2019-07-18 17:49:13 +00006481 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
6482 /*WithInit=*/false);
6483 VD = cast<VarDecl>(PrivateRef->getDecl());
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006484 }
6485 }
6486 DSAStack->addLoopControlVariable(D, VD);
Alexey Bataev6ab5bb12018-10-29 15:01:58 +00006487 const Decl *LD = DSAStack->getPossiblyLoopCunter();
6488 if (LD != D->getCanonicalDecl()) {
6489 DSAStack->resetPossibleLoopCounter();
6490 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
6491 MarkDeclarationsReferencedInExpr(
6492 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
6493 Var->getType().getNonLValueExprType(Context),
6494 ForLoc, /*RefersToCapture=*/true));
6495 }
Alexey Bataev05be1da2019-07-18 17:49:13 +00006496 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
6497 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
6498 // Referenced in a Construct, C/C++]. The loop iteration variable in the
6499 // associated for-loop of a simd construct with just one associated
6500 // for-loop may be listed in a linear clause with a constant-linear-step
6501 // that is the increment of the associated for-loop. The loop iteration
6502 // variable(s) in the associated for-loop(s) of a for or parallel for
6503 // construct may be listed in a private or lastprivate clause.
6504 DSAStackTy::DSAVarData DVar =
6505 DSAStack->getTopDSA(D, /*FromParent=*/false);
6506 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
6507 // is declared in the loop and it is predetermined as a private.
6508 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
6509 OpenMPClauseKind PredeterminedCKind =
6510 isOpenMPSimdDirective(DKind)
6511 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
6512 : OMPC_private;
6513 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6514 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
6515 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
6516 DVar.CKind != OMPC_private))) ||
6517 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
Alexey Bataev60e51c42019-10-10 20:13:02 +00006518 DKind == OMPD_master_taskloop ||
Alexey Bataev5bbcead2019-10-14 17:17:41 +00006519 DKind == OMPD_parallel_master_taskloop ||
Alexey Bataev05be1da2019-07-18 17:49:13 +00006520 isOpenMPDistributeDirective(DKind)) &&
6521 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6522 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
6523 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
6524 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
6525 << getOpenMPClauseName(DVar.CKind)
6526 << getOpenMPDirectiveName(DKind)
6527 << getOpenMPClauseName(PredeterminedCKind);
6528 if (DVar.RefExpr == nullptr)
6529 DVar.CKind = PredeterminedCKind;
6530 reportOriginalDsa(*this, DSAStack, D, DVar,
6531 /*IsLoopIterVar=*/true);
6532 } else if (LoopDeclRefExpr) {
6533 // Make the loop iteration variable private (for worksharing
6534 // constructs), linear (for simd directives with the only one
6535 // associated loop) or lastprivate (for simd directives with several
6536 // collapsed or ordered loops).
6537 if (DVar.CKind == OMPC_unknown)
6538 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
6539 PrivateRef);
6540 }
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006541 }
6542 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +00006543 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
Alexey Bataev9c821032015-04-30 04:23:23 +00006544 }
6545}
6546
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006547/// Called on a for stmt to check and extract its iteration space
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006548/// for further processing (such as collapsing).
Alexey Bataeve3727102018-04-18 15:57:46 +00006549static bool checkOpenMPIterationSpace(
Alexey Bataev4acb8592014-07-07 13:01:15 +00006550 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
6551 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
Alexey Bataevf138fda2018-08-13 19:04:24 +00006552 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
6553 Expr *OrderedLoopCountExpr,
Alexey Bataeve3727102018-04-18 15:57:46 +00006554 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
Alexey Bataevf8be4762019-08-14 19:30:06 +00006555 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
Alexey Bataeve3727102018-04-18 15:57:46 +00006556 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataevbef93a92019-10-07 18:54:57 +00006557 // OpenMP [2.9.1, Canonical Loop Form]
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006558 // for (init-expr; test-expr; incr-expr) structured-block
Alexey Bataevbef93a92019-10-07 18:54:57 +00006559 // for (range-decl: range-expr) structured-block
David Majnemer9d168222016-08-05 17:44:54 +00006560 auto *For = dyn_cast_or_null<ForStmt>(S);
Alexey Bataevbef93a92019-10-07 18:54:57 +00006561 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
6562 // Ranged for is supported only in OpenMP 5.0.
6563 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006564 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
Alexey Bataev10e775f2015-07-30 11:36:16 +00006565 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
Alexey Bataevf138fda2018-08-13 19:04:24 +00006566 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
Alexey Bataev10e775f2015-07-30 11:36:16 +00006567 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
Alexey Bataevf138fda2018-08-13 19:04:24 +00006568 if (TotalNestedLoopCount > 1) {
Alexey Bataev10e775f2015-07-30 11:36:16 +00006569 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
6570 SemaRef.Diag(DSA.getConstructLoc(),
6571 diag::note_omp_collapse_ordered_expr)
6572 << 2 << CollapseLoopCountExpr->getSourceRange()
6573 << OrderedLoopCountExpr->getSourceRange();
6574 else if (CollapseLoopCountExpr)
6575 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
6576 diag::note_omp_collapse_ordered_expr)
6577 << 0 << CollapseLoopCountExpr->getSourceRange();
6578 else
6579 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
6580 diag::note_omp_collapse_ordered_expr)
6581 << 1 << OrderedLoopCountExpr->getSourceRange();
6582 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006583 return true;
6584 }
Alexey Bataevbef93a92019-10-07 18:54:57 +00006585 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
6586 "No loop body.");
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006587
Alexey Bataevbef93a92019-10-07 18:54:57 +00006588 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
6589 For ? For->getForLoc() : CXXFor->getForLoc());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006590
6591 // Check init.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006592 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
Alexey Bataeve3727102018-04-18 15:57:46 +00006593 if (ISC.checkAndSetInit(Init))
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006594 return true;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006595
6596 bool HasErrors = false;
6597
6598 // Check loop variable's type.
Alexey Bataeve3727102018-04-18 15:57:46 +00006599 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006600 // OpenMP [2.6, Canonical Loop Form]
6601 // Var is one of the following:
6602 // A variable of signed or unsigned integer type.
6603 // For C++, a variable of a random access iterator type.
6604 // For C, a variable of a pointer type.
Alexey Bataeve3727102018-04-18 15:57:46 +00006605 QualType VarType = LCDecl->getType().getNonReferenceType();
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006606 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
6607 !VarType->isPointerType() &&
6608 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006609 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006610 << SemaRef.getLangOpts().CPlusPlus;
6611 HasErrors = true;
6612 }
6613
6614 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
6615 // a Construct
6616 // The loop iteration variable(s) in the associated for-loop(s) of a for or
6617 // parallel for construct is (are) private.
6618 // The loop iteration variable in the associated for-loop of a simd
6619 // construct with just one associated for-loop is linear with a
6620 // constant-linear-step that is the increment of the associated for-loop.
6621 // Exclude loop var from the list of variables with implicitly defined data
6622 // sharing attributes.
6623 VarsWithImplicitDSA.erase(LCDecl);
6624
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006625 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
6626
6627 // Check test-expr.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006628 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
Alexey Bataevc6ad97a2016-04-01 09:23:34 +00006629
6630 // Check incr-expr.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006631 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006632 }
6633
Alexey Bataeve3727102018-04-18 15:57:46 +00006634 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006635 return HasErrors;
6636
Alexander Musmana5f070a2014-10-01 06:03:56 +00006637 // Build the loop's iteration space representation.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006638 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
6639 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
Alexey Bataevf8be4762019-08-14 19:30:06 +00006640 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
6641 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
6642 (isOpenMPWorksharingDirective(DKind) ||
6643 isOpenMPTaskLoopDirective(DKind) ||
6644 isOpenMPDistributeDirective(DKind)),
6645 Captures);
6646 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
6647 ISC.buildCounterVar(Captures, DSA);
6648 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
6649 ISC.buildPrivateCounterVar();
6650 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
6651 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
6652 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
6653 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
6654 ISC.getConditionSrcRange();
6655 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
6656 ISC.getIncrementSrcRange();
6657 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
6658 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
6659 ISC.isStrictTestOp();
6660 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
6661 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
6662 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
6663 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
6664 ISC.buildFinalCondition(DSA.getCurScope());
6665 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
6666 ISC.doesInitDependOnLC();
6667 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
6668 ISC.doesCondDependOnLC();
6669 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
6670 ISC.getLoopDependentIdx();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006671
Alexey Bataevf8be4762019-08-14 19:30:06 +00006672 HasErrors |=
6673 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
6674 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
6675 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
6676 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
6677 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
6678 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
Alexey Bataevf138fda2018-08-13 19:04:24 +00006679 if (!HasErrors && DSA.isOrderedRegion()) {
6680 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
6681 if (CurrentNestedLoopCount <
6682 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
6683 DSA.getOrderedRegionParam().second->setLoopNumIterations(
Alexey Bataevf8be4762019-08-14 19:30:06 +00006684 CurrentNestedLoopCount,
6685 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
Alexey Bataevf138fda2018-08-13 19:04:24 +00006686 DSA.getOrderedRegionParam().second->setLoopCounter(
Alexey Bataevf8be4762019-08-14 19:30:06 +00006687 CurrentNestedLoopCount,
6688 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
Alexey Bataevf138fda2018-08-13 19:04:24 +00006689 }
6690 }
6691 for (auto &Pair : DSA.getDoacrossDependClauses()) {
6692 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
6693 // Erroneous case - clause has some problems.
6694 continue;
6695 }
6696 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
6697 Pair.second.size() <= CurrentNestedLoopCount) {
6698 // Erroneous case - clause has some problems.
6699 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
6700 continue;
6701 }
6702 Expr *CntValue;
6703 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
6704 CntValue = ISC.buildOrderedLoopData(
Alexey Bataevf8be4762019-08-14 19:30:06 +00006705 DSA.getCurScope(),
6706 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
Alexey Bataevf138fda2018-08-13 19:04:24 +00006707 Pair.first->getDependencyLoc());
6708 else
6709 CntValue = ISC.buildOrderedLoopData(
Alexey Bataevf8be4762019-08-14 19:30:06 +00006710 DSA.getCurScope(),
6711 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
Alexey Bataevf138fda2018-08-13 19:04:24 +00006712 Pair.first->getDependencyLoc(),
6713 Pair.second[CurrentNestedLoopCount].first,
6714 Pair.second[CurrentNestedLoopCount].second);
6715 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
6716 }
6717 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006718
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006719 return HasErrors;
6720}
6721
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006722/// Build 'VarRef = Start.
Alexey Bataev5a3af132016-03-29 08:58:54 +00006723static ExprResult
Alexey Bataeve3727102018-04-18 15:57:46 +00006724buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
Alexey Bataevf8be4762019-08-14 19:30:06 +00006725 ExprResult Start, bool IsNonRectangularLB,
Alexey Bataeve3727102018-04-18 15:57:46 +00006726 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006727 // Build 'VarRef = Start.
Alexey Bataevf8be4762019-08-14 19:30:06 +00006728 ExprResult NewStart = IsNonRectangularLB
6729 ? Start.get()
6730 : tryBuildCapture(SemaRef, Start.get(), Captures);
Alexey Bataev5a3af132016-03-29 08:58:54 +00006731 if (!NewStart.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006732 return ExprError();
Alexey Bataev11481f52016-02-17 10:29:05 +00006733 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
Alexey Bataev11481f52016-02-17 10:29:05 +00006734 VarRef.get()->getType())) {
6735 NewStart = SemaRef.PerformImplicitConversion(
6736 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
6737 /*AllowExplicit=*/true);
6738 if (!NewStart.isUsable())
6739 return ExprError();
6740 }
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006741
Alexey Bataeve3727102018-04-18 15:57:46 +00006742 ExprResult Init =
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006743 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
6744 return Init;
6745}
6746
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006747/// Build 'VarRef = Start + Iter * Step'.
Alexey Bataeve3727102018-04-18 15:57:46 +00006748static ExprResult buildCounterUpdate(
6749 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
6750 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
Alexey Bataevf8be4762019-08-14 19:30:06 +00006751 bool IsNonRectangularLB,
Alexey Bataeve3727102018-04-18 15:57:46 +00006752 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00006753 // Add parentheses (for debugging purposes only).
6754 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
6755 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
6756 !Step.isUsable())
6757 return ExprError();
6758
Alexey Bataev5a3af132016-03-29 08:58:54 +00006759 ExprResult NewStep = Step;
6760 if (Captures)
6761 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006762 if (NewStep.isInvalid())
6763 return ExprError();
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006764 ExprResult Update =
6765 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00006766 if (!Update.isUsable())
6767 return ExprError();
6768
Alexey Bataevc0214e02016-02-16 12:13:49 +00006769 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
6770 // 'VarRef = Start (+|-) Iter * Step'.
Alexey Bataevf8be4762019-08-14 19:30:06 +00006771 if (!Start.isUsable())
6772 return ExprError();
6773 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
6774 if (!NewStart.isUsable())
6775 return ExprError();
6776 if (Captures && !IsNonRectangularLB)
Alexey Bataev5a3af132016-03-29 08:58:54 +00006777 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00006778 if (NewStart.isInvalid())
6779 return ExprError();
Alexander Musmana5f070a2014-10-01 06:03:56 +00006780
Alexey Bataevc0214e02016-02-16 12:13:49 +00006781 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
6782 ExprResult SavedUpdate = Update;
6783 ExprResult UpdateVal;
6784 if (VarRef.get()->getType()->isOverloadableType() ||
6785 NewStart.get()->getType()->isOverloadableType() ||
6786 Update.get()->getType()->isOverloadableType()) {
Richard Smith2e3ed4a2019-08-16 19:53:22 +00006787 Sema::TentativeAnalysisScope Trap(SemaRef);
6788
Alexey Bataevc0214e02016-02-16 12:13:49 +00006789 Update =
6790 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
6791 if (Update.isUsable()) {
6792 UpdateVal =
6793 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
6794 VarRef.get(), SavedUpdate.get());
6795 if (UpdateVal.isUsable()) {
6796 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
6797 UpdateVal.get());
6798 }
6799 }
Alexey Bataevc0214e02016-02-16 12:13:49 +00006800 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006801
Alexey Bataevc0214e02016-02-16 12:13:49 +00006802 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
6803 if (!Update.isUsable() || !UpdateVal.isUsable()) {
6804 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
6805 NewStart.get(), SavedUpdate.get());
6806 if (!Update.isUsable())
6807 return ExprError();
6808
Alexey Bataev11481f52016-02-17 10:29:05 +00006809 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
6810 VarRef.get()->getType())) {
6811 Update = SemaRef.PerformImplicitConversion(
6812 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
6813 if (!Update.isUsable())
6814 return ExprError();
6815 }
Alexey Bataevc0214e02016-02-16 12:13:49 +00006816
6817 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
6818 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00006819 return Update;
6820}
6821
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006822/// Convert integer expression \a E to make it have at least \a Bits
Alexander Musmana5f070a2014-10-01 06:03:56 +00006823/// bits.
Alexey Bataeve3727102018-04-18 15:57:46 +00006824static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00006825 if (E == nullptr)
6826 return ExprError();
Alexey Bataeve3727102018-04-18 15:57:46 +00006827 ASTContext &C = SemaRef.Context;
Alexander Musmana5f070a2014-10-01 06:03:56 +00006828 QualType OldType = E->getType();
6829 unsigned HasBits = C.getTypeSize(OldType);
6830 if (HasBits >= Bits)
6831 return ExprResult(E);
6832 // OK to convert to signed, because new type has more bits than old.
6833 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
6834 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
6835 true);
6836}
6837
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006838/// Check if the given expression \a E is a constant integer that fits
Alexander Musmana5f070a2014-10-01 06:03:56 +00006839/// into \a Bits bits.
Alexey Bataeve3727102018-04-18 15:57:46 +00006840static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00006841 if (E == nullptr)
6842 return false;
6843 llvm::APSInt Result;
6844 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
6845 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
6846 return false;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006847}
6848
Alexey Bataev5a3af132016-03-29 08:58:54 +00006849/// Build preinits statement for the given declarations.
6850static Stmt *buildPreInits(ASTContext &Context,
Alexey Bataevc5514062017-10-25 15:44:52 +00006851 MutableArrayRef<Decl *> PreInits) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00006852 if (!PreInits.empty()) {
6853 return new (Context) DeclStmt(
6854 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
6855 SourceLocation(), SourceLocation());
6856 }
6857 return nullptr;
6858}
6859
6860/// Build preinits statement for the given declarations.
Alexey Bataevc5514062017-10-25 15:44:52 +00006861static Stmt *
6862buildPreInits(ASTContext &Context,
Alexey Bataeve3727102018-04-18 15:57:46 +00006863 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00006864 if (!Captures.empty()) {
6865 SmallVector<Decl *, 16> PreInits;
Alexey Bataeve3727102018-04-18 15:57:46 +00006866 for (const auto &Pair : Captures)
Alexey Bataev5a3af132016-03-29 08:58:54 +00006867 PreInits.push_back(Pair.second->getDecl());
6868 return buildPreInits(Context, PreInits);
6869 }
6870 return nullptr;
6871}
6872
6873/// Build postupdate expression for the given list of postupdates expressions.
6874static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
6875 Expr *PostUpdate = nullptr;
6876 if (!PostUpdates.empty()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00006877 for (Expr *E : PostUpdates) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00006878 Expr *ConvE = S.BuildCStyleCastExpr(
6879 E->getExprLoc(),
6880 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
6881 E->getExprLoc(), E)
6882 .get();
6883 PostUpdate = PostUpdate
6884 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
6885 PostUpdate, ConvE)
6886 .get()
6887 : ConvE;
6888 }
6889 }
6890 return PostUpdate;
6891}
6892
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006893/// Called on a for stmt to check itself and nested loops (if any).
Alexey Bataevabfc0692014-06-25 06:52:00 +00006894/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
6895/// number of collapsed loops otherwise.
Alexey Bataev4acb8592014-07-07 13:01:15 +00006896static unsigned
Alexey Bataeve3727102018-04-18 15:57:46 +00006897checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Alexey Bataev10e775f2015-07-30 11:36:16 +00006898 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
6899 DSAStackTy &DSA,
Alexey Bataeve3727102018-04-18 15:57:46 +00006900 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
Alexander Musmanc6388682014-12-15 07:07:06 +00006901 OMPLoopDirective::HelperExprs &Built) {
Alexey Bataeve2f07d42014-06-24 12:55:56 +00006902 unsigned NestedLoopCount = 1;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006903 if (CollapseLoopCountExpr) {
Alexey Bataeve2f07d42014-06-24 12:55:56 +00006904 // Found 'collapse' clause - calculate collapse number.
Fangrui Song407659a2018-11-30 23:41:18 +00006905 Expr::EvalResult Result;
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006906 if (!CollapseLoopCountExpr->isValueDependent() &&
6907 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
Fangrui Song407659a2018-11-30 23:41:18 +00006908 NestedLoopCount = Result.Val.getInt().getLimitedValue();
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006909 } else {
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006910 Built.clear(/*Size=*/1);
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006911 return 1;
6912 }
Alexey Bataev10e775f2015-07-30 11:36:16 +00006913 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00006914 unsigned OrderedLoopCount = 1;
Alexey Bataev10e775f2015-07-30 11:36:16 +00006915 if (OrderedLoopCountExpr) {
6916 // Found 'ordered' clause - calculate collapse number.
Fangrui Song407659a2018-11-30 23:41:18 +00006917 Expr::EvalResult EVResult;
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006918 if (!OrderedLoopCountExpr->isValueDependent() &&
6919 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
6920 SemaRef.getASTContext())) {
Fangrui Song407659a2018-11-30 23:41:18 +00006921 llvm::APSInt Result = EVResult.Val.getInt();
Alexey Bataev7b6bc882015-11-26 07:50:39 +00006922 if (Result.getLimitedValue() < NestedLoopCount) {
6923 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
6924 diag::err_omp_wrong_ordered_loop_count)
6925 << OrderedLoopCountExpr->getSourceRange();
6926 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
6927 diag::note_collapse_loop_count)
6928 << CollapseLoopCountExpr->getSourceRange();
6929 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00006930 OrderedLoopCount = Result.getLimitedValue();
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006931 } else {
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006932 Built.clear(/*Size=*/1);
Dmitri Gribenko04323c22019-05-17 17:16:53 +00006933 return 1;
Alexey Bataev7b6bc882015-11-26 07:50:39 +00006934 }
Alexey Bataeve2f07d42014-06-24 12:55:56 +00006935 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006936 // This is helper routine for loop directives (e.g., 'for', 'simd',
6937 // 'for simd', etc.).
Alexey Bataeve3727102018-04-18 15:57:46 +00006938 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev316ccf62019-01-29 18:51:58 +00006939 SmallVector<LoopIterationSpace, 4> IterSpaces(
6940 std::max(OrderedLoopCount, NestedLoopCount));
Alexander Musmana5f070a2014-10-01 06:03:56 +00006941 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006942 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00006943 if (checkOpenMPIterationSpace(
6944 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6945 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
Alexey Bataevf8be4762019-08-14 19:30:06 +00006946 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
Alexey Bataevabfc0692014-06-25 06:52:00 +00006947 return 0;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006948 // Move on to the next nested for loop, or to the loop body.
Alexander Musmana5f070a2014-10-01 06:03:56 +00006949 // OpenMP [2.8.1, simd construct, Restrictions]
6950 // All loops associated with the construct must be perfectly nested; that
6951 // is, there must be no intervening code nor any OpenMP directive between
6952 // any two loops.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006953 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
6954 CurStmt = For->getBody();
6955 } else {
6956 assert(isa<CXXForRangeStmt>(CurStmt) &&
6957 "Expected canonical for or range-based for loops.");
6958 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
6959 }
6960 CurStmt = CurStmt->IgnoreContainers();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006961 }
Alexey Bataevf138fda2018-08-13 19:04:24 +00006962 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
6963 if (checkOpenMPIterationSpace(
6964 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6965 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
Alexey Bataevf8be4762019-08-14 19:30:06 +00006966 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
Alexey Bataevf138fda2018-08-13 19:04:24 +00006967 return 0;
6968 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
6969 // Handle initialization of captured loop iterator variables.
6970 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
6971 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
6972 Captures[DRE] = DRE;
6973 }
6974 }
6975 // Move on to the next nested for loop, or to the loop body.
6976 // OpenMP [2.8.1, simd construct, Restrictions]
6977 // All loops associated with the construct must be perfectly nested; that
6978 // is, there must be no intervening code nor any OpenMP directive between
6979 // any two loops.
Alexey Bataevbef93a92019-10-07 18:54:57 +00006980 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
6981 CurStmt = For->getBody();
6982 } else {
6983 assert(isa<CXXForRangeStmt>(CurStmt) &&
6984 "Expected canonical for or range-based for loops.");
6985 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
6986 }
6987 CurStmt = CurStmt->IgnoreContainers();
Alexey Bataevf138fda2018-08-13 19:04:24 +00006988 }
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00006989
Alexander Musmana5f070a2014-10-01 06:03:56 +00006990 Built.clear(/* size */ NestedLoopCount);
6991
6992 if (SemaRef.CurContext->isDependentContext())
6993 return NestedLoopCount;
6994
6995 // An example of what is generated for the following code:
6996 //
Alexey Bataev10e775f2015-07-30 11:36:16 +00006997 // #pragma omp simd collapse(2) ordered(2)
Alexander Musmana5f070a2014-10-01 06:03:56 +00006998 // for (i = 0; i < NI; ++i)
Alexey Bataev10e775f2015-07-30 11:36:16 +00006999 // for (k = 0; k < NK; ++k)
7000 // for (j = J0; j < NJ; j+=2) {
7001 // <loop body>
7002 // }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007003 //
7004 // We generate the code below.
7005 // Note: the loop body may be outlined in CodeGen.
7006 // Note: some counters may be C++ classes, operator- is used to find number of
7007 // iterations and operator+= to calculate counter value.
7008 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
7009 // or i64 is currently supported).
7010 //
7011 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
7012 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
7013 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
7014 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
7015 // // similar updates for vars in clauses (e.g. 'linear')
7016 // <loop body (using local i and j)>
7017 // }
7018 // i = NI; // assign final values of counters
7019 // j = NJ;
7020 //
7021
7022 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
7023 // the iteration counts of the collapsed for loops.
Alexey Bataev62dbb972015-04-22 11:59:37 +00007024 // Precondition tests if there is at least one iteration (all conditions are
7025 // true).
7026 auto PreCond = ExprResult(IterSpaces[0].PreCond);
Alexey Bataeve3727102018-04-18 15:57:46 +00007027 Expr *N0 = IterSpaces[0].NumIterations;
7028 ExprResult LastIteration32 =
7029 widenIterationCount(/*Bits=*/32,
7030 SemaRef
7031 .PerformImplicitConversion(
7032 N0->IgnoreImpCasts(), N0->getType(),
7033 Sema::AA_Converting, /*AllowExplicit=*/true)
7034 .get(),
7035 SemaRef);
7036 ExprResult LastIteration64 = widenIterationCount(
7037 /*Bits=*/64,
7038 SemaRef
7039 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
7040 Sema::AA_Converting,
7041 /*AllowExplicit=*/true)
7042 .get(),
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007043 SemaRef);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007044
7045 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
7046 return NestedLoopCount;
7047
Alexey Bataeve3727102018-04-18 15:57:46 +00007048 ASTContext &C = SemaRef.Context;
Alexander Musmana5f070a2014-10-01 06:03:56 +00007049 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
7050
7051 Scope *CurScope = DSA.getCurScope();
7052 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
Alexey Bataev62dbb972015-04-22 11:59:37 +00007053 if (PreCond.isUsable()) {
Alexey Bataeva7206b92016-12-20 16:51:02 +00007054 PreCond =
7055 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
7056 PreCond.get(), IterSpaces[Cnt].PreCond);
Alexey Bataev62dbb972015-04-22 11:59:37 +00007057 }
Alexey Bataeve3727102018-04-18 15:57:46 +00007058 Expr *N = IterSpaces[Cnt].NumIterations;
Alexey Bataeva7206b92016-12-20 16:51:02 +00007059 SourceLocation Loc = N->getExprLoc();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007060 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
7061 if (LastIteration32.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007062 LastIteration32 = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00007063 CurScope, Loc, BO_Mul, LastIteration32.get(),
David Majnemer9d168222016-08-05 17:44:54 +00007064 SemaRef
7065 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7066 Sema::AA_Converting,
7067 /*AllowExplicit=*/true)
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007068 .get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00007069 if (LastIteration64.isUsable())
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007070 LastIteration64 = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00007071 CurScope, Loc, BO_Mul, LastIteration64.get(),
David Majnemer9d168222016-08-05 17:44:54 +00007072 SemaRef
7073 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7074 Sema::AA_Converting,
7075 /*AllowExplicit=*/true)
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007076 .get());
Alexander Musmana5f070a2014-10-01 06:03:56 +00007077 }
7078
7079 // Choose either the 32-bit or 64-bit version.
7080 ExprResult LastIteration = LastIteration64;
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +00007081 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
7082 (LastIteration32.isUsable() &&
7083 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
7084 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
7085 fitsInto(
7086 /*Bits=*/32,
7087 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
7088 LastIteration64.get(), SemaRef))))
Alexander Musmana5f070a2014-10-01 06:03:56 +00007089 LastIteration = LastIteration32;
Alexey Bataev7292c292016-04-25 12:22:29 +00007090 QualType VType = LastIteration.get()->getType();
7091 QualType RealVType = VType;
7092 QualType StrideVType = VType;
7093 if (isOpenMPTaskLoopDirective(DKind)) {
7094 VType =
7095 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
7096 StrideVType =
7097 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
7098 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007099
7100 if (!LastIteration.isUsable())
7101 return 0;
7102
7103 // Save the number of iterations.
7104 ExprResult NumIterations = LastIteration;
7105 {
7106 LastIteration = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00007107 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
7108 LastIteration.get(),
Alexander Musmana5f070a2014-10-01 06:03:56 +00007109 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7110 if (!LastIteration.isUsable())
7111 return 0;
7112 }
7113
7114 // Calculate the last iteration number beforehand instead of doing this on
7115 // each iteration. Do not do this if the number of iterations may be kfold-ed.
7116 llvm::APSInt Result;
7117 bool IsConstant =
7118 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
7119 ExprResult CalcLastIteration;
7120 if (!IsConstant) {
Alexey Bataev5a3af132016-03-29 08:58:54 +00007121 ExprResult SaveRef =
7122 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007123 LastIteration = SaveRef;
7124
7125 // Prepare SaveRef + 1.
7126 NumIterations = SemaRef.BuildBinOp(
Alexey Bataeva7206b92016-12-20 16:51:02 +00007127 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
Alexander Musmana5f070a2014-10-01 06:03:56 +00007128 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7129 if (!NumIterations.isUsable())
7130 return 0;
7131 }
7132
7133 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
7134
David Majnemer9d168222016-08-05 17:44:54 +00007135 // Build variables passed into runtime, necessary for worksharing directives.
Carlo Bertolliffafe102017-04-20 00:39:39 +00007136 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00007137 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7138 isOpenMPDistributeDirective(DKind)) {
Alexander Musmanc6388682014-12-15 07:07:06 +00007139 // Lower bound variable, initialized with zero.
Alexey Bataev39f915b82015-05-08 10:41:21 +00007140 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
7141 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00007142 SemaRef.AddInitializerToDecl(LBDecl,
7143 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7144 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007145
7146 // Upper bound variable, initialized with last iteration number.
Alexey Bataev39f915b82015-05-08 10:41:21 +00007147 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
7148 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
Alexander Musmanc6388682014-12-15 07:07:06 +00007149 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
Richard Smith3beb7c62017-01-12 02:27:38 +00007150 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007151
7152 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
7153 // This will be used to implement clause 'lastprivate'.
7154 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
Alexey Bataev39f915b82015-05-08 10:41:21 +00007155 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
7156 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00007157 SemaRef.AddInitializerToDecl(ILDecl,
7158 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7159 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007160
7161 // Stride variable returned by runtime (we initialize it to 1 by default).
Alexey Bataev7292c292016-04-25 12:22:29 +00007162 VarDecl *STDecl =
7163 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
7164 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
Richard Smith3beb7c62017-01-12 02:27:38 +00007165 SemaRef.AddInitializerToDecl(STDecl,
7166 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
7167 /*DirectInit*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007168
7169 // Build expression: UB = min(UB, LastIteration)
David Majnemer9d168222016-08-05 17:44:54 +00007170 // It is necessary for CodeGen of directives with static scheduling.
Alexander Musmanc6388682014-12-15 07:07:06 +00007171 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
7172 UB.get(), LastIteration.get());
7173 ExprResult CondOp = SemaRef.ActOnConditionalOp(
Alexey Bataev86ec3fe2018-07-25 14:40:26 +00007174 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
7175 LastIteration.get(), UB.get());
Alexander Musmanc6388682014-12-15 07:07:06 +00007176 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
7177 CondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007178 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
Carlo Bertolli9925f152016-06-27 14:55:37 +00007179
7180 // If we have a combined directive that combines 'distribute', 'for' or
7181 // 'simd' we need to be able to access the bounds of the schedule of the
7182 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
7183 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
7184 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Carlo Bertolliffafe102017-04-20 00:39:39 +00007185 // Lower bound variable, initialized with zero.
7186 VarDecl *CombLBDecl =
7187 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
7188 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
7189 SemaRef.AddInitializerToDecl(
7190 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7191 /*DirectInit*/ false);
7192
7193 // Upper bound variable, initialized with last iteration number.
7194 VarDecl *CombUBDecl =
7195 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
7196 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
7197 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
7198 /*DirectInit*/ false);
7199
7200 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
7201 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
7202 ExprResult CombCondOp =
7203 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
7204 LastIteration.get(), CombUB.get());
7205 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
7206 CombCondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007207 CombEUB =
7208 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007209
Alexey Bataeve3727102018-04-18 15:57:46 +00007210 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
Carlo Bertolli9925f152016-06-27 14:55:37 +00007211 // We expect to have at least 2 more parameters than the 'parallel'
7212 // directive does - the lower and upper bounds of the previous schedule.
7213 assert(CD->getNumParams() >= 4 &&
7214 "Unexpected number of parameters in loop combined directive");
7215
7216 // Set the proper type for the bounds given what we learned from the
7217 // enclosed loops.
Alexey Bataeve3727102018-04-18 15:57:46 +00007218 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
7219 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
Carlo Bertolli9925f152016-06-27 14:55:37 +00007220
7221 // Previous lower and upper bounds are obtained from the region
7222 // parameters.
7223 PrevLB =
7224 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
7225 PrevUB =
7226 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
7227 }
Alexander Musmanc6388682014-12-15 07:07:06 +00007228 }
7229
7230 // Build the iteration variable and its initialization before loop.
Alexander Musmana5f070a2014-10-01 06:03:56 +00007231 ExprResult IV;
Carlo Bertolliffafe102017-04-20 00:39:39 +00007232 ExprResult Init, CombInit;
Alexander Musmana5f070a2014-10-01 06:03:56 +00007233 {
Alexey Bataev7292c292016-04-25 12:22:29 +00007234 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
7235 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
David Majnemer9d168222016-08-05 17:44:54 +00007236 Expr *RHS =
7237 (isOpenMPWorksharingDirective(DKind) ||
7238 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
7239 ? LB.get()
7240 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
Alexander Musmanc6388682014-12-15 07:07:06 +00007241 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007242 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007243
7244 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7245 Expr *CombRHS =
7246 (isOpenMPWorksharingDirective(DKind) ||
7247 isOpenMPTaskLoopDirective(DKind) ||
7248 isOpenMPDistributeDirective(DKind))
7249 ? CombLB.get()
7250 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7251 CombInit =
7252 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007253 CombInit =
7254 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007255 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007256 }
7257
Alexey Bataev316ccf62019-01-29 18:51:58 +00007258 bool UseStrictCompare =
7259 RealVType->hasUnsignedIntegerRepresentation() &&
7260 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
7261 return LIS.IsStrictCompare;
7262 });
7263 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
7264 // unsigned IV)) for worksharing loops.
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007265 SourceLocation CondLoc = AStmt->getBeginLoc();
Alexey Bataev316ccf62019-01-29 18:51:58 +00007266 Expr *BoundUB = UB.get();
7267 if (UseStrictCompare) {
7268 BoundUB =
7269 SemaRef
7270 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
7271 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7272 .get();
7273 BoundUB =
7274 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
7275 }
Alexander Musmanc6388682014-12-15 07:07:06 +00007276 ExprResult Cond =
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00007277 (isOpenMPWorksharingDirective(DKind) ||
7278 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
Alexey Bataev316ccf62019-01-29 18:51:58 +00007279 ? SemaRef.BuildBinOp(CurScope, CondLoc,
7280 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
7281 BoundUB)
Alexander Musmanc6388682014-12-15 07:07:06 +00007282 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7283 NumIterations.get());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007284 ExprResult CombDistCond;
7285 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00007286 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7287 NumIterations.get());
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007288 }
7289
Carlo Bertolliffafe102017-04-20 00:39:39 +00007290 ExprResult CombCond;
7291 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00007292 Expr *BoundCombUB = CombUB.get();
7293 if (UseStrictCompare) {
7294 BoundCombUB =
7295 SemaRef
7296 .BuildBinOp(
7297 CurScope, CondLoc, BO_Add, BoundCombUB,
7298 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7299 .get();
7300 BoundCombUB =
7301 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
7302 .get();
7303 }
Carlo Bertolliffafe102017-04-20 00:39:39 +00007304 CombCond =
Alexey Bataev316ccf62019-01-29 18:51:58 +00007305 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7306 IV.get(), BoundCombUB);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007307 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007308 // Loop increment (IV = IV + 1)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007309 SourceLocation IncLoc = AStmt->getBeginLoc();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007310 ExprResult Inc =
7311 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
7312 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
7313 if (!Inc.isUsable())
7314 return 0;
7315 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007316 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007317 if (!Inc.isUsable())
7318 return 0;
7319
7320 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
7321 // Used for directives with static scheduling.
Carlo Bertolliffafe102017-04-20 00:39:39 +00007322 // In combined construct, add combined version that use CombLB and CombUB
7323 // base variables for the update
7324 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00007325 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7326 isOpenMPDistributeDirective(DKind)) {
Alexander Musmanc6388682014-12-15 07:07:06 +00007327 // LB + ST
7328 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
7329 if (!NextLB.isUsable())
7330 return 0;
7331 // LB = LB + ST
7332 NextLB =
7333 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007334 NextLB =
7335 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007336 if (!NextLB.isUsable())
7337 return 0;
7338 // UB + ST
7339 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
7340 if (!NextUB.isUsable())
7341 return 0;
7342 // UB = UB + ST
7343 NextUB =
7344 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007345 NextUB =
7346 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
Alexander Musmanc6388682014-12-15 07:07:06 +00007347 if (!NextUB.isUsable())
7348 return 0;
Carlo Bertolliffafe102017-04-20 00:39:39 +00007349 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7350 CombNextLB =
7351 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
7352 if (!NextLB.isUsable())
7353 return 0;
7354 // LB = LB + ST
7355 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
7356 CombNextLB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007357 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
7358 /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007359 if (!CombNextLB.isUsable())
7360 return 0;
7361 // UB + ST
7362 CombNextUB =
7363 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
7364 if (!CombNextUB.isUsable())
7365 return 0;
7366 // UB = UB + ST
7367 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
7368 CombNextUB.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007369 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
7370 /*DiscardedValue*/ false);
Carlo Bertolliffafe102017-04-20 00:39:39 +00007371 if (!CombNextUB.isUsable())
7372 return 0;
7373 }
Alexander Musmanc6388682014-12-15 07:07:06 +00007374 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007375
Carlo Bertolliffafe102017-04-20 00:39:39 +00007376 // Create increment expression for distribute loop when combined in a same
Carlo Bertolli8429d812017-02-17 21:29:13 +00007377 // directive with for as IV = IV + ST; ensure upper bound expression based
7378 // on PrevUB instead of NumIterations - used to implement 'for' when found
7379 // in combination with 'distribute', like in 'distribute parallel for'
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007380 SourceLocation DistIncLoc = AStmt->getBeginLoc();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007381 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
Carlo Bertolli8429d812017-02-17 21:29:13 +00007382 if (isOpenMPLoopBoundSharingDirective(DKind)) {
Alexey Bataev316ccf62019-01-29 18:51:58 +00007383 DistCond = SemaRef.BuildBinOp(
7384 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
Carlo Bertolli8429d812017-02-17 21:29:13 +00007385 assert(DistCond.isUsable() && "distribute cond expr was not built");
7386
7387 DistInc =
7388 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
7389 assert(DistInc.isUsable() && "distribute inc expr was not built");
7390 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
7391 DistInc.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007392 DistInc =
7393 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
Carlo Bertolli8429d812017-02-17 21:29:13 +00007394 assert(DistInc.isUsable() && "distribute inc expr was not built");
7395
7396 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
7397 // construct
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007398 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
Carlo Bertolli8429d812017-02-17 21:29:13 +00007399 ExprResult IsUBGreater =
7400 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
7401 ExprResult CondOp = SemaRef.ActOnConditionalOp(
7402 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
7403 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
7404 CondOp.get());
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007405 PrevEUB =
7406 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007407
Alexey Bataev316ccf62019-01-29 18:51:58 +00007408 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
7409 // parallel for is in combination with a distribute directive with
7410 // schedule(static, 1)
7411 Expr *BoundPrevUB = PrevUB.get();
7412 if (UseStrictCompare) {
7413 BoundPrevUB =
7414 SemaRef
7415 .BuildBinOp(
7416 CurScope, CondLoc, BO_Add, BoundPrevUB,
7417 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7418 .get();
7419 BoundPrevUB =
7420 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
7421 .get();
7422 }
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007423 ParForInDistCond =
Alexey Bataev316ccf62019-01-29 18:51:58 +00007424 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7425 IV.get(), BoundPrevUB);
Carlo Bertolli8429d812017-02-17 21:29:13 +00007426 }
7427
Alexander Musmana5f070a2014-10-01 06:03:56 +00007428 // Build updates and final values of the loop counters.
7429 bool HasErrors = false;
7430 Built.Counters.resize(NestedLoopCount);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007431 Built.Inits.resize(NestedLoopCount);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007432 Built.Updates.resize(NestedLoopCount);
7433 Built.Finals.resize(NestedLoopCount);
Alexey Bataevf8be4762019-08-14 19:30:06 +00007434 Built.DependentCounters.resize(NestedLoopCount);
7435 Built.DependentInits.resize(NestedLoopCount);
7436 Built.FinalsConditions.resize(NestedLoopCount);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007437 {
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00007438 // We implement the following algorithm for obtaining the
7439 // original loop iteration variable values based on the
7440 // value of the collapsed loop iteration variable IV.
7441 //
7442 // Let n+1 be the number of collapsed loops in the nest.
7443 // Iteration variables (I0, I1, .... In)
7444 // Iteration counts (N0, N1, ... Nn)
7445 //
7446 // Acc = IV;
7447 //
7448 // To compute Ik for loop k, 0 <= k <= n, generate:
7449 // Prod = N(k+1) * N(k+2) * ... * Nn;
7450 // Ik = Acc / Prod;
7451 // Acc -= Ik * Prod;
7452 //
7453 ExprResult Acc = IV;
7454 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
Alexander Musmana5f070a2014-10-01 06:03:56 +00007455 LoopIterationSpace &IS = IterSpaces[Cnt];
7456 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007457 ExprResult Iter;
Alexander Musmana5f070a2014-10-01 06:03:56 +00007458
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00007459 // Compute prod
7460 ExprResult Prod =
7461 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7462 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
7463 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
7464 IterSpaces[K].NumIterations);
7465
7466 // Iter = Acc / Prod
7467 // If there is at least one more inner loop to avoid
7468 // multiplication by 1.
7469 if (Cnt + 1 < NestedLoopCount)
7470 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
7471 Acc.get(), Prod.get());
7472 else
7473 Iter = Acc;
Alexander Musmana5f070a2014-10-01 06:03:56 +00007474 if (!Iter.isUsable()) {
7475 HasErrors = true;
7476 break;
7477 }
7478
Gheorghe-Teodor Bercea677960642019-01-09 20:45:26 +00007479 // Update Acc:
7480 // Acc -= Iter * Prod
7481 // Check if there is at least one more inner loop to avoid
7482 // multiplication by 1.
7483 if (Cnt + 1 < NestedLoopCount)
7484 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
7485 Iter.get(), Prod.get());
7486 else
7487 Prod = Iter;
7488 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
7489 Acc.get(), Prod.get());
7490
Alexey Bataev39f915b82015-05-08 10:41:21 +00007491 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007492 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
Alexey Bataeve3727102018-04-18 15:57:46 +00007493 DeclRefExpr *CounterVar = buildDeclRefExpr(
7494 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
7495 /*RefersToCapture=*/true);
Alexey Bataevf8be4762019-08-14 19:30:06 +00007496 ExprResult Init =
7497 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
7498 IS.CounterInit, IS.IsNonRectangularLB, Captures);
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007499 if (!Init.isUsable()) {
7500 HasErrors = true;
7501 break;
7502 }
Alexey Bataeve3727102018-04-18 15:57:46 +00007503 ExprResult Update = buildCounterUpdate(
Alexey Bataev5a3af132016-03-29 08:58:54 +00007504 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
Alexey Bataevf8be4762019-08-14 19:30:06 +00007505 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007506 if (!Update.isUsable()) {
7507 HasErrors = true;
7508 break;
7509 }
7510
7511 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
Alexey Bataevf8be4762019-08-14 19:30:06 +00007512 ExprResult Final =
7513 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
7514 IS.CounterInit, IS.NumIterations, IS.CounterStep,
7515 IS.Subtract, IS.IsNonRectangularLB, &Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007516 if (!Final.isUsable()) {
7517 HasErrors = true;
7518 break;
7519 }
7520
Alexander Musmana5f070a2014-10-01 06:03:56 +00007521 if (!Update.isUsable() || !Final.isUsable()) {
7522 HasErrors = true;
7523 break;
7524 }
7525 // Save results
7526 Built.Counters[Cnt] = IS.CounterVar;
Alexey Bataeva8899172015-08-06 12:30:57 +00007527 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
Alexey Bataevb08f89f2015-08-14 12:25:37 +00007528 Built.Inits[Cnt] = Init.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007529 Built.Updates[Cnt] = Update.get();
7530 Built.Finals[Cnt] = Final.get();
Alexey Bataevf8be4762019-08-14 19:30:06 +00007531 Built.DependentCounters[Cnt] = nullptr;
7532 Built.DependentInits[Cnt] = nullptr;
7533 Built.FinalsConditions[Cnt] = nullptr;
Alexey Bataev658ad4d2019-10-01 16:19:10 +00007534 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
Alexey Bataevf8be4762019-08-14 19:30:06 +00007535 Built.DependentCounters[Cnt] =
7536 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
7537 Built.DependentInits[Cnt] =
7538 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
7539 Built.FinalsConditions[Cnt] = IS.FinalCondition;
7540 }
Alexander Musmana5f070a2014-10-01 06:03:56 +00007541 }
7542 }
7543
7544 if (HasErrors)
7545 return 0;
7546
7547 // Save results
7548 Built.IterationVarRef = IV.get();
7549 Built.LastIteration = LastIteration.get();
Alexander Musman3276a272015-03-21 10:12:56 +00007550 Built.NumIterations = NumIterations.get();
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007551 Built.CalcLastIteration = SemaRef
7552 .ActOnFinishFullExpr(CalcLastIteration.get(),
Alexey Bataevf8be4762019-08-14 19:30:06 +00007553 /*DiscardedValue=*/false)
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +00007554 .get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007555 Built.PreCond = PreCond.get();
Alexey Bataev5a3af132016-03-29 08:58:54 +00007556 Built.PreInits = buildPreInits(C, Captures);
Alexander Musmana5f070a2014-10-01 06:03:56 +00007557 Built.Cond = Cond.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007558 Built.Init = Init.get();
7559 Built.Inc = Inc.get();
Alexander Musmanc6388682014-12-15 07:07:06 +00007560 Built.LB = LB.get();
7561 Built.UB = UB.get();
7562 Built.IL = IL.get();
7563 Built.ST = ST.get();
7564 Built.EUB = EUB.get();
7565 Built.NLB = NextLB.get();
7566 Built.NUB = NextUB.get();
Carlo Bertolli9925f152016-06-27 14:55:37 +00007567 Built.PrevLB = PrevLB.get();
7568 Built.PrevUB = PrevUB.get();
Carlo Bertolli8429d812017-02-17 21:29:13 +00007569 Built.DistInc = DistInc.get();
7570 Built.PrevEUB = PrevEUB.get();
Carlo Bertolliffafe102017-04-20 00:39:39 +00007571 Built.DistCombinedFields.LB = CombLB.get();
7572 Built.DistCombinedFields.UB = CombUB.get();
7573 Built.DistCombinedFields.EUB = CombEUB.get();
7574 Built.DistCombinedFields.Init = CombInit.get();
7575 Built.DistCombinedFields.Cond = CombCond.get();
7576 Built.DistCombinedFields.NLB = CombNextLB.get();
7577 Built.DistCombinedFields.NUB = CombNextUB.get();
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00007578 Built.DistCombinedFields.DistCond = CombDistCond.get();
7579 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007580
Alexey Bataevabfc0692014-06-25 06:52:00 +00007581 return NestedLoopCount;
Alexander Musmana8e9d2e2014-06-03 10:16:47 +00007582}
7583
Alexey Bataev10e775f2015-07-30 11:36:16 +00007584static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00007585 auto CollapseClauses =
7586 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
7587 if (CollapseClauses.begin() != CollapseClauses.end())
7588 return (*CollapseClauses.begin())->getNumForLoops();
Alexey Bataeve2f07d42014-06-24 12:55:56 +00007589 return nullptr;
7590}
7591
Alexey Bataev10e775f2015-07-30 11:36:16 +00007592static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
Benjamin Kramerfc600dc2015-08-30 15:12:28 +00007593 auto OrderedClauses =
7594 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
7595 if (OrderedClauses.begin() != OrderedClauses.end())
7596 return (*OrderedClauses.begin())->getNumForLoops();
Alexey Bataev10e775f2015-07-30 11:36:16 +00007597 return nullptr;
7598}
7599
Kelvin Lic5609492016-07-15 04:39:07 +00007600static bool checkSimdlenSafelenSpecified(Sema &S,
7601 const ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007602 const OMPSafelenClause *Safelen = nullptr;
7603 const OMPSimdlenClause *Simdlen = nullptr;
Kelvin Lic5609492016-07-15 04:39:07 +00007604
Alexey Bataeve3727102018-04-18 15:57:46 +00007605 for (const OMPClause *Clause : Clauses) {
Kelvin Lic5609492016-07-15 04:39:07 +00007606 if (Clause->getClauseKind() == OMPC_safelen)
7607 Safelen = cast<OMPSafelenClause>(Clause);
7608 else if (Clause->getClauseKind() == OMPC_simdlen)
7609 Simdlen = cast<OMPSimdlenClause>(Clause);
7610 if (Safelen && Simdlen)
7611 break;
7612 }
7613
7614 if (Simdlen && Safelen) {
Alexey Bataeve3727102018-04-18 15:57:46 +00007615 const Expr *SimdlenLength = Simdlen->getSimdlen();
7616 const Expr *SafelenLength = Safelen->getSafelen();
Kelvin Lic5609492016-07-15 04:39:07 +00007617 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
7618 SimdlenLength->isInstantiationDependent() ||
7619 SimdlenLength->containsUnexpandedParameterPack())
7620 return false;
7621 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
7622 SafelenLength->isInstantiationDependent() ||
7623 SafelenLength->containsUnexpandedParameterPack())
7624 return false;
Fangrui Song407659a2018-11-30 23:41:18 +00007625 Expr::EvalResult SimdlenResult, SafelenResult;
7626 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
7627 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
7628 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
7629 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
Kelvin Lic5609492016-07-15 04:39:07 +00007630 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
7631 // If both simdlen and safelen clauses are specified, the value of the
7632 // simdlen parameter must be less than or equal to the value of the safelen
7633 // parameter.
7634 if (SimdlenRes > SafelenRes) {
7635 S.Diag(SimdlenLength->getExprLoc(),
7636 diag::err_omp_wrong_simdlen_safelen_values)
7637 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
7638 return true;
7639 }
Alexey Bataev66b15b52015-08-21 11:14:16 +00007640 }
7641 return false;
7642}
7643
Alexey Bataeve3727102018-04-18 15:57:46 +00007644StmtResult
7645Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
7646 SourceLocation StartLoc, SourceLocation EndLoc,
7647 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007648 if (!AStmt)
7649 return StmtError();
7650
7651 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00007652 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00007653 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7654 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00007655 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataev10e775f2015-07-30 11:36:16 +00007656 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
7657 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
Alexey Bataevabfc0692014-06-25 06:52:00 +00007658 if (NestedLoopCount == 0)
Alexey Bataev1b59ab52014-02-27 08:29:12 +00007659 return StmtError();
Alexey Bataev1b59ab52014-02-27 08:29:12 +00007660
Alexander Musmana5f070a2014-10-01 06:03:56 +00007661 assert((CurContext->isDependentContext() || B.builtAll()) &&
7662 "omp simd loop exprs were not built");
7663
Alexander Musman3276a272015-03-21 10:12:56 +00007664 if (!CurContext->isDependentContext()) {
7665 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007666 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007667 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexander Musman3276a272015-03-21 10:12:56 +00007668 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007669 B.NumIterations, *this, CurScope,
7670 DSAStack))
Alexander Musman3276a272015-03-21 10:12:56 +00007671 return StmtError();
7672 }
7673 }
7674
Kelvin Lic5609492016-07-15 04:39:07 +00007675 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00007676 return StmtError();
7677
Reid Kleckner87a31802018-03-12 21:43:02 +00007678 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00007679 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
7680 Clauses, AStmt, B);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00007681}
7682
Alexey Bataeve3727102018-04-18 15:57:46 +00007683StmtResult
7684Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
7685 SourceLocation StartLoc, SourceLocation EndLoc,
7686 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007687 if (!AStmt)
7688 return StmtError();
7689
7690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00007691 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00007692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7693 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00007694 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataev10e775f2015-07-30 11:36:16 +00007695 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
7696 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
Alexey Bataevabfc0692014-06-25 06:52:00 +00007697 if (NestedLoopCount == 0)
Alexey Bataevf29276e2014-06-18 04:14:57 +00007698 return StmtError();
7699
Alexander Musmana5f070a2014-10-01 06:03:56 +00007700 assert((CurContext->isDependentContext() || B.builtAll()) &&
7701 "omp for loop exprs were not built");
7702
Alexey Bataev54acd402015-08-04 11:18:19 +00007703 if (!CurContext->isDependentContext()) {
7704 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007705 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007706 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev54acd402015-08-04 11:18:19 +00007707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007708 B.NumIterations, *this, CurScope,
7709 DSAStack))
Alexey Bataev54acd402015-08-04 11:18:19 +00007710 return StmtError();
7711 }
7712 }
7713
Reid Kleckner87a31802018-03-12 21:43:02 +00007714 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00007715 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
Alexey Bataev25e5b442015-09-15 12:52:43 +00007716 Clauses, AStmt, B, DSAStack->isCancelRegion());
Alexey Bataevf29276e2014-06-18 04:14:57 +00007717}
7718
Alexander Musmanf82886e2014-09-18 05:12:34 +00007719StmtResult Sema::ActOnOpenMPForSimdDirective(
7720 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00007721 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007722 if (!AStmt)
7723 return StmtError();
7724
7725 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmanc6388682014-12-15 07:07:06 +00007726 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00007727 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7728 // define the nested loops number.
Alexander Musmanf82886e2014-09-18 05:12:34 +00007729 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00007730 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00007731 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7732 VarsWithImplicitDSA, B);
Alexander Musmanf82886e2014-09-18 05:12:34 +00007733 if (NestedLoopCount == 0)
7734 return StmtError();
7735
Alexander Musmanc6388682014-12-15 07:07:06 +00007736 assert((CurContext->isDependentContext() || B.builtAll()) &&
7737 "omp for simd loop exprs were not built");
7738
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00007739 if (!CurContext->isDependentContext()) {
7740 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007741 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007742 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00007743 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007744 B.NumIterations, *this, CurScope,
7745 DSAStack))
Alexey Bataev58e5bdb2015-06-18 04:45:29 +00007746 return StmtError();
7747 }
7748 }
7749
Kelvin Lic5609492016-07-15 04:39:07 +00007750 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00007751 return StmtError();
7752
Reid Kleckner87a31802018-03-12 21:43:02 +00007753 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00007754 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
7755 Clauses, AStmt, B);
Alexander Musmanf82886e2014-09-18 05:12:34 +00007756}
7757
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007758StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
7759 Stmt *AStmt,
7760 SourceLocation StartLoc,
7761 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007762 if (!AStmt)
7763 return StmtError();
7764
7765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007766 auto BaseStmt = AStmt;
David Majnemer9d168222016-08-05 17:44:54 +00007767 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007768 BaseStmt = CS->getCapturedStmt();
David Majnemer9d168222016-08-05 17:44:54 +00007769 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007770 auto S = C->children();
Benjamin Kramer5733e352015-07-18 17:09:36 +00007771 if (S.begin() == S.end())
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007772 return StmtError();
7773 // All associated statements must be '#pragma omp section' except for
7774 // the first one.
Benjamin Kramer5733e352015-07-18 17:09:36 +00007775 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007776 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
7777 if (SectionStmt)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007778 Diag(SectionStmt->getBeginLoc(),
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007779 diag::err_omp_sections_substmt_not_section);
7780 return StmtError();
7781 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00007782 cast<OMPSectionDirective>(SectionStmt)
7783 ->setHasCancel(DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007784 }
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007785 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007786 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007787 return StmtError();
7788 }
7789
Reid Kleckner87a31802018-03-12 21:43:02 +00007790 setFunctionHasBranchProtectedScope();
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007791
Alexey Bataev25e5b442015-09-15 12:52:43 +00007792 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7793 DSAStack->isCancelRegion());
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00007794}
7795
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007796StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
7797 SourceLocation StartLoc,
7798 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007799 if (!AStmt)
7800 return StmtError();
7801
7802 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007803
Reid Kleckner87a31802018-03-12 21:43:02 +00007804 setFunctionHasBranchProtectedScope();
Alexey Bataev25e5b442015-09-15 12:52:43 +00007805 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007806
Alexey Bataev25e5b442015-09-15 12:52:43 +00007807 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
7808 DSAStack->isCancelRegion());
Alexey Bataev1e0498a2014-06-26 08:21:58 +00007809}
7810
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00007811StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
7812 Stmt *AStmt,
7813 SourceLocation StartLoc,
7814 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007815 if (!AStmt)
7816 return StmtError();
7817
7818 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev74a05c92014-07-15 02:55:09 +00007819
Reid Kleckner87a31802018-03-12 21:43:02 +00007820 setFunctionHasBranchProtectedScope();
Alexey Bataev74a05c92014-07-15 02:55:09 +00007821
Alexey Bataev3255bf32015-01-19 05:20:46 +00007822 // OpenMP [2.7.3, single Construct, Restrictions]
7823 // The copyprivate clause must not be used with the nowait clause.
Alexey Bataeve3727102018-04-18 15:57:46 +00007824 const OMPClause *Nowait = nullptr;
7825 const OMPClause *Copyprivate = nullptr;
7826 for (const OMPClause *Clause : Clauses) {
Alexey Bataev3255bf32015-01-19 05:20:46 +00007827 if (Clause->getClauseKind() == OMPC_nowait)
7828 Nowait = Clause;
7829 else if (Clause->getClauseKind() == OMPC_copyprivate)
7830 Copyprivate = Clause;
7831 if (Copyprivate && Nowait) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007832 Diag(Copyprivate->getBeginLoc(),
Alexey Bataev3255bf32015-01-19 05:20:46 +00007833 diag::err_omp_single_copyprivate_with_nowait);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007834 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
Alexey Bataev3255bf32015-01-19 05:20:46 +00007835 return StmtError();
7836 }
7837 }
7838
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00007839 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7840}
7841
Alexander Musman80c22892014-07-17 08:54:58 +00007842StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
7843 SourceLocation StartLoc,
7844 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007845 if (!AStmt)
7846 return StmtError();
7847
7848 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musman80c22892014-07-17 08:54:58 +00007849
Reid Kleckner87a31802018-03-12 21:43:02 +00007850 setFunctionHasBranchProtectedScope();
Alexander Musman80c22892014-07-17 08:54:58 +00007851
7852 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
7853}
7854
Alexey Bataev28c75412015-12-15 08:19:24 +00007855StmtResult Sema::ActOnOpenMPCriticalDirective(
7856 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
7857 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007858 if (!AStmt)
7859 return StmtError();
7860
7861 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00007862
Alexey Bataev28c75412015-12-15 08:19:24 +00007863 bool ErrorFound = false;
7864 llvm::APSInt Hint;
7865 SourceLocation HintLoc;
7866 bool DependentHint = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00007867 for (const OMPClause *C : Clauses) {
Alexey Bataev28c75412015-12-15 08:19:24 +00007868 if (C->getClauseKind() == OMPC_hint) {
7869 if (!DirName.getName()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007870 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
Alexey Bataev28c75412015-12-15 08:19:24 +00007871 ErrorFound = true;
7872 }
7873 Expr *E = cast<OMPHintClause>(C)->getHint();
7874 if (E->isTypeDependent() || E->isValueDependent() ||
Alexey Bataeve3727102018-04-18 15:57:46 +00007875 E->isInstantiationDependent()) {
Alexey Bataev28c75412015-12-15 08:19:24 +00007876 DependentHint = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00007877 } else {
Alexey Bataev28c75412015-12-15 08:19:24 +00007878 Hint = E->EvaluateKnownConstInt(Context);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007879 HintLoc = C->getBeginLoc();
Alexey Bataev28c75412015-12-15 08:19:24 +00007880 }
7881 }
7882 }
7883 if (ErrorFound)
7884 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00007885 const auto Pair = DSAStack->getCriticalWithHint(DirName);
Alexey Bataev28c75412015-12-15 08:19:24 +00007886 if (Pair.first && DirName.getName() && !DependentHint) {
7887 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
7888 Diag(StartLoc, diag::err_omp_critical_with_hint);
Alexey Bataeve3727102018-04-18 15:57:46 +00007889 if (HintLoc.isValid())
Alexey Bataev28c75412015-12-15 08:19:24 +00007890 Diag(HintLoc, diag::note_omp_critical_hint_here)
7891 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +00007892 else
Alexey Bataev28c75412015-12-15 08:19:24 +00007893 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
Alexey Bataeve3727102018-04-18 15:57:46 +00007894 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007895 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
Alexey Bataev28c75412015-12-15 08:19:24 +00007896 << 1
7897 << C->getHint()->EvaluateKnownConstInt(Context).toString(
7898 /*Radix=*/10, /*Signed=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +00007899 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007900 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
Alexey Bataeve3727102018-04-18 15:57:46 +00007901 }
Alexey Bataev28c75412015-12-15 08:19:24 +00007902 }
7903 }
7904
Reid Kleckner87a31802018-03-12 21:43:02 +00007905 setFunctionHasBranchProtectedScope();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00007906
Alexey Bataev28c75412015-12-15 08:19:24 +00007907 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
7908 Clauses, AStmt);
7909 if (!Pair.first && DirName.getName() && !DependentHint)
7910 DSAStack->addCriticalWithHint(Dir, Hint);
7911 return Dir;
Alexander Musmand9ed09f2014-07-21 09:42:05 +00007912}
7913
Alexey Bataev4acb8592014-07-07 13:01:15 +00007914StmtResult Sema::ActOnOpenMPParallelForDirective(
7915 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00007916 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007917 if (!AStmt)
7918 return StmtError();
7919
Alexey Bataeve3727102018-04-18 15:57:46 +00007920 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev4acb8592014-07-07 13:01:15 +00007921 // 1.2.2 OpenMP Language Terminology
7922 // Structured block - An executable statement with a single entry at the
7923 // top and a single exit at the bottom.
7924 // The point of exit cannot be a branch out of the structured block.
7925 // longjmp() and throw() must not violate the entry/exit criteria.
7926 CS->getCapturedDecl()->setNothrow();
7927
Alexander Musmanc6388682014-12-15 07:07:06 +00007928 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00007929 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7930 // define the nested loops number.
Alexey Bataev4acb8592014-07-07 13:01:15 +00007931 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00007932 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00007933 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7934 VarsWithImplicitDSA, B);
Alexey Bataev4acb8592014-07-07 13:01:15 +00007935 if (NestedLoopCount == 0)
7936 return StmtError();
7937
Alexander Musmana5f070a2014-10-01 06:03:56 +00007938 assert((CurContext->isDependentContext() || B.builtAll()) &&
7939 "omp parallel for loop exprs were not built");
7940
Alexey Bataev54acd402015-08-04 11:18:19 +00007941 if (!CurContext->isDependentContext()) {
7942 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007943 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007944 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev54acd402015-08-04 11:18:19 +00007945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007946 B.NumIterations, *this, CurScope,
7947 DSAStack))
Alexey Bataev54acd402015-08-04 11:18:19 +00007948 return StmtError();
7949 }
7950 }
7951
Reid Kleckner87a31802018-03-12 21:43:02 +00007952 setFunctionHasBranchProtectedScope();
Alexander Musmanc6388682014-12-15 07:07:06 +00007953 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
Alexey Bataev25e5b442015-09-15 12:52:43 +00007954 NestedLoopCount, Clauses, AStmt, B,
7955 DSAStack->isCancelRegion());
Alexey Bataev4acb8592014-07-07 13:01:15 +00007956}
7957
Alexander Musmane4e893b2014-09-23 09:33:00 +00007958StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
7959 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00007960 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00007961 if (!AStmt)
7962 return StmtError();
7963
Alexey Bataeve3727102018-04-18 15:57:46 +00007964 auto *CS = cast<CapturedStmt>(AStmt);
Alexander Musmane4e893b2014-09-23 09:33:00 +00007965 // 1.2.2 OpenMP Language Terminology
7966 // Structured block - An executable statement with a single entry at the
7967 // top and a single exit at the bottom.
7968 // The point of exit cannot be a branch out of the structured block.
7969 // longjmp() and throw() must not violate the entry/exit criteria.
7970 CS->getCapturedDecl()->setNothrow();
7971
Alexander Musmanc6388682014-12-15 07:07:06 +00007972 OMPLoopDirective::HelperExprs B;
Alexey Bataev10e775f2015-07-30 11:36:16 +00007973 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7974 // define the nested loops number.
Alexander Musmane4e893b2014-09-23 09:33:00 +00007975 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00007976 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev10e775f2015-07-30 11:36:16 +00007977 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
7978 VarsWithImplicitDSA, B);
Alexander Musmane4e893b2014-09-23 09:33:00 +00007979 if (NestedLoopCount == 0)
7980 return StmtError();
7981
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00007982 if (!CurContext->isDependentContext()) {
7983 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00007984 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00007985 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00007986 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00007987 B.NumIterations, *this, CurScope,
7988 DSAStack))
Alexey Bataev3b5b5c42015-06-18 10:10:12 +00007989 return StmtError();
7990 }
7991 }
7992
Kelvin Lic5609492016-07-15 04:39:07 +00007993 if (checkSimdlenSafelenSpecified(*this, Clauses))
Alexey Bataev66b15b52015-08-21 11:14:16 +00007994 return StmtError();
7995
Reid Kleckner87a31802018-03-12 21:43:02 +00007996 setFunctionHasBranchProtectedScope();
Alexander Musmana5f070a2014-10-01 06:03:56 +00007997 return OMPParallelForSimdDirective::Create(
Alexander Musmanc6388682014-12-15 07:07:06 +00007998 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
Alexander Musmane4e893b2014-09-23 09:33:00 +00007999}
8000
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008001StmtResult
8002Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
8003 Stmt *AStmt, SourceLocation StartLoc,
8004 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008005 if (!AStmt)
8006 return StmtError();
8007
8008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008009 auto BaseStmt = AStmt;
David Majnemer9d168222016-08-05 17:44:54 +00008010 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008011 BaseStmt = CS->getCapturedStmt();
David Majnemer9d168222016-08-05 17:44:54 +00008012 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008013 auto S = C->children();
Benjamin Kramer5733e352015-07-18 17:09:36 +00008014 if (S.begin() == S.end())
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008015 return StmtError();
8016 // All associated statements must be '#pragma omp section' except for
8017 // the first one.
Benjamin Kramer5733e352015-07-18 17:09:36 +00008018 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008019 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8020 if (SectionStmt)
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008021 Diag(SectionStmt->getBeginLoc(),
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008022 diag::err_omp_parallel_sections_substmt_not_section);
8023 return StmtError();
8024 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00008025 cast<OMPSectionDirective>(SectionStmt)
8026 ->setHasCancel(DSAStack->isCancelRegion());
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008027 }
8028 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008029 Diag(AStmt->getBeginLoc(),
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008030 diag::err_omp_parallel_sections_not_compound_stmt);
8031 return StmtError();
8032 }
8033
Reid Kleckner87a31802018-03-12 21:43:02 +00008034 setFunctionHasBranchProtectedScope();
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008035
Alexey Bataev25e5b442015-09-15 12:52:43 +00008036 return OMPParallelSectionsDirective::Create(
8037 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00008038}
8039
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00008040StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
8041 Stmt *AStmt, SourceLocation StartLoc,
8042 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008043 if (!AStmt)
8044 return StmtError();
8045
David Majnemer9d168222016-08-05 17:44:54 +00008046 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00008047 // 1.2.2 OpenMP Language Terminology
8048 // Structured block - An executable statement with a single entry at the
8049 // top and a single exit at the bottom.
8050 // The point of exit cannot be a branch out of the structured block.
8051 // longjmp() and throw() must not violate the entry/exit criteria.
8052 CS->getCapturedDecl()->setNothrow();
8053
Reid Kleckner87a31802018-03-12 21:43:02 +00008054 setFunctionHasBranchProtectedScope();
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00008055
Alexey Bataev25e5b442015-09-15 12:52:43 +00008056 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8057 DSAStack->isCancelRegion());
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00008058}
8059
Alexey Bataev68446b72014-07-18 07:47:19 +00008060StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
8061 SourceLocation EndLoc) {
8062 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
8063}
8064
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00008065StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
8066 SourceLocation EndLoc) {
8067 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
8068}
8069
Alexey Bataev2df347a2014-07-18 10:17:07 +00008070StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
8071 SourceLocation EndLoc) {
8072 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
8073}
8074
Alexey Bataev169d96a2017-07-18 20:17:46 +00008075StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
8076 Stmt *AStmt,
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00008077 SourceLocation StartLoc,
8078 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008079 if (!AStmt)
8080 return StmtError();
8081
8082 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00008083
Reid Kleckner87a31802018-03-12 21:43:02 +00008084 setFunctionHasBranchProtectedScope();
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00008085
Alexey Bataev169d96a2017-07-18 20:17:46 +00008086 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
Alexey Bataev3b1b8952017-07-25 15:53:26 +00008087 AStmt,
8088 DSAStack->getTaskgroupReductionRef());
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00008089}
8090
Alexey Bataev6125da92014-07-21 11:26:11 +00008091StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
8092 SourceLocation StartLoc,
8093 SourceLocation EndLoc) {
8094 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
8095 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
8096}
8097
Alexey Bataev346265e2015-09-25 10:37:12 +00008098StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
8099 Stmt *AStmt,
Alexey Bataev9fb6e642014-07-22 06:45:04 +00008100 SourceLocation StartLoc,
8101 SourceLocation EndLoc) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008102 const OMPClause *DependFound = nullptr;
8103 const OMPClause *DependSourceClause = nullptr;
8104 const OMPClause *DependSinkClause = nullptr;
Alexey Bataeveb482352015-12-18 05:05:56 +00008105 bool ErrorFound = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00008106 const OMPThreadsClause *TC = nullptr;
8107 const OMPSIMDClause *SC = nullptr;
8108 for (const OMPClause *C : Clauses) {
Alexey Bataeveb482352015-12-18 05:05:56 +00008109 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
8110 DependFound = C;
8111 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
8112 if (DependSourceClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008113 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
Alexey Bataeveb482352015-12-18 05:05:56 +00008114 << getOpenMPDirectiveName(OMPD_ordered)
8115 << getOpenMPClauseName(OMPC_depend) << 2;
8116 ErrorFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00008117 } else {
Alexey Bataeveb482352015-12-18 05:05:56 +00008118 DependSourceClause = C;
Alexey Bataeve3727102018-04-18 15:57:46 +00008119 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +00008120 if (DependSinkClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008121 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00008122 << 0;
8123 ErrorFound = true;
8124 }
8125 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
8126 if (DependSourceClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008127 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
Alexey Bataeva636c7f2015-12-23 10:27:45 +00008128 << 1;
8129 ErrorFound = true;
8130 }
8131 DependSinkClause = C;
Alexey Bataeveb482352015-12-18 05:05:56 +00008132 }
Alexey Bataeve3727102018-04-18 15:57:46 +00008133 } else if (C->getClauseKind() == OMPC_threads) {
Alexey Bataev346265e2015-09-25 10:37:12 +00008134 TC = cast<OMPThreadsClause>(C);
Alexey Bataeve3727102018-04-18 15:57:46 +00008135 } else if (C->getClauseKind() == OMPC_simd) {
Alexey Bataevd14d1e62015-09-28 06:39:35 +00008136 SC = cast<OMPSIMDClause>(C);
Alexey Bataeve3727102018-04-18 15:57:46 +00008137 }
Alexey Bataev346265e2015-09-25 10:37:12 +00008138 }
Alexey Bataeveb482352015-12-18 05:05:56 +00008139 if (!ErrorFound && !SC &&
8140 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
Alexey Bataevd14d1e62015-09-28 06:39:35 +00008141 // OpenMP [2.8.1,simd Construct, Restrictions]
8142 // An ordered construct with the simd clause is the only OpenMP construct
8143 // that can appear in the simd region.
8144 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
Alexey Bataeveb482352015-12-18 05:05:56 +00008145 ErrorFound = true;
8146 } else if (DependFound && (TC || SC)) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008147 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
Alexey Bataeveb482352015-12-18 05:05:56 +00008148 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
8149 ErrorFound = true;
Alexey Bataevf138fda2018-08-13 19:04:24 +00008150 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008151 Diag(DependFound->getBeginLoc(),
Alexey Bataeveb482352015-12-18 05:05:56 +00008152 diag::err_omp_ordered_directive_without_param);
8153 ErrorFound = true;
8154 } else if (TC || Clauses.empty()) {
Alexey Bataevf138fda2018-08-13 19:04:24 +00008155 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008156 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
Alexey Bataeveb482352015-12-18 05:05:56 +00008157 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
8158 << (TC != nullptr);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008159 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
Alexey Bataeveb482352015-12-18 05:05:56 +00008160 ErrorFound = true;
8161 }
8162 }
8163 if ((!AStmt && !DependFound) || ErrorFound)
Alexey Bataevd14d1e62015-09-28 06:39:35 +00008164 return StmtError();
Alexey Bataeveb482352015-12-18 05:05:56 +00008165
8166 if (AStmt) {
8167 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8168
Reid Kleckner87a31802018-03-12 21:43:02 +00008169 setFunctionHasBranchProtectedScope();
Alexey Bataevd14d1e62015-09-28 06:39:35 +00008170 }
Alexey Bataev346265e2015-09-25 10:37:12 +00008171
8172 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00008173}
8174
Alexey Bataev1d160b12015-03-13 12:27:31 +00008175namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008176/// Helper class for checking expression in 'omp atomic [update]'
Alexey Bataev1d160b12015-03-13 12:27:31 +00008177/// construct.
8178class OpenMPAtomicUpdateChecker {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008179 /// Error results for atomic update expressions.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008180 enum ExprAnalysisErrorCode {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008181 /// A statement is not an expression statement.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008182 NotAnExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008183 /// Expression is not builtin binary or unary operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008184 NotABinaryOrUnaryExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008185 /// Unary operation is not post-/pre- increment/decrement operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008186 NotAnUnaryIncDecExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008187 /// An expression is not of scalar type.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008188 NotAScalarType,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008189 /// A binary operation is not an assignment operation.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008190 NotAnAssignmentOp,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008191 /// RHS part of the binary operation is not a binary expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008192 NotABinaryExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008193 /// RHS part is not additive/multiplicative/shift/biwise binary
Alexey Bataev1d160b12015-03-13 12:27:31 +00008194 /// expression.
8195 NotABinaryOperator,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008196 /// RHS binary operation does not have reference to the updated LHS
Alexey Bataev1d160b12015-03-13 12:27:31 +00008197 /// part.
8198 NotAnUpdateExpression,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008199 /// No errors is found.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008200 NoError
8201 };
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008202 /// Reference to Sema.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008203 Sema &SemaRef;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008204 /// A location for note diagnostics (when error is found).
Alexey Bataev1d160b12015-03-13 12:27:31 +00008205 SourceLocation NoteLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008206 /// 'x' lvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008207 Expr *X;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008208 /// 'expr' rvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008209 Expr *E;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008210 /// Helper expression of the form
Alexey Bataevb4505a72015-03-30 05:20:59 +00008211 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8212 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8213 Expr *UpdateExpr;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008214 /// Is 'x' a LHS in a RHS part of full update expression. It is
Alexey Bataevb4505a72015-03-30 05:20:59 +00008215 /// important for non-associative operations.
8216 bool IsXLHSInRHSPart;
8217 BinaryOperatorKind Op;
8218 SourceLocation OpLoc;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008219 /// true if the source expression is a postfix unary operation, false
Alexey Bataevb78ca832015-04-01 03:33:17 +00008220 /// if it is a prefix unary operation.
8221 bool IsPostfixUpdate;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008222
8223public:
8224 OpenMPAtomicUpdateChecker(Sema &SemaRef)
Alexey Bataevb4505a72015-03-30 05:20:59 +00008225 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
Alexey Bataevb78ca832015-04-01 03:33:17 +00008226 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008227 /// Check specified statement that it is suitable for 'atomic update'
Alexey Bataev1d160b12015-03-13 12:27:31 +00008228 /// constructs and extract 'x', 'expr' and Operation from the original
Alexey Bataevb78ca832015-04-01 03:33:17 +00008229 /// expression. If DiagId and NoteId == 0, then only check is performed
8230 /// without error notification.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008231 /// \param DiagId Diagnostic which should be emitted if error is found.
8232 /// \param NoteId Diagnostic note for the main error message.
8233 /// \return true if statement is not an update expression, false otherwise.
Alexey Bataevb78ca832015-04-01 03:33:17 +00008234 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008235 /// Return the 'x' lvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008236 Expr *getX() const { return X; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008237 /// Return the 'expr' rvalue part of the source atomic expression.
Alexey Bataev1d160b12015-03-13 12:27:31 +00008238 Expr *getExpr() const { return E; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008239 /// Return the update expression used in calculation of the updated
Alexey Bataevb4505a72015-03-30 05:20:59 +00008240 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8241 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8242 Expr *getUpdateExpr() const { return UpdateExpr; }
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008243 /// Return true if 'x' is LHS in RHS part of full update expression,
Alexey Bataevb4505a72015-03-30 05:20:59 +00008244 /// false otherwise.
8245 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
8246
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008247 /// true if the source expression is a postfix unary operation, false
Alexey Bataevb78ca832015-04-01 03:33:17 +00008248 /// if it is a prefix unary operation.
8249 bool isPostfixUpdate() const { return IsPostfixUpdate; }
8250
Alexey Bataev1d160b12015-03-13 12:27:31 +00008251private:
Alexey Bataevb78ca832015-04-01 03:33:17 +00008252 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
8253 unsigned NoteId = 0);
Alexey Bataev1d160b12015-03-13 12:27:31 +00008254};
8255} // namespace
8256
8257bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
8258 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
8259 ExprAnalysisErrorCode ErrorFound = NoError;
8260 SourceLocation ErrorLoc, NoteLoc;
8261 SourceRange ErrorRange, NoteRange;
8262 // Allowed constructs are:
8263 // x = x binop expr;
8264 // x = expr binop x;
8265 if (AtomicBinOp->getOpcode() == BO_Assign) {
8266 X = AtomicBinOp->getLHS();
Alexey Bataeve3727102018-04-18 15:57:46 +00008267 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
Alexey Bataev1d160b12015-03-13 12:27:31 +00008268 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
8269 if (AtomicInnerBinOp->isMultiplicativeOp() ||
8270 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
8271 AtomicInnerBinOp->isBitwiseOp()) {
Alexey Bataevb4505a72015-03-30 05:20:59 +00008272 Op = AtomicInnerBinOp->getOpcode();
8273 OpLoc = AtomicInnerBinOp->getOperatorLoc();
Alexey Bataeve3727102018-04-18 15:57:46 +00008274 Expr *LHS = AtomicInnerBinOp->getLHS();
8275 Expr *RHS = AtomicInnerBinOp->getRHS();
Alexey Bataev1d160b12015-03-13 12:27:31 +00008276 llvm::FoldingSetNodeID XId, LHSId, RHSId;
8277 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
8278 /*Canonical=*/true);
8279 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
8280 /*Canonical=*/true);
8281 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
8282 /*Canonical=*/true);
8283 if (XId == LHSId) {
8284 E = RHS;
Alexey Bataevb4505a72015-03-30 05:20:59 +00008285 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008286 } else if (XId == RHSId) {
8287 E = LHS;
Alexey Bataevb4505a72015-03-30 05:20:59 +00008288 IsXLHSInRHSPart = false;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008289 } else {
8290 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8291 ErrorRange = AtomicInnerBinOp->getSourceRange();
8292 NoteLoc = X->getExprLoc();
8293 NoteRange = X->getSourceRange();
8294 ErrorFound = NotAnUpdateExpression;
8295 }
8296 } else {
8297 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8298 ErrorRange = AtomicInnerBinOp->getSourceRange();
8299 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
8300 NoteRange = SourceRange(NoteLoc, NoteLoc);
8301 ErrorFound = NotABinaryOperator;
8302 }
8303 } else {
8304 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
8305 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
8306 ErrorFound = NotABinaryExpression;
8307 }
8308 } else {
8309 ErrorLoc = AtomicBinOp->getExprLoc();
8310 ErrorRange = AtomicBinOp->getSourceRange();
8311 NoteLoc = AtomicBinOp->getOperatorLoc();
8312 NoteRange = SourceRange(NoteLoc, NoteLoc);
8313 ErrorFound = NotAnAssignmentOp;
8314 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00008315 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00008316 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8317 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8318 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00008319 }
8320 if (SemaRef.CurContext->isDependentContext())
Alexey Bataevb4505a72015-03-30 05:20:59 +00008321 E = X = UpdateExpr = nullptr;
Alexey Bataev5e018f92015-04-23 06:35:10 +00008322 return ErrorFound != NoError;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008323}
8324
8325bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
8326 unsigned NoteId) {
8327 ExprAnalysisErrorCode ErrorFound = NoError;
8328 SourceLocation ErrorLoc, NoteLoc;
8329 SourceRange ErrorRange, NoteRange;
8330 // Allowed constructs are:
8331 // x++;
8332 // x--;
8333 // ++x;
8334 // --x;
8335 // x binop= expr;
8336 // x = x binop expr;
8337 // x = expr binop x;
8338 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
8339 AtomicBody = AtomicBody->IgnoreParenImpCasts();
8340 if (AtomicBody->getType()->isScalarType() ||
8341 AtomicBody->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008342 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
Alexey Bataev1d160b12015-03-13 12:27:31 +00008343 AtomicBody->IgnoreParenImpCasts())) {
8344 // Check for Compound Assignment Operation
Alexey Bataevb4505a72015-03-30 05:20:59 +00008345 Op = BinaryOperator::getOpForCompoundAssignment(
Alexey Bataev1d160b12015-03-13 12:27:31 +00008346 AtomicCompAssignOp->getOpcode());
Alexey Bataevb4505a72015-03-30 05:20:59 +00008347 OpLoc = AtomicCompAssignOp->getOperatorLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00008348 E = AtomicCompAssignOp->getRHS();
Kelvin Li4f161cf2016-07-20 19:41:17 +00008349 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
Alexey Bataevb4505a72015-03-30 05:20:59 +00008350 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008351 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
8352 AtomicBody->IgnoreParenImpCasts())) {
8353 // Check for Binary Operation
David Majnemer9d168222016-08-05 17:44:54 +00008354 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
Alexey Bataevb4505a72015-03-30 05:20:59 +00008355 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00008356 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
David Majnemer9d168222016-08-05 17:44:54 +00008357 AtomicBody->IgnoreParenImpCasts())) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00008358 // Check for Unary Operation
8359 if (AtomicUnaryOp->isIncrementDecrementOp()) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008360 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
Alexey Bataevb4505a72015-03-30 05:20:59 +00008361 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
8362 OpLoc = AtomicUnaryOp->getOperatorLoc();
Kelvin Li4f161cf2016-07-20 19:41:17 +00008363 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
Alexey Bataevb4505a72015-03-30 05:20:59 +00008364 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
8365 IsXLHSInRHSPart = true;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008366 } else {
8367 ErrorFound = NotAnUnaryIncDecExpression;
8368 ErrorLoc = AtomicUnaryOp->getExprLoc();
8369 ErrorRange = AtomicUnaryOp->getSourceRange();
8370 NoteLoc = AtomicUnaryOp->getOperatorLoc();
8371 NoteRange = SourceRange(NoteLoc, NoteLoc);
8372 }
Alexey Bataev5a195472015-09-04 12:55:50 +00008373 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00008374 ErrorFound = NotABinaryOrUnaryExpression;
8375 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
8376 NoteRange = ErrorRange = AtomicBody->getSourceRange();
8377 }
8378 } else {
8379 ErrorFound = NotAScalarType;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008380 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00008381 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8382 }
8383 } else {
8384 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008385 NoteLoc = ErrorLoc = S->getBeginLoc();
Alexey Bataev1d160b12015-03-13 12:27:31 +00008386 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8387 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00008388 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00008389 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8390 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8391 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +00008392 }
8393 if (SemaRef.CurContext->isDependentContext())
Alexey Bataevb4505a72015-03-30 05:20:59 +00008394 E = X = UpdateExpr = nullptr;
Alexey Bataev5e018f92015-04-23 06:35:10 +00008395 if (ErrorFound == NoError && E && X) {
Alexey Bataevb4505a72015-03-30 05:20:59 +00008396 // Build an update expression of form 'OpaqueValueExpr(x) binop
8397 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
8398 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
8399 auto *OVEX = new (SemaRef.getASTContext())
8400 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
8401 auto *OVEExpr = new (SemaRef.getASTContext())
8402 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
Alexey Bataeve3727102018-04-18 15:57:46 +00008403 ExprResult Update =
Alexey Bataevb4505a72015-03-30 05:20:59 +00008404 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
8405 IsXLHSInRHSPart ? OVEExpr : OVEX);
8406 if (Update.isInvalid())
8407 return true;
8408 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
8409 Sema::AA_Casting);
8410 if (Update.isInvalid())
8411 return true;
8412 UpdateExpr = Update.get();
8413 }
Alexey Bataev5e018f92015-04-23 06:35:10 +00008414 return ErrorFound != NoError;
Alexey Bataev1d160b12015-03-13 12:27:31 +00008415}
8416
Alexey Bataev0162e452014-07-22 10:10:35 +00008417StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
8418 Stmt *AStmt,
8419 SourceLocation StartLoc,
8420 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008421 if (!AStmt)
8422 return StmtError();
8423
David Majnemer9d168222016-08-05 17:44:54 +00008424 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev0162e452014-07-22 10:10:35 +00008425 // 1.2.2 OpenMP Language Terminology
8426 // Structured block - An executable statement with a single entry at the
8427 // top and a single exit at the bottom.
8428 // The point of exit cannot be a branch out of the structured block.
8429 // longjmp() and throw() must not violate the entry/exit criteria.
Alexey Bataevdea47612014-07-23 07:46:59 +00008430 OpenMPClauseKind AtomicKind = OMPC_unknown;
8431 SourceLocation AtomicKindLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +00008432 for (const OMPClause *C : Clauses) {
Alexey Bataev67a4f222014-07-23 10:25:33 +00008433 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
Alexey Bataev459dec02014-07-24 06:46:57 +00008434 C->getClauseKind() == OMPC_update ||
8435 C->getClauseKind() == OMPC_capture) {
Alexey Bataevdea47612014-07-23 07:46:59 +00008436 if (AtomicKind != OMPC_unknown) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008437 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
Stephen Kelly1c301dc2018-08-09 21:09:38 +00008438 << SourceRange(C->getBeginLoc(), C->getEndLoc());
Alexey Bataevdea47612014-07-23 07:46:59 +00008439 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
8440 << getOpenMPClauseName(AtomicKind);
8441 } else {
8442 AtomicKind = C->getClauseKind();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008443 AtomicKindLoc = C->getBeginLoc();
Alexey Bataevf98b00c2014-07-23 02:27:21 +00008444 }
8445 }
8446 }
Alexey Bataev62cec442014-11-18 10:14:22 +00008447
Alexey Bataeve3727102018-04-18 15:57:46 +00008448 Stmt *Body = CS->getCapturedStmt();
Alexey Bataev10fec572015-03-11 04:48:56 +00008449 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
8450 Body = EWC->getSubExpr();
8451
Alexey Bataev62cec442014-11-18 10:14:22 +00008452 Expr *X = nullptr;
8453 Expr *V = nullptr;
8454 Expr *E = nullptr;
Alexey Bataevb4505a72015-03-30 05:20:59 +00008455 Expr *UE = nullptr;
8456 bool IsXLHSInRHSPart = false;
Alexey Bataevb78ca832015-04-01 03:33:17 +00008457 bool IsPostfixUpdate = false;
Alexey Bataev62cec442014-11-18 10:14:22 +00008458 // OpenMP [2.12.6, atomic Construct]
8459 // In the next expressions:
8460 // * x and v (as applicable) are both l-value expressions with scalar type.
8461 // * During the execution of an atomic region, multiple syntactic
8462 // occurrences of x must designate the same storage location.
8463 // * Neither of v and expr (as applicable) may access the storage location
8464 // designated by x.
8465 // * Neither of x and expr (as applicable) may access the storage location
8466 // designated by v.
8467 // * expr is an expression with scalar type.
8468 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
8469 // * binop, binop=, ++, and -- are not overloaded operators.
8470 // * The expression x binop expr must be numerically equivalent to x binop
8471 // (expr). This requirement is satisfied if the operators in expr have
8472 // precedence greater than binop, or by using parentheses around expr or
8473 // subexpressions of expr.
8474 // * The expression expr binop x must be numerically equivalent to (expr)
8475 // binop x. This requirement is satisfied if the operators in expr have
8476 // precedence equal to or greater than binop, or by using parentheses around
8477 // expr or subexpressions of expr.
8478 // * For forms that allow multiple occurrences of x, the number of times
8479 // that x is evaluated is unspecified.
Alexey Bataevdea47612014-07-23 07:46:59 +00008480 if (AtomicKind == OMPC_read) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008481 enum {
8482 NotAnExpression,
8483 NotAnAssignmentOp,
8484 NotAScalarType,
8485 NotAnLValue,
8486 NoError
8487 } ErrorFound = NoError;
Alexey Bataev62cec442014-11-18 10:14:22 +00008488 SourceLocation ErrorLoc, NoteLoc;
8489 SourceRange ErrorRange, NoteRange;
8490 // If clause is read:
8491 // v = x;
Alexey Bataeve3727102018-04-18 15:57:46 +00008492 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8493 const auto *AtomicBinOp =
Alexey Bataev62cec442014-11-18 10:14:22 +00008494 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8495 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8496 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
8497 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
8498 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8499 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
8500 if (!X->isLValue() || !V->isLValue()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008501 const Expr *NotLValueExpr = X->isLValue() ? V : X;
Alexey Bataev62cec442014-11-18 10:14:22 +00008502 ErrorFound = NotAnLValue;
8503 ErrorLoc = AtomicBinOp->getExprLoc();
8504 ErrorRange = AtomicBinOp->getSourceRange();
8505 NoteLoc = NotLValueExpr->getExprLoc();
8506 NoteRange = NotLValueExpr->getSourceRange();
8507 }
8508 } else if (!X->isInstantiationDependent() ||
8509 !V->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008510 const Expr *NotScalarExpr =
Alexey Bataev62cec442014-11-18 10:14:22 +00008511 (X->isInstantiationDependent() || X->getType()->isScalarType())
8512 ? V
8513 : X;
8514 ErrorFound = NotAScalarType;
8515 ErrorLoc = AtomicBinOp->getExprLoc();
8516 ErrorRange = AtomicBinOp->getSourceRange();
8517 NoteLoc = NotScalarExpr->getExprLoc();
8518 NoteRange = NotScalarExpr->getSourceRange();
8519 }
Alexey Bataev5a195472015-09-04 12:55:50 +00008520 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataev62cec442014-11-18 10:14:22 +00008521 ErrorFound = NotAnAssignmentOp;
8522 ErrorLoc = AtomicBody->getExprLoc();
8523 ErrorRange = AtomicBody->getSourceRange();
8524 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8525 : AtomicBody->getExprLoc();
8526 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8527 : AtomicBody->getSourceRange();
8528 }
8529 } else {
8530 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008531 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataev62cec442014-11-18 10:14:22 +00008532 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
Alexey Bataevdea47612014-07-23 07:46:59 +00008533 }
Alexey Bataev62cec442014-11-18 10:14:22 +00008534 if (ErrorFound != NoError) {
8535 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
8536 << ErrorRange;
Alexey Bataevf33eba62014-11-28 07:21:40 +00008537 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8538 << NoteRange;
Alexey Bataev62cec442014-11-18 10:14:22 +00008539 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00008540 }
8541 if (CurContext->isDependentContext())
Alexey Bataev62cec442014-11-18 10:14:22 +00008542 V = X = nullptr;
Alexey Bataevdea47612014-07-23 07:46:59 +00008543 } else if (AtomicKind == OMPC_write) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008544 enum {
8545 NotAnExpression,
8546 NotAnAssignmentOp,
8547 NotAScalarType,
8548 NotAnLValue,
8549 NoError
8550 } ErrorFound = NoError;
Alexey Bataevf33eba62014-11-28 07:21:40 +00008551 SourceLocation ErrorLoc, NoteLoc;
8552 SourceRange ErrorRange, NoteRange;
8553 // If clause is write:
8554 // x = expr;
Alexey Bataeve3727102018-04-18 15:57:46 +00008555 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8556 const auto *AtomicBinOp =
Alexey Bataevf33eba62014-11-28 07:21:40 +00008557 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8558 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
Alexey Bataevb8329262015-02-27 06:33:30 +00008559 X = AtomicBinOp->getLHS();
8560 E = AtomicBinOp->getRHS();
Alexey Bataevf33eba62014-11-28 07:21:40 +00008561 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8562 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
8563 if (!X->isLValue()) {
8564 ErrorFound = NotAnLValue;
8565 ErrorLoc = AtomicBinOp->getExprLoc();
8566 ErrorRange = AtomicBinOp->getSourceRange();
8567 NoteLoc = X->getExprLoc();
8568 NoteRange = X->getSourceRange();
8569 }
8570 } else if (!X->isInstantiationDependent() ||
8571 !E->isInstantiationDependent()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008572 const Expr *NotScalarExpr =
Alexey Bataevf33eba62014-11-28 07:21:40 +00008573 (X->isInstantiationDependent() || X->getType()->isScalarType())
8574 ? E
8575 : X;
8576 ErrorFound = NotAScalarType;
8577 ErrorLoc = AtomicBinOp->getExprLoc();
8578 ErrorRange = AtomicBinOp->getSourceRange();
8579 NoteLoc = NotScalarExpr->getExprLoc();
8580 NoteRange = NotScalarExpr->getSourceRange();
8581 }
Alexey Bataev5a195472015-09-04 12:55:50 +00008582 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataevf33eba62014-11-28 07:21:40 +00008583 ErrorFound = NotAnAssignmentOp;
8584 ErrorLoc = AtomicBody->getExprLoc();
8585 ErrorRange = AtomicBody->getSourceRange();
8586 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8587 : AtomicBody->getExprLoc();
8588 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8589 : AtomicBody->getSourceRange();
8590 }
8591 } else {
8592 ErrorFound = NotAnExpression;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008593 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevf33eba62014-11-28 07:21:40 +00008594 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
Alexey Bataevdea47612014-07-23 07:46:59 +00008595 }
Alexey Bataevf33eba62014-11-28 07:21:40 +00008596 if (ErrorFound != NoError) {
8597 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
8598 << ErrorRange;
8599 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8600 << NoteRange;
8601 return StmtError();
Alexey Bataeve3727102018-04-18 15:57:46 +00008602 }
8603 if (CurContext->isDependentContext())
Alexey Bataevf33eba62014-11-28 07:21:40 +00008604 E = X = nullptr;
Alexey Bataev67a4f222014-07-23 10:25:33 +00008605 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
Alexey Bataev1d160b12015-03-13 12:27:31 +00008606 // If clause is update:
8607 // x++;
8608 // x--;
8609 // ++x;
8610 // --x;
8611 // x binop= expr;
8612 // x = x binop expr;
8613 // x = expr binop x;
8614 OpenMPAtomicUpdateChecker Checker(*this);
8615 if (Checker.checkStatement(
8616 Body, (AtomicKind == OMPC_update)
8617 ? diag::err_omp_atomic_update_not_expression_statement
8618 : diag::err_omp_atomic_not_expression_statement,
8619 diag::note_omp_atomic_update))
Alexey Bataev67a4f222014-07-23 10:25:33 +00008620 return StmtError();
Alexey Bataev1d160b12015-03-13 12:27:31 +00008621 if (!CurContext->isDependentContext()) {
8622 E = Checker.getExpr();
8623 X = Checker.getX();
Alexey Bataevb4505a72015-03-30 05:20:59 +00008624 UE = Checker.getUpdateExpr();
8625 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev67a4f222014-07-23 10:25:33 +00008626 }
Alexey Bataev459dec02014-07-24 06:46:57 +00008627 } else if (AtomicKind == OMPC_capture) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008628 enum {
8629 NotAnAssignmentOp,
8630 NotACompoundStatement,
8631 NotTwoSubstatements,
8632 NotASpecificExpression,
8633 NoError
8634 } ErrorFound = NoError;
8635 SourceLocation ErrorLoc, NoteLoc;
8636 SourceRange ErrorRange, NoteRange;
Alexey Bataeve3727102018-04-18 15:57:46 +00008637 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008638 // If clause is a capture:
8639 // v = x++;
8640 // v = x--;
8641 // v = ++x;
8642 // v = --x;
8643 // v = x binop= expr;
8644 // v = x = x binop expr;
8645 // v = x = expr binop x;
Alexey Bataeve3727102018-04-18 15:57:46 +00008646 const auto *AtomicBinOp =
Alexey Bataevb78ca832015-04-01 03:33:17 +00008647 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8648 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8649 V = AtomicBinOp->getLHS();
8650 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
8651 OpenMPAtomicUpdateChecker Checker(*this);
8652 if (Checker.checkStatement(
8653 Body, diag::err_omp_atomic_capture_not_expression_statement,
8654 diag::note_omp_atomic_update))
8655 return StmtError();
8656 E = Checker.getExpr();
8657 X = Checker.getX();
8658 UE = Checker.getUpdateExpr();
8659 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
8660 IsPostfixUpdate = Checker.isPostfixUpdate();
Alexey Bataev5a195472015-09-04 12:55:50 +00008661 } else if (!AtomicBody->isInstantiationDependent()) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008662 ErrorLoc = AtomicBody->getExprLoc();
8663 ErrorRange = AtomicBody->getSourceRange();
8664 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8665 : AtomicBody->getExprLoc();
8666 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8667 : AtomicBody->getSourceRange();
8668 ErrorFound = NotAnAssignmentOp;
8669 }
8670 if (ErrorFound != NoError) {
8671 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
8672 << ErrorRange;
8673 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
8674 return StmtError();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008675 }
Alexey Bataeve3727102018-04-18 15:57:46 +00008676 if (CurContext->isDependentContext())
8677 UE = V = E = X = nullptr;
Alexey Bataevb78ca832015-04-01 03:33:17 +00008678 } else {
8679 // If clause is a capture:
8680 // { v = x; x = expr; }
8681 // { v = x; x++; }
8682 // { v = x; x--; }
8683 // { v = x; ++x; }
8684 // { v = x; --x; }
8685 // { v = x; x binop= expr; }
8686 // { v = x; x = x binop expr; }
8687 // { v = x; x = expr binop x; }
8688 // { x++; v = x; }
8689 // { x--; v = x; }
8690 // { ++x; v = x; }
8691 // { --x; v = x; }
8692 // { x binop= expr; v = x; }
8693 // { x = x binop expr; v = x; }
8694 // { x = expr binop x; v = x; }
8695 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
8696 // Check that this is { expr1; expr2; }
8697 if (CS->size() == 2) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008698 Stmt *First = CS->body_front();
8699 Stmt *Second = CS->body_back();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008700 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
8701 First = EWC->getSubExpr()->IgnoreParenImpCasts();
8702 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
8703 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
8704 // Need to find what subexpression is 'v' and what is 'x'.
8705 OpenMPAtomicUpdateChecker Checker(*this);
8706 bool IsUpdateExprFound = !Checker.checkStatement(Second);
8707 BinaryOperator *BinOp = nullptr;
8708 if (IsUpdateExprFound) {
8709 BinOp = dyn_cast<BinaryOperator>(First);
8710 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
8711 }
8712 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
8713 // { v = x; x++; }
8714 // { v = x; x--; }
8715 // { v = x; ++x; }
8716 // { v = x; --x; }
8717 // { v = x; x binop= expr; }
8718 // { v = x; x = x binop expr; }
8719 // { v = x; x = expr binop x; }
8720 // Check that the first expression has form v = x.
Alexey Bataeve3727102018-04-18 15:57:46 +00008721 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008722 llvm::FoldingSetNodeID XId, PossibleXId;
8723 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
8724 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
8725 IsUpdateExprFound = XId == PossibleXId;
8726 if (IsUpdateExprFound) {
8727 V = BinOp->getLHS();
8728 X = Checker.getX();
8729 E = Checker.getExpr();
8730 UE = Checker.getUpdateExpr();
8731 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev5e018f92015-04-23 06:35:10 +00008732 IsPostfixUpdate = true;
Alexey Bataevb78ca832015-04-01 03:33:17 +00008733 }
8734 }
8735 if (!IsUpdateExprFound) {
8736 IsUpdateExprFound = !Checker.checkStatement(First);
8737 BinOp = nullptr;
8738 if (IsUpdateExprFound) {
8739 BinOp = dyn_cast<BinaryOperator>(Second);
8740 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
8741 }
8742 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
8743 // { x++; v = x; }
8744 // { x--; v = x; }
8745 // { ++x; v = x; }
8746 // { --x; v = x; }
8747 // { x binop= expr; v = x; }
8748 // { x = x binop expr; v = x; }
8749 // { x = expr binop x; v = x; }
8750 // Check that the second expression has form v = x.
Alexey Bataeve3727102018-04-18 15:57:46 +00008751 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008752 llvm::FoldingSetNodeID XId, PossibleXId;
8753 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
8754 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
8755 IsUpdateExprFound = XId == PossibleXId;
8756 if (IsUpdateExprFound) {
8757 V = BinOp->getLHS();
8758 X = Checker.getX();
8759 E = Checker.getExpr();
8760 UE = Checker.getUpdateExpr();
8761 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
Alexey Bataev5e018f92015-04-23 06:35:10 +00008762 IsPostfixUpdate = false;
Alexey Bataevb78ca832015-04-01 03:33:17 +00008763 }
8764 }
8765 }
8766 if (!IsUpdateExprFound) {
8767 // { v = x; x = expr; }
Alexey Bataev5a195472015-09-04 12:55:50 +00008768 auto *FirstExpr = dyn_cast<Expr>(First);
8769 auto *SecondExpr = dyn_cast<Expr>(Second);
8770 if (!FirstExpr || !SecondExpr ||
8771 !(FirstExpr->isInstantiationDependent() ||
8772 SecondExpr->isInstantiationDependent())) {
8773 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
8774 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
Alexey Bataevb78ca832015-04-01 03:33:17 +00008775 ErrorFound = NotAnAssignmentOp;
Alexey Bataev5a195472015-09-04 12:55:50 +00008776 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008777 : First->getBeginLoc();
Alexey Bataev5a195472015-09-04 12:55:50 +00008778 NoteRange = ErrorRange = FirstBinOp
8779 ? FirstBinOp->getSourceRange()
Alexey Bataevb78ca832015-04-01 03:33:17 +00008780 : SourceRange(ErrorLoc, ErrorLoc);
8781 } else {
Alexey Bataev5a195472015-09-04 12:55:50 +00008782 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
8783 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
8784 ErrorFound = NotAnAssignmentOp;
8785 NoteLoc = ErrorLoc = SecondBinOp
8786 ? SecondBinOp->getOperatorLoc()
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008787 : Second->getBeginLoc();
Alexey Bataev5a195472015-09-04 12:55:50 +00008788 NoteRange = ErrorRange =
8789 SecondBinOp ? SecondBinOp->getSourceRange()
8790 : SourceRange(ErrorLoc, ErrorLoc);
Alexey Bataevb78ca832015-04-01 03:33:17 +00008791 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +00008792 Expr *PossibleXRHSInFirst =
Alexey Bataev5a195472015-09-04 12:55:50 +00008793 FirstBinOp->getRHS()->IgnoreParenImpCasts();
Alexey Bataeve3727102018-04-18 15:57:46 +00008794 Expr *PossibleXLHSInSecond =
Alexey Bataev5a195472015-09-04 12:55:50 +00008795 SecondBinOp->getLHS()->IgnoreParenImpCasts();
8796 llvm::FoldingSetNodeID X1Id, X2Id;
8797 PossibleXRHSInFirst->Profile(X1Id, Context,
8798 /*Canonical=*/true);
8799 PossibleXLHSInSecond->Profile(X2Id, Context,
8800 /*Canonical=*/true);
8801 IsUpdateExprFound = X1Id == X2Id;
8802 if (IsUpdateExprFound) {
8803 V = FirstBinOp->getLHS();
8804 X = SecondBinOp->getLHS();
8805 E = SecondBinOp->getRHS();
8806 UE = nullptr;
8807 IsXLHSInRHSPart = false;
8808 IsPostfixUpdate = true;
8809 } else {
8810 ErrorFound = NotASpecificExpression;
8811 ErrorLoc = FirstBinOp->getExprLoc();
8812 ErrorRange = FirstBinOp->getSourceRange();
8813 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
8814 NoteRange = SecondBinOp->getRHS()->getSourceRange();
8815 }
Alexey Bataevb78ca832015-04-01 03:33:17 +00008816 }
8817 }
8818 }
8819 }
8820 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008821 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008822 NoteRange = ErrorRange =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008823 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
Alexey Bataevb78ca832015-04-01 03:33:17 +00008824 ErrorFound = NotTwoSubstatements;
8825 }
8826 } else {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008827 NoteLoc = ErrorLoc = Body->getBeginLoc();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008828 NoteRange = ErrorRange =
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008829 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
Alexey Bataevb78ca832015-04-01 03:33:17 +00008830 ErrorFound = NotACompoundStatement;
8831 }
8832 if (ErrorFound != NoError) {
8833 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
8834 << ErrorRange;
8835 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
8836 return StmtError();
Alexey Bataevb78ca832015-04-01 03:33:17 +00008837 }
Alexey Bataeve3727102018-04-18 15:57:46 +00008838 if (CurContext->isDependentContext())
8839 UE = V = E = X = nullptr;
Alexey Bataev459dec02014-07-24 06:46:57 +00008840 }
Alexey Bataevdea47612014-07-23 07:46:59 +00008841 }
Alexey Bataev0162e452014-07-22 10:10:35 +00008842
Reid Kleckner87a31802018-03-12 21:43:02 +00008843 setFunctionHasBranchProtectedScope();
Alexey Bataev0162e452014-07-22 10:10:35 +00008844
Alexey Bataev62cec442014-11-18 10:14:22 +00008845 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
Alexey Bataevb78ca832015-04-01 03:33:17 +00008846 X, V, E, UE, IsXLHSInRHSPart,
8847 IsPostfixUpdate);
Alexey Bataev0162e452014-07-22 10:10:35 +00008848}
8849
Alexey Bataev0bd520b2014-09-19 08:19:49 +00008850StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
8851 Stmt *AStmt,
8852 SourceLocation StartLoc,
8853 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00008854 if (!AStmt)
8855 return StmtError();
8856
Alexey Bataeve3727102018-04-18 15:57:46 +00008857 auto *CS = cast<CapturedStmt>(AStmt);
Samuel Antao4af1b7b2015-12-02 17:44:43 +00008858 // 1.2.2 OpenMP Language Terminology
8859 // Structured block - An executable statement with a single entry at the
8860 // top and a single exit at the bottom.
8861 // The point of exit cannot be a branch out of the structured block.
8862 // longjmp() and throw() must not violate the entry/exit criteria.
8863 CS->getCapturedDecl()->setNothrow();
Alexey Bataev8451efa2018-01-15 19:06:12 +00008864 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
8865 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8866 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8867 // 1.2.2 OpenMP Language Terminology
8868 // Structured block - An executable statement with a single entry at the
8869 // top and a single exit at the bottom.
8870 // The point of exit cannot be a branch out of the structured block.
8871 // longjmp() and throw() must not violate the entry/exit criteria.
8872 CS->getCapturedDecl()->setNothrow();
8873 }
Alexey Bataev0bd520b2014-09-19 08:19:49 +00008874
Alexey Bataev13314bf2014-10-09 04:18:56 +00008875 // OpenMP [2.16, Nesting of Regions]
8876 // If specified, a teams construct must be contained within a target
8877 // construct. That target construct must contain no statements or directives
8878 // outside of the teams construct.
8879 if (DSAStack->hasInnerTeamsRegion()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008880 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
Alexey Bataev13314bf2014-10-09 04:18:56 +00008881 bool OMPTeamsFound = true;
Alexey Bataeve3727102018-04-18 15:57:46 +00008882 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
Alexey Bataev13314bf2014-10-09 04:18:56 +00008883 auto I = CS->body_begin();
8884 while (I != CS->body_end()) {
Alexey Bataeve3727102018-04-18 15:57:46 +00008885 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
Kelvin Li620ba602019-02-05 16:43:00 +00008886 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
8887 OMPTeamsFound) {
8888
Alexey Bataev13314bf2014-10-09 04:18:56 +00008889 OMPTeamsFound = false;
8890 break;
8891 }
8892 ++I;
8893 }
8894 assert(I != CS->body_end() && "Not found statement");
8895 S = *I;
Kelvin Li3834dce2016-06-27 19:15:43 +00008896 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +00008897 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
Kelvin Li3834dce2016-06-27 19:15:43 +00008898 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
Alexey Bataev13314bf2014-10-09 04:18:56 +00008899 }
8900 if (!OMPTeamsFound) {
8901 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
8902 Diag(DSAStack->getInnerTeamsRegionLoc(),
8903 diag::note_omp_nested_teams_construct_here);
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008904 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
Alexey Bataev13314bf2014-10-09 04:18:56 +00008905 << isa<OMPExecutableDirective>(S);
8906 return StmtError();
8907 }
8908 }
8909
Reid Kleckner87a31802018-03-12 21:43:02 +00008910 setFunctionHasBranchProtectedScope();
Alexey Bataev0bd520b2014-09-19 08:19:49 +00008911
8912 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8913}
8914
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00008915StmtResult
8916Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
8917 Stmt *AStmt, SourceLocation StartLoc,
8918 SourceLocation EndLoc) {
8919 if (!AStmt)
8920 return StmtError();
8921
Alexey Bataeve3727102018-04-18 15:57:46 +00008922 auto *CS = cast<CapturedStmt>(AStmt);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00008923 // 1.2.2 OpenMP Language Terminology
8924 // Structured block - An executable statement with a single entry at the
8925 // top and a single exit at the bottom.
8926 // The point of exit cannot be a branch out of the structured block.
8927 // longjmp() and throw() must not violate the entry/exit criteria.
8928 CS->getCapturedDecl()->setNothrow();
Alexey Bataev8451efa2018-01-15 19:06:12 +00008929 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
8930 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8931 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8932 // 1.2.2 OpenMP Language Terminology
8933 // Structured block - An executable statement with a single entry at the
8934 // top and a single exit at the bottom.
8935 // The point of exit cannot be a branch out of the structured block.
8936 // longjmp() and throw() must not violate the entry/exit criteria.
8937 CS->getCapturedDecl()->setNothrow();
8938 }
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00008939
Reid Kleckner87a31802018-03-12 21:43:02 +00008940 setFunctionHasBranchProtectedScope();
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00008941
8942 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
8943 AStmt);
8944}
8945
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008946StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
8947 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00008948 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008949 if (!AStmt)
8950 return StmtError();
8951
Alexey Bataeve3727102018-04-18 15:57:46 +00008952 auto *CS = cast<CapturedStmt>(AStmt);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008953 // 1.2.2 OpenMP Language Terminology
8954 // Structured block - An executable statement with a single entry at the
8955 // top and a single exit at the bottom.
8956 // The point of exit cannot be a branch out of the structured block.
8957 // longjmp() and throw() must not violate the entry/exit criteria.
8958 CS->getCapturedDecl()->setNothrow();
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00008959 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8960 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8961 CS = cast<CapturedStmt>(CS->getCapturedStmt());
8962 // 1.2.2 OpenMP Language Terminology
8963 // Structured block - An executable statement with a single entry at the
8964 // top and a single exit at the bottom.
8965 // The point of exit cannot be a branch out of the structured block.
8966 // longjmp() and throw() must not violate the entry/exit criteria.
8967 CS->getCapturedDecl()->setNothrow();
8968 }
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008969
8970 OMPLoopDirective::HelperExprs B;
8971 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8972 // define the nested loops number.
8973 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00008974 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00008975 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008976 VarsWithImplicitDSA, B);
8977 if (NestedLoopCount == 0)
8978 return StmtError();
8979
8980 assert((CurContext->isDependentContext() || B.builtAll()) &&
8981 "omp target parallel for loop exprs were not built");
8982
8983 if (!CurContext->isDependentContext()) {
8984 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00008985 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00008986 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008987 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00008988 B.NumIterations, *this, CurScope,
8989 DSAStack))
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008990 return StmtError();
8991 }
8992 }
8993
Reid Kleckner87a31802018-03-12 21:43:02 +00008994 setFunctionHasBranchProtectedScope();
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00008995 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
8996 NestedLoopCount, Clauses, AStmt,
8997 B, DSAStack->isCancelRegion());
8998}
8999
Alexey Bataev95b64a92017-05-30 16:00:04 +00009000/// Check for existence of a map clause in the list of clauses.
9001static bool hasClauses(ArrayRef<OMPClause *> Clauses,
9002 const OpenMPClauseKind K) {
9003 return llvm::any_of(
9004 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
9005}
Samuel Antaodf67fc42016-01-19 19:15:56 +00009006
Alexey Bataev95b64a92017-05-30 16:00:04 +00009007template <typename... Params>
9008static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
9009 const Params... ClauseTypes) {
9010 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
Samuel Antaodf67fc42016-01-19 19:15:56 +00009011}
9012
Michael Wong65f367f2015-07-21 13:44:28 +00009013StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
9014 Stmt *AStmt,
9015 SourceLocation StartLoc,
9016 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00009017 if (!AStmt)
9018 return StmtError();
9019
9020 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9021
Arpith Chacko Jacob46a04bb2016-01-21 19:57:55 +00009022 // OpenMP [2.10.1, Restrictions, p. 97]
9023 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00009024 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
9025 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9026 << "'map' or 'use_device_ptr'"
David Majnemer9d168222016-08-05 17:44:54 +00009027 << getOpenMPDirectiveName(OMPD_target_data);
Arpith Chacko Jacob46a04bb2016-01-21 19:57:55 +00009028 return StmtError();
9029 }
9030
Reid Kleckner87a31802018-03-12 21:43:02 +00009031 setFunctionHasBranchProtectedScope();
Michael Wong65f367f2015-07-21 13:44:28 +00009032
9033 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9034 AStmt);
9035}
9036
Samuel Antaodf67fc42016-01-19 19:15:56 +00009037StmtResult
9038Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
9039 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00009040 SourceLocation EndLoc, Stmt *AStmt) {
9041 if (!AStmt)
9042 return StmtError();
9043
Alexey Bataeve3727102018-04-18 15:57:46 +00009044 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00009045 // 1.2.2 OpenMP Language Terminology
9046 // Structured block - An executable statement with a single entry at the
9047 // top and a single exit at the bottom.
9048 // The point of exit cannot be a branch out of the structured block.
9049 // longjmp() and throw() must not violate the entry/exit criteria.
9050 CS->getCapturedDecl()->setNothrow();
9051 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
9052 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9053 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9054 // 1.2.2 OpenMP Language Terminology
9055 // Structured block - An executable statement with a single entry at the
9056 // top and a single exit at the bottom.
9057 // The point of exit cannot be a branch out of the structured block.
9058 // longjmp() and throw() must not violate the entry/exit criteria.
9059 CS->getCapturedDecl()->setNothrow();
9060 }
9061
Samuel Antaodf67fc42016-01-19 19:15:56 +00009062 // OpenMP [2.10.2, Restrictions, p. 99]
9063 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00009064 if (!hasClauses(Clauses, OMPC_map)) {
9065 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9066 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
Samuel Antaodf67fc42016-01-19 19:15:56 +00009067 return StmtError();
9068 }
9069
Alexey Bataev7828b252017-11-21 17:08:48 +00009070 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9071 AStmt);
Samuel Antaodf67fc42016-01-19 19:15:56 +00009072}
9073
Samuel Antao72590762016-01-19 20:04:50 +00009074StmtResult
9075Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
9076 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00009077 SourceLocation EndLoc, Stmt *AStmt) {
9078 if (!AStmt)
9079 return StmtError();
9080
Alexey Bataeve3727102018-04-18 15:57:46 +00009081 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00009082 // 1.2.2 OpenMP Language Terminology
9083 // Structured block - An executable statement with a single entry at the
9084 // top and a single exit at the bottom.
9085 // The point of exit cannot be a branch out of the structured block.
9086 // longjmp() and throw() must not violate the entry/exit criteria.
9087 CS->getCapturedDecl()->setNothrow();
9088 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
9089 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9090 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9091 // 1.2.2 OpenMP Language Terminology
9092 // Structured block - An executable statement with a single entry at the
9093 // top and a single exit at the bottom.
9094 // The point of exit cannot be a branch out of the structured block.
9095 // longjmp() and throw() must not violate the entry/exit criteria.
9096 CS->getCapturedDecl()->setNothrow();
9097 }
9098
Samuel Antao72590762016-01-19 20:04:50 +00009099 // OpenMP [2.10.3, Restrictions, p. 102]
9100 // At least one map clause must appear on the directive.
Alexey Bataev95b64a92017-05-30 16:00:04 +00009101 if (!hasClauses(Clauses, OMPC_map)) {
9102 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9103 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
Samuel Antao72590762016-01-19 20:04:50 +00009104 return StmtError();
9105 }
9106
Alexey Bataev7828b252017-11-21 17:08:48 +00009107 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9108 AStmt);
Samuel Antao72590762016-01-19 20:04:50 +00009109}
9110
Samuel Antao686c70c2016-05-26 17:30:50 +00009111StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
9112 SourceLocation StartLoc,
Alexey Bataev7828b252017-11-21 17:08:48 +00009113 SourceLocation EndLoc,
9114 Stmt *AStmt) {
9115 if (!AStmt)
9116 return StmtError();
9117
Alexey Bataeve3727102018-04-18 15:57:46 +00009118 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev7828b252017-11-21 17:08:48 +00009119 // 1.2.2 OpenMP Language Terminology
9120 // Structured block - An executable statement with a single entry at the
9121 // top and a single exit at the bottom.
9122 // The point of exit cannot be a branch out of the structured block.
9123 // longjmp() and throw() must not violate the entry/exit criteria.
9124 CS->getCapturedDecl()->setNothrow();
9125 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
9126 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9127 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9128 // 1.2.2 OpenMP Language Terminology
9129 // Structured block - An executable statement with a single entry at the
9130 // top and a single exit at the bottom.
9131 // The point of exit cannot be a branch out of the structured block.
9132 // longjmp() and throw() must not violate the entry/exit criteria.
9133 CS->getCapturedDecl()->setNothrow();
9134 }
9135
Alexey Bataev95b64a92017-05-30 16:00:04 +00009136 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
Samuel Antao686c70c2016-05-26 17:30:50 +00009137 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
9138 return StmtError();
9139 }
Alexey Bataev7828b252017-11-21 17:08:48 +00009140 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
9141 AStmt);
Samuel Antao686c70c2016-05-26 17:30:50 +00009142}
9143
Alexey Bataev13314bf2014-10-09 04:18:56 +00009144StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
9145 Stmt *AStmt, SourceLocation StartLoc,
9146 SourceLocation EndLoc) {
Alexey Bataev6b8046a2015-09-03 07:23:48 +00009147 if (!AStmt)
9148 return StmtError();
9149
Alexey Bataeve3727102018-04-18 15:57:46 +00009150 auto *CS = cast<CapturedStmt>(AStmt);
Alexey Bataev13314bf2014-10-09 04:18:56 +00009151 // 1.2.2 OpenMP Language Terminology
9152 // Structured block - An executable statement with a single entry at the
9153 // top and a single exit at the bottom.
9154 // The point of exit cannot be a branch out of the structured block.
9155 // longjmp() and throw() must not violate the entry/exit criteria.
9156 CS->getCapturedDecl()->setNothrow();
9157
Reid Kleckner87a31802018-03-12 21:43:02 +00009158 setFunctionHasBranchProtectedScope();
Alexey Bataev13314bf2014-10-09 04:18:56 +00009159
Alexey Bataevceabd412017-11-30 18:01:54 +00009160 DSAStack->setParentTeamsRegionLoc(StartLoc);
9161
Alexey Bataev13314bf2014-10-09 04:18:56 +00009162 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9163}
9164
Alexey Bataev6d4ed052015-07-01 06:57:41 +00009165StmtResult
9166Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
9167 SourceLocation EndLoc,
9168 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +00009169 if (DSAStack->isParentNowaitRegion()) {
9170 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
9171 return StmtError();
9172 }
9173 if (DSAStack->isParentOrderedRegion()) {
9174 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
9175 return StmtError();
9176 }
9177 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
9178 CancelRegion);
9179}
9180
Alexey Bataev87933c72015-09-18 08:07:34 +00009181StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
9182 SourceLocation StartLoc,
Alexey Bataev80909872015-07-02 11:25:17 +00009183 SourceLocation EndLoc,
9184 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev80909872015-07-02 11:25:17 +00009185 if (DSAStack->isParentNowaitRegion()) {
9186 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
9187 return StmtError();
9188 }
9189 if (DSAStack->isParentOrderedRegion()) {
9190 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
9191 return StmtError();
9192 }
Alexey Bataev25e5b442015-09-15 12:52:43 +00009193 DSAStack->setParentCancelRegion(/*Cancel=*/true);
Alexey Bataev87933c72015-09-18 08:07:34 +00009194 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9195 CancelRegion);
Alexey Bataev80909872015-07-02 11:25:17 +00009196}
9197
Alexey Bataev382967a2015-12-08 12:06:20 +00009198static bool checkGrainsizeNumTasksClauses(Sema &S,
9199 ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00009200 const OMPClause *PrevClause = nullptr;
Alexey Bataev382967a2015-12-08 12:06:20 +00009201 bool ErrorFound = false;
Alexey Bataeve3727102018-04-18 15:57:46 +00009202 for (const OMPClause *C : Clauses) {
Alexey Bataev382967a2015-12-08 12:06:20 +00009203 if (C->getClauseKind() == OMPC_grainsize ||
9204 C->getClauseKind() == OMPC_num_tasks) {
9205 if (!PrevClause)
9206 PrevClause = C;
9207 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009208 S.Diag(C->getBeginLoc(),
Alexey Bataev382967a2015-12-08 12:06:20 +00009209 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
9210 << getOpenMPClauseName(C->getClauseKind())
9211 << getOpenMPClauseName(PrevClause->getClauseKind());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009212 S.Diag(PrevClause->getBeginLoc(),
Alexey Bataev382967a2015-12-08 12:06:20 +00009213 diag::note_omp_previous_grainsize_num_tasks)
9214 << getOpenMPClauseName(PrevClause->getClauseKind());
9215 ErrorFound = true;
9216 }
9217 }
9218 }
9219 return ErrorFound;
9220}
9221
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00009222static bool checkReductionClauseWithNogroup(Sema &S,
9223 ArrayRef<OMPClause *> Clauses) {
Alexey Bataeve3727102018-04-18 15:57:46 +00009224 const OMPClause *ReductionClause = nullptr;
9225 const OMPClause *NogroupClause = nullptr;
9226 for (const OMPClause *C : Clauses) {
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00009227 if (C->getClauseKind() == OMPC_reduction) {
9228 ReductionClause = C;
9229 if (NogroupClause)
9230 break;
9231 continue;
9232 }
9233 if (C->getClauseKind() == OMPC_nogroup) {
9234 NogroupClause = C;
9235 if (ReductionClause)
9236 break;
9237 continue;
9238 }
9239 }
9240 if (ReductionClause && NogroupClause) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009241 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
9242 << SourceRange(NogroupClause->getBeginLoc(),
Stephen Kelly1c301dc2018-08-09 21:09:38 +00009243 NogroupClause->getEndLoc());
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00009244 return true;
9245 }
9246 return false;
9247}
9248
Alexey Bataev49f6e782015-12-01 04:18:41 +00009249StmtResult Sema::ActOnOpenMPTaskLoopDirective(
9250 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009251 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev49f6e782015-12-01 04:18:41 +00009252 if (!AStmt)
9253 return StmtError();
9254
9255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9256 OMPLoopDirective::HelperExprs B;
9257 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9258 // define the nested loops number.
9259 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009260 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
Alexey Bataev0a6ed842015-12-03 09:40:15 +00009261 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
Alexey Bataev49f6e782015-12-01 04:18:41 +00009262 VarsWithImplicitDSA, B);
9263 if (NestedLoopCount == 0)
9264 return StmtError();
9265
9266 assert((CurContext->isDependentContext() || B.builtAll()) &&
9267 "omp for loop exprs were not built");
9268
Alexey Bataev382967a2015-12-08 12:06:20 +00009269 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9270 // The grainsize clause and num_tasks clause are mutually exclusive and may
9271 // not appear on the same taskloop directive.
9272 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9273 return StmtError();
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00009274 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9275 // If a reduction clause is present on the taskloop directive, the nogroup
9276 // clause must not be specified.
9277 if (checkReductionClauseWithNogroup(*this, Clauses))
9278 return StmtError();
Alexey Bataev382967a2015-12-08 12:06:20 +00009279
Reid Kleckner87a31802018-03-12 21:43:02 +00009280 setFunctionHasBranchProtectedScope();
Alexey Bataev49f6e782015-12-01 04:18:41 +00009281 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9282 NestedLoopCount, Clauses, AStmt, B);
9283}
9284
Alexey Bataev0a6ed842015-12-03 09:40:15 +00009285StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
9286 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009287 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Alexey Bataev0a6ed842015-12-03 09:40:15 +00009288 if (!AStmt)
9289 return StmtError();
9290
9291 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9292 OMPLoopDirective::HelperExprs B;
9293 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9294 // define the nested loops number.
9295 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009296 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev0a6ed842015-12-03 09:40:15 +00009297 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9298 VarsWithImplicitDSA, B);
9299 if (NestedLoopCount == 0)
9300 return StmtError();
9301
9302 assert((CurContext->isDependentContext() || B.builtAll()) &&
9303 "omp for loop exprs were not built");
9304
Alexey Bataev5a3af132016-03-29 08:58:54 +00009305 if (!CurContext->isDependentContext()) {
9306 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009307 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00009308 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Alexey Bataev5a3af132016-03-29 08:58:54 +00009309 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
Alexey Bataev5dff95c2016-04-22 03:56:56 +00009310 B.NumIterations, *this, CurScope,
9311 DSAStack))
Alexey Bataev5a3af132016-03-29 08:58:54 +00009312 return StmtError();
9313 }
9314 }
9315
Alexey Bataev382967a2015-12-08 12:06:20 +00009316 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9317 // The grainsize clause and num_tasks clause are mutually exclusive and may
9318 // not appear on the same taskloop directive.
9319 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9320 return StmtError();
Alexey Bataevbcd0ae02017-07-11 19:16:44 +00009321 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9322 // If a reduction clause is present on the taskloop directive, the nogroup
9323 // clause must not be specified.
9324 if (checkReductionClauseWithNogroup(*this, Clauses))
9325 return StmtError();
Alexey Bataev438388c2017-11-22 18:34:02 +00009326 if (checkSimdlenSafelenSpecified(*this, Clauses))
9327 return StmtError();
Alexey Bataev382967a2015-12-08 12:06:20 +00009328
Reid Kleckner87a31802018-03-12 21:43:02 +00009329 setFunctionHasBranchProtectedScope();
Alexey Bataev0a6ed842015-12-03 09:40:15 +00009330 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
9331 NestedLoopCount, Clauses, AStmt, B);
9332}
9333
Alexey Bataev60e51c42019-10-10 20:13:02 +00009334StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
9335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9337 if (!AStmt)
9338 return StmtError();
9339
9340 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9341 OMPLoopDirective::HelperExprs B;
9342 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9343 // define the nested loops number.
9344 unsigned NestedLoopCount =
9345 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
9346 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9347 VarsWithImplicitDSA, B);
9348 if (NestedLoopCount == 0)
9349 return StmtError();
9350
9351 assert((CurContext->isDependentContext() || B.builtAll()) &&
9352 "omp for loop exprs were not built");
9353
9354 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9355 // The grainsize clause and num_tasks clause are mutually exclusive and may
9356 // not appear on the same taskloop directive.
9357 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9358 return StmtError();
9359 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9360 // If a reduction clause is present on the taskloop directive, the nogroup
9361 // clause must not be specified.
9362 if (checkReductionClauseWithNogroup(*this, Clauses))
9363 return StmtError();
9364
9365 setFunctionHasBranchProtectedScope();
9366 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9367 NestedLoopCount, Clauses, AStmt, B);
9368}
9369
Alexey Bataevb8552ab2019-10-18 16:47:35 +00009370StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
9371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9372 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9373 if (!AStmt)
9374 return StmtError();
9375
9376 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9377 OMPLoopDirective::HelperExprs B;
9378 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9379 // define the nested loops number.
9380 unsigned NestedLoopCount =
9381 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
9382 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9383 VarsWithImplicitDSA, B);
9384 if (NestedLoopCount == 0)
9385 return StmtError();
9386
9387 assert((CurContext->isDependentContext() || B.builtAll()) &&
9388 "omp for loop exprs were not built");
9389
9390 if (!CurContext->isDependentContext()) {
9391 // Finalize the clauses that need pre-built expressions for CodeGen.
9392 for (OMPClause *C : Clauses) {
9393 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9394 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9395 B.NumIterations, *this, CurScope,
9396 DSAStack))
9397 return StmtError();
9398 }
9399 }
9400
9401 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9402 // The grainsize clause and num_tasks clause are mutually exclusive and may
9403 // not appear on the same taskloop directive.
9404 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9405 return StmtError();
9406 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9407 // If a reduction clause is present on the taskloop directive, the nogroup
9408 // clause must not be specified.
9409 if (checkReductionClauseWithNogroup(*this, Clauses))
9410 return StmtError();
9411 if (checkSimdlenSafelenSpecified(*this, Clauses))
9412 return StmtError();
9413
9414 setFunctionHasBranchProtectedScope();
9415 return OMPMasterTaskLoopSimdDirective::Create(
9416 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9417}
9418
Alexey Bataev5bbcead2019-10-14 17:17:41 +00009419StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
9420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9422 if (!AStmt)
9423 return StmtError();
9424
9425 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9426 auto *CS = cast<CapturedStmt>(AStmt);
9427 // 1.2.2 OpenMP Language Terminology
9428 // Structured block - An executable statement with a single entry at the
9429 // top and a single exit at the bottom.
9430 // The point of exit cannot be a branch out of the structured block.
9431 // longjmp() and throw() must not violate the entry/exit criteria.
9432 CS->getCapturedDecl()->setNothrow();
9433 for (int ThisCaptureLevel =
9434 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
9435 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9436 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9437 // 1.2.2 OpenMP Language Terminology
9438 // Structured block - An executable statement with a single entry at the
9439 // top and a single exit at the bottom.
9440 // The point of exit cannot be a branch out of the structured block.
9441 // longjmp() and throw() must not violate the entry/exit criteria.
9442 CS->getCapturedDecl()->setNothrow();
9443 }
9444
9445 OMPLoopDirective::HelperExprs B;
9446 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9447 // define the nested loops number.
9448 unsigned NestedLoopCount = checkOpenMPLoop(
9449 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
9450 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
9451 VarsWithImplicitDSA, B);
9452 if (NestedLoopCount == 0)
9453 return StmtError();
9454
9455 assert((CurContext->isDependentContext() || B.builtAll()) &&
9456 "omp for loop exprs were not built");
9457
9458 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9459 // The grainsize clause and num_tasks clause are mutually exclusive and may
9460 // not appear on the same taskloop directive.
9461 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9462 return StmtError();
9463 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9464 // If a reduction clause is present on the taskloop directive, the nogroup
9465 // clause must not be specified.
9466 if (checkReductionClauseWithNogroup(*this, Clauses))
9467 return StmtError();
9468
9469 setFunctionHasBranchProtectedScope();
9470 return OMPParallelMasterTaskLoopDirective::Create(
9471 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9472}
9473
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00009474StmtResult Sema::ActOnOpenMPDistributeDirective(
9475 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009476 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00009477 if (!AStmt)
9478 return StmtError();
9479
9480 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9481 OMPLoopDirective::HelperExprs B;
9482 // In presence of clause 'collapse' with number of loops, it will
9483 // define the nested loops number.
9484 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009485 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00009486 nullptr /*ordered not a clause on distribute*/, AStmt,
9487 *this, *DSAStack, VarsWithImplicitDSA, B);
9488 if (NestedLoopCount == 0)
9489 return StmtError();
9490
9491 assert((CurContext->isDependentContext() || B.builtAll()) &&
9492 "omp for loop exprs were not built");
9493
Reid Kleckner87a31802018-03-12 21:43:02 +00009494 setFunctionHasBranchProtectedScope();
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00009495 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
9496 NestedLoopCount, Clauses, AStmt, B);
9497}
9498
Carlo Bertolli9925f152016-06-27 14:55:37 +00009499StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
9500 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009501 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Carlo Bertolli9925f152016-06-27 14:55:37 +00009502 if (!AStmt)
9503 return StmtError();
9504
Alexey Bataeve3727102018-04-18 15:57:46 +00009505 auto *CS = cast<CapturedStmt>(AStmt);
Carlo Bertolli9925f152016-06-27 14:55:37 +00009506 // 1.2.2 OpenMP Language Terminology
9507 // Structured block - An executable statement with a single entry at the
9508 // top and a single exit at the bottom.
9509 // The point of exit cannot be a branch out of the structured block.
9510 // longjmp() and throw() must not violate the entry/exit criteria.
9511 CS->getCapturedDecl()->setNothrow();
Alexey Bataev7f96c372017-11-22 17:19:31 +00009512 for (int ThisCaptureLevel =
9513 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
9514 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9515 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9516 // 1.2.2 OpenMP Language Terminology
9517 // Structured block - An executable statement with a single entry at the
9518 // top and a single exit at the bottom.
9519 // The point of exit cannot be a branch out of the structured block.
9520 // longjmp() and throw() must not violate the entry/exit criteria.
9521 CS->getCapturedDecl()->setNothrow();
9522 }
Carlo Bertolli9925f152016-06-27 14:55:37 +00009523
9524 OMPLoopDirective::HelperExprs B;
9525 // In presence of clause 'collapse' with number of loops, it will
9526 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009527 unsigned NestedLoopCount = checkOpenMPLoop(
Carlo Bertolli9925f152016-06-27 14:55:37 +00009528 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
Alexey Bataev7f96c372017-11-22 17:19:31 +00009529 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Carlo Bertolli9925f152016-06-27 14:55:37 +00009530 VarsWithImplicitDSA, B);
9531 if (NestedLoopCount == 0)
9532 return StmtError();
9533
9534 assert((CurContext->isDependentContext() || B.builtAll()) &&
9535 "omp for loop exprs were not built");
9536
Reid Kleckner87a31802018-03-12 21:43:02 +00009537 setFunctionHasBranchProtectedScope();
Carlo Bertolli9925f152016-06-27 14:55:37 +00009538 return OMPDistributeParallelForDirective::Create(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00009539 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9540 DSAStack->isCancelRegion());
Carlo Bertolli9925f152016-06-27 14:55:37 +00009541}
9542
Kelvin Li4a39add2016-07-05 05:00:15 +00009543StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
9544 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009545 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li4a39add2016-07-05 05:00:15 +00009546 if (!AStmt)
9547 return StmtError();
9548
Alexey Bataeve3727102018-04-18 15:57:46 +00009549 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li4a39add2016-07-05 05:00:15 +00009550 // 1.2.2 OpenMP Language Terminology
9551 // Structured block - An executable statement with a single entry at the
9552 // top and a single exit at the bottom.
9553 // The point of exit cannot be a branch out of the structured block.
9554 // longjmp() and throw() must not violate the entry/exit criteria.
9555 CS->getCapturedDecl()->setNothrow();
Alexey Bataev974acd62017-11-27 19:38:52 +00009556 for (int ThisCaptureLevel =
9557 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
9558 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9559 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9560 // 1.2.2 OpenMP Language Terminology
9561 // Structured block - An executable statement with a single entry at the
9562 // top and a single exit at the bottom.
9563 // The point of exit cannot be a branch out of the structured block.
9564 // longjmp() and throw() must not violate the entry/exit criteria.
9565 CS->getCapturedDecl()->setNothrow();
9566 }
Kelvin Li4a39add2016-07-05 05:00:15 +00009567
9568 OMPLoopDirective::HelperExprs B;
9569 // In presence of clause 'collapse' with number of loops, it will
9570 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009571 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li4a39add2016-07-05 05:00:15 +00009572 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev974acd62017-11-27 19:38:52 +00009573 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li4a39add2016-07-05 05:00:15 +00009574 VarsWithImplicitDSA, B);
9575 if (NestedLoopCount == 0)
9576 return StmtError();
9577
9578 assert((CurContext->isDependentContext() || B.builtAll()) &&
9579 "omp for loop exprs were not built");
9580
Alexey Bataev438388c2017-11-22 18:34:02 +00009581 if (!CurContext->isDependentContext()) {
9582 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009583 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +00009584 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9586 B.NumIterations, *this, CurScope,
9587 DSAStack))
9588 return StmtError();
9589 }
9590 }
9591
Kelvin Lic5609492016-07-15 04:39:07 +00009592 if (checkSimdlenSafelenSpecified(*this, Clauses))
9593 return StmtError();
9594
Reid Kleckner87a31802018-03-12 21:43:02 +00009595 setFunctionHasBranchProtectedScope();
Kelvin Li4a39add2016-07-05 05:00:15 +00009596 return OMPDistributeParallelForSimdDirective::Create(
9597 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9598}
9599
Kelvin Li787f3fc2016-07-06 04:45:38 +00009600StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
9601 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009602 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li787f3fc2016-07-06 04:45:38 +00009603 if (!AStmt)
9604 return StmtError();
9605
Alexey Bataeve3727102018-04-18 15:57:46 +00009606 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li787f3fc2016-07-06 04:45:38 +00009607 // 1.2.2 OpenMP Language Terminology
9608 // Structured block - An executable statement with a single entry at the
9609 // top and a single exit at the bottom.
9610 // The point of exit cannot be a branch out of the structured block.
9611 // longjmp() and throw() must not violate the entry/exit criteria.
9612 CS->getCapturedDecl()->setNothrow();
Alexey Bataev617db5f2017-12-04 15:38:33 +00009613 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
9614 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9615 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9616 // 1.2.2 OpenMP Language Terminology
9617 // Structured block - An executable statement with a single entry at the
9618 // top and a single exit at the bottom.
9619 // The point of exit cannot be a branch out of the structured block.
9620 // longjmp() and throw() must not violate the entry/exit criteria.
9621 CS->getCapturedDecl()->setNothrow();
9622 }
Kelvin Li787f3fc2016-07-06 04:45:38 +00009623
9624 OMPLoopDirective::HelperExprs B;
9625 // In presence of clause 'collapse' with number of loops, it will
9626 // define the nested loops number.
9627 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009628 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev617db5f2017-12-04 15:38:33 +00009629 nullptr /*ordered not a clause on distribute*/, CS, *this,
9630 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li787f3fc2016-07-06 04:45:38 +00009631 if (NestedLoopCount == 0)
9632 return StmtError();
9633
9634 assert((CurContext->isDependentContext() || B.builtAll()) &&
9635 "omp for loop exprs were not built");
9636
Alexey Bataev438388c2017-11-22 18:34:02 +00009637 if (!CurContext->isDependentContext()) {
9638 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009639 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +00009640 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9641 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9642 B.NumIterations, *this, CurScope,
9643 DSAStack))
9644 return StmtError();
9645 }
9646 }
9647
Kelvin Lic5609492016-07-15 04:39:07 +00009648 if (checkSimdlenSafelenSpecified(*this, Clauses))
9649 return StmtError();
9650
Reid Kleckner87a31802018-03-12 21:43:02 +00009651 setFunctionHasBranchProtectedScope();
Kelvin Li787f3fc2016-07-06 04:45:38 +00009652 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
9653 NestedLoopCount, Clauses, AStmt, B);
9654}
9655
Kelvin Lia579b912016-07-14 02:54:56 +00009656StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
9657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Lia579b912016-07-14 02:54:56 +00009659 if (!AStmt)
9660 return StmtError();
9661
Alexey Bataeve3727102018-04-18 15:57:46 +00009662 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Lia579b912016-07-14 02:54:56 +00009663 // 1.2.2 OpenMP Language Terminology
9664 // Structured block - An executable statement with a single entry at the
9665 // top and a single exit at the bottom.
9666 // The point of exit cannot be a branch out of the structured block.
9667 // longjmp() and throw() must not violate the entry/exit criteria.
9668 CS->getCapturedDecl()->setNothrow();
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
9670 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9671 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9672 // 1.2.2 OpenMP Language Terminology
9673 // Structured block - An executable statement with a single entry at the
9674 // top and a single exit at the bottom.
9675 // The point of exit cannot be a branch out of the structured block.
9676 // longjmp() and throw() must not violate the entry/exit criteria.
9677 CS->getCapturedDecl()->setNothrow();
9678 }
Kelvin Lia579b912016-07-14 02:54:56 +00009679
9680 OMPLoopDirective::HelperExprs B;
9681 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9682 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009683 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Lia579b912016-07-14 02:54:56 +00009684 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009685 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Kelvin Lia579b912016-07-14 02:54:56 +00009686 VarsWithImplicitDSA, B);
9687 if (NestedLoopCount == 0)
9688 return StmtError();
9689
9690 assert((CurContext->isDependentContext() || B.builtAll()) &&
9691 "omp target parallel for simd loop exprs were not built");
9692
9693 if (!CurContext->isDependentContext()) {
9694 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009695 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00009696 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Kelvin Lia579b912016-07-14 02:54:56 +00009697 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9698 B.NumIterations, *this, CurScope,
9699 DSAStack))
9700 return StmtError();
9701 }
9702 }
Kelvin Lic5609492016-07-15 04:39:07 +00009703 if (checkSimdlenSafelenSpecified(*this, Clauses))
Kelvin Lia579b912016-07-14 02:54:56 +00009704 return StmtError();
9705
Reid Kleckner87a31802018-03-12 21:43:02 +00009706 setFunctionHasBranchProtectedScope();
Kelvin Lia579b912016-07-14 02:54:56 +00009707 return OMPTargetParallelForSimdDirective::Create(
9708 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9709}
9710
Kelvin Li986330c2016-07-20 22:57:10 +00009711StmtResult Sema::ActOnOpenMPTargetSimdDirective(
9712 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009713 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li986330c2016-07-20 22:57:10 +00009714 if (!AStmt)
9715 return StmtError();
9716
Alexey Bataeve3727102018-04-18 15:57:46 +00009717 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li986330c2016-07-20 22:57:10 +00009718 // 1.2.2 OpenMP Language Terminology
9719 // Structured block - An executable statement with a single entry at the
9720 // top and a single exit at the bottom.
9721 // The point of exit cannot be a branch out of the structured block.
9722 // longjmp() and throw() must not violate the entry/exit criteria.
9723 CS->getCapturedDecl()->setNothrow();
Alexey Bataevf8365372017-11-17 17:57:25 +00009724 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
9725 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9726 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9727 // 1.2.2 OpenMP Language Terminology
9728 // Structured block - An executable statement with a single entry at the
9729 // top and a single exit at the bottom.
9730 // The point of exit cannot be a branch out of the structured block.
9731 // longjmp() and throw() must not violate the entry/exit criteria.
9732 CS->getCapturedDecl()->setNothrow();
9733 }
9734
Kelvin Li986330c2016-07-20 22:57:10 +00009735 OMPLoopDirective::HelperExprs B;
9736 // In presence of clause 'collapse' with number of loops, it will define the
9737 // nested loops number.
David Majnemer9d168222016-08-05 17:44:54 +00009738 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009739 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
Alexey Bataevf8365372017-11-17 17:57:25 +00009740 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
Kelvin Li986330c2016-07-20 22:57:10 +00009741 VarsWithImplicitDSA, B);
9742 if (NestedLoopCount == 0)
9743 return StmtError();
9744
9745 assert((CurContext->isDependentContext() || B.builtAll()) &&
9746 "omp target simd loop exprs were not built");
9747
9748 if (!CurContext->isDependentContext()) {
9749 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009750 for (OMPClause *C : Clauses) {
David Majnemer9d168222016-08-05 17:44:54 +00009751 if (auto *LC = dyn_cast<OMPLinearClause>(C))
Kelvin Li986330c2016-07-20 22:57:10 +00009752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9753 B.NumIterations, *this, CurScope,
9754 DSAStack))
9755 return StmtError();
9756 }
9757 }
9758
9759 if (checkSimdlenSafelenSpecified(*this, Clauses))
9760 return StmtError();
9761
Reid Kleckner87a31802018-03-12 21:43:02 +00009762 setFunctionHasBranchProtectedScope();
Kelvin Li986330c2016-07-20 22:57:10 +00009763 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
9764 NestedLoopCount, Clauses, AStmt, B);
9765}
9766
Kelvin Li02532872016-08-05 14:37:37 +00009767StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
9768 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009769 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li02532872016-08-05 14:37:37 +00009770 if (!AStmt)
9771 return StmtError();
9772
Alexey Bataeve3727102018-04-18 15:57:46 +00009773 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li02532872016-08-05 14:37:37 +00009774 // 1.2.2 OpenMP Language Terminology
9775 // Structured block - An executable statement with a single entry at the
9776 // top and a single exit at the bottom.
9777 // The point of exit cannot be a branch out of the structured block.
9778 // longjmp() and throw() must not violate the entry/exit criteria.
9779 CS->getCapturedDecl()->setNothrow();
Alexey Bataev95c6dd42017-11-29 15:14:16 +00009780 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
9781 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9782 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9783 // 1.2.2 OpenMP Language Terminology
9784 // Structured block - An executable statement with a single entry at the
9785 // top and a single exit at the bottom.
9786 // The point of exit cannot be a branch out of the structured block.
9787 // longjmp() and throw() must not violate the entry/exit criteria.
9788 CS->getCapturedDecl()->setNothrow();
9789 }
Kelvin Li02532872016-08-05 14:37:37 +00009790
9791 OMPLoopDirective::HelperExprs B;
9792 // In presence of clause 'collapse' with number of loops, it will
9793 // define the nested loops number.
9794 unsigned NestedLoopCount =
Alexey Bataeve3727102018-04-18 15:57:46 +00009795 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
Alexey Bataev95c6dd42017-11-29 15:14:16 +00009796 nullptr /*ordered not a clause on distribute*/, CS, *this,
9797 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li02532872016-08-05 14:37:37 +00009798 if (NestedLoopCount == 0)
9799 return StmtError();
9800
9801 assert((CurContext->isDependentContext() || B.builtAll()) &&
9802 "omp teams distribute loop exprs were not built");
9803
Reid Kleckner87a31802018-03-12 21:43:02 +00009804 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00009805
9806 DSAStack->setParentTeamsRegionLoc(StartLoc);
9807
David Majnemer9d168222016-08-05 17:44:54 +00009808 return OMPTeamsDistributeDirective::Create(
9809 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
Kelvin Li02532872016-08-05 14:37:37 +00009810}
9811
Kelvin Li4e325f72016-10-25 12:50:55 +00009812StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
9813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li4e325f72016-10-25 12:50:55 +00009815 if (!AStmt)
9816 return StmtError();
9817
Alexey Bataeve3727102018-04-18 15:57:46 +00009818 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li4e325f72016-10-25 12:50:55 +00009819 // 1.2.2 OpenMP Language Terminology
9820 // Structured block - An executable statement with a single entry at the
9821 // top and a single exit at the bottom.
9822 // The point of exit cannot be a branch out of the structured block.
9823 // longjmp() and throw() must not violate the entry/exit criteria.
9824 CS->getCapturedDecl()->setNothrow();
Alexey Bataev999277a2017-12-06 14:31:09 +00009825 for (int ThisCaptureLevel =
9826 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
9827 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9828 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9829 // 1.2.2 OpenMP Language Terminology
9830 // Structured block - An executable statement with a single entry at the
9831 // top and a single exit at the bottom.
9832 // The point of exit cannot be a branch out of the structured block.
9833 // longjmp() and throw() must not violate the entry/exit criteria.
9834 CS->getCapturedDecl()->setNothrow();
9835 }
9836
Kelvin Li4e325f72016-10-25 12:50:55 +00009837
9838 OMPLoopDirective::HelperExprs B;
9839 // In presence of clause 'collapse' with number of loops, it will
9840 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009841 unsigned NestedLoopCount = checkOpenMPLoop(
Samuel Antao4c8035b2016-12-12 18:00:20 +00009842 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataev999277a2017-12-06 14:31:09 +00009843 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Samuel Antao4c8035b2016-12-12 18:00:20 +00009844 VarsWithImplicitDSA, B);
Kelvin Li4e325f72016-10-25 12:50:55 +00009845
9846 if (NestedLoopCount == 0)
9847 return StmtError();
9848
9849 assert((CurContext->isDependentContext() || B.builtAll()) &&
9850 "omp teams distribute simd loop exprs were not built");
9851
9852 if (!CurContext->isDependentContext()) {
9853 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009854 for (OMPClause *C : Clauses) {
Kelvin Li4e325f72016-10-25 12:50:55 +00009855 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9857 B.NumIterations, *this, CurScope,
9858 DSAStack))
9859 return StmtError();
9860 }
9861 }
9862
9863 if (checkSimdlenSafelenSpecified(*this, Clauses))
9864 return StmtError();
9865
Reid Kleckner87a31802018-03-12 21:43:02 +00009866 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00009867
9868 DSAStack->setParentTeamsRegionLoc(StartLoc);
9869
Kelvin Li4e325f72016-10-25 12:50:55 +00009870 return OMPTeamsDistributeSimdDirective::Create(
9871 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9872}
9873
Kelvin Li579e41c2016-11-30 23:51:03 +00009874StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
9875 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009876 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li579e41c2016-11-30 23:51:03 +00009877 if (!AStmt)
9878 return StmtError();
9879
Alexey Bataeve3727102018-04-18 15:57:46 +00009880 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li579e41c2016-11-30 23:51:03 +00009881 // 1.2.2 OpenMP Language Terminology
9882 // Structured block - An executable statement with a single entry at the
9883 // top and a single exit at the bottom.
9884 // The point of exit cannot be a branch out of the structured block.
9885 // longjmp() and throw() must not violate the entry/exit criteria.
9886 CS->getCapturedDecl()->setNothrow();
9887
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00009888 for (int ThisCaptureLevel =
9889 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
9890 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9891 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9892 // 1.2.2 OpenMP Language Terminology
9893 // Structured block - An executable statement with a single entry at the
9894 // top and a single exit at the bottom.
9895 // The point of exit cannot be a branch out of the structured block.
9896 // longjmp() and throw() must not violate the entry/exit criteria.
9897 CS->getCapturedDecl()->setNothrow();
9898 }
9899
Kelvin Li579e41c2016-11-30 23:51:03 +00009900 OMPLoopDirective::HelperExprs B;
9901 // In presence of clause 'collapse' with number of loops, it will
9902 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009903 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li579e41c2016-11-30 23:51:03 +00009904 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
Carlo Bertolli56a2aa42017-12-04 20:57:19 +00009905 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li579e41c2016-11-30 23:51:03 +00009906 VarsWithImplicitDSA, B);
9907
9908 if (NestedLoopCount == 0)
9909 return StmtError();
9910
9911 assert((CurContext->isDependentContext() || B.builtAll()) &&
9912 "omp for loop exprs were not built");
9913
9914 if (!CurContext->isDependentContext()) {
9915 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +00009916 for (OMPClause *C : Clauses) {
Kelvin Li579e41c2016-11-30 23:51:03 +00009917 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9918 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9919 B.NumIterations, *this, CurScope,
9920 DSAStack))
9921 return StmtError();
9922 }
9923 }
9924
9925 if (checkSimdlenSafelenSpecified(*this, Clauses))
9926 return StmtError();
9927
Reid Kleckner87a31802018-03-12 21:43:02 +00009928 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00009929
9930 DSAStack->setParentTeamsRegionLoc(StartLoc);
9931
Kelvin Li579e41c2016-11-30 23:51:03 +00009932 return OMPTeamsDistributeParallelForSimdDirective::Create(
9933 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9934}
9935
Kelvin Li7ade93f2016-12-09 03:24:30 +00009936StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
9937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +00009938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li7ade93f2016-12-09 03:24:30 +00009939 if (!AStmt)
9940 return StmtError();
9941
Alexey Bataeve3727102018-04-18 15:57:46 +00009942 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li7ade93f2016-12-09 03:24:30 +00009943 // 1.2.2 OpenMP Language Terminology
9944 // Structured block - An executable statement with a single entry at the
9945 // top and a single exit at the bottom.
9946 // The point of exit cannot be a branch out of the structured block.
9947 // longjmp() and throw() must not violate the entry/exit criteria.
9948 CS->getCapturedDecl()->setNothrow();
9949
Carlo Bertolli62fae152017-11-20 20:46:39 +00009950 for (int ThisCaptureLevel =
9951 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
9952 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9953 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9954 // 1.2.2 OpenMP Language Terminology
9955 // Structured block - An executable statement with a single entry at the
9956 // top and a single exit at the bottom.
9957 // The point of exit cannot be a branch out of the structured block.
9958 // longjmp() and throw() must not violate the entry/exit criteria.
9959 CS->getCapturedDecl()->setNothrow();
9960 }
9961
Kelvin Li7ade93f2016-12-09 03:24:30 +00009962 OMPLoopDirective::HelperExprs B;
9963 // In presence of clause 'collapse' with number of loops, it will
9964 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +00009965 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Li7ade93f2016-12-09 03:24:30 +00009966 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
Carlo Bertolli62fae152017-11-20 20:46:39 +00009967 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li7ade93f2016-12-09 03:24:30 +00009968 VarsWithImplicitDSA, B);
9969
9970 if (NestedLoopCount == 0)
9971 return StmtError();
9972
9973 assert((CurContext->isDependentContext() || B.builtAll()) &&
9974 "omp for loop exprs were not built");
9975
Reid Kleckner87a31802018-03-12 21:43:02 +00009976 setFunctionHasBranchProtectedScope();
Alexey Bataevceabd412017-11-30 18:01:54 +00009977
9978 DSAStack->setParentTeamsRegionLoc(StartLoc);
9979
Kelvin Li7ade93f2016-12-09 03:24:30 +00009980 return OMPTeamsDistributeParallelForDirective::Create(
Alexey Bataevdcb4b8fb2017-11-22 20:19:50 +00009981 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9982 DSAStack->isCancelRegion());
Kelvin Li7ade93f2016-12-09 03:24:30 +00009983}
9984
Kelvin Libf594a52016-12-17 05:48:59 +00009985StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
9986 Stmt *AStmt,
9987 SourceLocation StartLoc,
9988 SourceLocation EndLoc) {
9989 if (!AStmt)
9990 return StmtError();
9991
Alexey Bataeve3727102018-04-18 15:57:46 +00009992 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Libf594a52016-12-17 05:48:59 +00009993 // 1.2.2 OpenMP Language Terminology
9994 // Structured block - An executable statement with a single entry at the
9995 // top and a single exit at the bottom.
9996 // The point of exit cannot be a branch out of the structured block.
9997 // longjmp() and throw() must not violate the entry/exit criteria.
9998 CS->getCapturedDecl()->setNothrow();
9999
Alexey Bataevf9fc42e2017-11-22 14:25:55 +000010000 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
10001 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10002 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10003 // 1.2.2 OpenMP Language Terminology
10004 // Structured block - An executable statement with a single entry at the
10005 // top and a single exit at the bottom.
10006 // The point of exit cannot be a branch out of the structured block.
10007 // longjmp() and throw() must not violate the entry/exit criteria.
10008 CS->getCapturedDecl()->setNothrow();
10009 }
Reid Kleckner87a31802018-03-12 21:43:02 +000010010 setFunctionHasBranchProtectedScope();
Kelvin Libf594a52016-12-17 05:48:59 +000010011
10012 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
10013 AStmt);
10014}
10015
Kelvin Li83c451e2016-12-25 04:52:54 +000010016StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
10017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +000010018 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li83c451e2016-12-25 04:52:54 +000010019 if (!AStmt)
10020 return StmtError();
10021
Alexey Bataeve3727102018-04-18 15:57:46 +000010022 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li83c451e2016-12-25 04:52:54 +000010023 // 1.2.2 OpenMP Language Terminology
10024 // Structured block - An executable statement with a single entry at the
10025 // top and a single exit at the bottom.
10026 // The point of exit cannot be a branch out of the structured block.
10027 // longjmp() and throw() must not violate the entry/exit criteria.
10028 CS->getCapturedDecl()->setNothrow();
Alexey Bataevdfa430f2017-12-08 15:03:50 +000010029 for (int ThisCaptureLevel =
10030 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
10031 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10032 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10033 // 1.2.2 OpenMP Language Terminology
10034 // Structured block - An executable statement with a single entry at the
10035 // top and a single exit at the bottom.
10036 // The point of exit cannot be a branch out of the structured block.
10037 // longjmp() and throw() must not violate the entry/exit criteria.
10038 CS->getCapturedDecl()->setNothrow();
10039 }
Kelvin Li83c451e2016-12-25 04:52:54 +000010040
10041 OMPLoopDirective::HelperExprs B;
10042 // In presence of clause 'collapse' with number of loops, it will
10043 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +000010044 unsigned NestedLoopCount = checkOpenMPLoop(
Alexey Bataevdfa430f2017-12-08 15:03:50 +000010045 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
10046 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li83c451e2016-12-25 04:52:54 +000010047 VarsWithImplicitDSA, B);
10048 if (NestedLoopCount == 0)
10049 return StmtError();
10050
10051 assert((CurContext->isDependentContext() || B.builtAll()) &&
10052 "omp target teams distribute loop exprs were not built");
10053
Reid Kleckner87a31802018-03-12 21:43:02 +000010054 setFunctionHasBranchProtectedScope();
Kelvin Li83c451e2016-12-25 04:52:54 +000010055 return OMPTargetTeamsDistributeDirective::Create(
10056 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10057}
10058
Kelvin Li80e8f562016-12-29 22:16:30 +000010059StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
10060 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +000010061 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li80e8f562016-12-29 22:16:30 +000010062 if (!AStmt)
10063 return StmtError();
10064
Alexey Bataeve3727102018-04-18 15:57:46 +000010065 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li80e8f562016-12-29 22:16:30 +000010066 // 1.2.2 OpenMP Language Terminology
10067 // Structured block - An executable statement with a single entry at the
10068 // top and a single exit at the bottom.
10069 // The point of exit cannot be a branch out of the structured block.
10070 // longjmp() and throw() must not violate the entry/exit criteria.
10071 CS->getCapturedDecl()->setNothrow();
Carlo Bertolli52978c32018-01-03 21:12:44 +000010072 for (int ThisCaptureLevel =
10073 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
10074 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10075 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10076 // 1.2.2 OpenMP Language Terminology
10077 // Structured block - An executable statement with a single entry at the
10078 // top and a single exit at the bottom.
10079 // The point of exit cannot be a branch out of the structured block.
10080 // longjmp() and throw() must not violate the entry/exit criteria.
10081 CS->getCapturedDecl()->setNothrow();
10082 }
10083
Kelvin Li80e8f562016-12-29 22:16:30 +000010084 OMPLoopDirective::HelperExprs B;
10085 // In presence of clause 'collapse' with number of loops, it will
10086 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +000010087 unsigned NestedLoopCount = checkOpenMPLoop(
Carlo Bertolli52978c32018-01-03 21:12:44 +000010088 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10089 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Li80e8f562016-12-29 22:16:30 +000010090 VarsWithImplicitDSA, B);
10091 if (NestedLoopCount == 0)
10092 return StmtError();
10093
10094 assert((CurContext->isDependentContext() || B.builtAll()) &&
10095 "omp target teams distribute parallel for loop exprs were not built");
10096
Alexey Bataev647dd842018-01-15 20:59:40 +000010097 if (!CurContext->isDependentContext()) {
10098 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000010099 for (OMPClause *C : Clauses) {
Alexey Bataev647dd842018-01-15 20:59:40 +000010100 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10102 B.NumIterations, *this, CurScope,
10103 DSAStack))
10104 return StmtError();
10105 }
10106 }
10107
Reid Kleckner87a31802018-03-12 21:43:02 +000010108 setFunctionHasBranchProtectedScope();
Kelvin Li80e8f562016-12-29 22:16:30 +000010109 return OMPTargetTeamsDistributeParallelForDirective::Create(
Alexey Bataev16e79882017-11-22 21:12:03 +000010110 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10111 DSAStack->isCancelRegion());
Kelvin Li80e8f562016-12-29 22:16:30 +000010112}
10113
Kelvin Li1851df52017-01-03 05:23:48 +000010114StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
10115 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +000010116 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Li1851df52017-01-03 05:23:48 +000010117 if (!AStmt)
10118 return StmtError();
10119
Alexey Bataeve3727102018-04-18 15:57:46 +000010120 auto *CS = cast<CapturedStmt>(AStmt);
Kelvin Li1851df52017-01-03 05:23:48 +000010121 // 1.2.2 OpenMP Language Terminology
10122 // Structured block - An executable statement with a single entry at the
10123 // top and a single exit at the bottom.
10124 // The point of exit cannot be a branch out of the structured block.
10125 // longjmp() and throw() must not violate the entry/exit criteria.
10126 CS->getCapturedDecl()->setNothrow();
Alexey Bataev647dd842018-01-15 20:59:40 +000010127 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
10128 OMPD_target_teams_distribute_parallel_for_simd);
10129 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10130 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10131 // 1.2.2 OpenMP Language Terminology
10132 // Structured block - An executable statement with a single entry at the
10133 // top and a single exit at the bottom.
10134 // The point of exit cannot be a branch out of the structured block.
10135 // longjmp() and throw() must not violate the entry/exit criteria.
10136 CS->getCapturedDecl()->setNothrow();
10137 }
Kelvin Li1851df52017-01-03 05:23:48 +000010138
10139 OMPLoopDirective::HelperExprs B;
10140 // In presence of clause 'collapse' with number of loops, it will
10141 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +000010142 unsigned NestedLoopCount =
10143 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
Alexey Bataev647dd842018-01-15 20:59:40 +000010144 getCollapseNumberExpr(Clauses),
10145 nullptr /*ordered not a clause on distribute*/, CS, *this,
10146 *DSAStack, VarsWithImplicitDSA, B);
Kelvin Li1851df52017-01-03 05:23:48 +000010147 if (NestedLoopCount == 0)
10148 return StmtError();
10149
10150 assert((CurContext->isDependentContext() || B.builtAll()) &&
10151 "omp target teams distribute parallel for simd loop exprs were not "
10152 "built");
10153
10154 if (!CurContext->isDependentContext()) {
10155 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000010156 for (OMPClause *C : Clauses) {
Kelvin Li1851df52017-01-03 05:23:48 +000010157 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10158 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10159 B.NumIterations, *this, CurScope,
10160 DSAStack))
10161 return StmtError();
10162 }
10163 }
10164
Alexey Bataev438388c2017-11-22 18:34:02 +000010165 if (checkSimdlenSafelenSpecified(*this, Clauses))
10166 return StmtError();
10167
Reid Kleckner87a31802018-03-12 21:43:02 +000010168 setFunctionHasBranchProtectedScope();
Kelvin Li1851df52017-01-03 05:23:48 +000010169 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
10170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10171}
10172
Kelvin Lida681182017-01-10 18:08:18 +000010173StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
10174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
Alexey Bataeve3727102018-04-18 15:57:46 +000010175 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
Kelvin Lida681182017-01-10 18:08:18 +000010176 if (!AStmt)
10177 return StmtError();
10178
10179 auto *CS = cast<CapturedStmt>(AStmt);
10180 // 1.2.2 OpenMP Language Terminology
10181 // Structured block - An executable statement with a single entry at the
10182 // top and a single exit at the bottom.
10183 // The point of exit cannot be a branch out of the structured block.
10184 // longjmp() and throw() must not violate the entry/exit criteria.
10185 CS->getCapturedDecl()->setNothrow();
Alexey Bataevfbe17fb2017-12-13 19:45:06 +000010186 for (int ThisCaptureLevel =
10187 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
10188 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10189 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10190 // 1.2.2 OpenMP Language Terminology
10191 // Structured block - An executable statement with a single entry at the
10192 // top and a single exit at the bottom.
10193 // The point of exit cannot be a branch out of the structured block.
10194 // longjmp() and throw() must not violate the entry/exit criteria.
10195 CS->getCapturedDecl()->setNothrow();
10196 }
Kelvin Lida681182017-01-10 18:08:18 +000010197
10198 OMPLoopDirective::HelperExprs B;
10199 // In presence of clause 'collapse' with number of loops, it will
10200 // define the nested loops number.
Alexey Bataeve3727102018-04-18 15:57:46 +000010201 unsigned NestedLoopCount = checkOpenMPLoop(
Kelvin Lida681182017-01-10 18:08:18 +000010202 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
Alexey Bataevfbe17fb2017-12-13 19:45:06 +000010203 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
Kelvin Lida681182017-01-10 18:08:18 +000010204 VarsWithImplicitDSA, B);
10205 if (NestedLoopCount == 0)
10206 return StmtError();
10207
10208 assert((CurContext->isDependentContext() || B.builtAll()) &&
10209 "omp target teams distribute simd loop exprs were not built");
10210
Alexey Bataev438388c2017-11-22 18:34:02 +000010211 if (!CurContext->isDependentContext()) {
10212 // Finalize the clauses that need pre-built expressions for CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000010213 for (OMPClause *C : Clauses) {
Alexey Bataev438388c2017-11-22 18:34:02 +000010214 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10215 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10216 B.NumIterations, *this, CurScope,
10217 DSAStack))
10218 return StmtError();
10219 }
10220 }
10221
10222 if (checkSimdlenSafelenSpecified(*this, Clauses))
10223 return StmtError();
10224
Reid Kleckner87a31802018-03-12 21:43:02 +000010225 setFunctionHasBranchProtectedScope();
Kelvin Lida681182017-01-10 18:08:18 +000010226 return OMPTargetTeamsDistributeSimdDirective::Create(
10227 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10228}
10229
Alexey Bataeved09d242014-05-28 05:53:51 +000010230OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010231 SourceLocation StartLoc,
10232 SourceLocation LParenLoc,
10233 SourceLocation EndLoc) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010234 OMPClause *Res = nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010235 switch (Kind) {
Alexey Bataev3778b602014-07-17 07:32:53 +000010236 case OMPC_final:
10237 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
10238 break;
Alexey Bataev568a8332014-03-06 06:15:19 +000010239 case OMPC_num_threads:
10240 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
10241 break;
Alexey Bataev62c87d22014-03-21 04:51:18 +000010242 case OMPC_safelen:
10243 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
10244 break;
Alexey Bataev66b15b52015-08-21 11:14:16 +000010245 case OMPC_simdlen:
10246 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
10247 break;
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010248 case OMPC_allocator:
10249 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
10250 break;
Alexander Musman8bd31e62014-05-27 15:12:19 +000010251 case OMPC_collapse:
10252 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
10253 break;
Alexey Bataev10e775f2015-07-30 11:36:16 +000010254 case OMPC_ordered:
10255 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
10256 break;
Michael Wonge710d542015-08-07 16:16:36 +000010257 case OMPC_device:
10258 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
10259 break;
Kelvin Li099bb8c2015-11-24 20:50:12 +000010260 case OMPC_num_teams:
10261 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
10262 break;
Kelvin Lia15fb1a2015-11-27 18:47:36 +000010263 case OMPC_thread_limit:
10264 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
10265 break;
Alexey Bataeva0569352015-12-01 10:17:31 +000010266 case OMPC_priority:
10267 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
10268 break;
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000010269 case OMPC_grainsize:
10270 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
10271 break;
Alexey Bataev382967a2015-12-08 12:06:20 +000010272 case OMPC_num_tasks:
10273 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
10274 break;
Alexey Bataev28c75412015-12-15 08:19:24 +000010275 case OMPC_hint:
10276 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
10277 break;
Alexey Bataev6b8046a2015-09-03 07:23:48 +000010278 case OMPC_if:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010279 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +000010280 case OMPC_proc_bind:
Alexey Bataev56dafe82014-06-20 07:16:17 +000010281 case OMPC_schedule:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010282 case OMPC_private:
10283 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +000010284 case OMPC_lastprivate:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010285 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +000010286 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000010287 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000010288 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +000010289 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +000010290 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +000010291 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000010292 case OMPC_copyprivate:
Alexey Bataev236070f2014-06-20 11:19:47 +000010293 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000010294 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000010295 case OMPC_mergeable:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010296 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010297 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000010298 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000010299 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000010300 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000010301 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000010302 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000010303 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000010304 case OMPC_depend:
Alexey Bataev346265e2015-09-25 10:37:12 +000010305 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000010306 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +000010307 case OMPC_map:
Alexey Bataevb825de12015-12-07 10:51:44 +000010308 case OMPC_nogroup:
Carlo Bertollib4adf552016-01-15 18:50:31 +000010309 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000010310 case OMPC_defaultmap:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010311 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000010312 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000010313 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000010314 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000010315 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000010316 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000010317 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000010318 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010319 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010320 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010321 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +000010322 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000010323 case OMPC_match:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010324 llvm_unreachable("Clause is not allowed.");
10325 }
10326 return Res;
10327}
10328
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010329// An OpenMP directive such as 'target parallel' has two captured regions:
10330// for the 'target' and 'parallel' respectively. This function returns
10331// the region in which to capture expressions associated with a clause.
10332// A return value of OMPD_unknown signifies that the expression should not
10333// be captured.
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010334static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
10335 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
10336 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010337 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010338 switch (CKind) {
10339 case OMPC_if:
10340 switch (DKind) {
10341 case OMPD_target_parallel:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010342 case OMPD_target_parallel_for:
Alexey Bataev5d7edca2017-11-09 17:32:15 +000010343 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010344 // If this clause applies to the nested 'parallel' region, capture within
10345 // the 'target' region, otherwise do not capture.
10346 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10347 CaptureRegion = OMPD_target;
10348 break;
Carlo Bertolli52978c32018-01-03 21:12:44 +000010349 case OMPD_target_teams_distribute_parallel_for:
10350 case OMPD_target_teams_distribute_parallel_for_simd:
10351 // If this clause applies to the nested 'parallel' region, capture within
10352 // the 'teams' region, otherwise do not capture.
10353 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10354 CaptureRegion = OMPD_teams;
10355 break;
Carlo Bertolli62fae152017-11-20 20:46:39 +000010356 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010357 case OMPD_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010358 CaptureRegion = OMPD_teams;
10359 break;
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010360 case OMPD_target_update:
Alexey Bataevfab20e42017-12-27 18:49:38 +000010361 case OMPD_target_enter_data:
10362 case OMPD_target_exit_data:
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010363 CaptureRegion = OMPD_task;
10364 break;
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010365 case OMPD_parallel_master_taskloop:
10366 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
10367 CaptureRegion = OMPD_parallel;
10368 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010369 case OMPD_cancel:
10370 case OMPD_parallel:
10371 case OMPD_parallel_sections:
10372 case OMPD_parallel_for:
10373 case OMPD_parallel_for_simd:
10374 case OMPD_target:
10375 case OMPD_target_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010376 case OMPD_target_teams:
10377 case OMPD_target_teams_distribute:
10378 case OMPD_target_teams_distribute_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010379 case OMPD_distribute_parallel_for:
10380 case OMPD_distribute_parallel_for_simd:
10381 case OMPD_task:
10382 case OMPD_taskloop:
10383 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010384 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010385 case OMPD_master_taskloop_simd:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010386 case OMPD_target_data:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010387 // Do not capture if-clause expressions.
10388 break;
10389 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010390 case OMPD_allocate:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010391 case OMPD_taskyield:
10392 case OMPD_barrier:
10393 case OMPD_taskwait:
10394 case OMPD_cancellation_point:
10395 case OMPD_flush:
10396 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010397 case OMPD_declare_mapper:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010398 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010399 case OMPD_declare_variant:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010400 case OMPD_declare_target:
10401 case OMPD_end_declare_target:
10402 case OMPD_teams:
10403 case OMPD_simd:
10404 case OMPD_for:
10405 case OMPD_for_simd:
10406 case OMPD_sections:
10407 case OMPD_section:
10408 case OMPD_single:
10409 case OMPD_master:
10410 case OMPD_critical:
10411 case OMPD_taskgroup:
10412 case OMPD_distribute:
10413 case OMPD_ordered:
10414 case OMPD_atomic:
10415 case OMPD_distribute_simd:
10416 case OMPD_teams_distribute:
10417 case OMPD_teams_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010418 case OMPD_requires:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010419 llvm_unreachable("Unexpected OpenMP directive with if-clause");
10420 case OMPD_unknown:
10421 llvm_unreachable("Unknown OpenMP directive");
10422 }
10423 break;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010424 case OMPC_num_threads:
10425 switch (DKind) {
10426 case OMPD_target_parallel:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010427 case OMPD_target_parallel_for:
Alexey Bataev5d7edca2017-11-09 17:32:15 +000010428 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010429 CaptureRegion = OMPD_target;
10430 break;
Carlo Bertolli62fae152017-11-20 20:46:39 +000010431 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010432 case OMPD_teams_distribute_parallel_for_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +000010433 case OMPD_target_teams_distribute_parallel_for:
10434 case OMPD_target_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010435 CaptureRegion = OMPD_teams;
10436 break;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010437 case OMPD_parallel:
10438 case OMPD_parallel_sections:
10439 case OMPD_parallel_for:
10440 case OMPD_parallel_for_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010441 case OMPD_distribute_parallel_for:
10442 case OMPD_distribute_parallel_for_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010443 case OMPD_parallel_master_taskloop:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010444 // Do not capture num_threads-clause expressions.
10445 break;
10446 case OMPD_target_data:
10447 case OMPD_target_enter_data:
10448 case OMPD_target_exit_data:
10449 case OMPD_target_update:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010450 case OMPD_target:
10451 case OMPD_target_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010452 case OMPD_target_teams:
10453 case OMPD_target_teams_distribute:
10454 case OMPD_target_teams_distribute_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010455 case OMPD_cancel:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010456 case OMPD_task:
10457 case OMPD_taskloop:
10458 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010459 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010460 case OMPD_master_taskloop_simd:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010461 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010462 case OMPD_allocate:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010463 case OMPD_taskyield:
10464 case OMPD_barrier:
10465 case OMPD_taskwait:
10466 case OMPD_cancellation_point:
10467 case OMPD_flush:
10468 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010469 case OMPD_declare_mapper:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010470 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010471 case OMPD_declare_variant:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010472 case OMPD_declare_target:
10473 case OMPD_end_declare_target:
10474 case OMPD_teams:
10475 case OMPD_simd:
10476 case OMPD_for:
10477 case OMPD_for_simd:
10478 case OMPD_sections:
10479 case OMPD_section:
10480 case OMPD_single:
10481 case OMPD_master:
10482 case OMPD_critical:
10483 case OMPD_taskgroup:
10484 case OMPD_distribute:
10485 case OMPD_ordered:
10486 case OMPD_atomic:
10487 case OMPD_distribute_simd:
10488 case OMPD_teams_distribute:
10489 case OMPD_teams_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010490 case OMPD_requires:
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000010491 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
10492 case OMPD_unknown:
10493 llvm_unreachable("Unknown OpenMP directive");
10494 }
10495 break;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010496 case OMPC_num_teams:
10497 switch (DKind) {
10498 case OMPD_target_teams:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010499 case OMPD_target_teams_distribute:
10500 case OMPD_target_teams_distribute_simd:
10501 case OMPD_target_teams_distribute_parallel_for:
10502 case OMPD_target_teams_distribute_parallel_for_simd:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010503 CaptureRegion = OMPD_target;
10504 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010505 case OMPD_teams_distribute_parallel_for:
10506 case OMPD_teams_distribute_parallel_for_simd:
10507 case OMPD_teams:
10508 case OMPD_teams_distribute:
10509 case OMPD_teams_distribute_simd:
10510 // Do not capture num_teams-clause expressions.
10511 break;
10512 case OMPD_distribute_parallel_for:
10513 case OMPD_distribute_parallel_for_simd:
10514 case OMPD_task:
10515 case OMPD_taskloop:
10516 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010517 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010518 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010519 case OMPD_parallel_master_taskloop:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010520 case OMPD_target_data:
10521 case OMPD_target_enter_data:
10522 case OMPD_target_exit_data:
10523 case OMPD_target_update:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010524 case OMPD_cancel:
10525 case OMPD_parallel:
10526 case OMPD_parallel_sections:
10527 case OMPD_parallel_for:
10528 case OMPD_parallel_for_simd:
10529 case OMPD_target:
10530 case OMPD_target_simd:
10531 case OMPD_target_parallel:
10532 case OMPD_target_parallel_for:
10533 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010534 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010535 case OMPD_allocate:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010536 case OMPD_taskyield:
10537 case OMPD_barrier:
10538 case OMPD_taskwait:
10539 case OMPD_cancellation_point:
10540 case OMPD_flush:
10541 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010542 case OMPD_declare_mapper:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010543 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010544 case OMPD_declare_variant:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010545 case OMPD_declare_target:
10546 case OMPD_end_declare_target:
10547 case OMPD_simd:
10548 case OMPD_for:
10549 case OMPD_for_simd:
10550 case OMPD_sections:
10551 case OMPD_section:
10552 case OMPD_single:
10553 case OMPD_master:
10554 case OMPD_critical:
10555 case OMPD_taskgroup:
10556 case OMPD_distribute:
10557 case OMPD_ordered:
10558 case OMPD_atomic:
10559 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010560 case OMPD_requires:
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000010561 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
10562 case OMPD_unknown:
10563 llvm_unreachable("Unknown OpenMP directive");
10564 }
10565 break;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010566 case OMPC_thread_limit:
10567 switch (DKind) {
10568 case OMPD_target_teams:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010569 case OMPD_target_teams_distribute:
10570 case OMPD_target_teams_distribute_simd:
10571 case OMPD_target_teams_distribute_parallel_for:
10572 case OMPD_target_teams_distribute_parallel_for_simd:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010573 CaptureRegion = OMPD_target;
10574 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010575 case OMPD_teams_distribute_parallel_for:
10576 case OMPD_teams_distribute_parallel_for_simd:
10577 case OMPD_teams:
10578 case OMPD_teams_distribute:
10579 case OMPD_teams_distribute_simd:
10580 // Do not capture thread_limit-clause expressions.
10581 break;
10582 case OMPD_distribute_parallel_for:
10583 case OMPD_distribute_parallel_for_simd:
10584 case OMPD_task:
10585 case OMPD_taskloop:
10586 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010587 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010588 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010589 case OMPD_parallel_master_taskloop:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010590 case OMPD_target_data:
10591 case OMPD_target_enter_data:
10592 case OMPD_target_exit_data:
10593 case OMPD_target_update:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010594 case OMPD_cancel:
10595 case OMPD_parallel:
10596 case OMPD_parallel_sections:
10597 case OMPD_parallel_for:
10598 case OMPD_parallel_for_simd:
10599 case OMPD_target:
10600 case OMPD_target_simd:
10601 case OMPD_target_parallel:
10602 case OMPD_target_parallel_for:
10603 case OMPD_target_parallel_for_simd:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010604 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010605 case OMPD_allocate:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010606 case OMPD_taskyield:
10607 case OMPD_barrier:
10608 case OMPD_taskwait:
10609 case OMPD_cancellation_point:
10610 case OMPD_flush:
10611 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010612 case OMPD_declare_mapper:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010613 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010614 case OMPD_declare_variant:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010615 case OMPD_declare_target:
10616 case OMPD_end_declare_target:
10617 case OMPD_simd:
10618 case OMPD_for:
10619 case OMPD_for_simd:
10620 case OMPD_sections:
10621 case OMPD_section:
10622 case OMPD_single:
10623 case OMPD_master:
10624 case OMPD_critical:
10625 case OMPD_taskgroup:
10626 case OMPD_distribute:
10627 case OMPD_ordered:
10628 case OMPD_atomic:
10629 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010630 case OMPD_requires:
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000010631 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
10632 case OMPD_unknown:
10633 llvm_unreachable("Unknown OpenMP directive");
10634 }
10635 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010636 case OMPC_schedule:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010637 switch (DKind) {
Alexey Bataev2ba67042017-11-28 21:11:44 +000010638 case OMPD_parallel_for:
10639 case OMPD_parallel_for_simd:
Alexey Bataev7f96c372017-11-22 17:19:31 +000010640 case OMPD_distribute_parallel_for:
Alexey Bataev974acd62017-11-27 19:38:52 +000010641 case OMPD_distribute_parallel_for_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +000010642 case OMPD_teams_distribute_parallel_for:
10643 case OMPD_teams_distribute_parallel_for_simd:
10644 case OMPD_target_parallel_for:
10645 case OMPD_target_parallel_for_simd:
10646 case OMPD_target_teams_distribute_parallel_for:
10647 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataev7f96c372017-11-22 17:19:31 +000010648 CaptureRegion = OMPD_parallel;
10649 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010650 case OMPD_for:
10651 case OMPD_for_simd:
10652 // Do not capture schedule-clause expressions.
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010653 break;
10654 case OMPD_task:
10655 case OMPD_taskloop:
10656 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010657 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010658 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010659 case OMPD_parallel_master_taskloop:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010660 case OMPD_target_data:
10661 case OMPD_target_enter_data:
10662 case OMPD_target_exit_data:
10663 case OMPD_target_update:
10664 case OMPD_teams:
10665 case OMPD_teams_distribute:
10666 case OMPD_teams_distribute_simd:
10667 case OMPD_target_teams_distribute:
10668 case OMPD_target_teams_distribute_simd:
10669 case OMPD_target:
10670 case OMPD_target_simd:
10671 case OMPD_target_parallel:
10672 case OMPD_cancel:
10673 case OMPD_parallel:
10674 case OMPD_parallel_sections:
10675 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010676 case OMPD_allocate:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010677 case OMPD_taskyield:
10678 case OMPD_barrier:
10679 case OMPD_taskwait:
10680 case OMPD_cancellation_point:
10681 case OMPD_flush:
10682 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010683 case OMPD_declare_mapper:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010684 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010685 case OMPD_declare_variant:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010686 case OMPD_declare_target:
10687 case OMPD_end_declare_target:
10688 case OMPD_simd:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010689 case OMPD_sections:
10690 case OMPD_section:
10691 case OMPD_single:
10692 case OMPD_master:
10693 case OMPD_critical:
10694 case OMPD_taskgroup:
10695 case OMPD_distribute:
10696 case OMPD_ordered:
10697 case OMPD_atomic:
10698 case OMPD_distribute_simd:
10699 case OMPD_target_teams:
Kelvin Li1408f912018-09-26 04:28:39 +000010700 case OMPD_requires:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +000010701 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
10702 case OMPD_unknown:
10703 llvm_unreachable("Unknown OpenMP directive");
10704 }
10705 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010706 case OMPC_dist_schedule:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010707 switch (DKind) {
10708 case OMPD_teams_distribute_parallel_for:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010709 case OMPD_teams_distribute_parallel_for_simd:
10710 case OMPD_teams_distribute:
10711 case OMPD_teams_distribute_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010712 case OMPD_target_teams_distribute_parallel_for:
10713 case OMPD_target_teams_distribute_parallel_for_simd:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010714 case OMPD_target_teams_distribute:
10715 case OMPD_target_teams_distribute_simd:
Alexey Bataevfd9b2af2018-01-04 20:50:08 +000010716 CaptureRegion = OMPD_teams;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010717 break;
10718 case OMPD_distribute_parallel_for:
10719 case OMPD_distribute_parallel_for_simd:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010720 case OMPD_distribute:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010721 case OMPD_distribute_simd:
10722 // Do not capture thread_limit-clause expressions.
10723 break;
10724 case OMPD_parallel_for:
10725 case OMPD_parallel_for_simd:
10726 case OMPD_target_parallel_for_simd:
10727 case OMPD_target_parallel_for:
10728 case OMPD_task:
10729 case OMPD_taskloop:
10730 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010731 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010732 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010733 case OMPD_parallel_master_taskloop:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010734 case OMPD_target_data:
10735 case OMPD_target_enter_data:
10736 case OMPD_target_exit_data:
10737 case OMPD_target_update:
10738 case OMPD_teams:
10739 case OMPD_target:
10740 case OMPD_target_simd:
10741 case OMPD_target_parallel:
10742 case OMPD_cancel:
10743 case OMPD_parallel:
10744 case OMPD_parallel_sections:
10745 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010746 case OMPD_allocate:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010747 case OMPD_taskyield:
10748 case OMPD_barrier:
10749 case OMPD_taskwait:
10750 case OMPD_cancellation_point:
10751 case OMPD_flush:
10752 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010753 case OMPD_declare_mapper:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010754 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010755 case OMPD_declare_variant:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010756 case OMPD_declare_target:
10757 case OMPD_end_declare_target:
10758 case OMPD_simd:
10759 case OMPD_for:
10760 case OMPD_for_simd:
10761 case OMPD_sections:
10762 case OMPD_section:
10763 case OMPD_single:
10764 case OMPD_master:
10765 case OMPD_critical:
10766 case OMPD_taskgroup:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010767 case OMPD_ordered:
10768 case OMPD_atomic:
10769 case OMPD_target_teams:
Kelvin Li1408f912018-09-26 04:28:39 +000010770 case OMPD_requires:
Carlo Bertolli62fae152017-11-20 20:46:39 +000010771 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
10772 case OMPD_unknown:
10773 llvm_unreachable("Unknown OpenMP directive");
10774 }
10775 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010776 case OMPC_device:
10777 switch (DKind) {
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010778 case OMPD_target_update:
Alexey Bataevfab20e42017-12-27 18:49:38 +000010779 case OMPD_target_enter_data:
10780 case OMPD_target_exit_data:
Alexey Bataev8451efa2018-01-15 19:06:12 +000010781 case OMPD_target:
Alexey Bataevf41c88f2018-01-16 15:05:16 +000010782 case OMPD_target_simd:
Alexey Bataev0c869ef2018-01-16 15:57:07 +000010783 case OMPD_target_teams:
Alexey Bataev54d5c7d2018-01-16 16:27:49 +000010784 case OMPD_target_parallel:
Alexey Bataev79df7562018-01-16 16:46:46 +000010785 case OMPD_target_teams_distribute:
Alexey Bataev8d16a432018-01-16 17:22:50 +000010786 case OMPD_target_teams_distribute_simd:
Alexey Bataev8ed895512018-01-16 17:41:04 +000010787 case OMPD_target_parallel_for:
Alexey Bataevd60d1ba2018-01-16 17:55:15 +000010788 case OMPD_target_parallel_for_simd:
Alexey Bataev9f9fb0b2018-01-16 19:02:33 +000010789 case OMPD_target_teams_distribute_parallel_for:
Alexey Bataev9350fc32018-01-16 19:18:24 +000010790 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010791 CaptureRegion = OMPD_task;
10792 break;
Alexey Bataev2ba67042017-11-28 21:11:44 +000010793 case OMPD_target_data:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010794 // Do not capture device-clause expressions.
10795 break;
10796 case OMPD_teams_distribute_parallel_for:
10797 case OMPD_teams_distribute_parallel_for_simd:
10798 case OMPD_teams:
10799 case OMPD_teams_distribute:
10800 case OMPD_teams_distribute_simd:
10801 case OMPD_distribute_parallel_for:
10802 case OMPD_distribute_parallel_for_simd:
10803 case OMPD_task:
10804 case OMPD_taskloop:
10805 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010806 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010807 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010808 case OMPD_parallel_master_taskloop:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010809 case OMPD_cancel:
10810 case OMPD_parallel:
10811 case OMPD_parallel_sections:
10812 case OMPD_parallel_for:
10813 case OMPD_parallel_for_simd:
10814 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010815 case OMPD_allocate:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010816 case OMPD_taskyield:
10817 case OMPD_barrier:
10818 case OMPD_taskwait:
10819 case OMPD_cancellation_point:
10820 case OMPD_flush:
10821 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010822 case OMPD_declare_mapper:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010823 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010824 case OMPD_declare_variant:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010825 case OMPD_declare_target:
10826 case OMPD_end_declare_target:
10827 case OMPD_simd:
10828 case OMPD_for:
10829 case OMPD_for_simd:
10830 case OMPD_sections:
10831 case OMPD_section:
10832 case OMPD_single:
10833 case OMPD_master:
10834 case OMPD_critical:
10835 case OMPD_taskgroup:
10836 case OMPD_distribute:
10837 case OMPD_ordered:
10838 case OMPD_atomic:
10839 case OMPD_distribute_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010840 case OMPD_requires:
Alexey Bataev2ba67042017-11-28 21:11:44 +000010841 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
10842 case OMPD_unknown:
10843 llvm_unreachable("Unknown OpenMP directive");
10844 }
10845 break;
Alexey Bataevb9c55e22019-10-14 19:29:52 +000010846 case OMPC_grainsize:
Alexey Bataevd88c7de2019-10-14 20:44:34 +000010847 case OMPC_num_tasks:
Alexey Bataev3a842ec2019-10-15 19:37:05 +000010848 case OMPC_final:
Alexey Bataev31ba4762019-10-16 18:09:37 +000010849 case OMPC_priority:
Alexey Bataevb9c55e22019-10-14 19:29:52 +000010850 switch (DKind) {
10851 case OMPD_task:
10852 case OMPD_taskloop:
10853 case OMPD_taskloop_simd:
10854 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010855 case OMPD_master_taskloop_simd:
Alexey Bataevb9c55e22019-10-14 19:29:52 +000010856 break;
10857 case OMPD_parallel_master_taskloop:
10858 CaptureRegion = OMPD_parallel;
10859 break;
10860 case OMPD_target_update:
10861 case OMPD_target_enter_data:
10862 case OMPD_target_exit_data:
10863 case OMPD_target:
10864 case OMPD_target_simd:
10865 case OMPD_target_teams:
10866 case OMPD_target_parallel:
10867 case OMPD_target_teams_distribute:
10868 case OMPD_target_teams_distribute_simd:
10869 case OMPD_target_parallel_for:
10870 case OMPD_target_parallel_for_simd:
10871 case OMPD_target_teams_distribute_parallel_for:
10872 case OMPD_target_teams_distribute_parallel_for_simd:
10873 case OMPD_target_data:
10874 case OMPD_teams_distribute_parallel_for:
10875 case OMPD_teams_distribute_parallel_for_simd:
10876 case OMPD_teams:
10877 case OMPD_teams_distribute:
10878 case OMPD_teams_distribute_simd:
10879 case OMPD_distribute_parallel_for:
10880 case OMPD_distribute_parallel_for_simd:
10881 case OMPD_cancel:
10882 case OMPD_parallel:
10883 case OMPD_parallel_sections:
10884 case OMPD_parallel_for:
10885 case OMPD_parallel_for_simd:
10886 case OMPD_threadprivate:
10887 case OMPD_allocate:
10888 case OMPD_taskyield:
10889 case OMPD_barrier:
10890 case OMPD_taskwait:
10891 case OMPD_cancellation_point:
10892 case OMPD_flush:
10893 case OMPD_declare_reduction:
10894 case OMPD_declare_mapper:
10895 case OMPD_declare_simd:
10896 case OMPD_declare_variant:
10897 case OMPD_declare_target:
10898 case OMPD_end_declare_target:
10899 case OMPD_simd:
10900 case OMPD_for:
10901 case OMPD_for_simd:
10902 case OMPD_sections:
10903 case OMPD_section:
10904 case OMPD_single:
10905 case OMPD_master:
10906 case OMPD_critical:
10907 case OMPD_taskgroup:
10908 case OMPD_distribute:
10909 case OMPD_ordered:
10910 case OMPD_atomic:
10911 case OMPD_distribute_simd:
10912 case OMPD_requires:
10913 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
10914 case OMPD_unknown:
10915 llvm_unreachable("Unknown OpenMP directive");
10916 }
10917 break;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010918 case OMPC_firstprivate:
10919 case OMPC_lastprivate:
10920 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000010921 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000010922 case OMPC_in_reduction:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010923 case OMPC_linear:
10924 case OMPC_default:
10925 case OMPC_proc_bind:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010926 case OMPC_safelen:
10927 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000010928 case OMPC_allocator:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010929 case OMPC_collapse:
10930 case OMPC_private:
10931 case OMPC_shared:
10932 case OMPC_aligned:
10933 case OMPC_copyin:
10934 case OMPC_copyprivate:
10935 case OMPC_ordered:
10936 case OMPC_nowait:
10937 case OMPC_untied:
10938 case OMPC_mergeable:
10939 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010940 case OMPC_allocate:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010941 case OMPC_flush:
10942 case OMPC_read:
10943 case OMPC_write:
10944 case OMPC_update:
10945 case OMPC_capture:
10946 case OMPC_seq_cst:
10947 case OMPC_depend:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010948 case OMPC_threads:
10949 case OMPC_simd:
10950 case OMPC_map:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010951 case OMPC_nogroup:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010952 case OMPC_hint:
10953 case OMPC_defaultmap:
10954 case OMPC_unknown:
10955 case OMPC_uniform:
10956 case OMPC_to:
10957 case OMPC_from:
10958 case OMPC_use_device_ptr:
10959 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000010960 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000010961 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000010962 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000010963 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000010964 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +000010965 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000010966 case OMPC_match:
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010967 llvm_unreachable("Unexpected OpenMP clause.");
10968 }
10969 return CaptureRegion;
10970}
10971
Alexey Bataev6b8046a2015-09-03 07:23:48 +000010972OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
10973 Expr *Condition, SourceLocation StartLoc,
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010974 SourceLocation LParenLoc,
Alexey Bataev6b8046a2015-09-03 07:23:48 +000010975 SourceLocation NameModifierLoc,
10976 SourceLocation ColonLoc,
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010977 SourceLocation EndLoc) {
10978 Expr *ValExpr = Condition;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010979 Stmt *HelperValStmt = nullptr;
10980 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010981 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
10982 !Condition->isInstantiationDependent() &&
10983 !Condition->containsUnexpandedParameterPack()) {
Richard Smith03a4aa32016-06-23 19:02:52 +000010984 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010985 if (Val.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000010986 return nullptr;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010987
Alexey Bataev8e769ee2017-12-22 21:01:52 +000010988 ValExpr = Val.get();
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010989
10990 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
10991 CaptureRegion =
10992 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
Alexey Bataev2ba67042017-11-28 21:11:44 +000010993 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000010994 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000010995 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000010996 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
10997 HelperValStmt = buildPreInits(Context, Captures);
10998 }
Alexey Bataevaadd52e2014-02-13 05:29:23 +000010999 }
11000
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +000011001 return new (Context)
11002 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
11003 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
Alexey Bataevaadd52e2014-02-13 05:29:23 +000011004}
11005
Alexey Bataev3778b602014-07-17 07:32:53 +000011006OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
11007 SourceLocation StartLoc,
11008 SourceLocation LParenLoc,
11009 SourceLocation EndLoc) {
11010 Expr *ValExpr = Condition;
Alexey Bataev3a842ec2019-10-15 19:37:05 +000011011 Stmt *HelperValStmt = nullptr;
11012 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataev3778b602014-07-17 07:32:53 +000011013 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11014 !Condition->isInstantiationDependent() &&
11015 !Condition->containsUnexpandedParameterPack()) {
Richard Smith03a4aa32016-06-23 19:02:52 +000011016 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
Alexey Bataev3778b602014-07-17 07:32:53 +000011017 if (Val.isInvalid())
11018 return nullptr;
11019
Richard Smith03a4aa32016-06-23 19:02:52 +000011020 ValExpr = MakeFullExpr(Val.get()).get();
Alexey Bataev3a842ec2019-10-15 19:37:05 +000011021
11022 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11023 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final);
11024 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11025 ValExpr = MakeFullExpr(ValExpr).get();
11026 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11027 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11028 HelperValStmt = buildPreInits(Context, Captures);
11029 }
Alexey Bataev3778b602014-07-17 07:32:53 +000011030 }
11031
Alexey Bataev3a842ec2019-10-15 19:37:05 +000011032 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
11033 StartLoc, LParenLoc, EndLoc);
Alexey Bataev3778b602014-07-17 07:32:53 +000011034}
Alexey Bataev3a842ec2019-10-15 19:37:05 +000011035
Alexander Musmana8e9d2e2014-06-03 10:16:47 +000011036ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
11037 Expr *Op) {
Alexey Bataev568a8332014-03-06 06:15:19 +000011038 if (!Op)
11039 return ExprError();
11040
11041 class IntConvertDiagnoser : public ICEConvertDiagnoser {
11042 public:
11043 IntConvertDiagnoser()
Alexey Bataeved09d242014-05-28 05:53:51 +000011044 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
Craig Toppere14c0f82014-03-12 04:55:44 +000011045 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
11046 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011047 return S.Diag(Loc, diag::err_omp_not_integral) << T;
11048 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011049 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
11050 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011051 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
11052 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011053 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
11054 QualType T,
11055 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011056 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
11057 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011058 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
11059 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011060 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
Alexey Bataeved09d242014-05-28 05:53:51 +000011061 << ConvTy->isEnumeralType() << ConvTy;
Alexey Bataev568a8332014-03-06 06:15:19 +000011062 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011063 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
11064 QualType T) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011065 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
11066 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011067 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
11068 QualType ConvTy) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011069 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
Alexey Bataeved09d242014-05-28 05:53:51 +000011070 << ConvTy->isEnumeralType() << ConvTy;
Alexey Bataev568a8332014-03-06 06:15:19 +000011071 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011072 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
11073 QualType) override {
Alexey Bataev568a8332014-03-06 06:15:19 +000011074 llvm_unreachable("conversion functions are permitted");
11075 }
11076 } ConvertDiagnoser;
11077 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
11078}
11079
Alexey Bataevb9c55e22019-10-14 19:29:52 +000011080static bool
11081isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
11082 bool StrictlyPositive, bool BuildCapture = false,
11083 OpenMPDirectiveKind DKind = OMPD_unknown,
11084 OpenMPDirectiveKind *CaptureRegion = nullptr,
11085 Stmt **HelperValStmt = nullptr) {
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011086 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
11087 !ValExpr->isInstantiationDependent()) {
11088 SourceLocation Loc = ValExpr->getExprLoc();
11089 ExprResult Value =
11090 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
11091 if (Value.isInvalid())
11092 return false;
11093
11094 ValExpr = Value.get();
11095 // The expression must evaluate to a non-negative integer value.
11096 llvm::APSInt Result;
11097 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
Alexey Bataeva0569352015-12-01 10:17:31 +000011098 Result.isSigned() &&
11099 !((!StrictlyPositive && Result.isNonNegative()) ||
11100 (StrictlyPositive && Result.isStrictlyPositive()))) {
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011101 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
Alexey Bataeva0569352015-12-01 10:17:31 +000011102 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11103 << ValExpr->getSourceRange();
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011104 return false;
11105 }
Alexey Bataevb9c55e22019-10-14 19:29:52 +000011106 if (!BuildCapture)
11107 return true;
11108 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind);
11109 if (*CaptureRegion != OMPD_unknown &&
11110 !SemaRef.CurContext->isDependentContext()) {
11111 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
11112 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11113 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
11114 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
11115 }
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011116 }
11117 return true;
11118}
11119
Alexey Bataev568a8332014-03-06 06:15:19 +000011120OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
11121 SourceLocation StartLoc,
11122 SourceLocation LParenLoc,
11123 SourceLocation EndLoc) {
11124 Expr *ValExpr = NumThreads;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000011125 Stmt *HelperValStmt = nullptr;
Alexey Bataev568a8332014-03-06 06:15:19 +000011126
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011127 // OpenMP [2.5, Restrictions]
11128 // The num_threads expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000011129 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
Alexey Bataeva0569352015-12-01 10:17:31 +000011130 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011131 return nullptr;
Alexey Bataev568a8332014-03-06 06:15:19 +000011132
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000011133 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000011134 OpenMPDirectiveKind CaptureRegion =
11135 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
11136 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000011137 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000011138 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +000011139 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11140 HelperValStmt = buildPreInits(Context, Captures);
11141 }
11142
11143 return new (Context) OMPNumThreadsClause(
11144 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
Alexey Bataev568a8332014-03-06 06:15:19 +000011145}
11146
Alexey Bataev62c87d22014-03-21 04:51:18 +000011147ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
Alexey Bataeva636c7f2015-12-23 10:27:45 +000011148 OpenMPClauseKind CKind,
11149 bool StrictlyPositive) {
Alexey Bataev62c87d22014-03-21 04:51:18 +000011150 if (!E)
11151 return ExprError();
11152 if (E->isValueDependent() || E->isTypeDependent() ||
11153 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
Nikola Smiljanic03ff2592014-05-29 14:05:12 +000011154 return E;
Alexey Bataev62c87d22014-03-21 04:51:18 +000011155 llvm::APSInt Result;
11156 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
11157 if (ICE.isInvalid())
11158 return ExprError();
Alexey Bataeva636c7f2015-12-23 10:27:45 +000011159 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
11160 (!StrictlyPositive && !Result.isNonNegative())) {
Alexey Bataev62c87d22014-03-21 04:51:18 +000011161 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
Alexey Bataeva636c7f2015-12-23 10:27:45 +000011162 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11163 << E->getSourceRange();
Alexey Bataev62c87d22014-03-21 04:51:18 +000011164 return ExprError();
11165 }
Alexander Musman09184fe2014-09-30 05:29:28 +000011166 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
11167 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
11168 << E->getSourceRange();
11169 return ExprError();
11170 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +000011171 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
11172 DSAStack->setAssociatedLoops(Result.getExtValue());
Alexey Bataev7b6bc882015-11-26 07:50:39 +000011173 else if (CKind == OMPC_ordered)
Alexey Bataeva636c7f2015-12-23 10:27:45 +000011174 DSAStack->setAssociatedLoops(Result.getExtValue());
Alexey Bataev62c87d22014-03-21 04:51:18 +000011175 return ICE;
11176}
11177
11178OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
11179 SourceLocation LParenLoc,
11180 SourceLocation EndLoc) {
11181 // OpenMP [2.8.1, simd construct, Description]
11182 // The parameter of the safelen clause must be a constant
11183 // positive integer expression.
11184 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
11185 if (Safelen.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000011186 return nullptr;
Alexey Bataev62c87d22014-03-21 04:51:18 +000011187 return new (Context)
Nikola Smiljanic01a75982014-05-29 10:55:11 +000011188 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
Alexey Bataev62c87d22014-03-21 04:51:18 +000011189}
11190
Alexey Bataev66b15b52015-08-21 11:14:16 +000011191OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
11192 SourceLocation LParenLoc,
11193 SourceLocation EndLoc) {
11194 // OpenMP [2.8.1, simd construct, Description]
11195 // The parameter of the simdlen clause must be a constant
11196 // positive integer expression.
11197 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
11198 if (Simdlen.isInvalid())
11199 return nullptr;
11200 return new (Context)
11201 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
11202}
11203
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011204/// Tries to find omp_allocator_handle_t type.
Alexey Bataev27ef9512019-03-20 20:14:22 +000011205static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
11206 DSAStackTy *Stack) {
11207 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011208 if (!OMPAllocatorHandleT.isNull())
11209 return true;
Alexey Bataev27ef9512019-03-20 20:14:22 +000011210 // Build the predefined allocator expressions.
11211 bool ErrorFound = false;
11212 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
11213 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
11214 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
11215 StringRef Allocator =
11216 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
11217 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
11218 auto *VD = dyn_cast_or_null<ValueDecl>(
11219 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
11220 if (!VD) {
11221 ErrorFound = true;
11222 break;
11223 }
11224 QualType AllocatorType =
11225 VD->getType().getNonLValueExprType(S.getASTContext());
11226 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
11227 if (!Res.isUsable()) {
11228 ErrorFound = true;
11229 break;
11230 }
11231 if (OMPAllocatorHandleT.isNull())
11232 OMPAllocatorHandleT = AllocatorType;
11233 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
11234 ErrorFound = true;
11235 break;
11236 }
11237 Stack->setAllocator(AllocatorKind, Res.get());
11238 }
11239 if (ErrorFound) {
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011240 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
11241 return false;
11242 }
Alexey Bataev27ef9512019-03-20 20:14:22 +000011243 OMPAllocatorHandleT.addConst();
11244 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011245 return true;
11246}
11247
11248OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
11249 SourceLocation LParenLoc,
11250 SourceLocation EndLoc) {
11251 // OpenMP [2.11.3, allocate Directive, Description]
11252 // allocator is an expression of omp_allocator_handle_t type.
Alexey Bataev27ef9512019-03-20 20:14:22 +000011253 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011254 return nullptr;
11255
11256 ExprResult Allocator = DefaultLvalueConversion(A);
11257 if (Allocator.isInvalid())
11258 return nullptr;
Alexey Bataev27ef9512019-03-20 20:14:22 +000011259 Allocator = PerformImplicitConversion(Allocator.get(),
11260 DSAStack->getOMPAllocatorHandleT(),
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011261 Sema::AA_Initializing,
11262 /*AllowExplicit=*/true);
11263 if (Allocator.isInvalid())
11264 return nullptr;
11265 return new (Context)
11266 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
11267}
11268
Alexander Musman64d33f12014-06-04 07:53:32 +000011269OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
11270 SourceLocation StartLoc,
Alexander Musman8bd31e62014-05-27 15:12:19 +000011271 SourceLocation LParenLoc,
11272 SourceLocation EndLoc) {
Alexander Musman64d33f12014-06-04 07:53:32 +000011273 // OpenMP [2.7.1, loop construct, Description]
Alexander Musman8bd31e62014-05-27 15:12:19 +000011274 // OpenMP [2.8.1, simd construct, Description]
Alexander Musman64d33f12014-06-04 07:53:32 +000011275 // OpenMP [2.9.6, distribute construct, Description]
Alexander Musman8bd31e62014-05-27 15:12:19 +000011276 // The parameter of the collapse clause must be a constant
11277 // positive integer expression.
Alexander Musman64d33f12014-06-04 07:53:32 +000011278 ExprResult NumForLoopsResult =
11279 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
11280 if (NumForLoopsResult.isInvalid())
Alexander Musman8bd31e62014-05-27 15:12:19 +000011281 return nullptr;
11282 return new (Context)
Alexander Musman64d33f12014-06-04 07:53:32 +000011283 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
Alexander Musman8bd31e62014-05-27 15:12:19 +000011284}
11285
Alexey Bataev10e775f2015-07-30 11:36:16 +000011286OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
11287 SourceLocation EndLoc,
11288 SourceLocation LParenLoc,
11289 Expr *NumForLoops) {
Alexey Bataev10e775f2015-07-30 11:36:16 +000011290 // OpenMP [2.7.1, loop construct, Description]
11291 // OpenMP [2.8.1, simd construct, Description]
11292 // OpenMP [2.9.6, distribute construct, Description]
11293 // The parameter of the ordered clause must be a constant
11294 // positive integer expression if any.
11295 if (NumForLoops && LParenLoc.isValid()) {
11296 ExprResult NumForLoopsResult =
11297 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
11298 if (NumForLoopsResult.isInvalid())
11299 return nullptr;
11300 NumForLoops = NumForLoopsResult.get();
Alexey Bataeve3727102018-04-18 15:57:46 +000011301 } else {
Alexey Bataev346265e2015-09-25 10:37:12 +000011302 NumForLoops = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000011303 }
Alexey Bataevf138fda2018-08-13 19:04:24 +000011304 auto *Clause = OMPOrderedClause::Create(
11305 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
11306 StartLoc, LParenLoc, EndLoc);
11307 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
11308 return Clause;
Alexey Bataev10e775f2015-07-30 11:36:16 +000011309}
11310
Alexey Bataeved09d242014-05-28 05:53:51 +000011311OMPClause *Sema::ActOnOpenMPSimpleClause(
11312 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
11313 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
Alexander Musmancb7f9c42014-05-15 13:04:49 +000011314 OMPClause *Res = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011315 switch (Kind) {
11316 case OMPC_default:
Alexey Bataev758e55e2013-09-06 18:03:48 +000011317 Res =
Alexey Bataeved09d242014-05-28 05:53:51 +000011318 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
11319 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011320 break;
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011321 case OMPC_proc_bind:
Alexey Bataeved09d242014-05-28 05:53:51 +000011322 Res = ActOnOpenMPProcBindClause(
11323 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
11324 LParenLoc, EndLoc);
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011325 break;
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000011326 case OMPC_atomic_default_mem_order:
11327 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
11328 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
11329 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11330 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000011331 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000011332 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +000011333 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +000011334 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000011335 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011336 case OMPC_allocator:
Alexander Musman8bd31e62014-05-27 15:12:19 +000011337 case OMPC_collapse:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011338 case OMPC_schedule:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011339 case OMPC_private:
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011340 case OMPC_firstprivate:
Alexander Musman1bb328c2014-06-04 13:06:39 +000011341 case OMPC_lastprivate:
Alexey Bataev758e55e2013-09-06 18:03:48 +000011342 case OMPC_shared:
Alexey Bataevc5e02582014-06-16 07:08:35 +000011343 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000011344 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000011345 case OMPC_in_reduction:
Alexander Musman8dba6642014-04-22 13:09:42 +000011346 case OMPC_linear:
Alexander Musmanf0d76e72014-05-29 14:36:25 +000011347 case OMPC_aligned:
Alexey Bataevd48bcd82014-03-31 03:36:38 +000011348 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000011349 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011350 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000011351 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000011352 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000011353 case OMPC_mergeable:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011354 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000011355 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000011356 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011357 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000011358 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000011359 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000011360 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000011361 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000011362 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000011363 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000011364 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000011365 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +000011366 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000011367 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011368 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000011369 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000011370 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000011371 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000011372 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000011373 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000011374 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000011375 case OMPC_defaultmap:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011376 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000011377 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000011378 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000011379 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000011380 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000011381 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000011382 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000011383 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000011384 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000011385 case OMPC_dynamic_allocators:
Alexey Bataev729e2422019-08-23 16:11:14 +000011386 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000011387 case OMPC_match:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011388 llvm_unreachable("Clause is not allowed.");
11389 }
11390 return Res;
11391}
11392
Alexey Bataev6402bca2015-12-28 07:25:51 +000011393static std::string
11394getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
11395 ArrayRef<unsigned> Exclude = llvm::None) {
Alexey Bataeve3727102018-04-18 15:57:46 +000011396 SmallString<256> Buffer;
11397 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev6402bca2015-12-28 07:25:51 +000011398 unsigned Bound = Last >= 2 ? Last - 2 : 0;
11399 unsigned Skipped = Exclude.size();
11400 auto S = Exclude.begin(), E = Exclude.end();
Alexey Bataeve3727102018-04-18 15:57:46 +000011401 for (unsigned I = First; I < Last; ++I) {
11402 if (std::find(S, E, I) != E) {
Alexey Bataev6402bca2015-12-28 07:25:51 +000011403 --Skipped;
11404 continue;
11405 }
Alexey Bataeve3727102018-04-18 15:57:46 +000011406 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
11407 if (I == Bound - Skipped)
11408 Out << " or ";
11409 else if (I != Bound + 1 - Skipped)
11410 Out << ", ";
Alexey Bataev6402bca2015-12-28 07:25:51 +000011411 }
Alexey Bataeve3727102018-04-18 15:57:46 +000011412 return Out.str();
Alexey Bataev6402bca2015-12-28 07:25:51 +000011413}
11414
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011415OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
11416 SourceLocation KindKwLoc,
11417 SourceLocation StartLoc,
11418 SourceLocation LParenLoc,
11419 SourceLocation EndLoc) {
11420 if (Kind == OMPC_DEFAULT_unknown) {
Alexey Bataev4ca40ed2014-05-12 04:23:46 +000011421 static_assert(OMPC_DEFAULT_unknown > 0,
11422 "OMPC_DEFAULT_unknown not greater than 0");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011423 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000011424 << getListOfPossibleValues(OMPC_default, /*First=*/0,
11425 /*Last=*/OMPC_DEFAULT_unknown)
11426 << getOpenMPClauseName(OMPC_default);
Alexander Musmancb7f9c42014-05-15 13:04:49 +000011427 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011428 }
Alexey Bataev758e55e2013-09-06 18:03:48 +000011429 switch (Kind) {
11430 case OMPC_DEFAULT_none:
Alexey Bataevbae9a792014-06-27 10:37:06 +000011431 DSAStack->setDefaultDSANone(KindKwLoc);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011432 break;
11433 case OMPC_DEFAULT_shared:
Alexey Bataevbae9a792014-06-27 10:37:06 +000011434 DSAStack->setDefaultDSAShared(KindKwLoc);
Alexey Bataev758e55e2013-09-06 18:03:48 +000011435 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000011436 case OMPC_DEFAULT_unknown:
Alexey Bataevaadd52e2014-02-13 05:29:23 +000011437 llvm_unreachable("Clause kind is not allowed.");
Alexey Bataev758e55e2013-09-06 18:03:48 +000011438 break;
11439 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011440 return new (Context)
11441 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011442}
11443
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011444OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
11445 SourceLocation KindKwLoc,
11446 SourceLocation StartLoc,
11447 SourceLocation LParenLoc,
11448 SourceLocation EndLoc) {
11449 if (Kind == OMPC_PROC_BIND_unknown) {
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011450 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000011451 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
11452 /*Last=*/OMPC_PROC_BIND_unknown)
11453 << getOpenMPClauseName(OMPC_proc_bind);
Alexander Musmancb7f9c42014-05-15 13:04:49 +000011454 return nullptr;
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011455 }
Alexey Bataeved09d242014-05-28 05:53:51 +000011456 return new (Context)
11457 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011458}
11459
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000011460OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
11461 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
11462 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
11463 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
11464 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11465 << getListOfPossibleValues(
11466 OMPC_atomic_default_mem_order, /*First=*/0,
11467 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
11468 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
11469 return nullptr;
11470 }
11471 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
11472 LParenLoc, EndLoc);
11473}
11474
Alexey Bataev56dafe82014-06-20 07:16:17 +000011475OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000011476 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
Alexey Bataev56dafe82014-06-20 07:16:17 +000011477 SourceLocation StartLoc, SourceLocation LParenLoc,
Alexey Bataev6402bca2015-12-28 07:25:51 +000011478 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
Alexey Bataev56dafe82014-06-20 07:16:17 +000011479 SourceLocation EndLoc) {
11480 OMPClause *Res = nullptr;
11481 switch (Kind) {
11482 case OMPC_schedule:
Alexey Bataev6402bca2015-12-28 07:25:51 +000011483 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
11484 assert(Argument.size() == NumberOfElements &&
11485 ArgumentLoc.size() == NumberOfElements);
Alexey Bataev56dafe82014-06-20 07:16:17 +000011486 Res = ActOnOpenMPScheduleClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000011487 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
11488 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
11489 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
11490 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
11491 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
Alexey Bataev56dafe82014-06-20 07:16:17 +000011492 break;
11493 case OMPC_if:
Alexey Bataev6402bca2015-12-28 07:25:51 +000011494 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
11495 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
11496 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
11497 DelimLoc, EndLoc);
Alexey Bataev6b8046a2015-09-03 07:23:48 +000011498 break;
Carlo Bertollib4adf552016-01-15 18:50:31 +000011499 case OMPC_dist_schedule:
11500 Res = ActOnOpenMPDistScheduleClause(
11501 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
11502 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
11503 break;
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000011504 case OMPC_defaultmap:
11505 enum { Modifier, DefaultmapKind };
11506 Res = ActOnOpenMPDefaultmapClause(
11507 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
11508 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
David Majnemer9d168222016-08-05 17:44:54 +000011509 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
11510 EndLoc);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000011511 break;
Alexey Bataev3778b602014-07-17 07:32:53 +000011512 case OMPC_final:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011513 case OMPC_num_threads:
11514 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000011515 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011516 case OMPC_allocator:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011517 case OMPC_collapse:
11518 case OMPC_default:
11519 case OMPC_proc_bind:
11520 case OMPC_private:
11521 case OMPC_firstprivate:
11522 case OMPC_lastprivate:
11523 case OMPC_shared:
11524 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000011525 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000011526 case OMPC_in_reduction:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011527 case OMPC_linear:
11528 case OMPC_aligned:
11529 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000011530 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011531 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000011532 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000011533 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000011534 case OMPC_mergeable:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011535 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000011536 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000011537 case OMPC_flush:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011538 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000011539 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000011540 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000011541 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000011542 case OMPC_seq_cst:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000011543 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000011544 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000011545 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000011546 case OMPC_simd:
Kelvin Li0bff7af2015-11-23 05:32:03 +000011547 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000011548 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011549 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000011550 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000011551 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000011552 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000011553 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000011554 case OMPC_hint:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011555 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000011556 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000011557 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000011558 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000011559 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000011560 case OMPC_is_device_ptr:
Kelvin Li1408f912018-09-26 04:28:39 +000011561 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000011562 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000011563 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000011564 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000011565 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +000011566 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000011567 case OMPC_match:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011568 llvm_unreachable("Clause is not allowed.");
11569 }
11570 return Res;
11571}
11572
Alexey Bataev6402bca2015-12-28 07:25:51 +000011573static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
11574 OpenMPScheduleClauseModifier M2,
11575 SourceLocation M1Loc, SourceLocation M2Loc) {
11576 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
11577 SmallVector<unsigned, 2> Excluded;
11578 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
11579 Excluded.push_back(M2);
11580 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
11581 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
11582 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
11583 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
11584 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
11585 << getListOfPossibleValues(OMPC_schedule,
11586 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
11587 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
11588 Excluded)
11589 << getOpenMPClauseName(OMPC_schedule);
11590 return true;
11591 }
11592 return false;
11593}
11594
Alexey Bataev56dafe82014-06-20 07:16:17 +000011595OMPClause *Sema::ActOnOpenMPScheduleClause(
Alexey Bataev6402bca2015-12-28 07:25:51 +000011596 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
Alexey Bataev56dafe82014-06-20 07:16:17 +000011597 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
Alexey Bataev6402bca2015-12-28 07:25:51 +000011598 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
11599 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
11600 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
11601 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
11602 return nullptr;
11603 // OpenMP, 2.7.1, Loop Construct, Restrictions
11604 // Either the monotonic modifier or the nonmonotonic modifier can be specified
11605 // but not both.
11606 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
11607 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
11608 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
11609 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
11610 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
11611 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
11612 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
11613 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
11614 return nullptr;
11615 }
Alexey Bataev56dafe82014-06-20 07:16:17 +000011616 if (Kind == OMPC_SCHEDULE_unknown) {
11617 std::string Values;
Alexey Bataev6402bca2015-12-28 07:25:51 +000011618 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
11619 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
11620 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
11621 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
11622 Exclude);
11623 } else {
11624 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
11625 /*Last=*/OMPC_SCHEDULE_unknown);
Alexey Bataev56dafe82014-06-20 07:16:17 +000011626 }
11627 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
11628 << Values << getOpenMPClauseName(OMPC_schedule);
11629 return nullptr;
11630 }
Alexey Bataev6402bca2015-12-28 07:25:51 +000011631 // OpenMP, 2.7.1, Loop Construct, Restrictions
11632 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
11633 // schedule(guided).
11634 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
11635 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
11636 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
11637 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
11638 diag::err_omp_schedule_nonmonotonic_static);
11639 return nullptr;
11640 }
Alexey Bataev56dafe82014-06-20 07:16:17 +000011641 Expr *ValExpr = ChunkSize;
Alexey Bataev3392d762016-02-16 11:18:12 +000011642 Stmt *HelperValStmt = nullptr;
Alexey Bataev56dafe82014-06-20 07:16:17 +000011643 if (ChunkSize) {
11644 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
11645 !ChunkSize->isInstantiationDependent() &&
11646 !ChunkSize->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000011647 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
Alexey Bataev56dafe82014-06-20 07:16:17 +000011648 ExprResult Val =
11649 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
11650 if (Val.isInvalid())
11651 return nullptr;
11652
11653 ValExpr = Val.get();
11654
11655 // OpenMP [2.7.1, Restrictions]
11656 // chunk_size must be a loop invariant integer expression with a positive
11657 // value.
11658 llvm::APSInt Result;
Alexey Bataev040d5402015-05-12 08:35:28 +000011659 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
11660 if (Result.isSigned() && !Result.isStrictlyPositive()) {
11661 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
Alexey Bataeva0569352015-12-01 10:17:31 +000011662 << "schedule" << 1 << ChunkSize->getSourceRange();
Alexey Bataev040d5402015-05-12 08:35:28 +000011663 return nullptr;
11664 }
Alexey Bataev2ba67042017-11-28 21:11:44 +000011665 } else if (getOpenMPCaptureRegionForClause(
11666 DSAStack->getCurrentDirective(), OMPC_schedule) !=
11667 OMPD_unknown &&
Alexey Bataevb46cdea2016-06-15 11:20:48 +000011668 !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000011669 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000011670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev5a3af132016-03-29 08:58:54 +000011671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11672 HelperValStmt = buildPreInits(Context, Captures);
Alexey Bataev56dafe82014-06-20 07:16:17 +000011673 }
11674 }
11675 }
11676
Alexey Bataev6402bca2015-12-28 07:25:51 +000011677 return new (Context)
11678 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
Alexey Bataev3392d762016-02-16 11:18:12 +000011679 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
Alexey Bataev56dafe82014-06-20 07:16:17 +000011680}
11681
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011682OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
11683 SourceLocation StartLoc,
11684 SourceLocation EndLoc) {
11685 OMPClause *Res = nullptr;
11686 switch (Kind) {
11687 case OMPC_ordered:
11688 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
11689 break;
Alexey Bataev236070f2014-06-20 11:19:47 +000011690 case OMPC_nowait:
11691 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
11692 break;
Alexey Bataev7aea99a2014-07-17 12:19:31 +000011693 case OMPC_untied:
11694 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
11695 break;
Alexey Bataev74ba3a52014-07-17 12:47:03 +000011696 case OMPC_mergeable:
11697 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
11698 break;
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011699 case OMPC_read:
11700 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
11701 break;
Alexey Bataevdea47612014-07-23 07:46:59 +000011702 case OMPC_write:
11703 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
11704 break;
Alexey Bataev67a4f222014-07-23 10:25:33 +000011705 case OMPC_update:
11706 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
11707 break;
Alexey Bataev459dec02014-07-24 06:46:57 +000011708 case OMPC_capture:
11709 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
11710 break;
Alexey Bataev82bad8b2014-07-24 08:55:34 +000011711 case OMPC_seq_cst:
11712 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
11713 break;
Alexey Bataev346265e2015-09-25 10:37:12 +000011714 case OMPC_threads:
11715 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
11716 break;
Alexey Bataevd14d1e62015-09-28 06:39:35 +000011717 case OMPC_simd:
11718 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
11719 break;
Alexey Bataevb825de12015-12-07 10:51:44 +000011720 case OMPC_nogroup:
11721 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
11722 break;
Kelvin Li1408f912018-09-26 04:28:39 +000011723 case OMPC_unified_address:
11724 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
11725 break;
Patrick Lyster4a370b92018-10-01 13:47:43 +000011726 case OMPC_unified_shared_memory:
11727 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
11728 break;
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000011729 case OMPC_reverse_offload:
11730 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
11731 break;
Patrick Lyster3fe9e392018-10-11 14:41:10 +000011732 case OMPC_dynamic_allocators:
11733 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
11734 break;
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011735 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000011736 case OMPC_final:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011737 case OMPC_num_threads:
11738 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000011739 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011740 case OMPC_allocator:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011741 case OMPC_collapse:
11742 case OMPC_schedule:
11743 case OMPC_private:
11744 case OMPC_firstprivate:
11745 case OMPC_lastprivate:
11746 case OMPC_shared:
11747 case OMPC_reduction:
Alexey Bataev169d96a2017-07-18 20:17:46 +000011748 case OMPC_task_reduction:
Alexey Bataevfa312f32017-07-21 18:48:21 +000011749 case OMPC_in_reduction:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011750 case OMPC_linear:
11751 case OMPC_aligned:
11752 case OMPC_copyin:
Alexey Bataevbae9a792014-06-27 10:37:06 +000011753 case OMPC_copyprivate:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011754 case OMPC_default:
11755 case OMPC_proc_bind:
11756 case OMPC_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000011757 case OMPC_allocate:
Alexey Bataev6125da92014-07-21 11:26:11 +000011758 case OMPC_flush:
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000011759 case OMPC_depend:
Michael Wonge710d542015-08-07 16:16:36 +000011760 case OMPC_device:
Kelvin Li0bff7af2015-11-23 05:32:03 +000011761 case OMPC_map:
Kelvin Li099bb8c2015-11-24 20:50:12 +000011762 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011763 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000011764 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000011765 case OMPC_grainsize:
Alexey Bataev382967a2015-12-08 12:06:20 +000011766 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000011767 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000011768 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000011769 case OMPC_defaultmap:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011770 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000011771 case OMPC_uniform:
Samuel Antao661c0902016-05-26 17:39:58 +000011772 case OMPC_to:
Samuel Antaoec172c62016-05-26 17:49:04 +000011773 case OMPC_from:
Carlo Bertolli2404b172016-07-13 15:37:16 +000011774 case OMPC_use_device_ptr:
Carlo Bertolli70594e92016-07-13 17:16:49 +000011775 case OMPC_is_device_ptr:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000011776 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +000011777 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000011778 case OMPC_match:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011779 llvm_unreachable("Clause is not allowed.");
11780 }
11781 return Res;
11782}
11783
Alexey Bataev236070f2014-06-20 11:19:47 +000011784OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
11785 SourceLocation EndLoc) {
Alexey Bataev6d4ed052015-07-01 06:57:41 +000011786 DSAStack->setNowaitRegion();
Alexey Bataev236070f2014-06-20 11:19:47 +000011787 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
11788}
11789
Alexey Bataev7aea99a2014-07-17 12:19:31 +000011790OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
11791 SourceLocation EndLoc) {
11792 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
11793}
11794
Alexey Bataev74ba3a52014-07-17 12:47:03 +000011795OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
11796 SourceLocation EndLoc) {
11797 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
11798}
11799
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011800OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
11801 SourceLocation EndLoc) {
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011802 return new (Context) OMPReadClause(StartLoc, EndLoc);
11803}
11804
Alexey Bataevdea47612014-07-23 07:46:59 +000011805OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
11806 SourceLocation EndLoc) {
11807 return new (Context) OMPWriteClause(StartLoc, EndLoc);
11808}
11809
Alexey Bataev67a4f222014-07-23 10:25:33 +000011810OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
11811 SourceLocation EndLoc) {
11812 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
11813}
11814
Alexey Bataev459dec02014-07-24 06:46:57 +000011815OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
11816 SourceLocation EndLoc) {
11817 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
11818}
11819
Alexey Bataev82bad8b2014-07-24 08:55:34 +000011820OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
11821 SourceLocation EndLoc) {
11822 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
11823}
11824
Alexey Bataev346265e2015-09-25 10:37:12 +000011825OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
11826 SourceLocation EndLoc) {
11827 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
11828}
11829
Alexey Bataevd14d1e62015-09-28 06:39:35 +000011830OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
11831 SourceLocation EndLoc) {
11832 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
11833}
11834
Alexey Bataevb825de12015-12-07 10:51:44 +000011835OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
11836 SourceLocation EndLoc) {
11837 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
11838}
11839
Kelvin Li1408f912018-09-26 04:28:39 +000011840OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
11841 SourceLocation EndLoc) {
11842 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
11843}
11844
Patrick Lyster4a370b92018-10-01 13:47:43 +000011845OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
11846 SourceLocation EndLoc) {
11847 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
11848}
11849
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000011850OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
11851 SourceLocation EndLoc) {
11852 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
11853}
11854
Patrick Lyster3fe9e392018-10-11 14:41:10 +000011855OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
11856 SourceLocation EndLoc) {
11857 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
11858}
11859
Alexey Bataevc5e02582014-06-16 07:08:35 +000011860OMPClause *Sema::ActOnOpenMPVarListClause(
11861 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
Michael Kruse4304e9d2019-02-19 16:38:20 +000011862 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
11863 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
11864 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind,
Kelvin Lief579432018-12-18 22:18:41 +000011865 OpenMPLinearClauseKind LinKind,
11866 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
Michael Kruse4304e9d2019-02-19 16:38:20 +000011867 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType,
11868 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) {
11869 SourceLocation StartLoc = Locs.StartLoc;
11870 SourceLocation LParenLoc = Locs.LParenLoc;
11871 SourceLocation EndLoc = Locs.EndLoc;
Alexander Musmancb7f9c42014-05-15 13:04:49 +000011872 OMPClause *Res = nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011873 switch (Kind) {
11874 case OMPC_private:
11875 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11876 break;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000011877 case OMPC_firstprivate:
11878 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11879 break;
Alexander Musman1bb328c2014-06-04 13:06:39 +000011880 case OMPC_lastprivate:
11881 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11882 break;
Alexey Bataev758e55e2013-09-06 18:03:48 +000011883 case OMPC_shared:
11884 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
11885 break;
Alexey Bataevc5e02582014-06-16 07:08:35 +000011886 case OMPC_reduction:
Alexey Bataev23b69422014-06-18 07:08:49 +000011887 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
Michael Kruse4304e9d2019-02-19 16:38:20 +000011888 EndLoc, ReductionOrMapperIdScopeSpec,
11889 ReductionOrMapperId);
Alexey Bataevc5e02582014-06-16 07:08:35 +000011890 break;
Alexey Bataev169d96a2017-07-18 20:17:46 +000011891 case OMPC_task_reduction:
11892 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
Michael Kruse4304e9d2019-02-19 16:38:20 +000011893 EndLoc, ReductionOrMapperIdScopeSpec,
11894 ReductionOrMapperId);
Alexey Bataev169d96a2017-07-18 20:17:46 +000011895 break;
Alexey Bataevfa312f32017-07-21 18:48:21 +000011896 case OMPC_in_reduction:
Michael Kruse4304e9d2019-02-19 16:38:20 +000011897 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
11898 EndLoc, ReductionOrMapperIdScopeSpec,
11899 ReductionOrMapperId);
Alexey Bataevfa312f32017-07-21 18:48:21 +000011900 break;
Alexander Musman8dba6642014-04-22 13:09:42 +000011901 case OMPC_linear:
11902 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
Kelvin Li0bff7af2015-11-23 05:32:03 +000011903 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
Alexander Musman8dba6642014-04-22 13:09:42 +000011904 break;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000011905 case OMPC_aligned:
11906 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
11907 ColonLoc, EndLoc);
11908 break;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000011909 case OMPC_copyin:
11910 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
11911 break;
Alexey Bataevbae9a792014-06-27 10:37:06 +000011912 case OMPC_copyprivate:
11913 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
11914 break;
Alexey Bataev6125da92014-07-21 11:26:11 +000011915 case OMPC_flush:
11916 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
11917 break;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000011918 case OMPC_depend:
David Majnemer9d168222016-08-05 17:44:54 +000011919 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
Kelvin Li0bff7af2015-11-23 05:32:03 +000011920 StartLoc, LParenLoc, EndLoc);
11921 break;
11922 case OMPC_map:
Michael Kruse4304e9d2019-02-19 16:38:20 +000011923 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
11924 ReductionOrMapperIdScopeSpec,
11925 ReductionOrMapperId, MapType, IsMapTypeImplicit,
11926 DepLinMapLoc, ColonLoc, VarList, Locs);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000011927 break;
Samuel Antao661c0902016-05-26 17:39:58 +000011928 case OMPC_to:
Michael Kruse01f670d2019-02-22 22:29:42 +000011929 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
11930 ReductionOrMapperId, Locs);
Samuel Antao661c0902016-05-26 17:39:58 +000011931 break;
Samuel Antaoec172c62016-05-26 17:49:04 +000011932 case OMPC_from:
Michael Kruse0336c752019-02-25 20:34:15 +000011933 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
11934 ReductionOrMapperId, Locs);
Samuel Antaoec172c62016-05-26 17:49:04 +000011935 break;
Carlo Bertolli2404b172016-07-13 15:37:16 +000011936 case OMPC_use_device_ptr:
Michael Kruse4304e9d2019-02-19 16:38:20 +000011937 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
Carlo Bertolli2404b172016-07-13 15:37:16 +000011938 break;
Carlo Bertolli70594e92016-07-13 17:16:49 +000011939 case OMPC_is_device_ptr:
Michael Kruse4304e9d2019-02-19 16:38:20 +000011940 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
Carlo Bertolli70594e92016-07-13 17:16:49 +000011941 break;
Alexey Bataeve04483e2019-03-27 14:14:31 +000011942 case OMPC_allocate:
11943 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
11944 ColonLoc, EndLoc);
11945 break;
Alexey Bataevaadd52e2014-02-13 05:29:23 +000011946 case OMPC_if:
Alexey Bataev3778b602014-07-17 07:32:53 +000011947 case OMPC_final:
Alexey Bataev568a8332014-03-06 06:15:19 +000011948 case OMPC_num_threads:
Alexey Bataev62c87d22014-03-21 04:51:18 +000011949 case OMPC_safelen:
Alexey Bataev66b15b52015-08-21 11:14:16 +000011950 case OMPC_simdlen:
Alexey Bataev9cc10fc2019-03-12 18:52:33 +000011951 case OMPC_allocator:
Alexander Musman8bd31e62014-05-27 15:12:19 +000011952 case OMPC_collapse:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011953 case OMPC_default:
Alexey Bataevbcbadb62014-05-06 06:04:14 +000011954 case OMPC_proc_bind:
Alexey Bataev56dafe82014-06-20 07:16:17 +000011955 case OMPC_schedule:
Alexey Bataev142e1fc2014-06-20 09:44:06 +000011956 case OMPC_ordered:
Alexey Bataev236070f2014-06-20 11:19:47 +000011957 case OMPC_nowait:
Alexey Bataev7aea99a2014-07-17 12:19:31 +000011958 case OMPC_untied:
Alexey Bataev74ba3a52014-07-17 12:47:03 +000011959 case OMPC_mergeable:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011960 case OMPC_threadprivate:
Alexey Bataevf98b00c2014-07-23 02:27:21 +000011961 case OMPC_read:
Alexey Bataevdea47612014-07-23 07:46:59 +000011962 case OMPC_write:
Alexey Bataev67a4f222014-07-23 10:25:33 +000011963 case OMPC_update:
Alexey Bataev459dec02014-07-24 06:46:57 +000011964 case OMPC_capture:
Alexey Bataev82bad8b2014-07-24 08:55:34 +000011965 case OMPC_seq_cst:
Michael Wonge710d542015-08-07 16:16:36 +000011966 case OMPC_device:
Alexey Bataev346265e2015-09-25 10:37:12 +000011967 case OMPC_threads:
Alexey Bataevd14d1e62015-09-28 06:39:35 +000011968 case OMPC_simd:
Kelvin Li099bb8c2015-11-24 20:50:12 +000011969 case OMPC_num_teams:
Kelvin Lia15fb1a2015-11-27 18:47:36 +000011970 case OMPC_thread_limit:
Alexey Bataeva0569352015-12-01 10:17:31 +000011971 case OMPC_priority:
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000011972 case OMPC_grainsize:
Alexey Bataevb825de12015-12-07 10:51:44 +000011973 case OMPC_nogroup:
Alexey Bataev382967a2015-12-08 12:06:20 +000011974 case OMPC_num_tasks:
Alexey Bataev28c75412015-12-15 08:19:24 +000011975 case OMPC_hint:
Carlo Bertollib4adf552016-01-15 18:50:31 +000011976 case OMPC_dist_schedule:
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000011977 case OMPC_defaultmap:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011978 case OMPC_unknown:
Alexey Bataeve48a5fc2016-04-12 05:28:34 +000011979 case OMPC_uniform:
Kelvin Li1408f912018-09-26 04:28:39 +000011980 case OMPC_unified_address:
Patrick Lyster4a370b92018-10-01 13:47:43 +000011981 case OMPC_unified_shared_memory:
Patrick Lyster6bdf63b2018-10-03 20:07:58 +000011982 case OMPC_reverse_offload:
Patrick Lyster3fe9e392018-10-11 14:41:10 +000011983 case OMPC_dynamic_allocators:
Patrick Lyster7a2a27c2018-11-02 12:18:11 +000011984 case OMPC_atomic_default_mem_order:
Alexey Bataev729e2422019-08-23 16:11:14 +000011985 case OMPC_device_type:
Alexey Bataevdba792c2019-09-23 18:13:31 +000011986 case OMPC_match:
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000011987 llvm_unreachable("Clause is not allowed.");
11988 }
11989 return Res;
11990}
11991
Alexey Bataev90c228f2016-02-08 09:29:13 +000011992ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
Alexey Bataev61205072016-03-02 04:57:40 +000011993 ExprObjectKind OK, SourceLocation Loc) {
Alexey Bataev90c228f2016-02-08 09:29:13 +000011994 ExprResult Res = BuildDeclRefExpr(
11995 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
11996 if (!Res.isUsable())
11997 return ExprError();
11998 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
11999 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
12000 if (!Res.isUsable())
12001 return ExprError();
12002 }
12003 if (VK != VK_LValue && Res.get()->isGLValue()) {
12004 Res = DefaultLvalueConversion(Res.get());
12005 if (!Res.isUsable())
12006 return ExprError();
12007 }
12008 return Res;
12009}
12010
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012011OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
12012 SourceLocation StartLoc,
12013 SourceLocation LParenLoc,
12014 SourceLocation EndLoc) {
12015 SmallVector<Expr *, 8> Vars;
Alexey Bataev03b340a2014-10-21 03:16:40 +000012016 SmallVector<Expr *, 8> PrivateCopies;
Alexey Bataeve3727102018-04-18 15:57:46 +000012017 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000012018 assert(RefExpr && "NULL expr in OpenMP private clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000012019 SourceLocation ELoc;
12020 SourceRange ERange;
12021 Expr *SimpleRefExpr = RefExpr;
12022 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevd985eda2016-02-10 11:29:16 +000012023 if (Res.second) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012024 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000012025 Vars.push_back(RefExpr);
Alexey Bataev03b340a2014-10-21 03:16:40 +000012026 PrivateCopies.push_back(nullptr);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012027 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000012028 ValueDecl *D = Res.first;
12029 if (!D)
12030 continue;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012031
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012032 QualType Type = D->getType();
12033 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012034
12035 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12036 // A variable that appears in a private clause must not have an incomplete
12037 // type or a reference type.
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012038 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012039 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012040 Type = Type.getNonReferenceType();
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012041
Joel E. Dennye6234d1422019-01-04 22:11:31 +000012042 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12043 // A variable that is privatized must not have a const-qualified type
12044 // unless it is of class type with a mutable member. This restriction does
12045 // not apply to the firstprivate clause.
12046 //
12047 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
12048 // A variable that appears in a private clause must not have a
12049 // const-qualified type unless it is of class type with a mutable member.
Joel E. Dennyd2649292019-01-04 22:11:56 +000012050 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
Joel E. Dennye6234d1422019-01-04 22:11:31 +000012051 continue;
12052
Alexey Bataev758e55e2013-09-06 18:03:48 +000012053 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12054 // in a Construct]
12055 // Variables with the predetermined data-sharing attributes may not be
12056 // listed in data-sharing attributes clauses, except for the cases
12057 // listed below. For these exceptions only, listing a predetermined
12058 // variable in a data-sharing attribute clause is allowed and overrides
12059 // the variable's predetermined data-sharing attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +000012060 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012061 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
Alexey Bataeved09d242014-05-28 05:53:51 +000012062 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12063 << getOpenMPClauseName(OMPC_private);
Alexey Bataeve3727102018-04-18 15:57:46 +000012064 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012065 continue;
12066 }
12067
Alexey Bataeve3727102018-04-18 15:57:46 +000012068 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012069 // Variably modified types are not supported for tasks.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000012070 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
Kelvin Libf594a52016-12-17 05:48:59 +000012071 isOpenMPTaskingDirective(CurrDir)) {
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012072 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12073 << getOpenMPClauseName(OMPC_private) << Type
Kelvin Libf594a52016-12-17 05:48:59 +000012074 << getOpenMPDirectiveName(CurrDir);
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012075 bool IsDecl =
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012076 !VD ||
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012077 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012078 Diag(D->getLocation(),
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012079 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012080 << D;
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012081 continue;
12082 }
12083
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012084 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12085 // A list item cannot appear in both a map clause and a data-sharing
12086 // attribute clause on the same construct
Joel E. Denny7d5bc552019-08-22 03:34:30 +000012087 //
12088 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12089 // A list item cannot appear in both a map clause and a data-sharing
12090 // attribute clause on the same construct unless the construct is a
12091 // combined construct.
12092 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
12093 CurrDir == OMPD_target) {
Samuel Antao6890b092016-07-28 14:25:09 +000012094 OpenMPClauseKind ConflictKind;
Samuel Antao90927002016-04-26 14:54:23 +000012095 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000012096 VD, /*CurrentRegionOnly=*/true,
Samuel Antao6890b092016-07-28 14:25:09 +000012097 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
12098 OpenMPClauseKind WhereFoundClauseKind) -> bool {
12099 ConflictKind = WhereFoundClauseKind;
12100 return true;
12101 })) {
12102 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012103 << getOpenMPClauseName(OMPC_private)
Samuel Antao6890b092016-07-28 14:25:09 +000012104 << getOpenMPClauseName(ConflictKind)
Kelvin Libf594a52016-12-17 05:48:59 +000012105 << getOpenMPDirectiveName(CurrDir);
Alexey Bataeve3727102018-04-18 15:57:46 +000012106 reportOriginalDsa(*this, DSAStack, D, DVar);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012107 continue;
12108 }
12109 }
12110
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012111 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
12112 // A variable of class type (or array thereof) that appears in a private
12113 // clause requires an accessible, unambiguous default constructor for the
12114 // class type.
Alexey Bataev03b340a2014-10-21 03:16:40 +000012115 // Generate helper private variable and initialize it with the default
12116 // value. The address of the original variable is replaced by the address of
12117 // the new private variable in CodeGen. This new variable is not added to
12118 // IdResolver, so the code in the OpenMP region uses original variable for
12119 // proper diagnostics.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012120 Type = Type.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012121 VarDecl *VDPrivate =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000012122 buildVarDecl(*this, ELoc, Type, D->getName(),
12123 D->hasAttrs() ? &D->getAttrs() : nullptr,
12124 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Richard Smith3beb7c62017-01-12 02:27:38 +000012125 ActOnUninitializedDecl(VDPrivate);
Alexey Bataev03b340a2014-10-21 03:16:40 +000012126 if (VDPrivate->isInvalidDecl())
12127 continue;
Alexey Bataeve3727102018-04-18 15:57:46 +000012128 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000012129 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
Alexey Bataev03b340a2014-10-21 03:16:40 +000012130
Alexey Bataev90c228f2016-02-08 09:29:13 +000012131 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012132 if (!VD && !CurContext->isDependentContext())
Alexey Bataev61205072016-03-02 04:57:40 +000012133 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataev90c228f2016-02-08 09:29:13 +000012134 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012135 Vars.push_back((VD || CurContext->isDependentContext())
12136 ? RefExpr->IgnoreParens()
12137 : Ref);
Alexey Bataev03b340a2014-10-21 03:16:40 +000012138 PrivateCopies.push_back(VDPrivateRefExpr);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012139 }
12140
Alexey Bataeved09d242014-05-28 05:53:51 +000012141 if (Vars.empty())
12142 return nullptr;
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012143
Alexey Bataev03b340a2014-10-21 03:16:40 +000012144 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
12145 PrivateCopies);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +000012146}
12147
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012148namespace {
12149class DiagsUninitializedSeveretyRAII {
12150private:
12151 DiagnosticsEngine &Diags;
12152 SourceLocation SavedLoc;
Alexey Bataeve3727102018-04-18 15:57:46 +000012153 bool IsIgnored = false;
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012154
12155public:
12156 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
12157 bool IsIgnored)
12158 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
12159 if (!IsIgnored) {
12160 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
12161 /*Map*/ diag::Severity::Ignored, Loc);
12162 }
12163 }
12164 ~DiagsUninitializedSeveretyRAII() {
12165 if (!IsIgnored)
12166 Diags.popMappings(SavedLoc);
12167 }
12168};
Alexander Kornienkoab9db512015-06-22 23:07:51 +000012169}
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012170
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012171OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
12172 SourceLocation StartLoc,
12173 SourceLocation LParenLoc,
12174 SourceLocation EndLoc) {
12175 SmallVector<Expr *, 8> Vars;
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012176 SmallVector<Expr *, 8> PrivateCopies;
12177 SmallVector<Expr *, 8> Inits;
Alexey Bataev417089f2016-02-17 13:19:37 +000012178 SmallVector<Decl *, 4> ExprCaptures;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012179 bool IsImplicitClause =
12180 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
Alexey Bataeve3727102018-04-18 15:57:46 +000012181 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012182
Alexey Bataeve3727102018-04-18 15:57:46 +000012183 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000012184 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000012185 SourceLocation ELoc;
12186 SourceRange ERange;
12187 Expr *SimpleRefExpr = RefExpr;
12188 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevd985eda2016-02-10 11:29:16 +000012189 if (Res.second) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012190 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000012191 Vars.push_back(RefExpr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012192 PrivateCopies.push_back(nullptr);
12193 Inits.push_back(nullptr);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012194 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000012195 ValueDecl *D = Res.first;
12196 if (!D)
12197 continue;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012198
Alexey Bataev60da77e2016-02-29 05:54:20 +000012199 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
Alexey Bataevd985eda2016-02-10 11:29:16 +000012200 QualType Type = D->getType();
12201 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012202
12203 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12204 // A variable that appears in a private clause must not have an incomplete
12205 // type or a reference type.
12206 if (RequireCompleteType(ELoc, Type,
Alexey Bataevd985eda2016-02-10 11:29:16 +000012207 diag::err_omp_firstprivate_incomplete_type))
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012208 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012209 Type = Type.getNonReferenceType();
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012210
12211 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
12212 // A variable of class type (or array thereof) that appears in a private
Alexey Bataev23b69422014-06-18 07:08:49 +000012213 // clause requires an accessible, unambiguous copy constructor for the
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012214 // class type.
Alexey Bataeve3727102018-04-18 15:57:46 +000012215 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012216
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012217 // If an implicit firstprivate variable found it was checked already.
Alexey Bataev005248a2016-02-25 05:25:57 +000012218 DSAStackTy::DSAVarData TopDVar;
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012219 if (!IsImplicitClause) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012220 DSAStackTy::DSAVarData DVar =
12221 DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataev005248a2016-02-25 05:25:57 +000012222 TopDVar = DVar;
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012223 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012224 bool IsConstant = ElemType.isConstant(Context);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012225 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
12226 // A list item that specifies a given variable may not appear in more
12227 // than one clause on the same directive, except that a variable may be
12228 // specified in both firstprivate and lastprivate clauses.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012229 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
12230 // A list item may appear in a firstprivate or lastprivate clause but not
12231 // both.
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012232 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
Alexey Bataevb358f992017-12-01 17:40:15 +000012233 (isOpenMPDistributeDirective(CurrDir) ||
12234 DVar.CKind != OMPC_lastprivate) &&
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012235 DVar.RefExpr) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012236 Diag(ELoc, diag::err_omp_wrong_dsa)
Alexey Bataeved09d242014-05-28 05:53:51 +000012237 << getOpenMPClauseName(DVar.CKind)
12238 << getOpenMPClauseName(OMPC_firstprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000012239 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012240 continue;
12241 }
12242
12243 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12244 // in a Construct]
12245 // Variables with the predetermined data-sharing attributes may not be
12246 // listed in data-sharing attributes clauses, except for the cases
12247 // listed below. For these exceptions only, listing a predetermined
12248 // variable in a data-sharing attribute clause is allowed and overrides
12249 // the variable's predetermined data-sharing attributes.
12250 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12251 // in a Construct, C/C++, p.2]
12252 // Variables with const-qualified type having no mutable member may be
12253 // listed in a firstprivate clause, even if they are static data members.
Alexey Bataevd985eda2016-02-10 11:29:16 +000012254 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012255 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
12256 Diag(ELoc, diag::err_omp_wrong_dsa)
Alexey Bataeved09d242014-05-28 05:53:51 +000012257 << getOpenMPClauseName(DVar.CKind)
12258 << getOpenMPClauseName(OMPC_firstprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000012259 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012260 continue;
12261 }
12262
12263 // OpenMP [2.9.3.4, Restrictions, p.2]
12264 // A list item that is private within a parallel region must not appear
12265 // in a firstprivate clause on a worksharing construct if any of the
12266 // worksharing regions arising from the worksharing construct ever bind
12267 // to any of the parallel regions arising from the parallel construct.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012268 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12269 // A list item that is private within a teams region must not appear in a
12270 // firstprivate clause on a distribute construct if any of the distribute
12271 // regions arising from the distribute construct ever bind to any of the
12272 // teams regions arising from the teams construct.
12273 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12274 // A list item that appears in a reduction clause of a teams construct
12275 // must not appear in a firstprivate clause on a distribute construct if
12276 // any of the distribute regions arising from the distribute construct
12277 // ever bind to any of the teams regions arising from the teams construct.
12278 if ((isOpenMPWorksharingDirective(CurrDir) ||
12279 isOpenMPDistributeDirective(CurrDir)) &&
Kelvin Li579e41c2016-11-30 23:51:03 +000012280 !isOpenMPParallelDirective(CurrDir) &&
12281 !isOpenMPTeamsDirective(CurrDir)) {
Alexey Bataevd985eda2016-02-10 11:29:16 +000012282 DVar = DSAStack->getImplicitDSA(D, true);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012283 if (DVar.CKind != OMPC_shared &&
12284 (isOpenMPParallelDirective(DVar.DKind) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012285 isOpenMPTeamsDirective(DVar.DKind) ||
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012286 DVar.DKind == OMPD_unknown)) {
Alexey Bataevf29276e2014-06-18 04:14:57 +000012287 Diag(ELoc, diag::err_omp_required_access)
12288 << getOpenMPClauseName(OMPC_firstprivate)
12289 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000012290 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevf29276e2014-06-18 04:14:57 +000012291 continue;
12292 }
12293 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012294 // OpenMP [2.9.3.4, Restrictions, p.3]
12295 // A list item that appears in a reduction clause of a parallel construct
12296 // must not appear in a firstprivate clause on a worksharing or task
12297 // construct if any of the worksharing or task regions arising from the
12298 // worksharing or task construct ever bind to any of the parallel regions
12299 // arising from the parallel construct.
12300 // OpenMP [2.9.3.4, Restrictions, p.4]
12301 // A list item that appears in a reduction clause in worksharing
12302 // construct must not appear in a firstprivate clause in a task construct
12303 // encountered during execution of any of the worksharing regions arising
12304 // from the worksharing construct.
Alexey Bataev35aaee62016-04-13 13:36:48 +000012305 if (isOpenMPTaskingDirective(CurrDir)) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000012306 DVar = DSAStack->hasInnermostDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +000012307 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
12308 [](OpenMPDirectiveKind K) {
Alexey Bataev7ace49d2016-05-17 08:55:33 +000012309 return isOpenMPParallelDirective(K) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012310 isOpenMPWorksharingDirective(K) ||
12311 isOpenMPTeamsDirective(K);
Alexey Bataev7ace49d2016-05-17 08:55:33 +000012312 },
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012313 /*FromParent=*/true);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012314 if (DVar.CKind == OMPC_reduction &&
12315 (isOpenMPParallelDirective(DVar.DKind) ||
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012316 isOpenMPWorksharingDirective(DVar.DKind) ||
12317 isOpenMPTeamsDirective(DVar.DKind))) {
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012318 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
12319 << getOpenMPDirectiveName(DVar.DKind);
Alexey Bataeve3727102018-04-18 15:57:46 +000012320 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +000012321 continue;
12322 }
12323 }
Carlo Bertolli6200a3d2015-12-14 14:51:25 +000012324
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012325 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12326 // A list item cannot appear in both a map clause and a data-sharing
12327 // attribute clause on the same construct
Joel E. Denny7d5bc552019-08-22 03:34:30 +000012328 //
12329 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12330 // A list item cannot appear in both a map clause and a data-sharing
12331 // attribute clause on the same construct unless the construct is a
12332 // combined construct.
12333 if ((LangOpts.OpenMP <= 45 &&
12334 isOpenMPTargetExecutionDirective(CurrDir)) ||
12335 CurrDir == OMPD_target) {
Samuel Antao6890b092016-07-28 14:25:09 +000012336 OpenMPClauseKind ConflictKind;
Samuel Antao90927002016-04-26 14:54:23 +000012337 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000012338 VD, /*CurrentRegionOnly=*/true,
Alexey Bataeve3727102018-04-18 15:57:46 +000012339 [&ConflictKind](
12340 OMPClauseMappableExprCommon::MappableExprComponentListRef,
12341 OpenMPClauseKind WhereFoundClauseKind) {
Samuel Antao6890b092016-07-28 14:25:09 +000012342 ConflictKind = WhereFoundClauseKind;
12343 return true;
12344 })) {
12345 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012346 << getOpenMPClauseName(OMPC_firstprivate)
Samuel Antao6890b092016-07-28 14:25:09 +000012347 << getOpenMPClauseName(ConflictKind)
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012348 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000012349 reportOriginalDsa(*this, DSAStack, D, DVar);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000012350 continue;
12351 }
12352 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012353 }
12354
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012355 // Variably modified types are not supported for tasks.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000012356 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
Alexey Bataev35aaee62016-04-13 13:36:48 +000012357 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012358 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12359 << getOpenMPClauseName(OMPC_firstprivate) << Type
12360 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12361 bool IsDecl =
Alexey Bataevd985eda2016-02-10 11:29:16 +000012362 !VD ||
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012363 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataevd985eda2016-02-10 11:29:16 +000012364 Diag(D->getLocation(),
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012365 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataevd985eda2016-02-10 11:29:16 +000012366 << D;
Alexey Bataevccb59ec2015-05-19 08:44:56 +000012367 continue;
12368 }
12369
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012370 Type = Type.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012371 VarDecl *VDPrivate =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000012372 buildVarDecl(*this, ELoc, Type, D->getName(),
12373 D->hasAttrs() ? &D->getAttrs() : nullptr,
12374 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012375 // Generate helper private variable and initialize it with the value of the
12376 // original variable. The address of the original variable is replaced by
12377 // the address of the new private variable in the CodeGen. This new variable
12378 // is not added to IdResolver, so the code in the OpenMP region uses
12379 // original variable for proper diagnostics and variable capturing.
12380 Expr *VDInitRefExpr = nullptr;
12381 // For arrays generate initializer for single element and replace it by the
12382 // original array element in CodeGen.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012383 if (Type->isArrayType()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012384 VarDecl *VDInit =
Alexey Bataevd985eda2016-02-10 11:29:16 +000012385 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012386 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
Alexey Bataeve3727102018-04-18 15:57:46 +000012387 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
Alexey Bataevf120c0d2015-05-19 07:46:42 +000012388 ElemType = ElemType.getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012389 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
12390 ".firstprivate.temp");
Alexey Bataev69c62a92015-04-15 04:52:20 +000012391 InitializedEntity Entity =
12392 InitializedEntity::InitializeVariable(VDInitTemp);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012393 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
12394
12395 InitializationSequence InitSeq(*this, Entity, Kind, Init);
12396 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
12397 if (Result.isInvalid())
12398 VDPrivate->setInvalidDecl();
12399 else
12400 VDPrivate->setInit(Result.getAs<Expr>());
Alexey Bataevf24e7b12015-10-08 09:10:53 +000012401 // Remove temp variable declaration.
12402 Context.Deallocate(VDInitTemp);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012403 } else {
Alexey Bataeve3727102018-04-18 15:57:46 +000012404 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
12405 ".firstprivate.temp");
Alexey Bataevd985eda2016-02-10 11:29:16 +000012406 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12407 RefExpr->getExprLoc());
Alexey Bataev69c62a92015-04-15 04:52:20 +000012408 AddInitializerToDecl(VDPrivate,
12409 DefaultLvalueConversion(VDInitRefExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000012410 /*DirectInit=*/false);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012411 }
12412 if (VDPrivate->isInvalidDecl()) {
12413 if (IsImplicitClause) {
Alexey Bataevd985eda2016-02-10 11:29:16 +000012414 Diag(RefExpr->getExprLoc(),
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012415 diag::note_omp_task_predetermined_firstprivate_here);
12416 }
12417 continue;
12418 }
12419 CurContext->addDecl(VDPrivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000012420 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Alexey Bataevd985eda2016-02-10 11:29:16 +000012421 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
12422 RefExpr->getExprLoc());
12423 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012424 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012425 if (TopDVar.CKind == OMPC_lastprivate) {
Alexey Bataev005248a2016-02-25 05:25:57 +000012426 Ref = TopDVar.PrivateCopy;
Alexey Bataeve3727102018-04-18 15:57:46 +000012427 } else {
Alexey Bataev61205072016-03-02 04:57:40 +000012428 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
Alexey Bataeve3727102018-04-18 15:57:46 +000012429 if (!isOpenMPCapturedDecl(D))
Alexey Bataev005248a2016-02-25 05:25:57 +000012430 ExprCaptures.push_back(Ref->getDecl());
12431 }
Alexey Bataev417089f2016-02-17 13:19:37 +000012432 }
Alexey Bataevd985eda2016-02-10 11:29:16 +000012433 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012434 Vars.push_back((VD || CurContext->isDependentContext())
12435 ? RefExpr->IgnoreParens()
12436 : Ref);
Alexey Bataev4a5bb772014-10-08 14:01:46 +000012437 PrivateCopies.push_back(VDPrivateRefExpr);
12438 Inits.push_back(VDInitRefExpr);
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012439 }
12440
Alexey Bataeved09d242014-05-28 05:53:51 +000012441 if (Vars.empty())
12442 return nullptr;
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012443
12444 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataev5a3af132016-03-29 08:58:54 +000012445 Vars, PrivateCopies, Inits,
12446 buildPreInits(Context, ExprCaptures));
Alexey Bataevd5af8e42013-10-01 05:32:34 +000012447}
12448
Alexander Musman1bb328c2014-06-04 13:06:39 +000012449OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
12450 SourceLocation StartLoc,
12451 SourceLocation LParenLoc,
12452 SourceLocation EndLoc) {
12453 SmallVector<Expr *, 8> Vars;
Alexey Bataev38e89532015-04-16 04:54:05 +000012454 SmallVector<Expr *, 8> SrcExprs;
12455 SmallVector<Expr *, 8> DstExprs;
12456 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataev005248a2016-02-25 05:25:57 +000012457 SmallVector<Decl *, 4> ExprCaptures;
12458 SmallVector<Expr *, 4> ExprPostUpdates;
Alexey Bataeve3727102018-04-18 15:57:46 +000012459 for (Expr *RefExpr : VarList) {
Alexander Musman1bb328c2014-06-04 13:06:39 +000012460 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000012461 SourceLocation ELoc;
12462 SourceRange ERange;
12463 Expr *SimpleRefExpr = RefExpr;
12464 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev74caaf22016-02-20 04:09:36 +000012465 if (Res.second) {
Alexander Musman1bb328c2014-06-04 13:06:39 +000012466 // It will be analyzed later.
12467 Vars.push_back(RefExpr);
Alexey Bataev38e89532015-04-16 04:54:05 +000012468 SrcExprs.push_back(nullptr);
12469 DstExprs.push_back(nullptr);
12470 AssignmentOps.push_back(nullptr);
Alexander Musman1bb328c2014-06-04 13:06:39 +000012471 }
Alexey Bataev74caaf22016-02-20 04:09:36 +000012472 ValueDecl *D = Res.first;
12473 if (!D)
12474 continue;
Alexander Musman1bb328c2014-06-04 13:06:39 +000012475
Alexey Bataev74caaf22016-02-20 04:09:36 +000012476 QualType Type = D->getType();
12477 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musman1bb328c2014-06-04 13:06:39 +000012478
12479 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
12480 // A variable that appears in a lastprivate clause must not have an
12481 // incomplete type or a reference type.
12482 if (RequireCompleteType(ELoc, Type,
Alexey Bataev74caaf22016-02-20 04:09:36 +000012483 diag::err_omp_lastprivate_incomplete_type))
Alexander Musman1bb328c2014-06-04 13:06:39 +000012484 continue;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000012485 Type = Type.getNonReferenceType();
Alexander Musman1bb328c2014-06-04 13:06:39 +000012486
Joel E. Dennye6234d1422019-01-04 22:11:31 +000012487 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12488 // A variable that is privatized must not have a const-qualified type
12489 // unless it is of class type with a mutable member. This restriction does
12490 // not apply to the firstprivate clause.
12491 //
12492 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
12493 // A variable that appears in a lastprivate clause must not have a
12494 // const-qualified type unless it is of class type with a mutable member.
Joel E. Dennyd2649292019-01-04 22:11:56 +000012495 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
Joel E. Dennye6234d1422019-01-04 22:11:31 +000012496 continue;
12497
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012498 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
Alexander Musman1bb328c2014-06-04 13:06:39 +000012499 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
12500 // in a Construct]
12501 // Variables with the predetermined data-sharing attributes may not be
12502 // listed in data-sharing attributes clauses, except for the cases
12503 // listed below.
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012504 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
12505 // A list item may appear in a firstprivate or lastprivate clause but not
12506 // both.
Alexey Bataeve3727102018-04-18 15:57:46 +000012507 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexander Musman1bb328c2014-06-04 13:06:39 +000012508 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
Alexey Bataevb358f992017-12-01 17:40:15 +000012509 (isOpenMPDistributeDirective(CurrDir) ||
12510 DVar.CKind != OMPC_firstprivate) &&
Alexander Musman1bb328c2014-06-04 13:06:39 +000012511 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
12512 Diag(ELoc, diag::err_omp_wrong_dsa)
12513 << getOpenMPClauseName(DVar.CKind)
12514 << getOpenMPClauseName(OMPC_lastprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000012515 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexander Musman1bb328c2014-06-04 13:06:39 +000012516 continue;
12517 }
12518
Alexey Bataevf29276e2014-06-18 04:14:57 +000012519 // OpenMP [2.14.3.5, Restrictions, p.2]
12520 // A list item that is private within a parallel region, or that appears in
12521 // the reduction clause of a parallel construct, must not appear in a
12522 // lastprivate clause on a worksharing construct if any of the corresponding
12523 // worksharing regions ever binds to any of the corresponding parallel
12524 // regions.
Alexey Bataev39f915b82015-05-08 10:41:21 +000012525 DSAStackTy::DSAVarData TopDVar = DVar;
Alexey Bataev549210e2014-06-24 04:39:47 +000012526 if (isOpenMPWorksharingDirective(CurrDir) &&
Kelvin Li579e41c2016-11-30 23:51:03 +000012527 !isOpenMPParallelDirective(CurrDir) &&
12528 !isOpenMPTeamsDirective(CurrDir)) {
Alexey Bataev74caaf22016-02-20 04:09:36 +000012529 DVar = DSAStack->getImplicitDSA(D, true);
Alexey Bataevf29276e2014-06-18 04:14:57 +000012530 if (DVar.CKind != OMPC_shared) {
12531 Diag(ELoc, diag::err_omp_required_access)
12532 << getOpenMPClauseName(OMPC_lastprivate)
12533 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000012534 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevf29276e2014-06-18 04:14:57 +000012535 continue;
12536 }
12537 }
Alexey Bataev74caaf22016-02-20 04:09:36 +000012538
Alexander Musman1bb328c2014-06-04 13:06:39 +000012539 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
Alexey Bataevf29276e2014-06-18 04:14:57 +000012540 // A variable of class type (or array thereof) that appears in a
12541 // lastprivate clause requires an accessible, unambiguous default
12542 // constructor for the class type, unless the list item is also specified
12543 // in a firstprivate clause.
Alexander Musman1bb328c2014-06-04 13:06:39 +000012544 // A variable of class type (or array thereof) that appears in a
12545 // lastprivate clause requires an accessible, unambiguous copy assignment
12546 // operator for the class type.
Alexey Bataev38e89532015-04-16 04:54:05 +000012547 Type = Context.getBaseElementType(Type).getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000012548 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
12549 Type.getUnqualifiedType(), ".lastprivate.src",
12550 D->hasAttrs() ? &D->getAttrs() : nullptr);
12551 DeclRefExpr *PseudoSrcExpr =
Alexey Bataev74caaf22016-02-20 04:09:36 +000012552 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
Alexey Bataeve3727102018-04-18 15:57:46 +000012553 VarDecl *DstVD =
Alexey Bataev60da77e2016-02-29 05:54:20 +000012554 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
Alexey Bataev74caaf22016-02-20 04:09:36 +000012555 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000012556 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
Alexey Bataev38e89532015-04-16 04:54:05 +000012557 // For arrays generate assignment operation for single element and replace
12558 // it by the original array element in CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000012559 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
12560 PseudoDstExpr, PseudoSrcExpr);
Alexey Bataev38e89532015-04-16 04:54:05 +000012561 if (AssignmentOp.isInvalid())
12562 continue;
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000012563 AssignmentOp =
12564 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataev38e89532015-04-16 04:54:05 +000012565 if (AssignmentOp.isInvalid())
12566 continue;
Alexander Musman1bb328c2014-06-04 13:06:39 +000012567
Alexey Bataev74caaf22016-02-20 04:09:36 +000012568 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012569 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012570 if (TopDVar.CKind == OMPC_firstprivate) {
Alexey Bataev005248a2016-02-25 05:25:57 +000012571 Ref = TopDVar.PrivateCopy;
Alexey Bataeve3727102018-04-18 15:57:46 +000012572 } else {
Alexey Bataev61205072016-03-02 04:57:40 +000012573 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000012574 if (!isOpenMPCapturedDecl(D))
Alexey Bataev005248a2016-02-25 05:25:57 +000012575 ExprCaptures.push_back(Ref->getDecl());
12576 }
12577 if (TopDVar.CKind == OMPC_firstprivate ||
Alexey Bataeve3727102018-04-18 15:57:46 +000012578 (!isOpenMPCapturedDecl(D) &&
Alexey Bataev2bbf7212016-03-03 03:52:24 +000012579 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
Alexey Bataev005248a2016-02-25 05:25:57 +000012580 ExprResult RefRes = DefaultLvalueConversion(Ref);
12581 if (!RefRes.isUsable())
12582 continue;
12583 ExprResult PostUpdateRes =
Alexey Bataev60da77e2016-02-29 05:54:20 +000012584 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
12585 RefRes.get());
Alexey Bataev005248a2016-02-25 05:25:57 +000012586 if (!PostUpdateRes.isUsable())
12587 continue;
Alexey Bataev78849fb2016-03-09 09:49:00 +000012588 ExprPostUpdates.push_back(
12589 IgnoredValueConversions(PostUpdateRes.get()).get());
Alexey Bataev005248a2016-02-25 05:25:57 +000012590 }
12591 }
Alexey Bataev7ace49d2016-05-17 08:55:33 +000012592 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012593 Vars.push_back((VD || CurContext->isDependentContext())
12594 ? RefExpr->IgnoreParens()
12595 : Ref);
Alexey Bataev38e89532015-04-16 04:54:05 +000012596 SrcExprs.push_back(PseudoSrcExpr);
12597 DstExprs.push_back(PseudoDstExpr);
12598 AssignmentOps.push_back(AssignmentOp.get());
Alexander Musman1bb328c2014-06-04 13:06:39 +000012599 }
12600
12601 if (Vars.empty())
12602 return nullptr;
12603
12604 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataev005248a2016-02-25 05:25:57 +000012605 Vars, SrcExprs, DstExprs, AssignmentOps,
Alexey Bataev5a3af132016-03-29 08:58:54 +000012606 buildPreInits(Context, ExprCaptures),
12607 buildPostUpdate(*this, ExprPostUpdates));
Alexander Musman1bb328c2014-06-04 13:06:39 +000012608}
12609
Alexey Bataev758e55e2013-09-06 18:03:48 +000012610OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
12611 SourceLocation StartLoc,
12612 SourceLocation LParenLoc,
12613 SourceLocation EndLoc) {
12614 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +000012615 for (Expr *RefExpr : VarList) {
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012616 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
Alexey Bataev60da77e2016-02-29 05:54:20 +000012617 SourceLocation ELoc;
12618 SourceRange ERange;
12619 Expr *SimpleRefExpr = RefExpr;
12620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012621 if (Res.second) {
Alexey Bataev758e55e2013-09-06 18:03:48 +000012622 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000012623 Vars.push_back(RefExpr);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012624 }
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012625 ValueDecl *D = Res.first;
12626 if (!D)
12627 continue;
Alexey Bataev758e55e2013-09-06 18:03:48 +000012628
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012629 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012630 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12631 // in a Construct]
12632 // Variables with the predetermined data-sharing attributes may not be
12633 // listed in data-sharing attributes clauses, except for the cases
12634 // listed below. For these exceptions only, listing a predetermined
12635 // variable in a data-sharing attribute clause is allowed and overrides
12636 // the variable's predetermined data-sharing attributes.
Alexey Bataeve3727102018-04-18 15:57:46 +000012637 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataeved09d242014-05-28 05:53:51 +000012638 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
12639 DVar.RefExpr) {
12640 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12641 << getOpenMPClauseName(OMPC_shared);
Alexey Bataeve3727102018-04-18 15:57:46 +000012642 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012643 continue;
12644 }
12645
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012646 DeclRefExpr *Ref = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000012647 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
Alexey Bataev61205072016-03-02 04:57:40 +000012648 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
Alexey Bataevb7a34b62016-02-25 03:59:29 +000012649 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000012650 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
12651 ? RefExpr->IgnoreParens()
12652 : Ref);
Alexey Bataev758e55e2013-09-06 18:03:48 +000012653 }
12654
Alexey Bataeved09d242014-05-28 05:53:51 +000012655 if (Vars.empty())
12656 return nullptr;
Alexey Bataev758e55e2013-09-06 18:03:48 +000012657
12658 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
12659}
12660
Alexey Bataevc5e02582014-06-16 07:08:35 +000012661namespace {
12662class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
12663 DSAStackTy *Stack;
12664
12665public:
12666 bool VisitDeclRefExpr(DeclRefExpr *E) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012667 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
12668 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
Alexey Bataevc5e02582014-06-16 07:08:35 +000012669 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
12670 return false;
12671 if (DVar.CKind != OMPC_unknown)
12672 return true;
Alexey Bataev7ace49d2016-05-17 08:55:33 +000012673 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
Alexey Bataeve3727102018-04-18 15:57:46 +000012674 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
Alexey Bataeveffbdf12017-07-21 17:24:30 +000012675 /*FromParent=*/true);
Alexey Bataeve3727102018-04-18 15:57:46 +000012676 return DVarPrivate.CKind != OMPC_unknown;
Alexey Bataevc5e02582014-06-16 07:08:35 +000012677 }
12678 return false;
12679 }
12680 bool VisitStmt(Stmt *S) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012681 for (Stmt *Child : S->children()) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000012682 if (Child && Visit(Child))
12683 return true;
12684 }
12685 return false;
12686 }
Alexey Bataev23b69422014-06-18 07:08:49 +000012687 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
Alexey Bataevc5e02582014-06-16 07:08:35 +000012688};
Alexey Bataev23b69422014-06-18 07:08:49 +000012689} // namespace
Alexey Bataevc5e02582014-06-16 07:08:35 +000012690
Alexey Bataev60da77e2016-02-29 05:54:20 +000012691namespace {
12692// Transform MemberExpression for specified FieldDecl of current class to
12693// DeclRefExpr to specified OMPCapturedExprDecl.
12694class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
12695 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
Alexey Bataeve3727102018-04-18 15:57:46 +000012696 ValueDecl *Field = nullptr;
12697 DeclRefExpr *CapturedExpr = nullptr;
Alexey Bataev60da77e2016-02-29 05:54:20 +000012698
12699public:
12700 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
12701 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
12702
12703 ExprResult TransformMemberExpr(MemberExpr *E) {
12704 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
12705 E->getMemberDecl() == Field) {
Alexey Bataev61205072016-03-02 04:57:40 +000012706 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
Alexey Bataev60da77e2016-02-29 05:54:20 +000012707 return CapturedExpr;
12708 }
12709 return BaseTransform::TransformMemberExpr(E);
12710 }
12711 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
12712};
12713} // namespace
12714
Alexey Bataev97d18bf2018-04-11 19:21:00 +000012715template <typename T, typename U>
Michael Kruse4304e9d2019-02-19 16:38:20 +000012716static T filterLookupForUDReductionAndMapper(
12717 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012718 for (U &Set : Lookups) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012719 for (auto *D : Set) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012720 if (T Res = Gen(cast<ValueDecl>(D)))
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012721 return Res;
12722 }
12723 }
12724 return T();
12725}
12726
Alexey Bataev43b90b72018-09-12 16:31:59 +000012727static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
12728 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
12729
12730 for (auto RD : D->redecls()) {
12731 // Don't bother with extra checks if we already know this one isn't visible.
12732 if (RD == D)
12733 continue;
12734
12735 auto ND = cast<NamedDecl>(RD);
12736 if (LookupResult::isVisible(SemaRef, ND))
12737 return ND;
12738 }
12739
12740 return nullptr;
12741}
12742
12743static void
Michael Kruse4304e9d2019-02-19 16:38:20 +000012744argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
Alexey Bataev43b90b72018-09-12 16:31:59 +000012745 SourceLocation Loc, QualType Ty,
12746 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
12747 // Find all of the associated namespaces and classes based on the
12748 // arguments we have.
12749 Sema::AssociatedNamespaceSet AssociatedNamespaces;
12750 Sema::AssociatedClassSet AssociatedClasses;
12751 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
12752 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
12753 AssociatedClasses);
12754
12755 // C++ [basic.lookup.argdep]p3:
12756 // Let X be the lookup set produced by unqualified lookup (3.4.1)
12757 // and let Y be the lookup set produced by argument dependent
12758 // lookup (defined as follows). If X contains [...] then Y is
12759 // empty. Otherwise Y is the set of declarations found in the
12760 // namespaces associated with the argument types as described
12761 // below. The set of declarations found by the lookup of the name
12762 // is the union of X and Y.
12763 //
12764 // Here, we compute Y and add its members to the overloaded
12765 // candidate set.
12766 for (auto *NS : AssociatedNamespaces) {
12767 // When considering an associated namespace, the lookup is the
12768 // same as the lookup performed when the associated namespace is
12769 // used as a qualifier (3.4.3.2) except that:
12770 //
12771 // -- Any using-directives in the associated namespace are
12772 // ignored.
12773 //
12774 // -- Any namespace-scope friend functions declared in
12775 // associated classes are visible within their respective
12776 // namespaces even if they are not visible during an ordinary
12777 // lookup (11.4).
Michael Kruse4304e9d2019-02-19 16:38:20 +000012778 DeclContext::lookup_result R = NS->lookup(Id.getName());
Alexey Bataev43b90b72018-09-12 16:31:59 +000012779 for (auto *D : R) {
12780 auto *Underlying = D;
12781 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
12782 Underlying = USD->getTargetDecl();
12783
Michael Kruse4304e9d2019-02-19 16:38:20 +000012784 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
12785 !isa<OMPDeclareMapperDecl>(Underlying))
Alexey Bataev43b90b72018-09-12 16:31:59 +000012786 continue;
12787
12788 if (!SemaRef.isVisible(D)) {
12789 D = findAcceptableDecl(SemaRef, D);
12790 if (!D)
12791 continue;
12792 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
12793 Underlying = USD->getTargetDecl();
12794 }
12795 Lookups.emplace_back();
12796 Lookups.back().addDecl(Underlying);
12797 }
12798 }
12799}
12800
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012801static ExprResult
12802buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
12803 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
12804 const DeclarationNameInfo &ReductionId, QualType Ty,
12805 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
12806 if (ReductionIdScopeSpec.isInvalid())
12807 return ExprError();
12808 SmallVector<UnresolvedSet<8>, 4> Lookups;
12809 if (S) {
12810 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
12811 Lookup.suppressDiagnostics();
12812 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000012813 NamedDecl *D = Lookup.getRepresentativeDecl();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012814 do {
12815 S = S->getParent();
12816 } while (S && !S->isDeclScope(D));
12817 if (S)
12818 S = S->getParent();
Alexey Bataev43b90b72018-09-12 16:31:59 +000012819 Lookups.emplace_back();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012820 Lookups.back().append(Lookup.begin(), Lookup.end());
12821 Lookup.clear();
12822 }
12823 } else if (auto *ULE =
12824 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
12825 Lookups.push_back(UnresolvedSet<8>());
12826 Decl *PrevD = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000012827 for (NamedDecl *D : ULE->decls()) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012828 if (D == PrevD)
12829 Lookups.push_back(UnresolvedSet<8>());
Don Hintonf170dff2019-03-19 06:14:14 +000012830 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012831 Lookups.back().addDecl(DRD);
12832 PrevD = D;
12833 }
12834 }
Alexey Bataevfdc20352017-08-25 15:43:55 +000012835 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
12836 Ty->isInstantiationDependentType() ||
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012837 Ty->containsUnexpandedParameterPack() ||
Michael Kruse4304e9d2019-02-19 16:38:20 +000012838 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012839 return !D->isInvalidDecl() &&
12840 (D->getType()->isDependentType() ||
12841 D->getType()->isInstantiationDependentType() ||
12842 D->getType()->containsUnexpandedParameterPack());
12843 })) {
12844 UnresolvedSet<8> ResSet;
Alexey Bataeve3727102018-04-18 15:57:46 +000012845 for (const UnresolvedSet<8> &Set : Lookups) {
Alexey Bataev43b90b72018-09-12 16:31:59 +000012846 if (Set.empty())
12847 continue;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012848 ResSet.append(Set.begin(), Set.end());
12849 // The last item marks the end of all declarations at the specified scope.
12850 ResSet.addDecl(Set[Set.size() - 1]);
12851 }
12852 return UnresolvedLookupExpr::Create(
12853 SemaRef.Context, /*NamingClass=*/nullptr,
12854 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
12855 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
12856 }
Alexey Bataev43b90b72018-09-12 16:31:59 +000012857 // Lookup inside the classes.
12858 // C++ [over.match.oper]p3:
12859 // For a unary operator @ with an operand of a type whose
12860 // cv-unqualified version is T1, and for a binary operator @ with
12861 // a left operand of a type whose cv-unqualified version is T1 and
12862 // a right operand of a type whose cv-unqualified version is T2,
12863 // three sets of candidate functions, designated member
12864 // candidates, non-member candidates and built-in candidates, are
12865 // constructed as follows:
12866 // -- If T1 is a complete class type or a class currently being
12867 // defined, the set of member candidates is the result of the
12868 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
12869 // the set of member candidates is empty.
12870 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
12871 Lookup.suppressDiagnostics();
12872 if (const auto *TyRec = Ty->getAs<RecordType>()) {
12873 // Complete the type if it can be completed.
12874 // If the type is neither complete nor being defined, bail out now.
12875 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
12876 TyRec->getDecl()->getDefinition()) {
12877 Lookup.clear();
12878 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
12879 if (Lookup.empty()) {
12880 Lookups.emplace_back();
12881 Lookups.back().append(Lookup.begin(), Lookup.end());
12882 }
12883 }
12884 }
12885 // Perform ADL.
Alexey Bataev09232662019-04-04 17:28:22 +000012886 if (SemaRef.getLangOpts().CPlusPlus)
Alexey Bataev74a04e82019-03-13 19:31:34 +000012887 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
Alexey Bataev09232662019-04-04 17:28:22 +000012888 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
12889 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
12890 if (!D->isInvalidDecl() &&
12891 SemaRef.Context.hasSameType(D->getType(), Ty))
12892 return D;
12893 return nullptr;
12894 }))
12895 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
12896 VK_LValue, Loc);
12897 if (SemaRef.getLangOpts().CPlusPlus) {
Alexey Bataev74a04e82019-03-13 19:31:34 +000012898 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
12899 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
12900 if (!D->isInvalidDecl() &&
12901 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
12902 !Ty.isMoreQualifiedThan(D->getType()))
12903 return D;
12904 return nullptr;
12905 })) {
12906 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
12907 /*DetectVirtual=*/false);
12908 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
12909 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
12910 VD->getType().getUnqualifiedType()))) {
12911 if (SemaRef.CheckBaseClassAccess(
12912 Loc, VD->getType(), Ty, Paths.front(),
12913 /*DiagID=*/0) != Sema::AR_inaccessible) {
12914 SemaRef.BuildBasePathArray(Paths, BasePath);
12915 return SemaRef.BuildDeclRefExpr(
12916 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
12917 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000012918 }
12919 }
12920 }
12921 }
12922 if (ReductionIdScopeSpec.isSet()) {
12923 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
12924 return ExprError();
12925 }
12926 return ExprEmpty();
12927}
12928
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012929namespace {
12930/// Data for the reduction-based clauses.
12931struct ReductionData {
12932 /// List of original reduction items.
12933 SmallVector<Expr *, 8> Vars;
12934 /// List of private copies of the reduction items.
12935 SmallVector<Expr *, 8> Privates;
12936 /// LHS expressions for the reduction_op expressions.
12937 SmallVector<Expr *, 8> LHSs;
12938 /// RHS expressions for the reduction_op expressions.
12939 SmallVector<Expr *, 8> RHSs;
12940 /// Reduction operation expression.
12941 SmallVector<Expr *, 8> ReductionOps;
Alexey Bataev88202be2017-07-27 13:20:36 +000012942 /// Taskgroup descriptors for the corresponding reduction items in
12943 /// in_reduction clauses.
12944 SmallVector<Expr *, 8> TaskgroupDescriptors;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012945 /// List of captures for clause.
12946 SmallVector<Decl *, 4> ExprCaptures;
12947 /// List of postupdate expressions.
12948 SmallVector<Expr *, 4> ExprPostUpdates;
12949 ReductionData() = delete;
12950 /// Reserves required memory for the reduction data.
12951 ReductionData(unsigned Size) {
12952 Vars.reserve(Size);
12953 Privates.reserve(Size);
12954 LHSs.reserve(Size);
12955 RHSs.reserve(Size);
12956 ReductionOps.reserve(Size);
Alexey Bataev88202be2017-07-27 13:20:36 +000012957 TaskgroupDescriptors.reserve(Size);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012958 ExprCaptures.reserve(Size);
12959 ExprPostUpdates.reserve(Size);
12960 }
12961 /// Stores reduction item and reduction operation only (required for dependent
12962 /// reduction item).
12963 void push(Expr *Item, Expr *ReductionOp) {
12964 Vars.emplace_back(Item);
12965 Privates.emplace_back(nullptr);
12966 LHSs.emplace_back(nullptr);
12967 RHSs.emplace_back(nullptr);
12968 ReductionOps.emplace_back(ReductionOp);
Alexey Bataev88202be2017-07-27 13:20:36 +000012969 TaskgroupDescriptors.emplace_back(nullptr);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012970 }
12971 /// Stores reduction data.
Alexey Bataev88202be2017-07-27 13:20:36 +000012972 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
12973 Expr *TaskgroupDescriptor) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012974 Vars.emplace_back(Item);
12975 Privates.emplace_back(Private);
12976 LHSs.emplace_back(LHS);
12977 RHSs.emplace_back(RHS);
12978 ReductionOps.emplace_back(ReductionOp);
Alexey Bataev88202be2017-07-27 13:20:36 +000012979 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000012980 }
12981};
12982} // namespace
12983
Alexey Bataeve3727102018-04-18 15:57:46 +000012984static bool checkOMPArraySectionConstantForReduction(
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000012985 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
12986 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
12987 const Expr *Length = OASE->getLength();
12988 if (Length == nullptr) {
12989 // For array sections of the form [1:] or [:], we would need to analyze
12990 // the lower bound...
12991 if (OASE->getColonLoc().isValid())
12992 return false;
12993
12994 // This is an array subscript which has implicit length 1!
12995 SingleElement = true;
12996 ArraySizes.push_back(llvm::APSInt::get(1));
12997 } else {
Fangrui Song407659a2018-11-30 23:41:18 +000012998 Expr::EvalResult Result;
12999 if (!Length->EvaluateAsInt(Result, Context))
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013000 return false;
13001
Fangrui Song407659a2018-11-30 23:41:18 +000013002 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013003 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
13004 ArraySizes.push_back(ConstantLengthValue);
13005 }
13006
13007 // Get the base of this array section and walk up from there.
13008 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
13009
13010 // We require length = 1 for all array sections except the right-most to
13011 // guarantee that the memory region is contiguous and has no holes in it.
13012 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
13013 Length = TempOASE->getLength();
13014 if (Length == nullptr) {
13015 // For array sections of the form [1:] or [:], we would need to analyze
13016 // the lower bound...
13017 if (OASE->getColonLoc().isValid())
13018 return false;
13019
13020 // This is an array subscript which has implicit length 1!
13021 ArraySizes.push_back(llvm::APSInt::get(1));
13022 } else {
Fangrui Song407659a2018-11-30 23:41:18 +000013023 Expr::EvalResult Result;
13024 if (!Length->EvaluateAsInt(Result, Context))
13025 return false;
13026
13027 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13028 if (ConstantLengthValue.getSExtValue() != 1)
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013029 return false;
13030
13031 ArraySizes.push_back(ConstantLengthValue);
13032 }
13033 Base = TempOASE->getBase()->IgnoreParenImpCasts();
13034 }
13035
13036 // If we have a single element, we don't need to add the implicit lengths.
13037 if (!SingleElement) {
13038 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
13039 // Has implicit length 1!
13040 ArraySizes.push_back(llvm::APSInt::get(1));
13041 Base = TempASE->getBase()->IgnoreParenImpCasts();
13042 }
13043 }
13044
13045 // This array section can be privatized as a single value or as a constant
13046 // sized array.
13047 return true;
13048}
13049
Alexey Bataeve3727102018-04-18 15:57:46 +000013050static bool actOnOMPReductionKindClause(
Alexey Bataev169d96a2017-07-18 20:17:46 +000013051 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
13052 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13053 SourceLocation ColonLoc, SourceLocation EndLoc,
13054 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013055 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013056 DeclarationName DN = ReductionId.getName();
13057 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
Alexey Bataevc5e02582014-06-16 07:08:35 +000013058 BinaryOperatorKind BOK = BO_Comma;
13059
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013060 ASTContext &Context = S.Context;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013061 // OpenMP [2.14.3.6, reduction clause]
13062 // C
13063 // reduction-identifier is either an identifier or one of the following
13064 // operators: +, -, *, &, |, ^, && and ||
13065 // C++
13066 // reduction-identifier is either an id-expression or one of the following
13067 // operators: +, -, *, &, |, ^, && and ||
Alexey Bataevc5e02582014-06-16 07:08:35 +000013068 switch (OOK) {
13069 case OO_Plus:
13070 case OO_Minus:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013071 BOK = BO_Add;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013072 break;
13073 case OO_Star:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013074 BOK = BO_Mul;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013075 break;
13076 case OO_Amp:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013077 BOK = BO_And;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013078 break;
13079 case OO_Pipe:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013080 BOK = BO_Or;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013081 break;
13082 case OO_Caret:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013083 BOK = BO_Xor;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013084 break;
13085 case OO_AmpAmp:
13086 BOK = BO_LAnd;
13087 break;
13088 case OO_PipePipe:
13089 BOK = BO_LOr;
13090 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013091 case OO_New:
13092 case OO_Delete:
13093 case OO_Array_New:
13094 case OO_Array_Delete:
13095 case OO_Slash:
13096 case OO_Percent:
13097 case OO_Tilde:
13098 case OO_Exclaim:
13099 case OO_Equal:
13100 case OO_Less:
13101 case OO_Greater:
13102 case OO_LessEqual:
13103 case OO_GreaterEqual:
13104 case OO_PlusEqual:
13105 case OO_MinusEqual:
13106 case OO_StarEqual:
13107 case OO_SlashEqual:
13108 case OO_PercentEqual:
13109 case OO_CaretEqual:
13110 case OO_AmpEqual:
13111 case OO_PipeEqual:
13112 case OO_LessLess:
13113 case OO_GreaterGreater:
13114 case OO_LessLessEqual:
13115 case OO_GreaterGreaterEqual:
13116 case OO_EqualEqual:
13117 case OO_ExclaimEqual:
Richard Smithd30b23d2017-12-01 02:13:10 +000013118 case OO_Spaceship:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013119 case OO_PlusPlus:
13120 case OO_MinusMinus:
13121 case OO_Comma:
13122 case OO_ArrowStar:
13123 case OO_Arrow:
13124 case OO_Call:
13125 case OO_Subscript:
13126 case OO_Conditional:
Richard Smith9be594e2015-10-22 05:12:22 +000013127 case OO_Coawait:
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013128 case NUM_OVERLOADED_OPERATORS:
13129 llvm_unreachable("Unexpected reduction identifier");
13130 case OO_None:
Alexey Bataeve3727102018-04-18 15:57:46 +000013131 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000013132 if (II->isStr("max"))
13133 BOK = BO_GT;
13134 else if (II->isStr("min"))
13135 BOK = BO_LT;
13136 }
13137 break;
13138 }
13139 SourceRange ReductionIdRange;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013140 if (ReductionIdScopeSpec.isValid())
Alexey Bataevc5e02582014-06-16 07:08:35 +000013141 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
Alexey Bataev4d4624c2017-07-20 16:47:47 +000013142 else
13143 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
Alexey Bataevc5e02582014-06-16 07:08:35 +000013144 ReductionIdRange.setEnd(ReductionId.getEndLoc());
Alexey Bataevc5e02582014-06-16 07:08:35 +000013145
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013146 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
13147 bool FirstIter = true;
Alexey Bataeve3727102018-04-18 15:57:46 +000013148 for (Expr *RefExpr : VarList) {
Alexey Bataevc5e02582014-06-16 07:08:35 +000013149 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
Alexey Bataevc5e02582014-06-16 07:08:35 +000013150 // OpenMP [2.1, C/C++]
13151 // A list item is a variable or array section, subject to the restrictions
13152 // specified in Section 2.4 on page 42 and in each of the sections
13153 // describing clauses and directives for which a list appears.
13154 // OpenMP [2.14.3.3, Restrictions, p.1]
13155 // A variable that is part of another variable (as an array or
13156 // structure element) cannot appear in a private clause.
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013157 if (!FirstIter && IR != ER)
13158 ++IR;
13159 FirstIter = false;
Alexey Bataev60da77e2016-02-29 05:54:20 +000013160 SourceLocation ELoc;
13161 SourceRange ERange;
13162 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013163 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
Alexey Bataev60da77e2016-02-29 05:54:20 +000013164 /*AllowArraySection=*/true);
13165 if (Res.second) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013166 // Try to find 'declare reduction' corresponding construct before using
13167 // builtin/overloaded operators.
13168 QualType Type = Context.DependentTy;
13169 CXXCastPath BasePath;
13170 ExprResult DeclareReductionRef = buildDeclareReductionRef(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013171 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013172 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013173 Expr *ReductionOp = nullptr;
13174 if (S.CurContext->isDependentContext() &&
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013175 (DeclareReductionRef.isUnset() ||
13176 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013177 ReductionOp = DeclareReductionRef.get();
13178 // It will be analyzed later.
13179 RD.push(RefExpr, ReductionOp);
Alexey Bataevc5e02582014-06-16 07:08:35 +000013180 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000013181 ValueDecl *D = Res.first;
13182 if (!D)
13183 continue;
13184
Alexey Bataev88202be2017-07-27 13:20:36 +000013185 Expr *TaskgroupDescriptor = nullptr;
Alexey Bataeva1764212015-09-30 09:22:36 +000013186 QualType Type;
Alexey Bataev60da77e2016-02-29 05:54:20 +000013187 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
13188 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
Alexey Bataeve3727102018-04-18 15:57:46 +000013189 if (ASE) {
Alexey Bataev31300ed2016-02-04 11:27:03 +000013190 Type = ASE->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000013191 } else if (OASE) {
13192 QualType BaseType =
13193 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
13194 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
Alexey Bataeva1764212015-09-30 09:22:36 +000013195 Type = ATy->getElementType();
13196 else
13197 Type = BaseType->getPointeeType();
Alexey Bataev31300ed2016-02-04 11:27:03 +000013198 Type = Type.getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000013199 } else {
Alexey Bataev60da77e2016-02-29 05:54:20 +000013200 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
Alexey Bataeve3727102018-04-18 15:57:46 +000013201 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000013202 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataeva1764212015-09-30 09:22:36 +000013203
Alexey Bataevc5e02582014-06-16 07:08:35 +000013204 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13205 // A variable that appears in a private clause must not have an incomplete
13206 // type or a reference type.
Joel E. Denny3cabf732018-06-28 19:54:49 +000013207 if (S.RequireCompleteType(ELoc, D->getType(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013208 diag::err_omp_reduction_incomplete_type))
Alexey Bataevc5e02582014-06-16 07:08:35 +000013209 continue;
13210 // OpenMP [2.14.3.6, reduction clause, Restrictions]
Alexey Bataevc5e02582014-06-16 07:08:35 +000013211 // A list item that appears in a reduction clause must not be
13212 // const-qualified.
Joel E. Dennyd2649292019-01-04 22:11:56 +000013213 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
13214 /*AcceptIfMutable*/ false, ASE || OASE))
Alexey Bataevc5e02582014-06-16 07:08:35 +000013215 continue;
Alexey Bataevbc529672018-09-28 19:33:14 +000013216
13217 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
Alexey Bataevc5e02582014-06-16 07:08:35 +000013218 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
13219 // If a list-item is a reference type then it must bind to the same object
13220 // for all threads of the team.
Alexey Bataevbc529672018-09-28 19:33:14 +000013221 if (!ASE && !OASE) {
13222 if (VD) {
13223 VarDecl *VDDef = VD->getDefinition();
13224 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
13225 DSARefChecker Check(Stack);
13226 if (Check.Visit(VDDef->getInit())) {
13227 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
13228 << getOpenMPClauseName(ClauseKind) << ERange;
13229 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
13230 continue;
13231 }
Alexey Bataeva1764212015-09-30 09:22:36 +000013232 }
Alexey Bataevc5e02582014-06-16 07:08:35 +000013233 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013234
Alexey Bataevbc529672018-09-28 19:33:14 +000013235 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
13236 // in a Construct]
13237 // Variables with the predetermined data-sharing attributes may not be
13238 // listed in data-sharing attributes clauses, except for the cases
13239 // listed below. For these exceptions only, listing a predetermined
13240 // variable in a data-sharing attribute clause is allowed and overrides
13241 // the variable's predetermined data-sharing attributes.
13242 // OpenMP [2.14.3.6, Restrictions, p.3]
13243 // Any number of reduction clauses can be specified on the directive,
13244 // but a list item can appear only once in the reduction clauses for that
13245 // directive.
13246 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
13247 if (DVar.CKind == OMPC_reduction) {
13248 S.Diag(ELoc, diag::err_omp_once_referenced)
13249 << getOpenMPClauseName(ClauseKind);
13250 if (DVar.RefExpr)
13251 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
13252 continue;
13253 }
13254 if (DVar.CKind != OMPC_unknown) {
13255 S.Diag(ELoc, diag::err_omp_wrong_dsa)
13256 << getOpenMPClauseName(DVar.CKind)
13257 << getOpenMPClauseName(OMPC_reduction);
Alexey Bataeve3727102018-04-18 15:57:46 +000013258 reportOriginalDsa(S, Stack, D, DVar);
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013259 continue;
Alexey Bataevf29276e2014-06-18 04:14:57 +000013260 }
Alexey Bataevbc529672018-09-28 19:33:14 +000013261
13262 // OpenMP [2.14.3.6, Restrictions, p.1]
13263 // A list item that appears in a reduction clause of a worksharing
13264 // construct must be shared in the parallel regions to which any of the
13265 // worksharing regions arising from the worksharing construct bind.
13266 if (isOpenMPWorksharingDirective(CurrDir) &&
13267 !isOpenMPParallelDirective(CurrDir) &&
13268 !isOpenMPTeamsDirective(CurrDir)) {
13269 DVar = Stack->getImplicitDSA(D, true);
13270 if (DVar.CKind != OMPC_shared) {
13271 S.Diag(ELoc, diag::err_omp_required_access)
13272 << getOpenMPClauseName(OMPC_reduction)
13273 << getOpenMPClauseName(OMPC_shared);
13274 reportOriginalDsa(S, Stack, D, DVar);
13275 continue;
13276 }
13277 }
Alexey Bataevf29276e2014-06-18 04:14:57 +000013278 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013279
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013280 // Try to find 'declare reduction' corresponding construct before using
13281 // builtin/overloaded operators.
13282 CXXCastPath BasePath;
13283 ExprResult DeclareReductionRef = buildDeclareReductionRef(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013284 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013285 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13286 if (DeclareReductionRef.isInvalid())
13287 continue;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013288 if (S.CurContext->isDependentContext() &&
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013289 (DeclareReductionRef.isUnset() ||
13290 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013291 RD.push(RefExpr, DeclareReductionRef.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013292 continue;
13293 }
13294 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
13295 // Not allowed reduction identifier is found.
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013296 S.Diag(ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013297 diag::err_omp_unknown_reduction_identifier)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013298 << Type << ReductionIdRange;
13299 continue;
13300 }
13301
13302 // OpenMP [2.14.3.6, reduction clause, Restrictions]
13303 // The type of a list item that appears in a reduction clause must be valid
13304 // for the reduction-identifier. For a max or min reduction in C, the type
13305 // of the list item must be an allowed arithmetic data type: char, int,
13306 // float, double, or _Bool, possibly modified with long, short, signed, or
13307 // unsigned. For a max or min reduction in C++, the type of the list item
13308 // must be an allowed arithmetic data type: char, wchar_t, int, float,
13309 // double, or bool, possibly modified with long, short, signed, or unsigned.
13310 if (DeclareReductionRef.isUnset()) {
13311 if ((BOK == BO_GT || BOK == BO_LT) &&
13312 !(Type->isScalarType() ||
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013313 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
13314 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
Alexey Bataev169d96a2017-07-18 20:17:46 +000013315 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013316 if (!ASE && !OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013317 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13318 VarDecl::DeclarationOnly;
13319 S.Diag(D->getLocation(),
13320 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013321 << D;
13322 }
13323 continue;
13324 }
13325 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013326 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
Alexey Bataev169d96a2017-07-18 20:17:46 +000013327 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
13328 << getOpenMPClauseName(ClauseKind);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013329 if (!ASE && !OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013330 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13331 VarDecl::DeclarationOnly;
13332 S.Diag(D->getLocation(),
13333 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013334 << D;
13335 }
13336 continue;
13337 }
13338 }
13339
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013340 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000013341 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
13342 D->hasAttrs() ? &D->getAttrs() : nullptr);
13343 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
13344 D->hasAttrs() ? &D->getAttrs() : nullptr);
13345 QualType PrivateTy = Type;
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013346
13347 // Try if we can determine constant lengths for all array sections and avoid
13348 // the VLA.
13349 bool ConstantLengthOASE = false;
13350 if (OASE) {
13351 bool SingleElement;
13352 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
Alexey Bataeve3727102018-04-18 15:57:46 +000013353 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013354 Context, OASE, SingleElement, ArraySizes);
13355
13356 // If we don't have a single element, we must emit a constant array type.
13357 if (ConstantLengthOASE && !SingleElement) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013358 for (llvm::APSInt &Size : ArraySizes)
Richard Smith772e2662019-10-04 01:25:59 +000013359 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
13360 ArrayType::Normal,
13361 /*IndexTypeQuals=*/0);
Jonas Hahnfeld4525c822017-10-23 19:01:35 +000013362 }
13363 }
13364
13365 if ((OASE && !ConstantLengthOASE) ||
Jonas Hahnfeld96087f32017-11-02 13:30:42 +000013366 (!OASE && !ASE &&
Alexey Bataev60da77e2016-02-29 05:54:20 +000013367 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
Alexey Bataev85260312019-07-11 20:35:31 +000013368 if (!Context.getTargetInfo().isVLASupported()) {
13369 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
13370 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13371 S.Diag(ELoc, diag::note_vla_unsupported);
13372 } else {
13373 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13374 S.targetDiag(ELoc, diag::note_vla_unsupported);
13375 }
Jonas Hahnfeld87d44262017-11-18 21:00:46 +000013376 continue;
13377 }
David Majnemer9d168222016-08-05 17:44:54 +000013378 // For arrays/array sections only:
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013379 // Create pseudo array type for private copy. The size for this array will
13380 // be generated during codegen.
13381 // For array subscripts or single variables Private Ty is the same as Type
13382 // (type of the variable or single array element).
13383 PrivateTy = Context.getVariableArrayType(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013384 Type,
Alexey Bataevd070a582017-10-25 15:54:04 +000013385 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013386 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
Alexey Bataev60da77e2016-02-29 05:54:20 +000013387 } else if (!ASE && !OASE &&
Alexey Bataeve3727102018-04-18 15:57:46 +000013388 Context.getAsArrayType(D->getType().getNonReferenceType())) {
Alexey Bataev60da77e2016-02-29 05:54:20 +000013389 PrivateTy = D->getType().getNonReferenceType();
Alexey Bataeve3727102018-04-18 15:57:46 +000013390 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013391 // Private copy.
Alexey Bataeve3727102018-04-18 15:57:46 +000013392 VarDecl *PrivateVD =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000013393 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
13394 D->hasAttrs() ? &D->getAttrs() : nullptr,
13395 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013396 // Add initializer for private variable.
13397 Expr *Init = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000013398 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
13399 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013400 if (DeclareReductionRef.isUsable()) {
13401 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
13402 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
13403 if (DRD->getInitializer()) {
13404 Init = DRDRef;
13405 RHSVD->setInit(DRDRef);
13406 RHSVD->setInitStyle(VarDecl::CallInit);
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013407 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013408 } else {
13409 switch (BOK) {
13410 case BO_Add:
13411 case BO_Xor:
13412 case BO_Or:
13413 case BO_LOr:
13414 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
13415 if (Type->isScalarType() || Type->isAnyComplexType())
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013416 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013417 break;
13418 case BO_Mul:
13419 case BO_LAnd:
13420 if (Type->isScalarType() || Type->isAnyComplexType()) {
13421 // '*' and '&&' reduction ops - initializer is '1'.
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013422 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
Alexey Bataevc5e02582014-06-16 07:08:35 +000013423 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013424 break;
13425 case BO_And: {
13426 // '&' reduction op - initializer is '~0'.
13427 QualType OrigType = Type;
13428 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
13429 Type = ComplexTy->getElementType();
13430 if (Type->isRealFloatingType()) {
13431 llvm::APFloat InitValue =
13432 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
13433 /*isIEEE=*/true);
13434 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
13435 Type, ELoc);
13436 } else if (Type->isScalarType()) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013437 uint64_t Size = Context.getTypeSize(Type);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013438 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
13439 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
13440 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
13441 }
13442 if (Init && OrigType->isAnyComplexType()) {
13443 // Init = 0xFFFF + 0xFFFFi;
13444 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013445 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013446 }
13447 Type = OrigType;
13448 break;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013449 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013450 case BO_LT:
13451 case BO_GT: {
13452 // 'min' reduction op - initializer is 'Largest representable number in
13453 // the reduction list item type'.
13454 // 'max' reduction op - initializer is 'Least representable number in
13455 // the reduction list item type'.
13456 if (Type->isIntegerType() || Type->isPointerType()) {
13457 bool IsSigned = Type->hasSignedIntegerRepresentation();
Alexey Bataeve3727102018-04-18 15:57:46 +000013458 uint64_t Size = Context.getTypeSize(Type);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013459 QualType IntTy =
13460 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
13461 llvm::APInt InitValue =
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013462 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
13463 : llvm::APInt::getMinValue(Size)
13464 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
13465 : llvm::APInt::getMaxValue(Size);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013466 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
13467 if (Type->isPointerType()) {
13468 // Cast to pointer type.
Alexey Bataeve3727102018-04-18 15:57:46 +000013469 ExprResult CastExpr = S.BuildCStyleCastExpr(
Alexey Bataevd070a582017-10-25 15:54:04 +000013470 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013471 if (CastExpr.isInvalid())
13472 continue;
13473 Init = CastExpr.get();
13474 }
13475 } else if (Type->isRealFloatingType()) {
13476 llvm::APFloat InitValue = llvm::APFloat::getLargest(
13477 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
13478 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
13479 Type, ELoc);
13480 }
13481 break;
13482 }
13483 case BO_PtrMemD:
13484 case BO_PtrMemI:
13485 case BO_MulAssign:
13486 case BO_Div:
13487 case BO_Rem:
13488 case BO_Sub:
13489 case BO_Shl:
13490 case BO_Shr:
13491 case BO_LE:
13492 case BO_GE:
13493 case BO_EQ:
13494 case BO_NE:
Richard Smithc70f1d62017-12-14 15:16:18 +000013495 case BO_Cmp:
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013496 case BO_AndAssign:
13497 case BO_XorAssign:
13498 case BO_OrAssign:
13499 case BO_Assign:
13500 case BO_AddAssign:
13501 case BO_SubAssign:
13502 case BO_DivAssign:
13503 case BO_RemAssign:
13504 case BO_ShlAssign:
13505 case BO_ShrAssign:
13506 case BO_Comma:
13507 llvm_unreachable("Unexpected reduction operation");
13508 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013509 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013510 if (Init && DeclareReductionRef.isUnset())
13511 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
13512 else if (!Init)
13513 S.ActOnUninitializedDecl(RHSVD);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013514 if (RHSVD->isInvalidDecl())
13515 continue;
Alexey Bataev09232662019-04-04 17:28:22 +000013516 if (!RHSVD->hasInit() &&
13517 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013518 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
13519 << Type << ReductionIdRange;
13520 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13521 VarDecl::DeclarationOnly;
13522 S.Diag(D->getLocation(),
13523 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev60da77e2016-02-29 05:54:20 +000013524 << D;
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013525 continue;
13526 }
Alexey Bataevf24e7b12015-10-08 09:10:53 +000013527 // Store initializer for single element in private copy. Will be used during
13528 // codegen.
13529 PrivateVD->setInit(RHSVD->getInit());
13530 PrivateVD->setInitStyle(RHSVD->getInitStyle());
Alexey Bataeve3727102018-04-18 15:57:46 +000013531 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013532 ExprResult ReductionOp;
13533 if (DeclareReductionRef.isUsable()) {
13534 QualType RedTy = DeclareReductionRef.get()->getType();
13535 QualType PtrRedTy = Context.getPointerType(RedTy);
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013536 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
13537 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013538 if (!BasePath.empty()) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013539 LHS = S.DefaultLvalueConversion(LHS.get());
13540 RHS = S.DefaultLvalueConversion(RHS.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013541 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
13542 CK_UncheckedDerivedToBase, LHS.get(),
13543 &BasePath, LHS.get()->getValueKind());
13544 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
13545 CK_UncheckedDerivedToBase, RHS.get(),
13546 &BasePath, RHS.get()->getValueKind());
Alexey Bataev794ba0d2015-04-10 10:43:45 +000013547 }
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013548 FunctionProtoType::ExtProtoInfo EPI;
13549 QualType Params[] = {PtrRedTy, PtrRedTy};
13550 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
13551 auto *OVE = new (Context) OpaqueValueExpr(
13552 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013553 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013554 Expr *Args[] = {LHS.get(), RHS.get()};
Bruno Riccic5885cf2018-12-21 15:20:32 +000013555 ReductionOp =
13556 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013557 } else {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013558 ReductionOp = S.BuildBinOp(
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013559 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013560 if (ReductionOp.isUsable()) {
13561 if (BOK != BO_LT && BOK != BO_GT) {
13562 ReductionOp =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013563 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013564 BO_Assign, LHSDRE, ReductionOp.get());
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013565 } else {
Alexey Bataevd070a582017-10-25 15:54:04 +000013566 auto *ConditionalOp = new (Context)
13567 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
13568 Type, VK_LValue, OK_Ordinary);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013569 ReductionOp =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013570 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013571 BO_Assign, LHSDRE, ConditionalOp);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013572 }
Alexey Bataev4d4624c2017-07-20 16:47:47 +000013573 if (ReductionOp.isUsable())
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000013574 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
13575 /*DiscardedValue*/ false);
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013576 }
Alexey Bataev4d4624c2017-07-20 16:47:47 +000013577 if (!ReductionOp.isUsable())
Alexey Bataeva839ddd2016-03-17 10:19:46 +000013578 continue;
Alexey Bataevc5e02582014-06-16 07:08:35 +000013579 }
13580
Alexey Bataevfa312f32017-07-21 18:48:21 +000013581 // OpenMP [2.15.4.6, Restrictions, p.2]
13582 // A list item that appears in an in_reduction clause of a task construct
13583 // must appear in a task_reduction clause of a construct associated with a
13584 // taskgroup region that includes the participating task in its taskgroup
13585 // set. The construct associated with the innermost region that meets this
13586 // condition must specify the same reduction-identifier as the in_reduction
13587 // clause.
13588 if (ClauseKind == OMPC_in_reduction) {
Alexey Bataevfa312f32017-07-21 18:48:21 +000013589 SourceRange ParentSR;
13590 BinaryOperatorKind ParentBOK;
13591 const Expr *ParentReductionOp;
Alexey Bataev88202be2017-07-27 13:20:36 +000013592 Expr *ParentBOKTD, *ParentReductionOpTD;
Alexey Bataevf189cb72017-07-24 14:52:13 +000013593 DSAStackTy::DSAVarData ParentBOKDSA =
Alexey Bataev88202be2017-07-27 13:20:36 +000013594 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
13595 ParentBOKTD);
Alexey Bataevf189cb72017-07-24 14:52:13 +000013596 DSAStackTy::DSAVarData ParentReductionOpDSA =
Alexey Bataev88202be2017-07-27 13:20:36 +000013597 Stack->getTopMostTaskgroupReductionData(
13598 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
Alexey Bataevf189cb72017-07-24 14:52:13 +000013599 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
13600 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
13601 if (!IsParentBOK && !IsParentReductionOp) {
13602 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
13603 continue;
13604 }
Alexey Bataevfa312f32017-07-21 18:48:21 +000013605 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
13606 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
13607 IsParentReductionOp) {
13608 bool EmitError = true;
13609 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
13610 llvm::FoldingSetNodeID RedId, ParentRedId;
13611 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
13612 DeclareReductionRef.get()->Profile(RedId, Context,
13613 /*Canonical=*/true);
13614 EmitError = RedId != ParentRedId;
13615 }
13616 if (EmitError) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013617 S.Diag(ReductionId.getBeginLoc(),
Alexey Bataevfa312f32017-07-21 18:48:21 +000013618 diag::err_omp_reduction_identifier_mismatch)
13619 << ReductionIdRange << RefExpr->getSourceRange();
13620 S.Diag(ParentSR.getBegin(),
13621 diag::note_omp_previous_reduction_identifier)
Alexey Bataevf189cb72017-07-24 14:52:13 +000013622 << ParentSR
13623 << (IsParentBOK ? ParentBOKDSA.RefExpr
13624 : ParentReductionOpDSA.RefExpr)
13625 ->getSourceRange();
Alexey Bataevfa312f32017-07-21 18:48:21 +000013626 continue;
13627 }
13628 }
Alexey Bataev88202be2017-07-27 13:20:36 +000013629 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
13630 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
Alexey Bataevfa312f32017-07-21 18:48:21 +000013631 }
13632
Alexey Bataev60da77e2016-02-29 05:54:20 +000013633 DeclRefExpr *Ref = nullptr;
13634 Expr *VarsExpr = RefExpr->IgnoreParens();
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013635 if (!VD && !S.CurContext->isDependentContext()) {
Alexey Bataev60da77e2016-02-29 05:54:20 +000013636 if (ASE || OASE) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013637 TransformExprToCaptures RebuildToCapture(S, D);
Alexey Bataev60da77e2016-02-29 05:54:20 +000013638 VarsExpr =
13639 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
13640 Ref = RebuildToCapture.getCapturedExpr();
Alexey Bataev61205072016-03-02 04:57:40 +000013641 } else {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013642 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataev5a3af132016-03-29 08:58:54 +000013643 }
Alexey Bataeve3727102018-04-18 15:57:46 +000013644 if (!S.isOpenMPCapturedDecl(D)) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013645 RD.ExprCaptures.emplace_back(Ref->getDecl());
Alexey Bataev5a3af132016-03-29 08:58:54 +000013646 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013647 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
Alexey Bataev5a3af132016-03-29 08:58:54 +000013648 if (!RefRes.isUsable())
13649 continue;
13650 ExprResult PostUpdateRes =
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013651 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
13652 RefRes.get());
Alexey Bataev5a3af132016-03-29 08:58:54 +000013653 if (!PostUpdateRes.isUsable())
13654 continue;
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013655 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
13656 Stack->getCurrentDirective() == OMPD_taskgroup) {
13657 S.Diag(RefExpr->getExprLoc(),
13658 diag::err_omp_reduction_non_addressable_expression)
Alexey Bataevbcd0ae02017-07-11 19:16:44 +000013659 << RefExpr->getSourceRange();
13660 continue;
13661 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013662 RD.ExprPostUpdates.emplace_back(
13663 S.IgnoredValueConversions(PostUpdateRes.get()).get());
Alexey Bataev61205072016-03-02 04:57:40 +000013664 }
13665 }
Alexey Bataev60da77e2016-02-29 05:54:20 +000013666 }
Alexey Bataev169d96a2017-07-18 20:17:46 +000013667 // All reduction items are still marked as reduction (to do not increase
13668 // code base size).
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013669 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
Alexey Bataevf189cb72017-07-24 14:52:13 +000013670 if (CurrDir == OMPD_taskgroup) {
13671 if (DeclareReductionRef.isUsable())
Alexey Bataev3b1b8952017-07-25 15:53:26 +000013672 Stack->addTaskgroupReductionData(D, ReductionIdRange,
13673 DeclareReductionRef.get());
Alexey Bataevf189cb72017-07-24 14:52:13 +000013674 else
Alexey Bataev3b1b8952017-07-25 15:53:26 +000013675 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
Alexey Bataevf189cb72017-07-24 14:52:13 +000013676 }
Alexey Bataev88202be2017-07-27 13:20:36 +000013677 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
13678 TaskgroupDescriptor);
Alexey Bataevc5e02582014-06-16 07:08:35 +000013679 }
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013680 return RD.Vars.empty();
13681}
Alexey Bataevc5e02582014-06-16 07:08:35 +000013682
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013683OMPClause *Sema::ActOnOpenMPReductionClause(
13684 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13685 SourceLocation ColonLoc, SourceLocation EndLoc,
13686 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13687 ArrayRef<Expr *> UnresolvedReductions) {
13688 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000013689 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
Alexey Bataev169d96a2017-07-18 20:17:46 +000013690 StartLoc, LParenLoc, ColonLoc, EndLoc,
13691 ReductionIdScopeSpec, ReductionId,
13692 UnresolvedReductions, RD))
Alexey Bataevc5e02582014-06-16 07:08:35 +000013693 return nullptr;
Alexey Bataev61205072016-03-02 04:57:40 +000013694
Alexey Bataevc5e02582014-06-16 07:08:35 +000013695 return OMPReductionClause::Create(
Alexey Bataevfad872fc2017-07-18 15:32:58 +000013696 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13697 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
13698 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
13699 buildPreInits(Context, RD.ExprCaptures),
13700 buildPostUpdate(*this, RD.ExprPostUpdates));
Alexey Bataevc5e02582014-06-16 07:08:35 +000013701}
13702
Alexey Bataev169d96a2017-07-18 20:17:46 +000013703OMPClause *Sema::ActOnOpenMPTaskReductionClause(
13704 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13705 SourceLocation ColonLoc, SourceLocation EndLoc,
13706 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13707 ArrayRef<Expr *> UnresolvedReductions) {
13708 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000013709 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
13710 StartLoc, LParenLoc, ColonLoc, EndLoc,
13711 ReductionIdScopeSpec, ReductionId,
Alexey Bataev169d96a2017-07-18 20:17:46 +000013712 UnresolvedReductions, RD))
13713 return nullptr;
13714
13715 return OMPTaskReductionClause::Create(
13716 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13717 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
13718 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
13719 buildPreInits(Context, RD.ExprCaptures),
13720 buildPostUpdate(*this, RD.ExprPostUpdates));
13721}
13722
Alexey Bataevfa312f32017-07-21 18:48:21 +000013723OMPClause *Sema::ActOnOpenMPInReductionClause(
13724 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13725 SourceLocation ColonLoc, SourceLocation EndLoc,
13726 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13727 ArrayRef<Expr *> UnresolvedReductions) {
13728 ReductionData RD(VarList.size());
Alexey Bataeve3727102018-04-18 15:57:46 +000013729 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
Alexey Bataevfa312f32017-07-21 18:48:21 +000013730 StartLoc, LParenLoc, ColonLoc, EndLoc,
13731 ReductionIdScopeSpec, ReductionId,
13732 UnresolvedReductions, RD))
13733 return nullptr;
13734
13735 return OMPInReductionClause::Create(
13736 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
13737 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
Alexey Bataev88202be2017-07-27 13:20:36 +000013738 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
Alexey Bataevfa312f32017-07-21 18:48:21 +000013739 buildPreInits(Context, RD.ExprCaptures),
13740 buildPostUpdate(*this, RD.ExprPostUpdates));
13741}
13742
Alexey Bataevecba70f2016-04-12 11:02:11 +000013743bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
13744 SourceLocation LinLoc) {
13745 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
13746 LinKind == OMPC_LINEAR_unknown) {
13747 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
13748 return true;
13749 }
13750 return false;
13751}
13752
Alexey Bataeve3727102018-04-18 15:57:46 +000013753bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
Alexey Bataevecba70f2016-04-12 11:02:11 +000013754 OpenMPLinearClauseKind LinKind,
13755 QualType Type) {
Alexey Bataeve3727102018-04-18 15:57:46 +000013756 const auto *VD = dyn_cast_or_null<VarDecl>(D);
Alexey Bataevecba70f2016-04-12 11:02:11 +000013757 // A variable must not have an incomplete type or a reference type.
13758 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
13759 return true;
13760 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
13761 !Type->isReferenceType()) {
13762 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
13763 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
13764 return true;
13765 }
13766 Type = Type.getNonReferenceType();
13767
Joel E. Dennybae586f2019-01-04 22:12:13 +000013768 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13769 // A variable that is privatized must not have a const-qualified type
13770 // unless it is of class type with a mutable member. This restriction does
13771 // not apply to the firstprivate clause.
13772 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
Alexey Bataevecba70f2016-04-12 11:02:11 +000013773 return true;
Alexey Bataevecba70f2016-04-12 11:02:11 +000013774
13775 // A list item must be of integral or pointer type.
13776 Type = Type.getUnqualifiedType().getCanonicalType();
13777 const auto *Ty = Type.getTypePtrOrNull();
13778 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
13779 !Ty->isPointerType())) {
13780 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
13781 if (D) {
13782 bool IsDecl =
13783 !VD ||
13784 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13785 Diag(D->getLocation(),
13786 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13787 << D;
13788 }
13789 return true;
13790 }
13791 return false;
13792}
13793
Alexey Bataev182227b2015-08-20 10:54:39 +000013794OMPClause *Sema::ActOnOpenMPLinearClause(
13795 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
13796 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
13797 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
Alexander Musman8dba6642014-04-22 13:09:42 +000013798 SmallVector<Expr *, 8> Vars;
Alexey Bataevbd9fec12015-08-18 06:47:21 +000013799 SmallVector<Expr *, 8> Privates;
Alexander Musman3276a272015-03-21 10:12:56 +000013800 SmallVector<Expr *, 8> Inits;
Alexey Bataev78849fb2016-03-09 09:49:00 +000013801 SmallVector<Decl *, 4> ExprCaptures;
13802 SmallVector<Expr *, 4> ExprPostUpdates;
Alexey Bataevecba70f2016-04-12 11:02:11 +000013803 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
Alexey Bataev182227b2015-08-20 10:54:39 +000013804 LinKind = OMPC_LINEAR_val;
Alexey Bataeve3727102018-04-18 15:57:46 +000013805 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000013806 assert(RefExpr && "NULL expr in OpenMP linear clause.");
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013807 SourceLocation ELoc;
13808 SourceRange ERange;
13809 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000013810 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013811 if (Res.second) {
Alexander Musman8dba6642014-04-22 13:09:42 +000013812 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000013813 Vars.push_back(RefExpr);
Alexey Bataevbd9fec12015-08-18 06:47:21 +000013814 Privates.push_back(nullptr);
Alexander Musman3276a272015-03-21 10:12:56 +000013815 Inits.push_back(nullptr);
Alexander Musman8dba6642014-04-22 13:09:42 +000013816 }
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013817 ValueDecl *D = Res.first;
13818 if (!D)
Alexander Musman8dba6642014-04-22 13:09:42 +000013819 continue;
Alexander Musman8dba6642014-04-22 13:09:42 +000013820
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013821 QualType Type = D->getType();
13822 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musman8dba6642014-04-22 13:09:42 +000013823
13824 // OpenMP [2.14.3.7, linear clause]
13825 // A list-item cannot appear in more than one linear clause.
13826 // A list-item that appears in a linear clause cannot appear in any
13827 // other data-sharing attribute clause.
Alexey Bataeve3727102018-04-18 15:57:46 +000013828 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexander Musman8dba6642014-04-22 13:09:42 +000013829 if (DVar.RefExpr) {
13830 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13831 << getOpenMPClauseName(OMPC_linear);
Alexey Bataeve3727102018-04-18 15:57:46 +000013832 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexander Musman8dba6642014-04-22 13:09:42 +000013833 continue;
13834 }
13835
Alexey Bataevecba70f2016-04-12 11:02:11 +000013836 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
Alexander Musman8dba6642014-04-22 13:09:42 +000013837 continue;
Alexey Bataevecba70f2016-04-12 11:02:11 +000013838 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
Alexander Musman8dba6642014-04-22 13:09:42 +000013839
Alexey Bataevbd9fec12015-08-18 06:47:21 +000013840 // Build private copy of original var.
Alexey Bataeve3727102018-04-18 15:57:46 +000013841 VarDecl *Private =
Alexey Bataev63cc8e92018-03-20 14:45:59 +000013842 buildVarDecl(*this, ELoc, Type, D->getName(),
13843 D->hasAttrs() ? &D->getAttrs() : nullptr,
13844 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000013845 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
Alexander Musman3276a272015-03-21 10:12:56 +000013846 // Build var to save initial value.
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013847 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000013848 Expr *InitExpr;
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013849 DeclRefExpr *Ref = nullptr;
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000013850 if (!VD && !CurContext->isDependentContext()) {
Alexey Bataev78849fb2016-03-09 09:49:00 +000013851 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000013852 if (!isOpenMPCapturedDecl(D)) {
Alexey Bataev78849fb2016-03-09 09:49:00 +000013853 ExprCaptures.push_back(Ref->getDecl());
13854 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
13855 ExprResult RefRes = DefaultLvalueConversion(Ref);
13856 if (!RefRes.isUsable())
13857 continue;
13858 ExprResult PostUpdateRes =
13859 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
13860 SimpleRefExpr, RefRes.get());
13861 if (!PostUpdateRes.isUsable())
13862 continue;
13863 ExprPostUpdates.push_back(
13864 IgnoredValueConversions(PostUpdateRes.get()).get());
13865 }
13866 }
13867 }
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000013868 if (LinKind == OMPC_LINEAR_uval)
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013869 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000013870 else
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013871 InitExpr = VD ? SimpleRefExpr : Ref;
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000013872 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000013873 /*DirectInit=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000013874 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
Alexey Bataev2bbf7212016-03-03 03:52:24 +000013875
13876 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
Alexey Bataevbe8b8b52016-07-07 11:04:06 +000013877 Vars.push_back((VD || CurContext->isDependentContext())
13878 ? RefExpr->IgnoreParens()
13879 : Ref);
Alexey Bataevbd9fec12015-08-18 06:47:21 +000013880 Privates.push_back(PrivateRef);
Alexander Musman3276a272015-03-21 10:12:56 +000013881 Inits.push_back(InitRef);
Alexander Musman8dba6642014-04-22 13:09:42 +000013882 }
13883
13884 if (Vars.empty())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000013885 return nullptr;
Alexander Musman8dba6642014-04-22 13:09:42 +000013886
13887 Expr *StepExpr = Step;
Alexander Musman3276a272015-03-21 10:12:56 +000013888 Expr *CalcStepExpr = nullptr;
Alexander Musman8dba6642014-04-22 13:09:42 +000013889 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
13890 !Step->isInstantiationDependent() &&
13891 !Step->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013892 SourceLocation StepLoc = Step->getBeginLoc();
Alexander Musmana8e9d2e2014-06-03 10:16:47 +000013893 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
Alexander Musman8dba6642014-04-22 13:09:42 +000013894 if (Val.isInvalid())
Alexander Musmancb7f9c42014-05-15 13:04:49 +000013895 return nullptr;
Nikola Smiljanic01a75982014-05-29 10:55:11 +000013896 StepExpr = Val.get();
Alexander Musman8dba6642014-04-22 13:09:42 +000013897
Alexander Musman3276a272015-03-21 10:12:56 +000013898 // Build var to save the step value.
13899 VarDecl *SaveVar =
Alexey Bataev39f915b82015-05-08 10:41:21 +000013900 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
Alexander Musman3276a272015-03-21 10:12:56 +000013901 ExprResult SaveRef =
Alexey Bataev39f915b82015-05-08 10:41:21 +000013902 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
Alexander Musman3276a272015-03-21 10:12:56 +000013903 ExprResult CalcStep =
13904 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000013905 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
Alexander Musman3276a272015-03-21 10:12:56 +000013906
Alexander Musman8dba6642014-04-22 13:09:42 +000013907 // Warn about zero linear step (it would be probably better specified as
13908 // making corresponding variables 'const').
13909 llvm::APSInt Result;
Alexander Musman3276a272015-03-21 10:12:56 +000013910 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
13911 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
Alexander Musman8dba6642014-04-22 13:09:42 +000013912 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
13913 << (Vars.size() > 1);
Alexander Musman3276a272015-03-21 10:12:56 +000013914 if (!IsConstant && CalcStep.isUsable()) {
13915 // Calculate the step beforehand instead of doing this on each iteration.
13916 // (This is not used if the number of iterations may be kfold-ed).
13917 CalcStepExpr = CalcStep.get();
13918 }
Alexander Musman8dba6642014-04-22 13:09:42 +000013919 }
13920
Alexey Bataev182227b2015-08-20 10:54:39 +000013921 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
13922 ColonLoc, EndLoc, Vars, Privates, Inits,
Alexey Bataev5a3af132016-03-29 08:58:54 +000013923 StepExpr, CalcStepExpr,
13924 buildPreInits(Context, ExprCaptures),
13925 buildPostUpdate(*this, ExprPostUpdates));
Alexander Musman3276a272015-03-21 10:12:56 +000013926}
13927
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013928static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
13929 Expr *NumIterations, Sema &SemaRef,
13930 Scope *S, DSAStackTy *Stack) {
Alexander Musman3276a272015-03-21 10:12:56 +000013931 // Walk the vars and build update/final expressions for the CodeGen.
13932 SmallVector<Expr *, 8> Updates;
13933 SmallVector<Expr *, 8> Finals;
Alexey Bataev195ae902019-08-08 13:42:45 +000013934 SmallVector<Expr *, 8> UsedExprs;
Alexander Musman3276a272015-03-21 10:12:56 +000013935 Expr *Step = Clause.getStep();
13936 Expr *CalcStep = Clause.getCalcStep();
13937 // OpenMP [2.14.3.7, linear clause]
13938 // If linear-step is not specified it is assumed to be 1.
Alexey Bataeve3727102018-04-18 15:57:46 +000013939 if (!Step)
Alexander Musman3276a272015-03-21 10:12:56 +000013940 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000013941 else if (CalcStep)
Alexander Musman3276a272015-03-21 10:12:56 +000013942 Step = cast<BinaryOperator>(CalcStep)->getLHS();
13943 bool HasErrors = false;
13944 auto CurInit = Clause.inits().begin();
Alexey Bataevbd9fec12015-08-18 06:47:21 +000013945 auto CurPrivate = Clause.privates().begin();
Alexey Bataeve3727102018-04-18 15:57:46 +000013946 OpenMPLinearClauseKind LinKind = Clause.getModifier();
13947 for (Expr *RefExpr : Clause.varlists()) {
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013948 SourceLocation ELoc;
13949 SourceRange ERange;
13950 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000013951 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013952 ValueDecl *D = Res.first;
13953 if (Res.second || !D) {
13954 Updates.push_back(nullptr);
13955 Finals.push_back(nullptr);
13956 HasErrors = true;
13957 continue;
13958 }
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013959 auto &&Info = Stack->isLoopControlVariable(D);
Alexey Bataev2b86f212017-11-29 21:31:48 +000013960 // OpenMP [2.15.11, distribute simd Construct]
13961 // A list item may not appear in a linear clause, unless it is the loop
13962 // iteration variable.
13963 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
13964 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
13965 SemaRef.Diag(ELoc,
13966 diag::err_omp_linear_distribute_var_non_loop_iteration);
13967 Updates.push_back(nullptr);
13968 Finals.push_back(nullptr);
13969 HasErrors = true;
13970 continue;
13971 }
Alexander Musman3276a272015-03-21 10:12:56 +000013972 Expr *InitExpr = *CurInit;
13973
13974 // Build privatized reference to the current linear var.
David Majnemer9d168222016-08-05 17:44:54 +000013975 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
Alexey Bataev84cfb1d2015-08-21 06:41:23 +000013976 Expr *CapturedRef;
13977 if (LinKind == OMPC_LINEAR_uval)
13978 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
13979 else
13980 CapturedRef =
13981 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
13982 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
13983 /*RefersToCapture=*/true);
Alexander Musman3276a272015-03-21 10:12:56 +000013984
13985 // Build update: Var = InitExpr + IV * Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013986 ExprResult Update;
Alexey Bataeve3727102018-04-18 15:57:46 +000013987 if (!Info.first)
Alexey Bataevf8be4762019-08-14 19:30:06 +000013988 Update = buildCounterUpdate(
13989 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
13990 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000013991 else
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013992 Update = *CurPrivate;
Stephen Kellyf2ceec42018-08-09 21:08:08 +000013993 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000013994 /*DiscardedValue*/ false);
Alexander Musman3276a272015-03-21 10:12:56 +000013995
13996 // Build final: Var = InitExpr + NumIterations * Step
Alexey Bataev5dff95c2016-04-22 03:56:56 +000013997 ExprResult Final;
Alexey Bataeve3727102018-04-18 15:57:46 +000013998 if (!Info.first)
13999 Final =
14000 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
Alexey Bataevf8be4762019-08-14 19:30:06 +000014001 InitExpr, NumIterations, Step, /*Subtract=*/false,
14002 /*IsNonRectangularLB=*/false);
Alexey Bataeve3727102018-04-18 15:57:46 +000014003 else
Alexey Bataev5dff95c2016-04-22 03:56:56 +000014004 Final = *CurPrivate;
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014005 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000014006 /*DiscardedValue*/ false);
Alexey Bataev5dff95c2016-04-22 03:56:56 +000014007
Alexander Musman3276a272015-03-21 10:12:56 +000014008 if (!Update.isUsable() || !Final.isUsable()) {
14009 Updates.push_back(nullptr);
14010 Finals.push_back(nullptr);
Alexey Bataev195ae902019-08-08 13:42:45 +000014011 UsedExprs.push_back(nullptr);
Alexander Musman3276a272015-03-21 10:12:56 +000014012 HasErrors = true;
14013 } else {
14014 Updates.push_back(Update.get());
14015 Finals.push_back(Final.get());
Alexey Bataev195ae902019-08-08 13:42:45 +000014016 if (!Info.first)
14017 UsedExprs.push_back(SimpleRefExpr);
Alexander Musman3276a272015-03-21 10:12:56 +000014018 }
Richard Trieucc3949d2016-02-18 22:34:54 +000014019 ++CurInit;
14020 ++CurPrivate;
Alexander Musman3276a272015-03-21 10:12:56 +000014021 }
Alexey Bataev195ae902019-08-08 13:42:45 +000014022 if (Expr *S = Clause.getStep())
14023 UsedExprs.push_back(S);
14024 // Fill the remaining part with the nullptr.
14025 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
Alexander Musman3276a272015-03-21 10:12:56 +000014026 Clause.setUpdates(Updates);
14027 Clause.setFinals(Finals);
Alexey Bataev195ae902019-08-08 13:42:45 +000014028 Clause.setUsedExprs(UsedExprs);
Alexander Musman3276a272015-03-21 10:12:56 +000014029 return HasErrors;
Alexander Musman8dba6642014-04-22 13:09:42 +000014030}
14031
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014032OMPClause *Sema::ActOnOpenMPAlignedClause(
14033 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
14034 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014035 SmallVector<Expr *, 8> Vars;
Alexey Bataeve3727102018-04-18 15:57:46 +000014036 for (Expr *RefExpr : VarList) {
Alexey Bataev1efd1662016-03-29 10:59:56 +000014037 assert(RefExpr && "NULL expr in OpenMP linear clause.");
14038 SourceLocation ELoc;
14039 SourceRange ERange;
14040 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000014041 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataev1efd1662016-03-29 10:59:56 +000014042 if (Res.second) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014043 // It will be analyzed later.
14044 Vars.push_back(RefExpr);
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014045 }
Alexey Bataev1efd1662016-03-29 10:59:56 +000014046 ValueDecl *D = Res.first;
14047 if (!D)
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014048 continue;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014049
Alexey Bataev1efd1662016-03-29 10:59:56 +000014050 QualType QType = D->getType();
14051 auto *VD = dyn_cast<VarDecl>(D);
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014052
14053 // OpenMP [2.8.1, simd construct, Restrictions]
14054 // The type of list items appearing in the aligned clause must be
14055 // array, pointer, reference to array, or reference to pointer.
Alexey Bataevf120c0d2015-05-19 07:46:42 +000014056 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014057 const Type *Ty = QType.getTypePtrOrNull();
Alexey Bataev1efd1662016-03-29 10:59:56 +000014058 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014059 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
Alexey Bataev1efd1662016-03-29 10:59:56 +000014060 << QType << getLangOpts().CPlusPlus << ERange;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014061 bool IsDecl =
Alexey Bataev1efd1662016-03-29 10:59:56 +000014062 !VD ||
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014063 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataev1efd1662016-03-29 10:59:56 +000014064 Diag(D->getLocation(),
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014065 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataev1efd1662016-03-29 10:59:56 +000014066 << D;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014067 continue;
14068 }
14069
14070 // OpenMP [2.8.1, simd construct, Restrictions]
14071 // A list-item cannot appear in more than one aligned clause.
Alexey Bataeve3727102018-04-18 15:57:46 +000014072 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
Alexey Bataevd93d3762016-04-12 09:35:56 +000014073 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014074 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
14075 << getOpenMPClauseName(OMPC_aligned);
14076 continue;
14077 }
14078
Alexey Bataev1efd1662016-03-29 10:59:56 +000014079 DeclRefExpr *Ref = nullptr;
Alexey Bataeve3727102018-04-18 15:57:46 +000014080 if (!VD && isOpenMPCapturedDecl(D))
Alexey Bataev1efd1662016-03-29 10:59:56 +000014081 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14082 Vars.push_back(DefaultFunctionArrayConversion(
14083 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
14084 .get());
Alexander Musmanf0d76e72014-05-29 14:36:25 +000014085 }
14086
14087 // OpenMP [2.8.1, simd construct, Description]
14088 // The parameter of the aligned clause, alignment, must be a constant
14089 // positive integer expression.
14090 // If no optional parameter is specified, implementation-defined default
14091 // alignments for SIMD instructions on the target platforms are assumed.
14092 if (Alignment != nullptr) {
14093 ExprResult AlignResult =
14094 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
14095 if (AlignResult.isInvalid())
14096 return nullptr;
14097 Alignment = AlignResult.get();
14098 }
14099 if (Vars.empty())
14100 return nullptr;
14101
14102 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
14103 EndLoc, Vars, Alignment);
14104}
14105
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014106OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
14107 SourceLocation StartLoc,
14108 SourceLocation LParenLoc,
14109 SourceLocation EndLoc) {
14110 SmallVector<Expr *, 8> Vars;
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014111 SmallVector<Expr *, 8> SrcExprs;
14112 SmallVector<Expr *, 8> DstExprs;
14113 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataeve3727102018-04-18 15:57:46 +000014114 for (Expr *RefExpr : VarList) {
Alexey Bataeved09d242014-05-28 05:53:51 +000014115 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
14116 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014117 // It will be analyzed later.
Alexey Bataeved09d242014-05-28 05:53:51 +000014118 Vars.push_back(RefExpr);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014119 SrcExprs.push_back(nullptr);
14120 DstExprs.push_back(nullptr);
14121 AssignmentOps.push_back(nullptr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014122 continue;
14123 }
14124
Alexey Bataeved09d242014-05-28 05:53:51 +000014125 SourceLocation ELoc = RefExpr->getExprLoc();
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014126 // OpenMP [2.1, C/C++]
14127 // A list item is a variable name.
14128 // OpenMP [2.14.4.1, Restrictions, p.1]
14129 // A list item that appears in a copyin clause must be threadprivate.
Alexey Bataeve3727102018-04-18 15:57:46 +000014130 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014131 if (!DE || !isa<VarDecl>(DE->getDecl())) {
Alexey Bataev48c0bfb2016-01-20 09:07:54 +000014132 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
14133 << 0 << RefExpr->getSourceRange();
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014134 continue;
14135 }
14136
14137 Decl *D = DE->getDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +000014138 auto *VD = cast<VarDecl>(D);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014139
14140 QualType Type = VD->getType();
14141 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
14142 // It will be analyzed later.
14143 Vars.push_back(DE);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014144 SrcExprs.push_back(nullptr);
14145 DstExprs.push_back(nullptr);
14146 AssignmentOps.push_back(nullptr);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014147 continue;
14148 }
14149
14150 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
14151 // A list item that appears in a copyin clause must be threadprivate.
14152 if (!DSAStack->isThreadPrivate(VD)) {
14153 Diag(ELoc, diag::err_omp_required_access)
Alexey Bataeved09d242014-05-28 05:53:51 +000014154 << getOpenMPClauseName(OMPC_copyin)
14155 << getOpenMPDirectiveName(OMPD_threadprivate);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014156 continue;
14157 }
14158
14159 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14160 // A variable of class type (or array thereof) that appears in a
Alexey Bataev23b69422014-06-18 07:08:49 +000014161 // copyin clause requires an accessible, unambiguous copy assignment
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014162 // operator for the class type.
Alexey Bataeve3727102018-04-18 15:57:46 +000014163 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14164 VarDecl *SrcVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014165 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +000014166 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000014167 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
Alexey Bataevf120c0d2015-05-19 07:46:42 +000014168 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
Alexey Bataeve3727102018-04-18 15:57:46 +000014169 VarDecl *DstVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014170 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
Alexey Bataev1d7f0fa2015-09-10 09:48:30 +000014171 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000014172 DeclRefExpr *PseudoDstExpr =
Alexey Bataevf120c0d2015-05-19 07:46:42 +000014173 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014174 // For arrays generate assignment operation for single element and replace
14175 // it by the original array element in CodeGen.
Alexey Bataeve3727102018-04-18 15:57:46 +000014176 ExprResult AssignmentOp =
14177 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
14178 PseudoSrcExpr);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014179 if (AssignmentOp.isInvalid())
14180 continue;
14181 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000014182 /*DiscardedValue*/ false);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014183 if (AssignmentOp.isInvalid())
14184 continue;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014185
14186 DSAStack->addDSA(VD, DE, OMPC_copyin);
14187 Vars.push_back(DE);
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014188 SrcExprs.push_back(PseudoSrcExpr);
14189 DstExprs.push_back(PseudoDstExpr);
14190 AssignmentOps.push_back(AssignmentOp.get());
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014191 }
14192
Alexey Bataeved09d242014-05-28 05:53:51 +000014193 if (Vars.empty())
14194 return nullptr;
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014195
Alexey Bataevf56f98c2015-04-16 05:39:01 +000014196 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14197 SrcExprs, DstExprs, AssignmentOps);
Alexey Bataevd48bcd82014-03-31 03:36:38 +000014198}
14199
Alexey Bataevbae9a792014-06-27 10:37:06 +000014200OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
14201 SourceLocation StartLoc,
14202 SourceLocation LParenLoc,
14203 SourceLocation EndLoc) {
14204 SmallVector<Expr *, 8> Vars;
Alexey Bataeva63048e2015-03-23 06:18:07 +000014205 SmallVector<Expr *, 8> SrcExprs;
14206 SmallVector<Expr *, 8> DstExprs;
14207 SmallVector<Expr *, 8> AssignmentOps;
Alexey Bataeve3727102018-04-18 15:57:46 +000014208 for (Expr *RefExpr : VarList) {
Alexey Bataeve122da12016-03-17 10:50:17 +000014209 assert(RefExpr && "NULL expr in OpenMP linear clause.");
14210 SourceLocation ELoc;
14211 SourceRange ERange;
14212 Expr *SimpleRefExpr = RefExpr;
Alexey Bataevbc529672018-09-28 19:33:14 +000014213 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
Alexey Bataeve122da12016-03-17 10:50:17 +000014214 if (Res.second) {
Alexey Bataevbae9a792014-06-27 10:37:06 +000014215 // It will be analyzed later.
14216 Vars.push_back(RefExpr);
Alexey Bataeva63048e2015-03-23 06:18:07 +000014217 SrcExprs.push_back(nullptr);
14218 DstExprs.push_back(nullptr);
14219 AssignmentOps.push_back(nullptr);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014220 }
Alexey Bataeve122da12016-03-17 10:50:17 +000014221 ValueDecl *D = Res.first;
14222 if (!D)
Alexey Bataevbae9a792014-06-27 10:37:06 +000014223 continue;
Alexey Bataevbae9a792014-06-27 10:37:06 +000014224
Alexey Bataeve122da12016-03-17 10:50:17 +000014225 QualType Type = D->getType();
14226 auto *VD = dyn_cast<VarDecl>(D);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014227
14228 // OpenMP [2.14.4.2, Restrictions, p.2]
14229 // A list item that appears in a copyprivate clause may not appear in a
14230 // private or firstprivate clause on the single construct.
Alexey Bataeve122da12016-03-17 10:50:17 +000014231 if (!VD || !DSAStack->isThreadPrivate(VD)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014232 DSAStackTy::DSAVarData DVar =
14233 DSAStack->getTopDSA(D, /*FromParent=*/false);
Alexey Bataeva63048e2015-03-23 06:18:07 +000014234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
14235 DVar.RefExpr) {
Alexey Bataevbae9a792014-06-27 10:37:06 +000014236 Diag(ELoc, diag::err_omp_wrong_dsa)
14237 << getOpenMPClauseName(DVar.CKind)
14238 << getOpenMPClauseName(OMPC_copyprivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000014239 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014240 continue;
14241 }
14242
14243 // OpenMP [2.11.4.2, Restrictions, p.1]
14244 // All list items that appear in a copyprivate clause must be either
14245 // threadprivate or private in the enclosing context.
14246 if (DVar.CKind == OMPC_unknown) {
Alexey Bataeve122da12016-03-17 10:50:17 +000014247 DVar = DSAStack->getImplicitDSA(D, false);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014248 if (DVar.CKind == OMPC_shared) {
14249 Diag(ELoc, diag::err_omp_required_access)
14250 << getOpenMPClauseName(OMPC_copyprivate)
14251 << "threadprivate or private in the enclosing context";
Alexey Bataeve3727102018-04-18 15:57:46 +000014252 reportOriginalDsa(*this, DSAStack, D, DVar);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014253 continue;
14254 }
14255 }
14256 }
14257
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014258 // Variably modified types are not supported.
Alexey Bataev5129d3a2015-05-21 09:47:46 +000014259 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014260 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
Alexey Bataevccb59ec2015-05-19 08:44:56 +000014261 << getOpenMPClauseName(OMPC_copyprivate) << Type
14262 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014263 bool IsDecl =
Alexey Bataeve122da12016-03-17 10:50:17 +000014264 !VD ||
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014265 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Alexey Bataeve122da12016-03-17 10:50:17 +000014266 Diag(D->getLocation(),
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014267 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
Alexey Bataeve122da12016-03-17 10:50:17 +000014268 << D;
Alexey Bataev7a3e5852015-05-19 08:19:24 +000014269 continue;
14270 }
Alexey Bataevccb59ec2015-05-19 08:44:56 +000014271
Alexey Bataevbae9a792014-06-27 10:37:06 +000014272 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14273 // A variable of class type (or array thereof) that appears in a
14274 // copyin clause requires an accessible, unambiguous copy assignment
14275 // operator for the class type.
Alexey Bataevbd9fec12015-08-18 06:47:21 +000014276 Type = Context.getBaseElementType(Type.getNonReferenceType())
14277 .getUnqualifiedType();
Alexey Bataeve3727102018-04-18 15:57:46 +000014278 VarDecl *SrcVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014279 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
Alexey Bataeve122da12016-03-17 10:50:17 +000014280 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000014281 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
14282 VarDecl *DstVD =
Stephen Kellyf2ceec42018-08-09 21:08:08 +000014283 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
Alexey Bataeve122da12016-03-17 10:50:17 +000014284 D->hasAttrs() ? &D->getAttrs() : nullptr);
Alexey Bataeve3727102018-04-18 15:57:46 +000014285 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14286 ExprResult AssignmentOp = BuildBinOp(
14287 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
Alexey Bataeva63048e2015-03-23 06:18:07 +000014288 if (AssignmentOp.isInvalid())
14289 continue;
Aaron Ballmanfb6deeb2019-01-04 16:58:14 +000014290 AssignmentOp =
14291 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
Alexey Bataeva63048e2015-03-23 06:18:07 +000014292 if (AssignmentOp.isInvalid())
14293 continue;
Alexey Bataevbae9a792014-06-27 10:37:06 +000014294
14295 // No need to mark vars as copyprivate, they are already threadprivate or
14296 // implicitly private.
Alexey Bataeve3727102018-04-18 15:57:46 +000014297 assert(VD || isOpenMPCapturedDecl(D));
Alexey Bataeve122da12016-03-17 10:50:17 +000014298 Vars.push_back(
14299 VD ? RefExpr->IgnoreParens()
14300 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
Alexey Bataeva63048e2015-03-23 06:18:07 +000014301 SrcExprs.push_back(PseudoSrcExpr);
14302 DstExprs.push_back(PseudoDstExpr);
14303 AssignmentOps.push_back(AssignmentOp.get());
Alexey Bataevbae9a792014-06-27 10:37:06 +000014304 }
14305
14306 if (Vars.empty())
14307 return nullptr;
14308
Alexey Bataeva63048e2015-03-23 06:18:07 +000014309 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14310 Vars, SrcExprs, DstExprs, AssignmentOps);
Alexey Bataevbae9a792014-06-27 10:37:06 +000014311}
14312
Alexey Bataev6125da92014-07-21 11:26:11 +000014313OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
14314 SourceLocation StartLoc,
14315 SourceLocation LParenLoc,
14316 SourceLocation EndLoc) {
14317 if (VarList.empty())
14318 return nullptr;
14319
14320 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
14321}
Alexey Bataevdea47612014-07-23 07:46:59 +000014322
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014323OMPClause *
14324Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
14325 SourceLocation DepLoc, SourceLocation ColonLoc,
14326 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
14327 SourceLocation LParenLoc, SourceLocation EndLoc) {
Alexey Bataeveb482352015-12-18 05:05:56 +000014328 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014329 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
Alexey Bataeveb482352015-12-18 05:05:56 +000014330 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000014331 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
Alexey Bataeveb482352015-12-18 05:05:56 +000014332 return nullptr;
14333 }
14334 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014335 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
14336 DepKind == OMPC_DEPEND_sink)) {
Alexey Bataev6402bca2015-12-28 07:25:51 +000014337 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014338 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
Alexey Bataev6402bca2015-12-28 07:25:51 +000014339 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14340 /*Last=*/OMPC_DEPEND_unknown, Except)
14341 << getOpenMPClauseName(OMPC_depend);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014342 return nullptr;
14343 }
14344 SmallVector<Expr *, 8> Vars;
Alexey Bataev8b427062016-05-25 12:36:08 +000014345 DSAStackTy::OperatorOffsetTy OpsOffs;
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014346 llvm::APSInt DepCounter(/*BitWidth=*/32);
14347 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
Alexey Bataevf138fda2018-08-13 19:04:24 +000014348 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
14349 if (const Expr *OrderedCountExpr =
14350 DSAStack->getParentOrderedRegionParam().first) {
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014351 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
14352 TotalDepCount.setIsUnsigned(/*Val=*/true);
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014353 }
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014354 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014355 for (Expr *RefExpr : VarList) {
Alexey Bataev17daedf2018-02-15 22:42:57 +000014356 assert(RefExpr && "NULL expr in OpenMP shared clause.");
14357 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14358 // It will be analyzed later.
14359 Vars.push_back(RefExpr);
14360 continue;
14361 }
14362
14363 SourceLocation ELoc = RefExpr->getExprLoc();
Alexey Bataeve3727102018-04-18 15:57:46 +000014364 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
Alexey Bataev17daedf2018-02-15 22:42:57 +000014365 if (DepKind == OMPC_DEPEND_sink) {
Alexey Bataevf138fda2018-08-13 19:04:24 +000014366 if (DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000014367 DepCounter >= TotalDepCount) {
14368 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
14369 continue;
14370 }
14371 ++DepCounter;
14372 // OpenMP [2.13.9, Summary]
14373 // depend(dependence-type : vec), where dependence-type is:
14374 // 'sink' and where vec is the iteration vector, which has the form:
14375 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
14376 // where n is the value specified by the ordered clause in the loop
14377 // directive, xi denotes the loop iteration variable of the i-th nested
14378 // loop associated with the loop directive, and di is a constant
14379 // non-negative integer.
14380 if (CurContext->isDependentContext()) {
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014381 // It will be analyzed later.
14382 Vars.push_back(RefExpr);
14383 continue;
14384 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000014385 SimpleExpr = SimpleExpr->IgnoreImplicit();
14386 OverloadedOperatorKind OOK = OO_None;
14387 SourceLocation OOLoc;
14388 Expr *LHS = SimpleExpr;
14389 Expr *RHS = nullptr;
14390 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
14391 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
14392 OOLoc = BO->getOperatorLoc();
14393 LHS = BO->getLHS()->IgnoreParenImpCasts();
14394 RHS = BO->getRHS()->IgnoreParenImpCasts();
14395 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
14396 OOK = OCE->getOperator();
14397 OOLoc = OCE->getOperatorLoc();
14398 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
14399 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
14400 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
14401 OOK = MCE->getMethodDecl()
14402 ->getNameInfo()
14403 .getName()
14404 .getCXXOverloadedOperator();
14405 OOLoc = MCE->getCallee()->getExprLoc();
14406 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
14407 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014408 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000014409 SourceLocation ELoc;
14410 SourceRange ERange;
Alexey Bataevbc529672018-09-28 19:33:14 +000014411 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
Alexey Bataev17daedf2018-02-15 22:42:57 +000014412 if (Res.second) {
14413 // It will be analyzed later.
14414 Vars.push_back(RefExpr);
14415 }
14416 ValueDecl *D = Res.first;
14417 if (!D)
14418 continue;
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014419
Alexey Bataev17daedf2018-02-15 22:42:57 +000014420 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
14421 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
14422 continue;
14423 }
14424 if (RHS) {
14425 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
14426 RHS, OMPC_depend, /*StrictlyPositive=*/false);
14427 if (RHSRes.isInvalid())
14428 continue;
14429 }
14430 if (!CurContext->isDependentContext() &&
Alexey Bataevf138fda2018-08-13 19:04:24 +000014431 DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000014432 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014433 const ValueDecl *VD =
Alexey Bataev17daedf2018-02-15 22:42:57 +000014434 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
Alexey Bataeve3727102018-04-18 15:57:46 +000014435 if (VD)
Alexey Bataev17daedf2018-02-15 22:42:57 +000014436 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
14437 << 1 << VD;
Alexey Bataeve3727102018-04-18 15:57:46 +000014438 else
Alexey Bataev17daedf2018-02-15 22:42:57 +000014439 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
Alexey Bataev17daedf2018-02-15 22:42:57 +000014440 continue;
14441 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014442 OpsOffs.emplace_back(RHS, OOK);
Alexey Bataev17daedf2018-02-15 22:42:57 +000014443 } else {
14444 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
14445 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
14446 (ASE &&
14447 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
14448 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
14449 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
14450 << RefExpr->getSourceRange();
14451 continue;
14452 }
Richard Smith2e3ed4a2019-08-16 19:53:22 +000014453
14454 ExprResult Res;
14455 {
14456 Sema::TentativeAnalysisScope Trap(*this);
14457 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
14458 RefExpr->IgnoreParenImpCasts());
14459 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000014460 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
14461 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
14462 << RefExpr->getSourceRange();
14463 continue;
14464 }
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014465 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000014466 Vars.push_back(RefExpr->IgnoreParenImpCasts());
Alexey Bataeva636c7f2015-12-23 10:27:45 +000014467 }
Alexey Bataev17daedf2018-02-15 22:42:57 +000014468
14469 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
14470 TotalDepCount > VarList.size() &&
Alexey Bataevf138fda2018-08-13 19:04:24 +000014471 DSAStack->getParentOrderedRegionParam().first &&
Alexey Bataev17daedf2018-02-15 22:42:57 +000014472 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
14473 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
14474 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
14475 }
14476 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
14477 Vars.empty())
14478 return nullptr;
14479
Alexey Bataev8b427062016-05-25 12:36:08 +000014480 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
Alexey Bataevf138fda2018-08-13 19:04:24 +000014481 DepKind, DepLoc, ColonLoc, Vars,
14482 TotalDepCount.getZExtValue());
Alexey Bataev17daedf2018-02-15 22:42:57 +000014483 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
14484 DSAStack->isParentOrderedRegion())
Alexey Bataev8b427062016-05-25 12:36:08 +000014485 DSAStack->addDoacrossDependClause(C, OpsOffs);
14486 return C;
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +000014487}
Michael Wonge710d542015-08-07 16:16:36 +000014488
14489OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
14490 SourceLocation LParenLoc,
14491 SourceLocation EndLoc) {
14492 Expr *ValExpr = Device;
Alexey Bataev931e19b2017-10-02 16:32:39 +000014493 Stmt *HelperValStmt = nullptr;
Michael Wonge710d542015-08-07 16:16:36 +000014494
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014495 // OpenMP [2.9.1, Restrictions]
14496 // The device expression must evaluate to a non-negative integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000014497 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
Alexey Bataeva0569352015-12-01 10:17:31 +000014498 /*StrictlyPositive=*/false))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000014499 return nullptr;
14500
Alexey Bataev931e19b2017-10-02 16:32:39 +000014501 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000014502 OpenMPDirectiveKind CaptureRegion =
14503 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
14504 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000014505 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000014506 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev931e19b2017-10-02 16:32:39 +000014507 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14508 HelperValStmt = buildPreInits(Context, Captures);
14509 }
14510
Alexey Bataev8451efa2018-01-15 19:06:12 +000014511 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
14512 StartLoc, LParenLoc, EndLoc);
Michael Wonge710d542015-08-07 16:16:36 +000014513}
Kelvin Li0bff7af2015-11-23 05:32:03 +000014514
Alexey Bataeve3727102018-04-18 15:57:46 +000014515static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
Alexey Bataev95c23e72018-02-27 21:31:11 +000014516 DSAStackTy *Stack, QualType QTy,
14517 bool FullCheck = true) {
Kelvin Li0bff7af2015-11-23 05:32:03 +000014518 NamedDecl *ND;
14519 if (QTy->isIncompleteType(&ND)) {
14520 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
14521 return false;
Kelvin Li0bff7af2015-11-23 05:32:03 +000014522 }
Alexey Bataev95c23e72018-02-27 21:31:11 +000014523 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
14524 !QTy.isTrivialType(SemaRef.Context))
14525 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
Kelvin Li0bff7af2015-11-23 05:32:03 +000014526 return true;
14527}
14528
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000014529/// Return true if it can be proven that the provided array expression
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014530/// (array section or array subscript) does NOT specify the whole size of the
14531/// array whose base type is \a BaseQTy.
Alexey Bataeve3727102018-04-18 15:57:46 +000014532static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014533 const Expr *E,
14534 QualType BaseQTy) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014535 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014536
14537 // If this is an array subscript, it refers to the whole size if the size of
14538 // the dimension is constant and equals 1. Also, an array section assumes the
14539 // format of an array subscript if no colon is used.
14540 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014541 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014542 return ATy->getSize().getSExtValue() != 1;
14543 // Size can't be evaluated statically.
14544 return false;
14545 }
14546
14547 assert(OASE && "Expecting array section if not an array subscript.");
Alexey Bataeve3727102018-04-18 15:57:46 +000014548 const Expr *LowerBound = OASE->getLowerBound();
14549 const Expr *Length = OASE->getLength();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014550
14551 // If there is a lower bound that does not evaluates to zero, we are not
David Majnemer9d168222016-08-05 17:44:54 +000014552 // covering the whole dimension.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014553 if (LowerBound) {
Fangrui Song407659a2018-11-30 23:41:18 +000014554 Expr::EvalResult Result;
14555 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014556 return false; // Can't get the integer value as a constant.
Fangrui Song407659a2018-11-30 23:41:18 +000014557
14558 llvm::APSInt ConstLowerBound = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014559 if (ConstLowerBound.getSExtValue())
14560 return true;
14561 }
14562
14563 // If we don't have a length we covering the whole dimension.
14564 if (!Length)
14565 return false;
14566
14567 // If the base is a pointer, we don't have a way to get the size of the
14568 // pointee.
14569 if (BaseQTy->isPointerType())
14570 return false;
14571
14572 // We can only check if the length is the same as the size of the dimension
14573 // if we have a constant array.
Alexey Bataeve3727102018-04-18 15:57:46 +000014574 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014575 if (!CATy)
14576 return false;
14577
Fangrui Song407659a2018-11-30 23:41:18 +000014578 Expr::EvalResult Result;
14579 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014580 return false; // Can't get the integer value as a constant.
14581
Fangrui Song407659a2018-11-30 23:41:18 +000014582 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014583 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
14584}
14585
14586// Return true if it can be proven that the provided array expression (array
14587// section or array subscript) does NOT specify a single element of the array
14588// whose base type is \a BaseQTy.
Alexey Bataeve3727102018-04-18 15:57:46 +000014589static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
David Majnemer9d168222016-08-05 17:44:54 +000014590 const Expr *E,
14591 QualType BaseQTy) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014592 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014593
14594 // An array subscript always refer to a single element. Also, an array section
14595 // assumes the format of an array subscript if no colon is used.
14596 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
14597 return false;
14598
14599 assert(OASE && "Expecting array section if not an array subscript.");
Alexey Bataeve3727102018-04-18 15:57:46 +000014600 const Expr *Length = OASE->getLength();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014601
14602 // If we don't have a length we have to check if the array has unitary size
14603 // for this dimension. Also, we should always expect a length if the base type
14604 // is pointer.
14605 if (!Length) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014606 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014607 return ATy->getSize().getSExtValue() != 1;
14608 // We cannot assume anything.
14609 return false;
14610 }
14611
14612 // Check if the length evaluates to 1.
Fangrui Song407659a2018-11-30 23:41:18 +000014613 Expr::EvalResult Result;
14614 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014615 return false; // Can't get the integer value as a constant.
14616
Fangrui Song407659a2018-11-30 23:41:18 +000014617 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014618 return ConstLength.getSExtValue() != 1;
14619}
14620
Samuel Antao661c0902016-05-26 17:39:58 +000014621// Return the expression of the base of the mappable expression or null if it
14622// cannot be determined and do all the necessary checks to see if the expression
14623// is valid as a standalone mappable expression. In the process, record all the
Samuel Antao90927002016-04-26 14:54:23 +000014624// components of the expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000014625static const Expr *checkMapClauseExpressionBase(
Samuel Antao90927002016-04-26 14:54:23 +000014626 Sema &SemaRef, Expr *E,
Samuel Antao661c0902016-05-26 17:39:58 +000014627 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014628 OpenMPClauseKind CKind, bool NoDiagnose) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014629 SourceLocation ELoc = E->getExprLoc();
14630 SourceRange ERange = E->getSourceRange();
14631
14632 // The base of elements of list in a map clause have to be either:
14633 // - a reference to variable or field.
14634 // - a member expression.
14635 // - an array expression.
14636 //
14637 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
14638 // reference to 'r'.
14639 //
14640 // If we have:
14641 //
14642 // struct SS {
14643 // Bla S;
14644 // foo() {
14645 // #pragma omp target map (S.Arr[:12]);
14646 // }
14647 // }
14648 //
14649 // We want to retrieve the member expression 'this->S';
14650
Alexey Bataeve3727102018-04-18 15:57:46 +000014651 const Expr *RelevantExpr = nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014652
Samuel Antao5de996e2016-01-22 20:21:36 +000014653 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
14654 // If a list item is an array section, it must specify contiguous storage.
14655 //
14656 // For this restriction it is sufficient that we make sure only references
14657 // to variables or fields and array expressions, and that no array sections
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014658 // exist except in the rightmost expression (unless they cover the whole
14659 // dimension of the array). E.g. these would be invalid:
Samuel Antao5de996e2016-01-22 20:21:36 +000014660 //
14661 // r.ArrS[3:5].Arr[6:7]
14662 //
14663 // r.ArrS[3:5].x
14664 //
14665 // but these would be valid:
14666 // r.ArrS[3].Arr[6:7]
14667 //
14668 // r.ArrS[3].x
14669
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014670 bool AllowUnitySizeArraySection = true;
14671 bool AllowWholeSizeArraySection = true;
Samuel Antao5de996e2016-01-22 20:21:36 +000014672
Dmitry Polukhin644a9252016-03-11 07:58:34 +000014673 while (!RelevantExpr) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014674 E = E->IgnoreParenImpCasts();
14675
14676 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
14677 if (!isa<VarDecl>(CurE->getDecl()))
Alexey Bataev27041fa2017-12-05 15:22:49 +000014678 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014679
14680 RelevantExpr = CurE;
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014681
14682 // If we got a reference to a declaration, we should not expect any array
14683 // section before that.
14684 AllowUnitySizeArraySection = false;
14685 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000014686
14687 // Record the component.
Alexey Bataev27041fa2017-12-05 15:22:49 +000014688 CurComponents.emplace_back(CurE, CurE->getDecl());
14689 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014690 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
Samuel Antao5de996e2016-01-22 20:21:36 +000014691
14692 if (isa<CXXThisExpr>(BaseE))
14693 // We found a base expression: this->Val.
14694 RelevantExpr = CurE;
14695 else
14696 E = BaseE;
14697
14698 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014699 if (!NoDiagnose) {
14700 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
14701 << CurE->getSourceRange();
14702 return nullptr;
14703 }
14704 if (RelevantExpr)
14705 return nullptr;
14706 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000014707 }
14708
14709 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
14710
14711 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
14712 // A bit-field cannot appear in a map clause.
14713 //
14714 if (FD->isBitField()) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014715 if (!NoDiagnose) {
14716 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
14717 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
14718 return nullptr;
14719 }
14720 if (RelevantExpr)
14721 return nullptr;
14722 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000014723 }
14724
14725 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14726 // If the type of a list item is a reference to a type T then the type
14727 // will be considered to be T for all purposes of this clause.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014728 QualType CurType = BaseE->getType().getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000014729
14730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
14731 // A list item cannot be a variable that is a member of a structure with
14732 // a union type.
14733 //
Alexey Bataeve3727102018-04-18 15:57:46 +000014734 if (CurType->isUnionType()) {
14735 if (!NoDiagnose) {
14736 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
14737 << CurE->getSourceRange();
14738 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014739 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014740 continue;
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014741 }
Samuel Antao5de996e2016-01-22 20:21:36 +000014742
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014743 // If we got a member expression, we should not expect any array section
14744 // before that:
14745 //
14746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
14747 // If a list item is an element of a structure, only the rightmost symbol
14748 // of the variable reference can be an array section.
14749 //
14750 AllowUnitySizeArraySection = false;
14751 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000014752
14753 // Record the component.
Alexey Bataev27041fa2017-12-05 15:22:49 +000014754 CurComponents.emplace_back(CurE, FD);
14755 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014756 E = CurE->getBase()->IgnoreParenImpCasts();
14757
14758 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014759 if (!NoDiagnose) {
14760 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
14761 << 0 << CurE->getSourceRange();
14762 return nullptr;
14763 }
14764 continue;
Samuel Antao5de996e2016-01-22 20:21:36 +000014765 }
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014766
14767 // If we got an array subscript that express the whole dimension we
14768 // can have any array expressions before. If it only expressing part of
14769 // the dimension, we can only have unitary-size array expressions.
Alexey Bataeve3727102018-04-18 15:57:46 +000014770 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014771 E->getType()))
14772 AllowWholeSizeArraySection = false;
Samuel Antao90927002016-04-26 14:54:23 +000014773
Patrick Lystere13b1e32019-01-02 19:28:48 +000014774 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
14775 Expr::EvalResult Result;
14776 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
14777 if (!Result.Val.getInt().isNullValue()) {
14778 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
14779 diag::err_omp_invalid_map_this_expr);
14780 SemaRef.Diag(CurE->getIdx()->getExprLoc(),
14781 diag::note_omp_invalid_subscript_on_this_ptr_map);
14782 }
14783 }
14784 RelevantExpr = TE;
14785 }
14786
Samuel Antao90927002016-04-26 14:54:23 +000014787 // Record the component - we don't have any declaration associated.
Alexey Bataev27041fa2017-12-05 15:22:49 +000014788 CurComponents.emplace_back(CurE, nullptr);
14789 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014790 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
Samuel Antao5de996e2016-01-22 20:21:36 +000014791 E = CurE->getBase()->IgnoreParenImpCasts();
14792
Alexey Bataev27041fa2017-12-05 15:22:49 +000014793 QualType CurType =
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014794 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
14795
Samuel Antao5de996e2016-01-22 20:21:36 +000014796 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14797 // If the type of a list item is a reference to a type T then the type
14798 // will be considered to be T for all purposes of this clause.
Samuel Antao5de996e2016-01-22 20:21:36 +000014799 if (CurType->isReferenceType())
14800 CurType = CurType->getPointeeType();
14801
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014802 bool IsPointer = CurType->isAnyPointerType();
14803
14804 if (!IsPointer && !CurType->isArrayType()) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014805 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
14806 << 0 << CurE->getSourceRange();
Alexey Bataev27041fa2017-12-05 15:22:49 +000014807 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014808 }
14809
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014810 bool NotWhole =
Alexey Bataeve3727102018-04-18 15:57:46 +000014811 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014812 bool NotUnity =
Alexey Bataeve3727102018-04-18 15:57:46 +000014813 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014814
Samuel Antaodab51bb2016-07-18 23:22:11 +000014815 if (AllowWholeSizeArraySection) {
14816 // Any array section is currently allowed. Allowing a whole size array
14817 // section implies allowing a unity array section as well.
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014818 //
14819 // If this array section refers to the whole dimension we can still
14820 // accept other array sections before this one, except if the base is a
14821 // pointer. Otherwise, only unitary sections are accepted.
14822 if (NotWhole || IsPointer)
14823 AllowWholeSizeArraySection = false;
Samuel Antaodab51bb2016-07-18 23:22:11 +000014824 } else if (AllowUnitySizeArraySection && NotUnity) {
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014825 // A unity or whole array section is not allowed and that is not
14826 // compatible with the properties of the current array section.
14827 SemaRef.Diag(
14828 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
14829 << CurE->getSourceRange();
Alexey Bataev27041fa2017-12-05 15:22:49 +000014830 return nullptr;
Samuel Antaoa9f35cb2016-03-09 15:46:05 +000014831 }
Samuel Antao90927002016-04-26 14:54:23 +000014832
Patrick Lystere13b1e32019-01-02 19:28:48 +000014833 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
14834 Expr::EvalResult ResultR;
14835 Expr::EvalResult ResultL;
14836 if (CurE->getLength()->EvaluateAsInt(ResultR,
14837 SemaRef.getASTContext())) {
14838 if (!ResultR.Val.getInt().isOneValue()) {
14839 SemaRef.Diag(CurE->getLength()->getExprLoc(),
14840 diag::err_omp_invalid_map_this_expr);
14841 SemaRef.Diag(CurE->getLength()->getExprLoc(),
14842 diag::note_omp_invalid_length_on_this_ptr_mapping);
14843 }
14844 }
14845 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
14846 ResultL, SemaRef.getASTContext())) {
14847 if (!ResultL.Val.getInt().isNullValue()) {
14848 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
14849 diag::err_omp_invalid_map_this_expr);
14850 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
14851 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
14852 }
14853 }
14854 RelevantExpr = TE;
14855 }
14856
Samuel Antao90927002016-04-26 14:54:23 +000014857 // Record the component - we don't have any declaration associated.
Alexey Bataev27041fa2017-12-05 15:22:49 +000014858 CurComponents.emplace_back(CurE, nullptr);
14859 } else {
Alexey Bataevb7a9b742017-12-05 19:20:09 +000014860 if (!NoDiagnose) {
14861 // If nothing else worked, this is not a valid map clause expression.
14862 SemaRef.Diag(
14863 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
14864 << ERange;
14865 }
Alexey Bataev27041fa2017-12-05 15:22:49 +000014866 return nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014867 }
Samuel Antao5de996e2016-01-22 20:21:36 +000014868 }
14869
14870 return RelevantExpr;
14871}
14872
14873// Return true if expression E associated with value VD has conflicts with other
14874// map information.
Alexey Bataeve3727102018-04-18 15:57:46 +000014875static bool checkMapConflicts(
14876 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
Samuel Antao90927002016-04-26 14:54:23 +000014877 bool CurrentRegionOnly,
Samuel Antao661c0902016-05-26 17:39:58 +000014878 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
14879 OpenMPClauseKind CKind) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014880 assert(VD && E);
Samuel Antao5de996e2016-01-22 20:21:36 +000014881 SourceLocation ELoc = E->getExprLoc();
14882 SourceRange ERange = E->getSourceRange();
14883
14884 // In order to easily check the conflicts we need to match each component of
14885 // the expression under test with the components of the expressions that are
14886 // already in the stack.
14887
Samuel Antao5de996e2016-01-22 20:21:36 +000014888 assert(!CurComponents.empty() && "Map clause expression with no components!");
Samuel Antao90927002016-04-26 14:54:23 +000014889 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
Samuel Antao5de996e2016-01-22 20:21:36 +000014890 "Map clause expression with unexpected base!");
14891
14892 // Variables to help detecting enclosing problems in data environment nests.
14893 bool IsEnclosedByDataEnvironmentExpr = false;
Samuel Antao90927002016-04-26 14:54:23 +000014894 const Expr *EnclosingExpr = nullptr;
Samuel Antao5de996e2016-01-22 20:21:36 +000014895
Samuel Antao90927002016-04-26 14:54:23 +000014896 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
14897 VD, CurrentRegionOnly,
Alexey Bataeve3727102018-04-18 15:57:46 +000014898 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
14899 ERange, CKind, &EnclosingExpr,
14900 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
14901 StackComponents,
14902 OpenMPClauseKind) {
Samuel Antao5de996e2016-01-22 20:21:36 +000014903 assert(!StackComponents.empty() &&
14904 "Map clause expression with no components!");
Samuel Antao90927002016-04-26 14:54:23 +000014905 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
Samuel Antao5de996e2016-01-22 20:21:36 +000014906 "Map clause expression with unexpected base!");
Fangrui Song16fe49a2018-04-18 19:32:01 +000014907 (void)VD;
Samuel Antao5de996e2016-01-22 20:21:36 +000014908
Samuel Antao90927002016-04-26 14:54:23 +000014909 // The whole expression in the stack.
Alexey Bataeve3727102018-04-18 15:57:46 +000014910 const Expr *RE = StackComponents.front().getAssociatedExpression();
Samuel Antao90927002016-04-26 14:54:23 +000014911
Samuel Antao5de996e2016-01-22 20:21:36 +000014912 // Expressions must start from the same base. Here we detect at which
14913 // point both expressions diverge from each other and see if we can
14914 // detect if the memory referred to both expressions is contiguous and
14915 // do not overlap.
14916 auto CI = CurComponents.rbegin();
14917 auto CE = CurComponents.rend();
14918 auto SI = StackComponents.rbegin();
14919 auto SE = StackComponents.rend();
14920 for (; CI != CE && SI != SE; ++CI, ++SI) {
14921
14922 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
14923 // At most one list item can be an array item derived from a given
14924 // variable in map clauses of the same construct.
Samuel Antao90927002016-04-26 14:54:23 +000014925 if (CurrentRegionOnly &&
14926 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
14927 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
14928 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
14929 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
14930 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
Samuel Antao5de996e2016-01-22 20:21:36 +000014931 diag::err_omp_multiple_array_items_in_map_clause)
Samuel Antao90927002016-04-26 14:54:23 +000014932 << CI->getAssociatedExpression()->getSourceRange();
14933 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
14934 diag::note_used_here)
14935 << SI->getAssociatedExpression()->getSourceRange();
Samuel Antao5de996e2016-01-22 20:21:36 +000014936 return true;
14937 }
14938
14939 // Do both expressions have the same kind?
Samuel Antao90927002016-04-26 14:54:23 +000014940 if (CI->getAssociatedExpression()->getStmtClass() !=
14941 SI->getAssociatedExpression()->getStmtClass())
Samuel Antao5de996e2016-01-22 20:21:36 +000014942 break;
14943
14944 // Are we dealing with different variables/fields?
Samuel Antao90927002016-04-26 14:54:23 +000014945 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
Samuel Antao5de996e2016-01-22 20:21:36 +000014946 break;
14947 }
Kelvin Li9f645ae2016-07-18 22:49:16 +000014948 // Check if the extra components of the expressions in the enclosing
14949 // data environment are redundant for the current base declaration.
14950 // If they are, the maps completely overlap, which is legal.
14951 for (; SI != SE; ++SI) {
14952 QualType Type;
Alexey Bataeve3727102018-04-18 15:57:46 +000014953 if (const auto *ASE =
David Majnemer9d168222016-08-05 17:44:54 +000014954 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
Kelvin Li9f645ae2016-07-18 22:49:16 +000014955 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
Alexey Bataeve3727102018-04-18 15:57:46 +000014956 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
David Majnemer9d168222016-08-05 17:44:54 +000014957 SI->getAssociatedExpression())) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014958 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
Kelvin Li9f645ae2016-07-18 22:49:16 +000014959 Type =
14960 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
14961 }
14962 if (Type.isNull() || Type->isAnyPointerType() ||
Alexey Bataeve3727102018-04-18 15:57:46 +000014963 checkArrayExpressionDoesNotReferToWholeSize(
Kelvin Li9f645ae2016-07-18 22:49:16 +000014964 SemaRef, SI->getAssociatedExpression(), Type))
14965 break;
14966 }
Samuel Antao5de996e2016-01-22 20:21:36 +000014967
14968 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
14969 // List items of map clauses in the same construct must not share
14970 // original storage.
14971 //
14972 // If the expressions are exactly the same or one is a subset of the
14973 // other, it means they are sharing storage.
14974 if (CI == CE && SI == SE) {
14975 if (CurrentRegionOnly) {
Alexey Bataeve3727102018-04-18 15:57:46 +000014976 if (CKind == OMPC_map) {
Samuel Antao661c0902016-05-26 17:39:58 +000014977 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
Alexey Bataeve3727102018-04-18 15:57:46 +000014978 } else {
Samuel Antaoec172c62016-05-26 17:49:04 +000014979 assert(CKind == OMPC_to || CKind == OMPC_from);
Samuel Antao661c0902016-05-26 17:39:58 +000014980 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
14981 << ERange;
14982 }
Samuel Antao5de996e2016-01-22 20:21:36 +000014983 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
14984 << RE->getSourceRange();
14985 return true;
Samuel Antao5de996e2016-01-22 20:21:36 +000014986 }
Alexey Bataeve3727102018-04-18 15:57:46 +000014987 // If we find the same expression in the enclosing data environment,
14988 // that is legal.
14989 IsEnclosedByDataEnvironmentExpr = true;
14990 return false;
Samuel Antao5de996e2016-01-22 20:21:36 +000014991 }
14992
Samuel Antao90927002016-04-26 14:54:23 +000014993 QualType DerivedType =
14994 std::prev(CI)->getAssociatedDeclaration()->getType();
14995 SourceLocation DerivedLoc =
14996 std::prev(CI)->getAssociatedExpression()->getExprLoc();
Samuel Antao5de996e2016-01-22 20:21:36 +000014997
14998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
14999 // If the type of a list item is a reference to a type T then the type
15000 // will be considered to be T for all purposes of this clause.
Samuel Antao90927002016-04-26 14:54:23 +000015001 DerivedType = DerivedType.getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000015002
15003 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
15004 // A variable for which the type is pointer and an array section
15005 // derived from that variable must not appear as list items of map
15006 // clauses of the same construct.
15007 //
15008 // Also, cover one of the cases in:
15009 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15010 // If any part of the original storage of a list item has corresponding
15011 // storage in the device data environment, all of the original storage
15012 // must have corresponding storage in the device data environment.
15013 //
15014 if (DerivedType->isAnyPointerType()) {
15015 if (CI == CE || SI == SE) {
15016 SemaRef.Diag(
15017 DerivedLoc,
15018 diag::err_omp_pointer_mapped_along_with_derived_section)
15019 << DerivedLoc;
Alexey Bataev2819260b2018-02-27 17:42:00 +000015020 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15021 << RE->getSourceRange();
15022 return true;
Alexey Bataeve3727102018-04-18 15:57:46 +000015023 }
15024 if (CI->getAssociatedExpression()->getStmtClass() !=
Alexey Bataev2819260b2018-02-27 17:42:00 +000015025 SI->getAssociatedExpression()->getStmtClass() ||
15026 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
15027 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
Samuel Antao5de996e2016-01-22 20:21:36 +000015028 assert(CI != CE && SI != SE);
Alexey Bataev2819260b2018-02-27 17:42:00 +000015029 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
Samuel Antao5de996e2016-01-22 20:21:36 +000015030 << DerivedLoc;
Alexey Bataev2819260b2018-02-27 17:42:00 +000015031 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15032 << RE->getSourceRange();
15033 return true;
Samuel Antao5de996e2016-01-22 20:21:36 +000015034 }
Samuel Antao5de996e2016-01-22 20:21:36 +000015035 }
15036
15037 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
15038 // List items of map clauses in the same construct must not share
15039 // original storage.
15040 //
15041 // An expression is a subset of the other.
15042 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015043 if (CKind == OMPC_map) {
Alexey Bataeve82445f2018-09-20 13:54:02 +000015044 if (CI != CE || SI != SE) {
15045 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
15046 // a pointer.
15047 auto Begin =
15048 CI != CE ? CurComponents.begin() : StackComponents.begin();
15049 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
15050 auto It = Begin;
15051 while (It != End && !It->getAssociatedDeclaration())
15052 std::advance(It, 1);
15053 assert(It != End &&
15054 "Expected at least one component with the declaration.");
15055 if (It != Begin && It->getAssociatedDeclaration()
15056 ->getType()
15057 .getCanonicalType()
15058 ->isAnyPointerType()) {
15059 IsEnclosedByDataEnvironmentExpr = false;
15060 EnclosingExpr = nullptr;
15061 return false;
15062 }
15063 }
Samuel Antao661c0902016-05-26 17:39:58 +000015064 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
Alexey Bataeve3727102018-04-18 15:57:46 +000015065 } else {
Samuel Antaoec172c62016-05-26 17:49:04 +000015066 assert(CKind == OMPC_to || CKind == OMPC_from);
Samuel Antao661c0902016-05-26 17:39:58 +000015067 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15068 << ERange;
15069 }
Samuel Antao5de996e2016-01-22 20:21:36 +000015070 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15071 << RE->getSourceRange();
15072 return true;
15073 }
15074
15075 // The current expression uses the same base as other expression in the
Samuel Antao90927002016-04-26 14:54:23 +000015076 // data environment but does not contain it completely.
Samuel Antao5de996e2016-01-22 20:21:36 +000015077 if (!CurrentRegionOnly && SI != SE)
15078 EnclosingExpr = RE;
15079
15080 // The current expression is a subset of the expression in the data
15081 // environment.
15082 IsEnclosedByDataEnvironmentExpr |=
15083 (!CurrentRegionOnly && CI != CE && SI == SE);
15084
15085 return false;
15086 });
15087
15088 if (CurrentRegionOnly)
15089 return FoundError;
15090
15091 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15092 // If any part of the original storage of a list item has corresponding
15093 // storage in the device data environment, all of the original storage must
15094 // have corresponding storage in the device data environment.
15095 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
15096 // If a list item is an element of a structure, and a different element of
15097 // the structure has a corresponding list item in the device data environment
15098 // prior to a task encountering the construct associated with the map clause,
Samuel Antao90927002016-04-26 14:54:23 +000015099 // then the list item must also have a corresponding list item in the device
Samuel Antao5de996e2016-01-22 20:21:36 +000015100 // data environment prior to the task encountering the construct.
15101 //
15102 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
15103 SemaRef.Diag(ELoc,
15104 diag::err_omp_original_storage_is_shared_and_does_not_contain)
15105 << ERange;
15106 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
15107 << EnclosingExpr->getSourceRange();
15108 return true;
15109 }
15110
15111 return FoundError;
15112}
15113
Michael Kruse4304e9d2019-02-19 16:38:20 +000015114// Look up the user-defined mapper given the mapper name and mapped type, and
15115// build a reference to it.
Benjamin Kramerba2ea932019-03-28 17:18:42 +000015116static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
15117 CXXScopeSpec &MapperIdScopeSpec,
15118 const DeclarationNameInfo &MapperId,
15119 QualType Type,
15120 Expr *UnresolvedMapper) {
Michael Kruse4304e9d2019-02-19 16:38:20 +000015121 if (MapperIdScopeSpec.isInvalid())
15122 return ExprError();
Michael Kruse945249b2019-09-26 22:53:01 +000015123 // Get the actual type for the array type.
15124 if (Type->isArrayType()) {
15125 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
15126 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
15127 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000015128 // Find all user-defined mappers with the given MapperId.
15129 SmallVector<UnresolvedSet<8>, 4> Lookups;
15130 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
15131 Lookup.suppressDiagnostics();
15132 if (S) {
15133 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
15134 NamedDecl *D = Lookup.getRepresentativeDecl();
15135 while (S && !S->isDeclScope(D))
15136 S = S->getParent();
15137 if (S)
15138 S = S->getParent();
15139 Lookups.emplace_back();
15140 Lookups.back().append(Lookup.begin(), Lookup.end());
15141 Lookup.clear();
15142 }
15143 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
15144 // Extract the user-defined mappers with the given MapperId.
15145 Lookups.push_back(UnresolvedSet<8>());
15146 for (NamedDecl *D : ULE->decls()) {
15147 auto *DMD = cast<OMPDeclareMapperDecl>(D);
15148 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
15149 Lookups.back().addDecl(DMD);
15150 }
15151 }
15152 // Defer the lookup for dependent types. The results will be passed through
15153 // UnresolvedMapper on instantiation.
15154 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
15155 Type->isInstantiationDependentType() ||
15156 Type->containsUnexpandedParameterPack() ||
15157 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
15158 return !D->isInvalidDecl() &&
15159 (D->getType()->isDependentType() ||
15160 D->getType()->isInstantiationDependentType() ||
15161 D->getType()->containsUnexpandedParameterPack());
15162 })) {
15163 UnresolvedSet<8> URS;
15164 for (const UnresolvedSet<8> &Set : Lookups) {
15165 if (Set.empty())
15166 continue;
15167 URS.append(Set.begin(), Set.end());
15168 }
15169 return UnresolvedLookupExpr::Create(
15170 SemaRef.Context, /*NamingClass=*/nullptr,
15171 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
15172 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
15173 }
Michael Kruse945249b2019-09-26 22:53:01 +000015174 SourceLocation Loc = MapperId.getLoc();
Michael Kruse4304e9d2019-02-19 16:38:20 +000015175 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15176 // The type must be of struct, union or class type in C and C++
Michael Kruse945249b2019-09-26 22:53:01 +000015177 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
15178 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
15179 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
15180 return ExprError();
15181 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000015182 // Perform argument dependent lookup.
15183 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
15184 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
15185 // Return the first user-defined mapper with the desired type.
15186 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15187 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
15188 if (!D->isInvalidDecl() &&
15189 SemaRef.Context.hasSameType(D->getType(), Type))
15190 return D;
15191 return nullptr;
15192 }))
15193 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15194 // Find the first user-defined mapper with a type derived from the desired
15195 // type.
15196 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15197 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
15198 if (!D->isInvalidDecl() &&
15199 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
15200 !Type.isMoreQualifiedThan(D->getType()))
15201 return D;
15202 return nullptr;
15203 })) {
15204 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
15205 /*DetectVirtual=*/false);
15206 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
15207 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
15208 VD->getType().getUnqualifiedType()))) {
15209 if (SemaRef.CheckBaseClassAccess(
15210 Loc, VD->getType(), Type, Paths.front(),
15211 /*DiagID=*/0) != Sema::AR_inaccessible) {
15212 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15213 }
15214 }
15215 }
15216 }
15217 // Report error if a mapper is specified, but cannot be found.
15218 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
15219 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
15220 << Type << MapperId.getName();
15221 return ExprError();
15222 }
15223 return ExprEmpty();
15224}
15225
Samuel Antao661c0902016-05-26 17:39:58 +000015226namespace {
15227// Utility struct that gathers all the related lists associated with a mappable
15228// expression.
Alexey Bataeve3727102018-04-18 15:57:46 +000015229struct MappableVarListInfo {
Samuel Antao661c0902016-05-26 17:39:58 +000015230 // The list of expressions.
15231 ArrayRef<Expr *> VarList;
15232 // The list of processed expressions.
15233 SmallVector<Expr *, 16> ProcessedVarList;
15234 // The mappble components for each expression.
15235 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
15236 // The base declaration of the variable.
15237 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
Michael Kruse4304e9d2019-02-19 16:38:20 +000015238 // The reference to the user-defined mapper associated with every expression.
15239 SmallVector<Expr *, 16> UDMapperList;
Samuel Antao661c0902016-05-26 17:39:58 +000015240
15241 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
15242 // We have a list of components and base declarations for each entry in the
15243 // variable list.
15244 VarComponents.reserve(VarList.size());
15245 VarBaseDeclarations.reserve(VarList.size());
15246 }
15247};
15248}
15249
15250// Check the validity of the provided variable list for the provided clause kind
Michael Kruse4304e9d2019-02-19 16:38:20 +000015251// \a CKind. In the check process the valid expressions, mappable expression
15252// components, variables, and user-defined mappers are extracted and used to
15253// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
15254// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
15255// and \a MapperId are expected to be valid if the clause kind is 'map'.
15256static void checkMappableExpressionList(
15257 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
15258 MappableVarListInfo &MVLI, SourceLocation StartLoc,
Michael Kruse01f670d2019-02-22 22:29:42 +000015259 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
15260 ArrayRef<Expr *> UnresolvedMappers,
Michael Kruse4304e9d2019-02-19 16:38:20 +000015261 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
Michael Kruse01f670d2019-02-22 22:29:42 +000015262 bool IsMapTypeImplicit = false) {
Samuel Antaoec172c62016-05-26 17:49:04 +000015263 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
15264 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
Samuel Antao661c0902016-05-26 17:39:58 +000015265 "Unexpected clause kind with mappable expressions!");
Michael Kruse01f670d2019-02-22 22:29:42 +000015266
15267 // If the identifier of user-defined mapper is not specified, it is "default".
15268 // We do not change the actual name in this clause to distinguish whether a
15269 // mapper is specified explicitly, i.e., it is not explicitly specified when
15270 // MapperId.getName() is empty.
15271 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
15272 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
15273 MapperId.setName(DeclNames.getIdentifier(
15274 &SemaRef.getASTContext().Idents.get("default")));
15275 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000015276
15277 // Iterators to find the current unresolved mapper expression.
15278 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
15279 bool UpdateUMIt = false;
15280 Expr *UnresolvedMapper = nullptr;
Kelvin Li0bff7af2015-11-23 05:32:03 +000015281
Samuel Antao90927002016-04-26 14:54:23 +000015282 // Keep track of the mappable components and base declarations in this clause.
15283 // Each entry in the list is going to have a list of components associated. We
15284 // record each set of the components so that we can build the clause later on.
15285 // In the end we should have the same amount of declarations and component
15286 // lists.
Samuel Antao90927002016-04-26 14:54:23 +000015287
Alexey Bataeve3727102018-04-18 15:57:46 +000015288 for (Expr *RE : MVLI.VarList) {
Samuel Antaoec172c62016-05-26 17:49:04 +000015289 assert(RE && "Null expr in omp to/from/map clause");
Kelvin Li0bff7af2015-11-23 05:32:03 +000015290 SourceLocation ELoc = RE->getExprLoc();
15291
Michael Kruse4304e9d2019-02-19 16:38:20 +000015292 // Find the current unresolved mapper expression.
15293 if (UpdateUMIt && UMIt != UMEnd) {
15294 UMIt++;
15295 assert(
15296 UMIt != UMEnd &&
15297 "Expect the size of UnresolvedMappers to match with that of VarList");
15298 }
15299 UpdateUMIt = true;
15300 if (UMIt != UMEnd)
15301 UnresolvedMapper = *UMIt;
15302
Alexey Bataeve3727102018-04-18 15:57:46 +000015303 const Expr *VE = RE->IgnoreParenLValueCasts();
Kelvin Li0bff7af2015-11-23 05:32:03 +000015304
15305 if (VE->isValueDependent() || VE->isTypeDependent() ||
15306 VE->isInstantiationDependent() ||
15307 VE->containsUnexpandedParameterPack()) {
Michael Kruse0336c752019-02-25 20:34:15 +000015308 // Try to find the associated user-defined mapper.
15309 ExprResult ER = buildUserDefinedMapperRef(
15310 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15311 VE->getType().getCanonicalType(), UnresolvedMapper);
15312 if (ER.isInvalid())
15313 continue;
15314 MVLI.UDMapperList.push_back(ER.get());
Samuel Antao5de996e2016-01-22 20:21:36 +000015315 // We can only analyze this information once the missing information is
15316 // resolved.
Samuel Antao661c0902016-05-26 17:39:58 +000015317 MVLI.ProcessedVarList.push_back(RE);
Kelvin Li0bff7af2015-11-23 05:32:03 +000015318 continue;
15319 }
15320
Alexey Bataeve3727102018-04-18 15:57:46 +000015321 Expr *SimpleExpr = RE->IgnoreParenCasts();
Kelvin Li0bff7af2015-11-23 05:32:03 +000015322
Samuel Antao5de996e2016-01-22 20:21:36 +000015323 if (!RE->IgnoreParenImpCasts()->isLValue()) {
Samuel Antao661c0902016-05-26 17:39:58 +000015324 SemaRef.Diag(ELoc,
15325 diag::err_omp_expected_named_var_member_or_array_expression)
Samuel Antao5de996e2016-01-22 20:21:36 +000015326 << RE->getSourceRange();
Kelvin Li0bff7af2015-11-23 05:32:03 +000015327 continue;
15328 }
15329
Samuel Antao90927002016-04-26 14:54:23 +000015330 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
15331 ValueDecl *CurDeclaration = nullptr;
15332
15333 // Obtain the array or member expression bases if required. Also, fill the
15334 // components array with all the components identified in the process.
Alexey Bataeve3727102018-04-18 15:57:46 +000015335 const Expr *BE = checkMapClauseExpressionBase(
15336 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
Samuel Antao5de996e2016-01-22 20:21:36 +000015337 if (!BE)
15338 continue;
15339
Samuel Antao90927002016-04-26 14:54:23 +000015340 assert(!CurComponents.empty() &&
15341 "Invalid mappable expression information.");
Kelvin Li0bff7af2015-11-23 05:32:03 +000015342
Patrick Lystere13b1e32019-01-02 19:28:48 +000015343 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
15344 // Add store "this" pointer to class in DSAStackTy for future checking
15345 DSAS->addMappedClassesQualTypes(TE->getType());
Michael Kruse0336c752019-02-25 20:34:15 +000015346 // Try to find the associated user-defined mapper.
15347 ExprResult ER = buildUserDefinedMapperRef(
15348 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15349 VE->getType().getCanonicalType(), UnresolvedMapper);
15350 if (ER.isInvalid())
15351 continue;
15352 MVLI.UDMapperList.push_back(ER.get());
Patrick Lystere13b1e32019-01-02 19:28:48 +000015353 // Skip restriction checking for variable or field declarations
15354 MVLI.ProcessedVarList.push_back(RE);
15355 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15356 MVLI.VarComponents.back().append(CurComponents.begin(),
15357 CurComponents.end());
15358 MVLI.VarBaseDeclarations.push_back(nullptr);
15359 continue;
15360 }
15361
Samuel Antao90927002016-04-26 14:54:23 +000015362 // For the following checks, we rely on the base declaration which is
15363 // expected to be associated with the last component. The declaration is
15364 // expected to be a variable or a field (if 'this' is being mapped).
15365 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
15366 assert(CurDeclaration && "Null decl on map clause.");
15367 assert(
15368 CurDeclaration->isCanonicalDecl() &&
15369 "Expecting components to have associated only canonical declarations.");
15370
15371 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
Alexey Bataeve3727102018-04-18 15:57:46 +000015372 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
Samuel Antao5de996e2016-01-22 20:21:36 +000015373
15374 assert((VD || FD) && "Only variables or fields are expected here!");
NAKAMURA Takumi6dcb8142016-01-23 01:38:20 +000015375 (void)FD;
Samuel Antao5de996e2016-01-22 20:21:36 +000015376
15377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
Samuel Antao661c0902016-05-26 17:39:58 +000015378 // threadprivate variables cannot appear in a map clause.
15379 // OpenMP 4.5 [2.10.5, target update Construct]
15380 // threadprivate variables cannot appear in a from clause.
15381 if (VD && DSAS->isThreadPrivate(VD)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015382 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
Samuel Antao661c0902016-05-26 17:39:58 +000015383 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
15384 << getOpenMPClauseName(CKind);
Alexey Bataeve3727102018-04-18 15:57:46 +000015385 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
Kelvin Li0bff7af2015-11-23 05:32:03 +000015386 continue;
15387 }
15388
Samuel Antao5de996e2016-01-22 20:21:36 +000015389 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
15390 // A list item cannot appear in both a map clause and a data-sharing
15391 // attribute clause on the same construct.
Kelvin Li0bff7af2015-11-23 05:32:03 +000015392
Samuel Antao5de996e2016-01-22 20:21:36 +000015393 // Check conflicts with other map clause expressions. We check the conflicts
15394 // with the current construct separately from the enclosing data
Samuel Antao661c0902016-05-26 17:39:58 +000015395 // environment, because the restrictions are different. We only have to
15396 // check conflicts across regions for the map clauses.
Alexey Bataeve3727102018-04-18 15:57:46 +000015397 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
Samuel Antao661c0902016-05-26 17:39:58 +000015398 /*CurrentRegionOnly=*/true, CurComponents, CKind))
Samuel Antao5de996e2016-01-22 20:21:36 +000015399 break;
Samuel Antao661c0902016-05-26 17:39:58 +000015400 if (CKind == OMPC_map &&
Alexey Bataeve3727102018-04-18 15:57:46 +000015401 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
Samuel Antao661c0902016-05-26 17:39:58 +000015402 /*CurrentRegionOnly=*/false, CurComponents, CKind))
Samuel Antao5de996e2016-01-22 20:21:36 +000015403 break;
Kelvin Li0bff7af2015-11-23 05:32:03 +000015404
Samuel Antao661c0902016-05-26 17:39:58 +000015405 // OpenMP 4.5 [2.10.5, target update Construct]
Samuel Antao5de996e2016-01-22 20:21:36 +000015406 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15407 // If the type of a list item is a reference to a type T then the type will
15408 // be considered to be T for all purposes of this clause.
Alexey Bataev354df2e2018-05-02 18:44:10 +000015409 auto I = llvm::find_if(
15410 CurComponents,
15411 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
15412 return MC.getAssociatedDeclaration();
15413 });
15414 assert(I != CurComponents.end() && "Null decl on map clause.");
15415 QualType Type =
15416 I->getAssociatedDeclaration()->getType().getNonReferenceType();
Samuel Antao5de996e2016-01-22 20:21:36 +000015417
Samuel Antao661c0902016-05-26 17:39:58 +000015418 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
15419 // A list item in a to or from clause must have a mappable type.
Samuel Antao5de996e2016-01-22 20:21:36 +000015420 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
Kelvin Li0bff7af2015-11-23 05:32:03 +000015421 // A list item must have a mappable type.
Alexey Bataeve3727102018-04-18 15:57:46 +000015422 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
Samuel Antao661c0902016-05-26 17:39:58 +000015423 DSAS, Type))
Kelvin Li0bff7af2015-11-23 05:32:03 +000015424 continue;
15425
Samuel Antao661c0902016-05-26 17:39:58 +000015426 if (CKind == OMPC_map) {
15427 // target enter data
15428 // OpenMP [2.10.2, Restrictions, p. 99]
15429 // A map-type must be specified in all map clauses and must be either
15430 // to or alloc.
15431 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
15432 if (DKind == OMPD_target_enter_data &&
15433 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
15434 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
15435 << (IsMapTypeImplicit ? 1 : 0)
15436 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
15437 << getOpenMPDirectiveName(DKind);
Carlo Bertollib74bfc82016-03-18 21:43:32 +000015438 continue;
15439 }
Samuel Antao661c0902016-05-26 17:39:58 +000015440
15441 // target exit_data
15442 // OpenMP [2.10.3, Restrictions, p. 102]
15443 // A map-type must be specified in all map clauses and must be either
15444 // from, release, or delete.
15445 if (DKind == OMPD_target_exit_data &&
15446 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
15447 MapType == OMPC_MAP_delete)) {
15448 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
15449 << (IsMapTypeImplicit ? 1 : 0)
15450 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
15451 << getOpenMPDirectiveName(DKind);
15452 continue;
15453 }
15454
15455 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15456 // A list item cannot appear in both a map clause and a data-sharing
15457 // attribute clause on the same construct
Joel E. Denny7d5bc552019-08-22 03:34:30 +000015458 //
15459 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15460 // A list item cannot appear in both a map clause and a data-sharing
15461 // attribute clause on the same construct unless the construct is a
15462 // combined construct.
15463 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
15464 isOpenMPTargetExecutionDirective(DKind)) ||
15465 DKind == OMPD_target)) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015466 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
Samuel Antao661c0902016-05-26 17:39:58 +000015467 if (isOpenMPPrivate(DVar.CKind)) {
Samuel Antao6890b092016-07-28 14:25:09 +000015468 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
Samuel Antao661c0902016-05-26 17:39:58 +000015469 << getOpenMPClauseName(DVar.CKind)
Samuel Antao6890b092016-07-28 14:25:09 +000015470 << getOpenMPClauseName(OMPC_map)
Samuel Antao661c0902016-05-26 17:39:58 +000015471 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000015472 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
Samuel Antao661c0902016-05-26 17:39:58 +000015473 continue;
15474 }
15475 }
Michael Kruse01f670d2019-02-22 22:29:42 +000015476 }
Michael Kruse4304e9d2019-02-19 16:38:20 +000015477
Michael Kruse01f670d2019-02-22 22:29:42 +000015478 // Try to find the associated user-defined mapper.
Michael Kruse0336c752019-02-25 20:34:15 +000015479 ExprResult ER = buildUserDefinedMapperRef(
15480 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15481 Type.getCanonicalType(), UnresolvedMapper);
15482 if (ER.isInvalid())
15483 continue;
15484 MVLI.UDMapperList.push_back(ER.get());
Carlo Bertollib74bfc82016-03-18 21:43:32 +000015485
Samuel Antao90927002016-04-26 14:54:23 +000015486 // Save the current expression.
Samuel Antao661c0902016-05-26 17:39:58 +000015487 MVLI.ProcessedVarList.push_back(RE);
Samuel Antao90927002016-04-26 14:54:23 +000015488
15489 // Store the components in the stack so that they can be used to check
15490 // against other clauses later on.
Samuel Antao6890b092016-07-28 14:25:09 +000015491 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
15492 /*WhereFoundClauseKind=*/OMPC_map);
Samuel Antao90927002016-04-26 14:54:23 +000015493
15494 // Save the components and declaration to create the clause. For purposes of
15495 // the clause creation, any component list that has has base 'this' uses
Samuel Antao686c70c2016-05-26 17:30:50 +000015496 // null as base declaration.
Samuel Antao661c0902016-05-26 17:39:58 +000015497 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15498 MVLI.VarComponents.back().append(CurComponents.begin(),
15499 CurComponents.end());
15500 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
15501 : CurDeclaration);
Kelvin Li0bff7af2015-11-23 05:32:03 +000015502 }
Samuel Antao661c0902016-05-26 17:39:58 +000015503}
15504
Michael Kruse4304e9d2019-02-19 16:38:20 +000015505OMPClause *Sema::ActOnOpenMPMapClause(
15506 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15507 ArrayRef<SourceLocation> MapTypeModifiersLoc,
15508 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
15509 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
15510 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
15511 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
15512 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
15513 OMPC_MAP_MODIFIER_unknown,
15514 OMPC_MAP_MODIFIER_unknown};
Kelvin Lief579432018-12-18 22:18:41 +000015515 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
15516
15517 // Process map-type-modifiers, flag errors for duplicate modifiers.
15518 unsigned Count = 0;
15519 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
15520 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
15521 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
15522 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
15523 continue;
15524 }
15525 assert(Count < OMPMapClause::NumberOfModifiers &&
Gheorghe-Teodor Berceaa3afcf22019-01-09 20:38:35 +000015526 "Modifiers exceed the allowed number of map type modifiers");
Kelvin Lief579432018-12-18 22:18:41 +000015527 Modifiers[Count] = MapTypeModifiers[I];
15528 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
15529 ++Count;
15530 }
15531
Michael Kruse4304e9d2019-02-19 16:38:20 +000015532 MappableVarListInfo MVLI(VarList);
15533 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
Michael Kruse01f670d2019-02-22 22:29:42 +000015534 MapperIdScopeSpec, MapperId, UnresolvedMappers,
15535 MapType, IsMapTypeImplicit);
Michael Kruse4304e9d2019-02-19 16:38:20 +000015536
Samuel Antao5de996e2016-01-22 20:21:36 +000015537 // We need to produce a map clause even if we don't have variables so that
15538 // other diagnostics related with non-existing map clauses are accurate.
Michael Kruse4304e9d2019-02-19 16:38:20 +000015539 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
15540 MVLI.VarBaseDeclarations, MVLI.VarComponents,
15541 MVLI.UDMapperList, Modifiers, ModifiersLoc,
15542 MapperIdScopeSpec.getWithLocInContext(Context),
15543 MapperId, MapType, IsMapTypeImplicit, MapLoc);
Kelvin Li0bff7af2015-11-23 05:32:03 +000015544}
Kelvin Li099bb8c2015-11-24 20:50:12 +000015545
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015546QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
15547 TypeResult ParsedType) {
15548 assert(ParsedType.isUsable());
15549
15550 QualType ReductionType = GetTypeFromParser(ParsedType.get());
15551 if (ReductionType.isNull())
15552 return QualType();
15553
15554 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
15555 // A type name in a declare reduction directive cannot be a function type, an
15556 // array type, a reference type, or a type qualified with const, volatile or
15557 // restrict.
15558 if (ReductionType.hasQualifiers()) {
15559 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
15560 return QualType();
15561 }
15562
15563 if (ReductionType->isFunctionType()) {
15564 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
15565 return QualType();
15566 }
15567 if (ReductionType->isReferenceType()) {
15568 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
15569 return QualType();
15570 }
15571 if (ReductionType->isArrayType()) {
15572 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
15573 return QualType();
15574 }
15575 return ReductionType;
15576}
15577
15578Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
15579 Scope *S, DeclContext *DC, DeclarationName Name,
15580 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
15581 AccessSpecifier AS, Decl *PrevDeclInScope) {
15582 SmallVector<Decl *, 8> Decls;
15583 Decls.reserve(ReductionTypes.size());
15584
15585 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
Richard Smithbecb92d2017-10-10 22:33:17 +000015586 forRedeclarationInCurContext());
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015587 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
15588 // A reduction-identifier may not be re-declared in the current scope for the
15589 // same type or for a type that is compatible according to the base language
15590 // rules.
15591 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
15592 OMPDeclareReductionDecl *PrevDRD = nullptr;
15593 bool InCompoundScope = true;
15594 if (S != nullptr) {
15595 // Find previous declaration with the same name not referenced in other
15596 // declarations.
15597 FunctionScopeInfo *ParentFn = getEnclosingFunction();
15598 InCompoundScope =
15599 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
15600 LookupName(Lookup, S);
15601 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
15602 /*AllowInlineNamespace=*/false);
15603 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
Alexey Bataeve3727102018-04-18 15:57:46 +000015604 LookupResult::Filter Filter = Lookup.makeFilter();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015605 while (Filter.hasNext()) {
15606 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
15607 if (InCompoundScope) {
15608 auto I = UsedAsPrevious.find(PrevDecl);
15609 if (I == UsedAsPrevious.end())
15610 UsedAsPrevious[PrevDecl] = false;
Alexey Bataeve3727102018-04-18 15:57:46 +000015611 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015612 UsedAsPrevious[D] = true;
15613 }
15614 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
15615 PrevDecl->getLocation();
15616 }
15617 Filter.done();
15618 if (InCompoundScope) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015619 for (const auto &PrevData : UsedAsPrevious) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015620 if (!PrevData.second) {
15621 PrevDRD = PrevData.first;
15622 break;
15623 }
15624 }
15625 }
15626 } else if (PrevDeclInScope != nullptr) {
15627 auto *PrevDRDInScope = PrevDRD =
15628 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
15629 do {
15630 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
15631 PrevDRDInScope->getLocation();
15632 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
15633 } while (PrevDRDInScope != nullptr);
15634 }
Alexey Bataeve3727102018-04-18 15:57:46 +000015635 for (const auto &TyData : ReductionTypes) {
15636 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015637 bool Invalid = false;
15638 if (I != PreviousRedeclTypes.end()) {
15639 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
15640 << TyData.first;
15641 Diag(I->second, diag::note_previous_definition);
15642 Invalid = true;
15643 }
15644 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
15645 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
15646 Name, TyData.first, PrevDRD);
15647 DC->addDecl(DRD);
15648 DRD->setAccess(AS);
15649 Decls.push_back(DRD);
15650 if (Invalid)
15651 DRD->setInvalidDecl();
15652 else
15653 PrevDRD = DRD;
15654 }
15655
15656 return DeclGroupPtrTy::make(
15657 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
15658}
15659
15660void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
15661 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15662
15663 // Enter new function scope.
15664 PushFunctionScope();
Reid Kleckner87a31802018-03-12 21:43:02 +000015665 setFunctionHasBranchProtectedScope();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015666 getCurFunction()->setHasOMPDeclareReductionCombiner();
15667
15668 if (S != nullptr)
15669 PushDeclContext(S, DRD);
15670 else
15671 CurContext = DRD;
15672
Faisal Valid143a0c2017-04-01 21:30:49 +000015673 PushExpressionEvaluationContext(
15674 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015675
15676 QualType ReductionType = DRD->getType();
Alexey Bataeva839ddd2016-03-17 10:19:46 +000015677 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
15678 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
15679 // uses semantics of argument handles by value, but it should be passed by
15680 // reference. C lang does not support references, so pass all parameters as
15681 // pointers.
15682 // Create 'T omp_in;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000015683 VarDecl *OmpInParm =
Alexey Bataeva839ddd2016-03-17 10:19:46 +000015684 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015685 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
15686 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
15687 // uses semantics of argument handles by value, but it should be passed by
15688 // reference. C lang does not support references, so pass all parameters as
15689 // pointers.
15690 // Create 'T omp_out;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000015691 VarDecl *OmpOutParm =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015692 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
15693 if (S != nullptr) {
15694 PushOnScopeChains(OmpInParm, S);
15695 PushOnScopeChains(OmpOutParm, S);
15696 } else {
15697 DRD->addDecl(OmpInParm);
15698 DRD->addDecl(OmpOutParm);
15699 }
Alexey Bataeve6aa4692018-09-13 16:54:05 +000015700 Expr *InE =
15701 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
15702 Expr *OutE =
15703 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
15704 DRD->setCombinerData(InE, OutE);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015705}
15706
15707void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
15708 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15709 DiscardCleanupsInEvaluationContext();
15710 PopExpressionEvaluationContext();
15711
15712 PopDeclContext();
15713 PopFunctionScopeInfo();
15714
15715 if (Combiner != nullptr)
15716 DRD->setCombiner(Combiner);
15717 else
15718 DRD->setInvalidDecl();
15719}
15720
Alexey Bataev070f43a2017-09-06 14:49:58 +000015721VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015722 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15723
15724 // Enter new function scope.
15725 PushFunctionScope();
Reid Kleckner87a31802018-03-12 21:43:02 +000015726 setFunctionHasBranchProtectedScope();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015727
15728 if (S != nullptr)
15729 PushDeclContext(S, DRD);
15730 else
15731 CurContext = DRD;
15732
Faisal Valid143a0c2017-04-01 21:30:49 +000015733 PushExpressionEvaluationContext(
15734 ExpressionEvaluationContext::PotentiallyEvaluated);
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015735
15736 QualType ReductionType = DRD->getType();
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015737 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
15738 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
15739 // uses semantics of argument handles by value, but it should be passed by
15740 // reference. C lang does not support references, so pass all parameters as
15741 // pointers.
15742 // Create 'T omp_priv;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000015743 VarDecl *OmpPrivParm =
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015744 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
Alexey Bataeva839ddd2016-03-17 10:19:46 +000015745 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
15746 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
15747 // uses semantics of argument handles by value, but it should be passed by
15748 // reference. C lang does not support references, so pass all parameters as
15749 // pointers.
15750 // Create 'T omp_orig;' variable.
Alexey Bataeve3727102018-04-18 15:57:46 +000015751 VarDecl *OmpOrigParm =
Alexey Bataeva839ddd2016-03-17 10:19:46 +000015752 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015753 if (S != nullptr) {
15754 PushOnScopeChains(OmpPrivParm, S);
15755 PushOnScopeChains(OmpOrigParm, S);
15756 } else {
15757 DRD->addDecl(OmpPrivParm);
15758 DRD->addDecl(OmpOrigParm);
15759 }
Alexey Bataeve6aa4692018-09-13 16:54:05 +000015760 Expr *OrigE =
15761 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
15762 Expr *PrivE =
15763 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
15764 DRD->setInitializerData(OrigE, PrivE);
Alexey Bataev070f43a2017-09-06 14:49:58 +000015765 return OmpPrivParm;
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015766}
15767
Alexey Bataev070f43a2017-09-06 14:49:58 +000015768void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
15769 VarDecl *OmpPrivParm) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015770 auto *DRD = cast<OMPDeclareReductionDecl>(D);
15771 DiscardCleanupsInEvaluationContext();
15772 PopExpressionEvaluationContext();
15773
15774 PopDeclContext();
15775 PopFunctionScopeInfo();
15776
Alexey Bataev070f43a2017-09-06 14:49:58 +000015777 if (Initializer != nullptr) {
15778 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
15779 } else if (OmpPrivParm->hasInit()) {
15780 DRD->setInitializer(OmpPrivParm->getInit(),
15781 OmpPrivParm->isDirectInit()
15782 ? OMPDeclareReductionDecl::DirectInit
15783 : OMPDeclareReductionDecl::CopyInit);
15784 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015785 DRD->setInvalidDecl();
Alexey Bataev070f43a2017-09-06 14:49:58 +000015786 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015787}
15788
15789Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
15790 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015791 for (Decl *D : DeclReductions.get()) {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015792 if (IsValid) {
Alexey Bataeve3727102018-04-18 15:57:46 +000015793 if (S)
15794 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
15795 /*AddToContext=*/false);
15796 } else {
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015797 D->setInvalidDecl();
Alexey Bataeve3727102018-04-18 15:57:46 +000015798 }
Alexey Bataev94a4f0c2016-03-03 05:21:39 +000015799 }
15800 return DeclReductions;
15801}
15802
Michael Kruse251e1482019-02-01 20:25:04 +000015803TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
15804 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
15805 QualType T = TInfo->getType();
15806 if (D.isInvalidType())
15807 return true;
15808
15809 if (getLangOpts().CPlusPlus) {
15810 // Check that there are no default arguments (C++ only).
15811 CheckExtraCXXDefaultArguments(D);
15812 }
15813
15814 return CreateParsedType(T, TInfo);
15815}
15816
15817QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
15818 TypeResult ParsedType) {
15819 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
15820
15821 QualType MapperType = GetTypeFromParser(ParsedType.get());
15822 assert(!MapperType.isNull() && "Expect valid mapper type");
15823
15824 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15825 // The type must be of struct, union or class type in C and C++
15826 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
15827 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
15828 return QualType();
15829 }
15830 return MapperType;
15831}
15832
15833OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
15834 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
15835 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
15836 Decl *PrevDeclInScope) {
15837 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
15838 forRedeclarationInCurContext());
15839 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15840 // A mapper-identifier may not be redeclared in the current scope for the
15841 // same type or for a type that is compatible according to the base language
15842 // rules.
15843 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
15844 OMPDeclareMapperDecl *PrevDMD = nullptr;
15845 bool InCompoundScope = true;
15846 if (S != nullptr) {
15847 // Find previous declaration with the same name not referenced in other
15848 // declarations.
15849 FunctionScopeInfo *ParentFn = getEnclosingFunction();
15850 InCompoundScope =
15851 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
15852 LookupName(Lookup, S);
15853 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
15854 /*AllowInlineNamespace=*/false);
15855 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
15856 LookupResult::Filter Filter = Lookup.makeFilter();
15857 while (Filter.hasNext()) {
15858 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
15859 if (InCompoundScope) {
15860 auto I = UsedAsPrevious.find(PrevDecl);
15861 if (I == UsedAsPrevious.end())
15862 UsedAsPrevious[PrevDecl] = false;
15863 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
15864 UsedAsPrevious[D] = true;
15865 }
15866 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
15867 PrevDecl->getLocation();
15868 }
15869 Filter.done();
15870 if (InCompoundScope) {
15871 for (const auto &PrevData : UsedAsPrevious) {
15872 if (!PrevData.second) {
15873 PrevDMD = PrevData.first;
15874 break;
15875 }
15876 }
15877 }
15878 } else if (PrevDeclInScope) {
15879 auto *PrevDMDInScope = PrevDMD =
15880 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
15881 do {
15882 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
15883 PrevDMDInScope->getLocation();
15884 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
15885 } while (PrevDMDInScope != nullptr);
15886 }
15887 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
15888 bool Invalid = false;
15889 if (I != PreviousRedeclTypes.end()) {
15890 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
15891 << MapperType << Name;
15892 Diag(I->second, diag::note_previous_definition);
15893 Invalid = true;
15894 }
15895 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
15896 MapperType, VN, PrevDMD);
15897 DC->addDecl(DMD);
15898 DMD->setAccess(AS);
15899 if (Invalid)
15900 DMD->setInvalidDecl();
15901
15902 // Enter new function scope.
15903 PushFunctionScope();
15904 setFunctionHasBranchProtectedScope();
15905
15906 CurContext = DMD;
15907
15908 return DMD;
15909}
15910
15911void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
15912 Scope *S,
15913 QualType MapperType,
15914 SourceLocation StartLoc,
15915 DeclarationName VN) {
15916 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
15917 if (S)
15918 PushOnScopeChains(VD, S);
15919 else
15920 DMD->addDecl(VD);
15921 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
15922 DMD->setMapperVarRef(MapperVarRefExpr);
15923}
15924
15925Sema::DeclGroupPtrTy
15926Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
15927 ArrayRef<OMPClause *> ClauseList) {
15928 PopDeclContext();
15929 PopFunctionScopeInfo();
15930
15931 if (D) {
15932 if (S)
15933 PushOnScopeChains(D, S, /*AddToContext=*/false);
15934 D->CreateClauses(Context, ClauseList);
15935 }
15936
15937 return DeclGroupPtrTy::make(DeclGroupRef(D));
15938}
15939
David Majnemer9d168222016-08-05 17:44:54 +000015940OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
Kelvin Li099bb8c2015-11-24 20:50:12 +000015941 SourceLocation StartLoc,
15942 SourceLocation LParenLoc,
15943 SourceLocation EndLoc) {
15944 Expr *ValExpr = NumTeams;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000015945 Stmt *HelperValStmt = nullptr;
Kelvin Li099bb8c2015-11-24 20:50:12 +000015946
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015947 // OpenMP [teams Constrcut, Restrictions]
15948 // The num_teams expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000015949 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
Alexey Bataeva0569352015-12-01 10:17:31 +000015950 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015951 return nullptr;
Kelvin Li099bb8c2015-11-24 20:50:12 +000015952
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000015953 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000015954 OpenMPDirectiveKind CaptureRegion =
15955 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
15956 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000015957 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000015958 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +000015959 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15960 HelperValStmt = buildPreInits(Context, Captures);
15961 }
15962
15963 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
15964 StartLoc, LParenLoc, EndLoc);
Kelvin Li099bb8c2015-11-24 20:50:12 +000015965}
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015966
15967OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
15968 SourceLocation StartLoc,
15969 SourceLocation LParenLoc,
15970 SourceLocation EndLoc) {
15971 Expr *ValExpr = ThreadLimit;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000015972 Stmt *HelperValStmt = nullptr;
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015973
15974 // OpenMP [teams Constrcut, Restrictions]
15975 // The thread_limit expression must evaluate to a positive integer value.
Alexey Bataeve3727102018-04-18 15:57:46 +000015976 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
Alexey Bataeva0569352015-12-01 10:17:31 +000015977 /*StrictlyPositive=*/true))
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015978 return nullptr;
15979
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000015980 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
Alexey Bataev2ba67042017-11-28 21:11:44 +000015981 OpenMPDirectiveKind CaptureRegion =
15982 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
15983 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000015984 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000015985 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +000015986 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15987 HelperValStmt = buildPreInits(Context, Captures);
15988 }
15989
15990 return new (Context) OMPThreadLimitClause(
15991 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
Kelvin Lia15fb1a2015-11-27 18:47:36 +000015992}
Alexey Bataeva0569352015-12-01 10:17:31 +000015993
15994OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
15995 SourceLocation StartLoc,
15996 SourceLocation LParenLoc,
15997 SourceLocation EndLoc) {
15998 Expr *ValExpr = Priority;
Alexey Bataev31ba4762019-10-16 18:09:37 +000015999 Stmt *HelperValStmt = nullptr;
16000 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataeva0569352015-12-01 10:17:31 +000016001
16002 // OpenMP [2.9.1, task Constrcut]
16003 // The priority-value is a non-negative numerical scalar expression.
Alexey Bataev31ba4762019-10-16 18:09:37 +000016004 if (!isNonNegativeIntegerValue(
16005 ValExpr, *this, OMPC_priority,
16006 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
16007 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
Alexey Bataeva0569352015-12-01 10:17:31 +000016008 return nullptr;
16009
Alexey Bataev31ba4762019-10-16 18:09:37 +000016010 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
16011 StartLoc, LParenLoc, EndLoc);
Alexey Bataeva0569352015-12-01 10:17:31 +000016012}
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000016013
16014OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
16015 SourceLocation StartLoc,
16016 SourceLocation LParenLoc,
16017 SourceLocation EndLoc) {
16018 Expr *ValExpr = Grainsize;
Alexey Bataevb9c55e22019-10-14 19:29:52 +000016019 Stmt *HelperValStmt = nullptr;
16020 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000016021
16022 // OpenMP [2.9.2, taskloop Constrcut]
16023 // The parameter of the grainsize clause must be a positive integer
16024 // expression.
Alexey Bataevb9c55e22019-10-14 19:29:52 +000016025 if (!isNonNegativeIntegerValue(
16026 ValExpr, *this, OMPC_grainsize,
16027 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16028 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000016029 return nullptr;
16030
Alexey Bataevb9c55e22019-10-14 19:29:52 +000016031 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
16032 StartLoc, LParenLoc, EndLoc);
Alexey Bataev1fd4aed2015-12-07 12:52:51 +000016033}
Alexey Bataev382967a2015-12-08 12:06:20 +000016034
16035OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
16036 SourceLocation StartLoc,
16037 SourceLocation LParenLoc,
16038 SourceLocation EndLoc) {
16039 Expr *ValExpr = NumTasks;
Alexey Bataevd88c7de2019-10-14 20:44:34 +000016040 Stmt *HelperValStmt = nullptr;
16041 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
Alexey Bataev382967a2015-12-08 12:06:20 +000016042
16043 // OpenMP [2.9.2, taskloop Constrcut]
16044 // The parameter of the num_tasks clause must be a positive integer
16045 // expression.
Alexey Bataevd88c7de2019-10-14 20:44:34 +000016046 if (!isNonNegativeIntegerValue(
16047 ValExpr, *this, OMPC_num_tasks,
16048 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16049 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
Alexey Bataev382967a2015-12-08 12:06:20 +000016050 return nullptr;
16051
Alexey Bataevd88c7de2019-10-14 20:44:34 +000016052 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
16053 StartLoc, LParenLoc, EndLoc);
Alexey Bataev382967a2015-12-08 12:06:20 +000016054}
16055
Alexey Bataev28c75412015-12-15 08:19:24 +000016056OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
16057 SourceLocation LParenLoc,
16058 SourceLocation EndLoc) {
16059 // OpenMP [2.13.2, critical construct, Description]
16060 // ... where hint-expression is an integer constant expression that evaluates
16061 // to a valid lock hint.
16062 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
16063 if (HintExpr.isInvalid())
16064 return nullptr;
16065 return new (Context)
16066 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
16067}
16068
Carlo Bertollib4adf552016-01-15 18:50:31 +000016069OMPClause *Sema::ActOnOpenMPDistScheduleClause(
16070 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16071 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
16072 SourceLocation EndLoc) {
16073 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
16074 std::string Values;
16075 Values += "'";
16076 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
16077 Values += "'";
16078 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16079 << Values << getOpenMPClauseName(OMPC_dist_schedule);
16080 return nullptr;
16081 }
16082 Expr *ValExpr = ChunkSize;
Alexey Bataev3392d762016-02-16 11:18:12 +000016083 Stmt *HelperValStmt = nullptr;
Carlo Bertollib4adf552016-01-15 18:50:31 +000016084 if (ChunkSize) {
16085 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16086 !ChunkSize->isInstantiationDependent() &&
16087 !ChunkSize->containsUnexpandedParameterPack()) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +000016088 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
Carlo Bertollib4adf552016-01-15 18:50:31 +000016089 ExprResult Val =
16090 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16091 if (Val.isInvalid())
16092 return nullptr;
16093
16094 ValExpr = Val.get();
16095
16096 // OpenMP [2.7.1, Restrictions]
16097 // chunk_size must be a loop invariant integer expression with a positive
16098 // value.
16099 llvm::APSInt Result;
16100 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
16101 if (Result.isSigned() && !Result.isStrictlyPositive()) {
16102 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16103 << "dist_schedule" << ChunkSize->getSourceRange();
16104 return nullptr;
16105 }
Alexey Bataev2ba67042017-11-28 21:11:44 +000016106 } else if (getOpenMPCaptureRegionForClause(
16107 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
16108 OMPD_unknown &&
Alexey Bataevb46cdea2016-06-15 11:20:48 +000016109 !CurContext->isDependentContext()) {
Alexey Bataev8e769ee2017-12-22 21:01:52 +000016110 ValExpr = MakeFullExpr(ValExpr).get();
Alexey Bataeve3727102018-04-18 15:57:46 +000016111 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
Alexey Bataev5a3af132016-03-29 08:58:54 +000016112 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16113 HelperValStmt = buildPreInits(Context, Captures);
Carlo Bertollib4adf552016-01-15 18:50:31 +000016114 }
16115 }
16116 }
16117
16118 return new (Context)
16119 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
Alexey Bataev3392d762016-02-16 11:18:12 +000016120 Kind, ValExpr, HelperValStmt);
Carlo Bertollib4adf552016-01-15 18:50:31 +000016121}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000016122
16123OMPClause *Sema::ActOnOpenMPDefaultmapClause(
16124 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
16125 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16126 SourceLocation KindLoc, SourceLocation EndLoc) {
16127 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
David Majnemer9d168222016-08-05 17:44:54 +000016128 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000016129 std::string Value;
16130 SourceLocation Loc;
16131 Value += "'";
16132 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
16133 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
David Majnemer9d168222016-08-05 17:44:54 +000016134 OMPC_DEFAULTMAP_MODIFIER_tofrom);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000016135 Loc = MLoc;
16136 } else {
16137 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
David Majnemer9d168222016-08-05 17:44:54 +000016138 OMPC_DEFAULTMAP_scalar);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000016139 Loc = KindLoc;
16140 }
16141 Value += "'";
16142 Diag(Loc, diag::err_omp_unexpected_clause_value)
16143 << Value << getOpenMPClauseName(OMPC_defaultmap);
16144 return nullptr;
16145 }
Alexey Bataev2fd0cb22017-10-05 17:51:39 +000016146 DSAStack->setDefaultDMAToFromScalar(StartLoc);
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +000016147
16148 return new (Context)
16149 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
16150}
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016151
16152bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
16153 DeclContext *CurLexicalContext = getCurLexicalContext();
16154 if (!CurLexicalContext->isFileContext() &&
16155 !CurLexicalContext->isExternCContext() &&
Alexey Bataev502ec492017-10-03 20:00:00 +000016156 !CurLexicalContext->isExternCXXContext() &&
16157 !isa<CXXRecordDecl>(CurLexicalContext) &&
16158 !isa<ClassTemplateDecl>(CurLexicalContext) &&
16159 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
16160 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016161 Diag(Loc, diag::err_omp_region_not_file_context);
16162 return false;
16163 }
Kelvin Libc38e632018-09-10 02:07:09 +000016164 ++DeclareTargetNestingLevel;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016165 return true;
16166}
16167
16168void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
Kelvin Libc38e632018-09-10 02:07:09 +000016169 assert(DeclareTargetNestingLevel > 0 &&
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016170 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
Kelvin Libc38e632018-09-10 02:07:09 +000016171 --DeclareTargetNestingLevel;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016172}
16173
Alexey Bataev729e2422019-08-23 16:11:14 +000016174NamedDecl *
16175Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
16176 const DeclarationNameInfo &Id,
16177 NamedDeclSetType &SameDirectiveDecls) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016178 LookupResult Lookup(*this, Id, LookupOrdinaryName);
16179 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
16180
16181 if (Lookup.isAmbiguous())
Alexey Bataev729e2422019-08-23 16:11:14 +000016182 return nullptr;
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016183 Lookup.suppressDiagnostics();
16184
16185 if (!Lookup.isSingleResult()) {
Bruno Ricci70ad3962019-03-25 17:08:51 +000016186 VarOrFuncDeclFilterCCC CCC(*this);
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016187 if (TypoCorrection Corrected =
Bruno Ricci70ad3962019-03-25 17:08:51 +000016188 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016189 CTK_ErrorRecovery)) {
16190 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
16191 << Id.getName());
16192 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
Alexey Bataev729e2422019-08-23 16:11:14 +000016193 return nullptr;
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016194 }
16195
16196 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
Alexey Bataev729e2422019-08-23 16:11:14 +000016197 return nullptr;
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016198 }
16199
16200 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
Alexey Bataev729e2422019-08-23 16:11:14 +000016201 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
16202 !isa<FunctionTemplateDecl>(ND)) {
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016203 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
Alexey Bataev729e2422019-08-23 16:11:14 +000016204 return nullptr;
16205 }
16206 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
16207 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
16208 return ND;
16209}
16210
16211void Sema::ActOnOpenMPDeclareTargetName(
16212 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
16213 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
16214 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
16215 isa<FunctionTemplateDecl>(ND)) &&
16216 "Expected variable, function or function template.");
16217
16218 // Diagnose marking after use as it may lead to incorrect diagnosis and
16219 // codegen.
16220 if (LangOpts.OpenMP >= 50 &&
16221 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
16222 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
16223
16224 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
16225 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
16226 if (DevTy.hasValue() && *DevTy != DT) {
16227 Diag(Loc, diag::err_omp_device_type_mismatch)
16228 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
16229 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
16230 return;
16231 }
16232 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
16233 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
16234 if (!Res) {
16235 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
16236 SourceRange(Loc, Loc));
16237 ND->addAttr(A);
16238 if (ASTMutationListener *ML = Context.getASTMutationListener())
16239 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
16240 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
16241 } else if (*Res != MT) {
16242 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
Alexey Bataeve3727102018-04-18 15:57:46 +000016243 }
Dmitry Polukhind69b5052016-05-09 14:59:13 +000016244}
16245
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016246static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
16247 Sema &SemaRef, Decl *D) {
Alexey Bataev30a78212018-09-11 13:59:10 +000016248 if (!D || !isa<VarDecl>(D))
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016249 return;
Alexey Bataev30a78212018-09-11 13:59:10 +000016250 auto *VD = cast<VarDecl>(D);
Alexey Bataev217ff1e2019-08-16 20:15:02 +000016251 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
16252 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16253 if (SemaRef.LangOpts.OpenMP >= 50 &&
16254 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
16255 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
16256 VD->hasGlobalStorage()) {
16257 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
16258 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16259 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
16260 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
16261 // If a lambda declaration and definition appears between a
16262 // declare target directive and the matching end declare target
16263 // directive, all variables that are captured by the lambda
16264 // expression must also appear in a to clause.
16265 SemaRef.Diag(VD->getLocation(),
Alexey Bataevc4299552019-08-20 17:50:13 +000016266 diag::err_omp_lambda_capture_in_declare_target_not_to);
Alexey Bataev217ff1e2019-08-16 20:15:02 +000016267 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
16268 << VD << 0 << SR;
16269 return;
16270 }
16271 }
16272 if (MapTy.hasValue())
Alexey Bataev30a78212018-09-11 13:59:10 +000016273 return;
16274 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
16275 SemaRef.Diag(SL, diag::note_used_here) << SR;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016276}
16277
16278static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
16279 Sema &SemaRef, DSAStackTy *Stack,
16280 ValueDecl *VD) {
Alexey Bataevebcfc9e2019-08-22 16:48:26 +000016281 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
Alexey Bataeve3727102018-04-18 15:57:46 +000016282 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
16283 /*FullCheck=*/false);
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016284}
16285
Kelvin Li1ce87c72017-12-12 20:08:12 +000016286void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
16287 SourceLocation IdLoc) {
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016288 if (!D || D->isInvalidDecl())
16289 return;
16290 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
Stephen Kellyf2ceec42018-08-09 21:08:08 +000016291 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
Alexey Bataeve3727102018-04-18 15:57:46 +000016292 if (auto *VD = dyn_cast<VarDecl>(D)) {
Alexey Bataevc1943e72018-07-09 19:58:08 +000016293 // Only global variables can be marked as declare target.
Alexey Bataev30a78212018-09-11 13:59:10 +000016294 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
16295 !VD->isStaticDataMember())
Alexey Bataevc1943e72018-07-09 19:58:08 +000016296 return;
16297 // 2.10.6: threadprivate variable cannot appear in a declare target
16298 // directive.
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016299 if (DSAStack->isThreadPrivate(VD)) {
16300 Diag(SL, diag::err_omp_threadprivate_in_target);
Alexey Bataeve3727102018-04-18 15:57:46 +000016301 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016302 return;
16303 }
16304 }
Alexey Bataev97b72212018-08-14 18:31:20 +000016305 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
16306 D = FTD->getTemplatedDecl();
Alexey Bataev9fd495b2019-08-20 19:50:13 +000016307 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
Alexey Bataev30a78212018-09-11 13:59:10 +000016308 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
16309 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
Alexey Bataev9fd495b2019-08-20 19:50:13 +000016310 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
Kelvin Li1ce87c72017-12-12 20:08:12 +000016311 Diag(IdLoc, diag::err_omp_function_in_link_clause);
16312 Diag(FD->getLocation(), diag::note_defined_here) << FD;
16313 return;
16314 }
Alexey Bataev9fd495b2019-08-20 19:50:13 +000016315 // Mark the function as must be emitted for the device.
Alexey Bataev729e2422019-08-23 16:11:14 +000016316 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
16317 OMPDeclareTargetDeclAttr::getDeviceType(FD);
16318 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16319 *DevTy != OMPDeclareTargetDeclAttr::DT_Host)
Alexey Bataev9fd495b2019-08-20 19:50:13 +000016320 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false);
Alexey Bataev729e2422019-08-23 16:11:14 +000016321 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16322 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost)
16323 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false);
Kelvin Li1ce87c72017-12-12 20:08:12 +000016324 }
Alexey Bataev30a78212018-09-11 13:59:10 +000016325 if (auto *VD = dyn_cast<ValueDecl>(D)) {
16326 // Problem if any with var declared with incomplete type will be reported
16327 // as normal, so no need to check it here.
16328 if ((E || !VD->getType()->isIncompleteType()) &&
16329 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
16330 return;
16331 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
16332 // Checking declaration inside declare target region.
16333 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
16334 isa<FunctionTemplateDecl>(D)) {
16335 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
Alexey Bataev729e2422019-08-23 16:11:14 +000016336 Context, OMPDeclareTargetDeclAttr::MT_To,
16337 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
Alexey Bataev30a78212018-09-11 13:59:10 +000016338 D->addAttr(A);
16339 if (ASTMutationListener *ML = Context.getASTMutationListener())
16340 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
16341 }
16342 return;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016343 }
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016344 }
Alexey Bataev30a78212018-09-11 13:59:10 +000016345 if (!E)
16346 return;
Dmitry Polukhin0b0da292016-04-06 11:38:59 +000016347 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
16348}
Samuel Antao661c0902016-05-26 17:39:58 +000016349
16350OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
Michael Kruse01f670d2019-02-22 22:29:42 +000016351 CXXScopeSpec &MapperIdScopeSpec,
16352 DeclarationNameInfo &MapperId,
16353 const OMPVarListLocTy &Locs,
16354 ArrayRef<Expr *> UnresolvedMappers) {
Samuel Antao661c0902016-05-26 17:39:58 +000016355 MappableVarListInfo MVLI(VarList);
Michael Kruse01f670d2019-02-22 22:29:42 +000016356 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
16357 MapperIdScopeSpec, MapperId, UnresolvedMappers);
Samuel Antao661c0902016-05-26 17:39:58 +000016358 if (MVLI.ProcessedVarList.empty())
16359 return nullptr;
16360
Michael Kruse01f670d2019-02-22 22:29:42 +000016361 return OMPToClause::Create(
16362 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
16363 MVLI.VarComponents, MVLI.UDMapperList,
16364 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
Samuel Antao661c0902016-05-26 17:39:58 +000016365}
Samuel Antaoec172c62016-05-26 17:49:04 +000016366
16367OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
Michael Kruse0336c752019-02-25 20:34:15 +000016368 CXXScopeSpec &MapperIdScopeSpec,
16369 DeclarationNameInfo &MapperId,
16370 const OMPVarListLocTy &Locs,
16371 ArrayRef<Expr *> UnresolvedMappers) {
Samuel Antaoec172c62016-05-26 17:49:04 +000016372 MappableVarListInfo MVLI(VarList);
Michael Kruse01f670d2019-02-22 22:29:42 +000016373 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
16374 MapperIdScopeSpec, MapperId, UnresolvedMappers);
Samuel Antaoec172c62016-05-26 17:49:04 +000016375 if (MVLI.ProcessedVarList.empty())
16376 return nullptr;
16377
Michael Kruse0336c752019-02-25 20:34:15 +000016378 return OMPFromClause::Create(
16379 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
16380 MVLI.VarComponents, MVLI.UDMapperList,
16381 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
Samuel Antaoec172c62016-05-26 17:49:04 +000016382}
Carlo Bertolli2404b172016-07-13 15:37:16 +000016383
16384OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
Michael Kruse4304e9d2019-02-19 16:38:20 +000016385 const OMPVarListLocTy &Locs) {
Samuel Antaocc10b852016-07-28 14:23:26 +000016386 MappableVarListInfo MVLI(VarList);
16387 SmallVector<Expr *, 8> PrivateCopies;
16388 SmallVector<Expr *, 8> Inits;
16389
Alexey Bataeve3727102018-04-18 15:57:46 +000016390 for (Expr *RefExpr : VarList) {
Carlo Bertolli2404b172016-07-13 15:37:16 +000016391 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
16392 SourceLocation ELoc;
16393 SourceRange ERange;
16394 Expr *SimpleRefExpr = RefExpr;
16395 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16396 if (Res.second) {
16397 // It will be analyzed later.
Samuel Antaocc10b852016-07-28 14:23:26 +000016398 MVLI.ProcessedVarList.push_back(RefExpr);
16399 PrivateCopies.push_back(nullptr);
16400 Inits.push_back(nullptr);
Carlo Bertolli2404b172016-07-13 15:37:16 +000016401 }
16402 ValueDecl *D = Res.first;
16403 if (!D)
16404 continue;
16405
16406 QualType Type = D->getType();
Samuel Antaocc10b852016-07-28 14:23:26 +000016407 Type = Type.getNonReferenceType().getUnqualifiedType();
16408
16409 auto *VD = dyn_cast<VarDecl>(D);
16410
16411 // Item should be a pointer or reference to pointer.
16412 if (!Type->isPointerType()) {
Carlo Bertolli2404b172016-07-13 15:37:16 +000016413 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
16414 << 0 << RefExpr->getSourceRange();
16415 continue;
16416 }
Samuel Antaocc10b852016-07-28 14:23:26 +000016417
16418 // Build the private variable and the expression that refers to it.
Alexey Bataev63cc8e92018-03-20 14:45:59 +000016419 auto VDPrivate =
16420 buildVarDecl(*this, ELoc, Type, D->getName(),
16421 D->hasAttrs() ? &D->getAttrs() : nullptr,
16422 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
Samuel Antaocc10b852016-07-28 14:23:26 +000016423 if (VDPrivate->isInvalidDecl())
16424 continue;
16425
16426 CurContext->addDecl(VDPrivate);
Alexey Bataeve3727102018-04-18 15:57:46 +000016427 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
Samuel Antaocc10b852016-07-28 14:23:26 +000016428 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
16429
16430 // Add temporary variable to initialize the private copy of the pointer.
Alexey Bataeve3727102018-04-18 15:57:46 +000016431 VarDecl *VDInit =
Samuel Antaocc10b852016-07-28 14:23:26 +000016432 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
Alexey Bataeve3727102018-04-18 15:57:46 +000016433 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
16434 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
Samuel Antaocc10b852016-07-28 14:23:26 +000016435 AddInitializerToDecl(VDPrivate,
16436 DefaultLvalueConversion(VDInitRefExpr).get(),
Richard Smith3beb7c62017-01-12 02:27:38 +000016437 /*DirectInit=*/false);
Samuel Antaocc10b852016-07-28 14:23:26 +000016438
16439 // If required, build a capture to implement the privatization initialized
16440 // with the current list item value.
16441 DeclRefExpr *Ref = nullptr;
16442 if (!VD)
16443 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16444 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
16445 PrivateCopies.push_back(VDPrivateRefExpr);
16446 Inits.push_back(VDInitRefExpr);
16447
16448 // We need to add a data sharing attribute for this variable to make sure it
16449 // is correctly captured. A variable that shows up in a use_device_ptr has
16450 // similar properties of a first private variable.
16451 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16452
16453 // Create a mappable component for the list item. List items in this clause
16454 // only need a component.
16455 MVLI.VarBaseDeclarations.push_back(D);
16456 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16457 MVLI.VarComponents.back().push_back(
16458 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
Carlo Bertolli2404b172016-07-13 15:37:16 +000016459 }
16460
Samuel Antaocc10b852016-07-28 14:23:26 +000016461 if (MVLI.ProcessedVarList.empty())
Carlo Bertolli2404b172016-07-13 15:37:16 +000016462 return nullptr;
16463
Samuel Antaocc10b852016-07-28 14:23:26 +000016464 return OMPUseDevicePtrClause::Create(
Michael Kruse4304e9d2019-02-19 16:38:20 +000016465 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
16466 MVLI.VarBaseDeclarations, MVLI.VarComponents);
Carlo Bertolli2404b172016-07-13 15:37:16 +000016467}
Carlo Bertolli70594e92016-07-13 17:16:49 +000016468
16469OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
Michael Kruse4304e9d2019-02-19 16:38:20 +000016470 const OMPVarListLocTy &Locs) {
Samuel Antao6890b092016-07-28 14:25:09 +000016471 MappableVarListInfo MVLI(VarList);
Alexey Bataeve3727102018-04-18 15:57:46 +000016472 for (Expr *RefExpr : VarList) {
Kelvin Li84376252016-12-14 15:39:58 +000016473 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
Carlo Bertolli70594e92016-07-13 17:16:49 +000016474 SourceLocation ELoc;
16475 SourceRange ERange;
16476 Expr *SimpleRefExpr = RefExpr;
16477 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16478 if (Res.second) {
16479 // It will be analyzed later.
Samuel Antao6890b092016-07-28 14:25:09 +000016480 MVLI.ProcessedVarList.push_back(RefExpr);
Carlo Bertolli70594e92016-07-13 17:16:49 +000016481 }
16482 ValueDecl *D = Res.first;
16483 if (!D)
16484 continue;
16485
16486 QualType Type = D->getType();
16487 // item should be a pointer or array or reference to pointer or array
16488 if (!Type.getNonReferenceType()->isPointerType() &&
16489 !Type.getNonReferenceType()->isArrayType()) {
16490 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
16491 << 0 << RefExpr->getSourceRange();
16492 continue;
16493 }
Samuel Antao6890b092016-07-28 14:25:09 +000016494
16495 // Check if the declaration in the clause does not show up in any data
16496 // sharing attribute.
Alexey Bataeve3727102018-04-18 15:57:46 +000016497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
Samuel Antao6890b092016-07-28 14:25:09 +000016498 if (isOpenMPPrivate(DVar.CKind)) {
16499 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16500 << getOpenMPClauseName(DVar.CKind)
16501 << getOpenMPClauseName(OMPC_is_device_ptr)
16502 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
Alexey Bataeve3727102018-04-18 15:57:46 +000016503 reportOriginalDsa(*this, DSAStack, D, DVar);
Samuel Antao6890b092016-07-28 14:25:09 +000016504 continue;
16505 }
16506
Alexey Bataeve3727102018-04-18 15:57:46 +000016507 const Expr *ConflictExpr;
Samuel Antao6890b092016-07-28 14:25:09 +000016508 if (DSAStack->checkMappableExprComponentListsForDecl(
David Majnemer9d168222016-08-05 17:44:54 +000016509 D, /*CurrentRegionOnly=*/true,
Samuel Antao6890b092016-07-28 14:25:09 +000016510 [&ConflictExpr](
16511 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
16512 OpenMPClauseKind) -> bool {
16513 ConflictExpr = R.front().getAssociatedExpression();
16514 return true;
16515 })) {
16516 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
16517 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
16518 << ConflictExpr->getSourceRange();
16519 continue;
16520 }
16521
16522 // Store the components in the stack so that they can be used to check
16523 // against other clauses later on.
16524 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
16525 DSAStack->addMappableExpressionComponents(
16526 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
16527
16528 // Record the expression we've just processed.
16529 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
16530
16531 // Create a mappable component for the list item. List items in this clause
16532 // only need a component. We use a null declaration to signal fields in
16533 // 'this'.
16534 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
16535 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
16536 "Unexpected device pointer expression!");
16537 MVLI.VarBaseDeclarations.push_back(
16538 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
16539 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16540 MVLI.VarComponents.back().push_back(MC);
Carlo Bertolli70594e92016-07-13 17:16:49 +000016541 }
16542
Samuel Antao6890b092016-07-28 14:25:09 +000016543 if (MVLI.ProcessedVarList.empty())
Carlo Bertolli70594e92016-07-13 17:16:49 +000016544 return nullptr;
16545
Michael Kruse4304e9d2019-02-19 16:38:20 +000016546 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
16547 MVLI.VarBaseDeclarations,
16548 MVLI.VarComponents);
Carlo Bertolli70594e92016-07-13 17:16:49 +000016549}
Alexey Bataeve04483e2019-03-27 14:14:31 +000016550
16551OMPClause *Sema::ActOnOpenMPAllocateClause(
16552 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16553 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16554 if (Allocator) {
16555 // OpenMP [2.11.4 allocate Clause, Description]
16556 // allocator is an expression of omp_allocator_handle_t type.
16557 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
16558 return nullptr;
16559
16560 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
16561 if (AllocatorRes.isInvalid())
16562 return nullptr;
16563 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
16564 DSAStack->getOMPAllocatorHandleT(),
16565 Sema::AA_Initializing,
16566 /*AllowExplicit=*/true);
16567 if (AllocatorRes.isInvalid())
16568 return nullptr;
16569 Allocator = AllocatorRes.get();
Alexey Bataev84c8bae2019-04-01 16:56:59 +000016570 } else {
16571 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
16572 // allocate clauses that appear on a target construct or on constructs in a
16573 // target region must specify an allocator expression unless a requires
16574 // directive with the dynamic_allocators clause is present in the same
16575 // compilation unit.
16576 if (LangOpts.OpenMPIsDevice &&
16577 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
16578 targetDiag(StartLoc, diag::err_expected_allocator_expression);
Alexey Bataeve04483e2019-03-27 14:14:31 +000016579 }
16580 // Analyze and build list of variables.
16581 SmallVector<Expr *, 8> Vars;
16582 for (Expr *RefExpr : VarList) {
16583 assert(RefExpr && "NULL expr in OpenMP private clause.");
16584 SourceLocation ELoc;
16585 SourceRange ERange;
16586 Expr *SimpleRefExpr = RefExpr;
16587 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16588 if (Res.second) {
16589 // It will be analyzed later.
16590 Vars.push_back(RefExpr);
16591 }
16592 ValueDecl *D = Res.first;
16593 if (!D)
16594 continue;
16595
16596 auto *VD = dyn_cast<VarDecl>(D);
16597 DeclRefExpr *Ref = nullptr;
16598 if (!VD && !CurContext->isDependentContext())
16599 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16600 Vars.push_back((VD || CurContext->isDependentContext())
16601 ? RefExpr->IgnoreParens()
16602 : Ref);
16603 }
16604
16605 if (Vars.empty())
16606 return nullptr;
16607
16608 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
16609 ColonLoc, EndLoc, Vars);
16610}