Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 6058, column 22
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-09-28-092409-31635-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp

/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp

1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements semantic analysis for OpenMP directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#include "TreeTransform.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/CXXInheritance.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclOpenMP.h"
21#include "clang/AST/OpenMPClause.h"
22#include "clang/AST/StmtCXX.h"
23#include "clang/AST/StmtOpenMP.h"
24#include "clang/AST/StmtVisitor.h"
25#include "clang/AST/TypeOrdering.h"
26#include "clang/Basic/DiagnosticSema.h"
27#include "clang/Basic/OpenMPKinds.h"
28#include "clang/Basic/PartialDiagnostic.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Sema/Initialization.h"
31#include "clang/Sema/Lookup.h"
32#include "clang/Sema/Scope.h"
33#include "clang/Sema/ScopeInfo.h"
34#include "clang/Sema/SemaInternal.h"
35#include "llvm/ADT/IndexedMap.h"
36#include "llvm/ADT/PointerEmbeddedInt.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/Frontend/OpenMP/OMPConstants.h"
39#include <set>
40
41using namespace clang;
42using namespace llvm::omp;
43
44//===----------------------------------------------------------------------===//
45// Stack of data-sharing attributes for variables
46//===----------------------------------------------------------------------===//
47
48static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, bool NoDiagnose);
52
53namespace {
54/// Default data sharing attributes, which can be applied to directive.
55enum DefaultDataSharingAttributes {
56 DSA_unspecified = 0, /// Data sharing attribute not specified.
57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
60};
61
62/// Stack for tracking declarations used in OpenMP directives and
63/// clauses and their data-sharing attributes.
64class DSAStackTy {
65public:
66 struct DSAVarData {
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 bool AppliedToPointee = false;
74 DSAVarData() = default;
75 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
76 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
77 SourceLocation ImplicitDSALoc, unsigned Modifier,
78 bool AppliedToPointee)
79 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
80 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
81 AppliedToPointee(AppliedToPointee) {}
82 };
83 using OperatorOffsetTy =
84 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
85 using DoacrossDependMapTy =
86 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
87 /// Kind of the declaration used in the uses_allocators clauses.
88 enum class UsesAllocatorsDeclKind {
89 /// Predefined allocator
90 PredefinedAllocator,
91 /// User-defined allocator
92 UserDefinedAllocator,
93 /// The declaration that represent allocator trait
94 AllocatorTrait,
95 };
96
97private:
98 struct DSAInfo {
99 OpenMPClauseKind Attributes = OMPC_unknown;
100 unsigned Modifier = 0;
101 /// Pointer to a reference expression and a flag which shows that the
102 /// variable is marked as lastprivate(true) or not (false).
103 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
104 DeclRefExpr *PrivateCopy = nullptr;
105 /// true if the attribute is applied to the pointee, not the variable
106 /// itself.
107 bool AppliedToPointee = false;
108 };
109 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
110 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
111 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
112 using LoopControlVariablesMapTy =
113 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
114 /// Struct that associates a component with the clause kind where they are
115 /// found.
116 struct MappedExprComponentTy {
117 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
118 OpenMPClauseKind Kind = OMPC_unknown;
119 };
120 using MappedExprComponentsTy =
121 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
122 using CriticalsWithHintsTy =
123 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
124 struct ReductionData {
125 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
126 SourceRange ReductionRange;
127 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
128 ReductionData() = default;
129 void set(BinaryOperatorKind BO, SourceRange RR) {
130 ReductionRange = RR;
131 ReductionOp = BO;
132 }
133 void set(const Expr *RefExpr, SourceRange RR) {
134 ReductionRange = RR;
135 ReductionOp = RefExpr;
136 }
137 };
138 using DeclReductionMapTy =
139 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
140 struct DefaultmapInfo {
141 OpenMPDefaultmapClauseModifier ImplicitBehavior =
142 OMPC_DEFAULTMAP_MODIFIER_unknown;
143 SourceLocation SLoc;
144 DefaultmapInfo() = default;
145 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
146 : ImplicitBehavior(M), SLoc(Loc) {}
147 };
148
149 struct SharingMapTy {
150 DeclSAMapTy SharingMap;
151 DeclReductionMapTy ReductionMap;
152 UsedRefMapTy AlignedMap;
153 UsedRefMapTy NontemporalMap;
154 MappedExprComponentsTy MappedExprComponents;
155 LoopControlVariablesMapTy LCVMap;
156 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
157 SourceLocation DefaultAttrLoc;
158 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
159 OpenMPDirectiveKind Directive = OMPD_unknown;
160 DeclarationNameInfo DirectiveName;
161 Scope *CurScope = nullptr;
162 DeclContext *Context = nullptr;
163 SourceLocation ConstructLoc;
164 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
165 /// get the data (loop counters etc.) about enclosing loop-based construct.
166 /// This data is required during codegen.
167 DoacrossDependMapTy DoacrossDepends;
168 /// First argument (Expr *) contains optional argument of the
169 /// 'ordered' clause, the second one is true if the regions has 'ordered'
170 /// clause, false otherwise.
171 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
172 unsigned AssociatedLoops = 1;
173 bool HasMutipleLoops = false;
174 const Decl *PossiblyLoopCounter = nullptr;
175 bool NowaitRegion = false;
176 bool CancelRegion = false;
177 bool LoopStart = false;
178 bool BodyComplete = false;
179 SourceLocation PrevScanLocation;
180 SourceLocation PrevOrderedLocation;
181 SourceLocation InnerTeamsRegionLoc;
182 /// Reference to the taskgroup task_reduction reference expression.
183 Expr *TaskgroupReductionRef = nullptr;
184 llvm::DenseSet<QualType> MappedClassesQualTypes;
185 SmallVector<Expr *, 4> InnerUsedAllocators;
186 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
187 /// List of globals marked as declare target link in this target region
188 /// (isOpenMPTargetExecutionDirective(Directive) == true).
189 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
190 /// List of decls used in inclusive/exclusive clauses of the scan directive.
191 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
192 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
193 UsesAllocatorsDecls;
194 Expr *DeclareMapperVar = nullptr;
195 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
196 Scope *CurScope, SourceLocation Loc)
197 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
198 ConstructLoc(Loc) {}
199 SharingMapTy() = default;
200 };
201
202 using StackTy = SmallVector<SharingMapTy, 4>;
203
204 /// Stack of used declaration and their data-sharing attributes.
205 DeclSAMapTy Threadprivates;
206 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
207 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
208 /// true, if check for DSA must be from parent directive, false, if
209 /// from current directive.
210 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
211 Sema &SemaRef;
212 bool ForceCapturing = false;
213 /// true if all the variables in the target executable directives must be
214 /// captured by reference.
215 bool ForceCaptureByReferenceInTargetExecutable = false;
216 CriticalsWithHintsTy Criticals;
217 unsigned IgnoredStackElements = 0;
218
219 /// Iterators over the stack iterate in order from innermost to outermost
220 /// directive.
221 using const_iterator = StackTy::const_reverse_iterator;
222 const_iterator begin() const {
223 return Stack.empty() ? const_iterator()
224 : Stack.back().first.rbegin() + IgnoredStackElements;
225 }
226 const_iterator end() const {
227 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
228 }
229 using iterator = StackTy::reverse_iterator;
230 iterator begin() {
231 return Stack.empty() ? iterator()
232 : Stack.back().first.rbegin() + IgnoredStackElements;
233 }
234 iterator end() {
235 return Stack.empty() ? iterator() : Stack.back().first.rend();
236 }
237
238 // Convenience operations to get at the elements of the stack.
239
240 bool isStackEmpty() const {
241 return Stack.empty() ||
242 Stack.back().second != CurrentNonCapturingFunctionScope ||
243 Stack.back().first.size() <= IgnoredStackElements;
244 }
245 size_t getStackSize() const {
246 return isStackEmpty() ? 0
247 : Stack.back().first.size() - IgnoredStackElements;
248 }
249
250 SharingMapTy *getTopOfStackOrNull() {
251 size_t Size = getStackSize();
252 if (Size == 0)
253 return nullptr;
254 return &Stack.back().first[Size - 1];
255 }
256 const SharingMapTy *getTopOfStackOrNull() const {
257 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
258 }
259 SharingMapTy &getTopOfStack() {
260 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 260, __PRETTY_FUNCTION__))
;
261 return *getTopOfStackOrNull();
262 }
263 const SharingMapTy &getTopOfStack() const {
264 return const_cast<DSAStackTy&>(*this).getTopOfStack();
265 }
266
267 SharingMapTy *getSecondOnStackOrNull() {
268 size_t Size = getStackSize();
269 if (Size <= 1)
270 return nullptr;
271 return &Stack.back().first[Size - 2];
272 }
273 const SharingMapTy *getSecondOnStackOrNull() const {
274 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
275 }
276
277 /// Get the stack element at a certain level (previously returned by
278 /// \c getNestingLevel).
279 ///
280 /// Note that nesting levels count from outermost to innermost, and this is
281 /// the reverse of our iteration order where new inner levels are pushed at
282 /// the front of the stack.
283 SharingMapTy &getStackElemAtLevel(unsigned Level) {
284 assert(Level < getStackSize() && "no such stack element")((Level < getStackSize() && "no such stack element"
) ? static_cast<void> (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 284, __PRETTY_FUNCTION__))
;
285 return Stack.back().first[Level];
286 }
287 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
288 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
289 }
290
291 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
292
293 /// Checks if the variable is a local for OpenMP region.
294 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
295
296 /// Vector of previously declared requires directives
297 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
298 /// omp_allocator_handle_t type.
299 QualType OMPAllocatorHandleT;
300 /// omp_depend_t type.
301 QualType OMPDependT;
302 /// omp_event_handle_t type.
303 QualType OMPEventHandleT;
304 /// omp_alloctrait_t type.
305 QualType OMPAlloctraitT;
306 /// Expression for the predefined allocators.
307 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
308 nullptr};
309 /// Vector of previously encountered target directives
310 SmallVector<SourceLocation, 2> TargetLocations;
311 SourceLocation AtomicLocation;
312
313public:
314 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
315
316 /// Sets omp_allocator_handle_t type.
317 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
318 /// Gets omp_allocator_handle_t type.
319 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
320 /// Sets omp_alloctrait_t type.
321 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
322 /// Gets omp_alloctrait_t type.
323 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
324 /// Sets the given default allocator.
325 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
326 Expr *Allocator) {
327 OMPPredefinedAllocators[AllocatorKind] = Allocator;
328 }
329 /// Returns the specified default allocator.
330 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
331 return OMPPredefinedAllocators[AllocatorKind];
332 }
333 /// Sets omp_depend_t type.
334 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
335 /// Gets omp_depend_t type.
336 QualType getOMPDependT() const { return OMPDependT; }
337
338 /// Sets omp_event_handle_t type.
339 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
340 /// Gets omp_event_handle_t type.
341 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
342
343 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
344 OpenMPClauseKind getClauseParsingMode() const {
345 assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode."
) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 345, __PRETTY_FUNCTION__))
;
346 return ClauseKindMode;
347 }
348 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
349
350 bool isBodyComplete() const {
351 const SharingMapTy *Top = getTopOfStackOrNull();
352 return Top && Top->BodyComplete;
353 }
354 void setBodyComplete() {
355 getTopOfStack().BodyComplete = true;
356 }
357
358 bool isForceVarCapturing() const { return ForceCapturing; }
359 void setForceVarCapturing(bool V) { ForceCapturing = V; }
360
361 void setForceCaptureByReferenceInTargetExecutable(bool V) {
362 ForceCaptureByReferenceInTargetExecutable = V;
363 }
364 bool isForceCaptureByReferenceInTargetExecutable() const {
365 return ForceCaptureByReferenceInTargetExecutable;
366 }
367
368 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
369 Scope *CurScope, SourceLocation Loc) {
370 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 371, __PRETTY_FUNCTION__))
371 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 371, __PRETTY_FUNCTION__))
;
372 if (Stack.empty() ||
373 Stack.back().second != CurrentNonCapturingFunctionScope)
374 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
375 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
376 Stack.back().first.back().DefaultAttrLoc = Loc;
377 }
378
379 void pop() {
380 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 381, __PRETTY_FUNCTION__))
381 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 381, __PRETTY_FUNCTION__))
;
382 assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 383, __PRETTY_FUNCTION__))
383 "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 383, __PRETTY_FUNCTION__))
;
384 Stack.back().first.pop_back();
385 }
386
387 /// RAII object to temporarily leave the scope of a directive when we want to
388 /// logically operate in its parent.
389 class ParentDirectiveScope {
390 DSAStackTy &Self;
391 bool Active;
392 public:
393 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
394 : Self(Self), Active(false) {
395 if (Activate)
396 enable();
397 }
398 ~ParentDirectiveScope() { disable(); }
399 void disable() {
400 if (Active) {
401 --Self.IgnoredStackElements;
402 Active = false;
403 }
404 }
405 void enable() {
406 if (!Active) {
407 ++Self.IgnoredStackElements;
408 Active = true;
409 }
410 }
411 };
412
413 /// Marks that we're started loop parsing.
414 void loopInit() {
415 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 416, __PRETTY_FUNCTION__))
416 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 416, __PRETTY_FUNCTION__))
;
417 getTopOfStack().LoopStart = true;
418 }
419 /// Start capturing of the variables in the loop context.
420 void loopStart() {
421 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 422, __PRETTY_FUNCTION__))
422 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 422, __PRETTY_FUNCTION__))
;
423 getTopOfStack().LoopStart = false;
424 }
425 /// true, if variables are captured, false otherwise.
426 bool isLoopStarted() const {
427 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 428, __PRETTY_FUNCTION__))
428 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 428, __PRETTY_FUNCTION__))
;
429 return !getTopOfStack().LoopStart;
430 }
431 /// Marks (or clears) declaration as possibly loop counter.
432 void resetPossibleLoopCounter(const Decl *D = nullptr) {
433 getTopOfStack().PossiblyLoopCounter =
434 D ? D->getCanonicalDecl() : D;
435 }
436 /// Gets the possible loop counter decl.
437 const Decl *getPossiblyLoopCunter() const {
438 return getTopOfStack().PossiblyLoopCounter;
439 }
440 /// Start new OpenMP region stack in new non-capturing function.
441 void pushFunction() {
442 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 443, __PRETTY_FUNCTION__))
443 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 443, __PRETTY_FUNCTION__))
;
444 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
445 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 445, __PRETTY_FUNCTION__))
;
446 CurrentNonCapturingFunctionScope = CurFnScope;
447 }
448 /// Pop region stack for non-capturing function.
449 void popFunction(const FunctionScopeInfo *OldFSI) {
450 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 451, __PRETTY_FUNCTION__))
451 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 451, __PRETTY_FUNCTION__))
;
452 if (!Stack.empty() && Stack.back().second == OldFSI) {
453 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 453, __PRETTY_FUNCTION__))
;
454 Stack.pop_back();
455 }
456 CurrentNonCapturingFunctionScope = nullptr;
457 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
458 if (!isa<CapturingScopeInfo>(FSI)) {
459 CurrentNonCapturingFunctionScope = FSI;
460 break;
461 }
462 }
463 }
464
465 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
466 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
467 }
468 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
469 getCriticalWithHint(const DeclarationNameInfo &Name) const {
470 auto I = Criticals.find(Name.getAsString());
471 if (I != Criticals.end())
472 return I->second;
473 return std::make_pair(nullptr, llvm::APSInt());
474 }
475 /// If 'aligned' declaration for given variable \a D was not seen yet,
476 /// add it and return NULL; otherwise return previous occurrence's expression
477 /// for diagnostics.
478 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
479 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
480 /// add it and return NULL; otherwise return previous occurrence's expression
481 /// for diagnostics.
482 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
483
484 /// Register specified variable as loop control variable.
485 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
486 /// Check if the specified variable is a loop control variable for
487 /// current region.
488 /// \return The index of the loop control variable in the list of associated
489 /// for-loops (from outer to inner).
490 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
491 /// Check if the specified variable is a loop control variable for
492 /// parent region.
493 /// \return The index of the loop control variable in the list of associated
494 /// for-loops (from outer to inner).
495 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
496 /// Check if the specified variable is a loop control variable for
497 /// current region.
498 /// \return The index of the loop control variable in the list of associated
499 /// for-loops (from outer to inner).
500 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
501 unsigned Level) const;
502 /// Get the loop control variable for the I-th loop (or nullptr) in
503 /// parent directive.
504 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
505
506 /// Marks the specified decl \p D as used in scan directive.
507 void markDeclAsUsedInScanDirective(ValueDecl *D) {
508 if (SharingMapTy *Stack = getSecondOnStackOrNull())
509 Stack->UsedInScanDirective.insert(D);
510 }
511
512 /// Checks if the specified declaration was used in the inner scan directive.
513 bool isUsedInScanDirective(ValueDecl *D) const {
514 if (const SharingMapTy *Stack = getTopOfStackOrNull())
515 return Stack->UsedInScanDirective.count(D) > 0;
516 return false;
517 }
518
519 /// Adds explicit data sharing attribute to the specified declaration.
520 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
521 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
522 bool AppliedToPointee = false);
523
524 /// Adds additional information for the reduction items with the reduction id
525 /// represented as an operator.
526 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
527 BinaryOperatorKind BOK);
528 /// Adds additional information for the reduction items with the reduction id
529 /// represented as reduction identifier.
530 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531 const Expr *ReductionRef);
532 /// Returns the location and reduction operation from the innermost parent
533 /// region for the given \p D.
534 const DSAVarData
535 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
536 BinaryOperatorKind &BOK,
537 Expr *&TaskgroupDescriptor) const;
538 /// Returns the location and reduction operation from the innermost parent
539 /// region for the given \p D.
540 const DSAVarData
541 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
542 const Expr *&ReductionRef,
543 Expr *&TaskgroupDescriptor) const;
544 /// Return reduction reference expression for the current taskgroup or
545 /// parallel/worksharing directives with task reductions.
546 Expr *getTaskgroupReductionRef() const {
547 assert((getTopOfStack().Directive == OMPD_taskgroup ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
548 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
549 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
550 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
551 "taskgroup reference expression requested for non taskgroup or "(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
552 "parallel/worksharing directive.")(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 552, __PRETTY_FUNCTION__))
;
553 return getTopOfStack().TaskgroupReductionRef;
554 }
555 /// Checks if the given \p VD declaration is actually a taskgroup reduction
556 /// descriptor variable at the \p Level of OpenMP regions.
557 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
558 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
559 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
560 ->getDecl() == VD;
561 }
562
563 /// Returns data sharing attributes from top of the stack for the
564 /// specified declaration.
565 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
566 /// Returns data-sharing attributes for the specified declaration.
567 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
568 /// Returns data-sharing attributes for the specified declaration.
569 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
570 /// Checks if the specified variables has data-sharing attributes which
571 /// match specified \a CPred predicate in any directive which matches \a DPred
572 /// predicate.
573 const DSAVarData
574 hasDSA(ValueDecl *D,
575 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
576 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
577 bool FromParent) const;
578 /// Checks if the specified variables has data-sharing attributes which
579 /// match specified \a CPred predicate in any innermost directive which
580 /// matches \a DPred predicate.
581 const DSAVarData
582 hasInnermostDSA(ValueDecl *D,
583 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
585 bool FromParent) const;
586 /// Checks if the specified variables has explicit data-sharing
587 /// attributes which match specified \a CPred predicate at the specified
588 /// OpenMP region.
589 bool
590 hasExplicitDSA(const ValueDecl *D,
591 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
592 unsigned Level, bool NotLastprivate = false) const;
593
594 /// Returns true if the directive at level \Level matches in the
595 /// specified \a DPred predicate.
596 bool hasExplicitDirective(
597 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
598 unsigned Level) const;
599
600 /// Finds a directive which matches specified \a DPred predicate.
601 bool hasDirective(
602 const llvm::function_ref<bool(
603 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
604 DPred,
605 bool FromParent) const;
606
607 /// Returns currently analyzed directive.
608 OpenMPDirectiveKind getCurrentDirective() const {
609 const SharingMapTy *Top = getTopOfStackOrNull();
610 return Top ? Top->Directive : OMPD_unknown;
611 }
612 /// Returns directive kind at specified level.
613 OpenMPDirectiveKind getDirective(unsigned Level) const {
614 assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 614, __PRETTY_FUNCTION__))
;
615 return getStackElemAtLevel(Level).Directive;
616 }
617 /// Returns the capture region at the specified level.
618 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
619 unsigned OpenMPCaptureLevel) const {
620 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
621 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
622 return CaptureRegions[OpenMPCaptureLevel];
623 }
624 /// Returns parent directive.
625 OpenMPDirectiveKind getParentDirective() const {
626 const SharingMapTy *Parent = getSecondOnStackOrNull();
627 return Parent ? Parent->Directive : OMPD_unknown;
628 }
629
630 /// Add requires decl to internal vector
631 void addRequiresDecl(OMPRequiresDecl *RD) {
632 RequiresDecls.push_back(RD);
633 }
634
635 /// Checks if the defined 'requires' directive has specified type of clause.
636 template <typename ClauseType>
637 bool hasRequiresDeclWithClause() const {
638 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
639 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
640 return isa<ClauseType>(C);
641 });
642 });
643 }
644
645 /// Checks for a duplicate clause amongst previously declared requires
646 /// directives
647 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
648 bool IsDuplicate = false;
649 for (OMPClause *CNew : ClauseList) {
650 for (const OMPRequiresDecl *D : RequiresDecls) {
651 for (const OMPClause *CPrev : D->clauselists()) {
652 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
653 SemaRef.Diag(CNew->getBeginLoc(),
654 diag::err_omp_requires_clause_redeclaration)
655 << getOpenMPClauseName(CNew->getClauseKind());
656 SemaRef.Diag(CPrev->getBeginLoc(),
657 diag::note_omp_requires_previous_clause)
658 << getOpenMPClauseName(CPrev->getClauseKind());
659 IsDuplicate = true;
660 }
661 }
662 }
663 }
664 return IsDuplicate;
665 }
666
667 /// Add location of previously encountered target to internal vector
668 void addTargetDirLocation(SourceLocation LocStart) {
669 TargetLocations.push_back(LocStart);
670 }
671
672 /// Add location for the first encountered atomicc directive.
673 void addAtomicDirectiveLoc(SourceLocation Loc) {
674 if (AtomicLocation.isInvalid())
675 AtomicLocation = Loc;
676 }
677
678 /// Returns the location of the first encountered atomic directive in the
679 /// module.
680 SourceLocation getAtomicDirectiveLoc() const {
681 return AtomicLocation;
682 }
683
684 // Return previously encountered target region locations.
685 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
686 return TargetLocations;
687 }
688
689 /// Set default data sharing attribute to none.
690 void setDefaultDSANone(SourceLocation Loc) {
691 getTopOfStack().DefaultAttr = DSA_none;
692 getTopOfStack().DefaultAttrLoc = Loc;
693 }
694 /// Set default data sharing attribute to shared.
695 void setDefaultDSAShared(SourceLocation Loc) {
696 getTopOfStack().DefaultAttr = DSA_shared;
697 getTopOfStack().DefaultAttrLoc = Loc;
698 }
699 /// Set default data sharing attribute to firstprivate.
700 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
701 getTopOfStack().DefaultAttr = DSA_firstprivate;
702 getTopOfStack().DefaultAttrLoc = Loc;
703 }
704 /// Set default data mapping attribute to Modifier:Kind
705 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
706 OpenMPDefaultmapClauseKind Kind,
707 SourceLocation Loc) {
708 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
709 DMI.ImplicitBehavior = M;
710 DMI.SLoc = Loc;
711 }
712 /// Check whether the implicit-behavior has been set in defaultmap
713 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
714 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
715 return getTopOfStack()
716 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
717 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
718 getTopOfStack()
719 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
720 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
721 getTopOfStack()
722 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
723 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
724 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
725 OMPC_DEFAULTMAP_MODIFIER_unknown;
726 }
727
728 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
729 return getStackSize() <= Level ? DSA_unspecified
730 : getStackElemAtLevel(Level).DefaultAttr;
731 }
732 DefaultDataSharingAttributes getDefaultDSA() const {
733 return isStackEmpty() ? DSA_unspecified
734 : getTopOfStack().DefaultAttr;
735 }
736 SourceLocation getDefaultDSALocation() const {
737 return isStackEmpty() ? SourceLocation()
738 : getTopOfStack().DefaultAttrLoc;
739 }
740 OpenMPDefaultmapClauseModifier
741 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
742 return isStackEmpty()
743 ? OMPC_DEFAULTMAP_MODIFIER_unknown
744 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
745 }
746 OpenMPDefaultmapClauseModifier
747 getDefaultmapModifierAtLevel(unsigned Level,
748 OpenMPDefaultmapClauseKind Kind) const {
749 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
750 }
751 bool isDefaultmapCapturedByRef(unsigned Level,
752 OpenMPDefaultmapClauseKind Kind) const {
753 OpenMPDefaultmapClauseModifier M =
754 getDefaultmapModifierAtLevel(Level, Kind);
755 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
756 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
757 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
760 }
761 return true;
762 }
763 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
764 OpenMPDefaultmapClauseKind Kind) {
765 switch (Kind) {
766 case OMPC_DEFAULTMAP_scalar:
767 case OMPC_DEFAULTMAP_pointer:
768 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
769 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
770 (M == OMPC_DEFAULTMAP_MODIFIER_default);
771 case OMPC_DEFAULTMAP_aggregate:
772 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
773 default:
774 break;
775 }
776 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 776)
;
777 }
778 bool mustBeFirstprivateAtLevel(unsigned Level,
779 OpenMPDefaultmapClauseKind Kind) const {
780 OpenMPDefaultmapClauseModifier M =
781 getDefaultmapModifierAtLevel(Level, Kind);
782 return mustBeFirstprivateBase(M, Kind);
783 }
784 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
785 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
786 return mustBeFirstprivateBase(M, Kind);
787 }
788
789 /// Checks if the specified variable is a threadprivate.
790 bool isThreadPrivate(VarDecl *D) {
791 const DSAVarData DVar = getTopDSA(D, false);
792 return isOpenMPThreadPrivate(DVar.CKind);
793 }
794
795 /// Marks current region as ordered (it has an 'ordered' clause).
796 void setOrderedRegion(bool IsOrdered, const Expr *Param,
797 OMPOrderedClause *Clause) {
798 if (IsOrdered)
799 getTopOfStack().OrderedRegion.emplace(Param, Clause);
800 else
801 getTopOfStack().OrderedRegion.reset();
802 }
803 /// Returns true, if region is ordered (has associated 'ordered' clause),
804 /// false - otherwise.
805 bool isOrderedRegion() const {
806 if (const SharingMapTy *Top = getTopOfStackOrNull())
807 return Top->OrderedRegion.hasValue();
808 return false;
809 }
810 /// Returns optional parameter for the ordered region.
811 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
812 if (const SharingMapTy *Top = getTopOfStackOrNull())
813 if (Top->OrderedRegion.hasValue())
814 return Top->OrderedRegion.getValue();
815 return std::make_pair(nullptr, nullptr);
816 }
817 /// Returns true, if parent region is ordered (has associated
818 /// 'ordered' clause), false - otherwise.
819 bool isParentOrderedRegion() const {
820 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
821 return Parent->OrderedRegion.hasValue();
822 return false;
823 }
824 /// Returns optional parameter for the ordered region.
825 std::pair<const Expr *, OMPOrderedClause *>
826 getParentOrderedRegionParam() const {
827 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
828 if (Parent->OrderedRegion.hasValue())
829 return Parent->OrderedRegion.getValue();
830 return std::make_pair(nullptr, nullptr);
831 }
832 /// Marks current region as nowait (it has a 'nowait' clause).
833 void setNowaitRegion(bool IsNowait = true) {
834 getTopOfStack().NowaitRegion = IsNowait;
835 }
836 /// Returns true, if parent region is nowait (has associated
837 /// 'nowait' clause), false - otherwise.
838 bool isParentNowaitRegion() const {
839 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840 return Parent->NowaitRegion;
841 return false;
842 }
843 /// Marks parent region as cancel region.
844 void setParentCancelRegion(bool Cancel = true) {
845 if (SharingMapTy *Parent = getSecondOnStackOrNull())
846 Parent->CancelRegion |= Cancel;
847 }
848 /// Return true if current region has inner cancel construct.
849 bool isCancelRegion() const {
850 const SharingMapTy *Top = getTopOfStackOrNull();
851 return Top ? Top->CancelRegion : false;
852 }
853
854 /// Mark that parent region already has scan directive.
855 void setParentHasScanDirective(SourceLocation Loc) {
856 if (SharingMapTy *Parent = getSecondOnStackOrNull())
857 Parent->PrevScanLocation = Loc;
858 }
859 /// Return true if current region has inner cancel construct.
860 bool doesParentHasScanDirective() const {
861 const SharingMapTy *Top = getSecondOnStackOrNull();
862 return Top ? Top->PrevScanLocation.isValid() : false;
863 }
864 /// Return true if current region has inner cancel construct.
865 SourceLocation getParentScanDirectiveLoc() const {
866 const SharingMapTy *Top = getSecondOnStackOrNull();
867 return Top ? Top->PrevScanLocation : SourceLocation();
868 }
869 /// Mark that parent region already has ordered directive.
870 void setParentHasOrderedDirective(SourceLocation Loc) {
871 if (SharingMapTy *Parent = getSecondOnStackOrNull())
872 Parent->PrevOrderedLocation = Loc;
873 }
874 /// Return true if current region has inner ordered construct.
875 bool doesParentHasOrderedDirective() const {
876 const SharingMapTy *Top = getSecondOnStackOrNull();
877 return Top ? Top->PrevOrderedLocation.isValid() : false;
878 }
879 /// Returns the location of the previously specified ordered directive.
880 SourceLocation getParentOrderedDirectiveLoc() const {
881 const SharingMapTy *Top = getSecondOnStackOrNull();
882 return Top ? Top->PrevOrderedLocation : SourceLocation();
883 }
884
885 /// Set collapse value for the region.
886 void setAssociatedLoops(unsigned Val) {
887 getTopOfStack().AssociatedLoops = Val;
888 if (Val > 1)
889 getTopOfStack().HasMutipleLoops = true;
890 }
891 /// Return collapse value for region.
892 unsigned getAssociatedLoops() const {
893 const SharingMapTy *Top = getTopOfStackOrNull();
894 return Top ? Top->AssociatedLoops : 0;
895 }
896 /// Returns true if the construct is associated with multiple loops.
897 bool hasMutipleLoops() const {
898 const SharingMapTy *Top = getTopOfStackOrNull();
899 return Top ? Top->HasMutipleLoops : false;
900 }
901
902 /// Marks current target region as one with closely nested teams
903 /// region.
904 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
905 if (SharingMapTy *Parent = getSecondOnStackOrNull())
906 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
907 }
908 /// Returns true, if current region has closely nested teams region.
909 bool hasInnerTeamsRegion() const {
910 return getInnerTeamsRegionLoc().isValid();
911 }
912 /// Returns location of the nested teams region (if any).
913 SourceLocation getInnerTeamsRegionLoc() const {
914 const SharingMapTy *Top = getTopOfStackOrNull();
915 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
916 }
917
918 Scope *getCurScope() const {
919 const SharingMapTy *Top = getTopOfStackOrNull();
920 return Top ? Top->CurScope : nullptr;
921 }
922 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
923 SourceLocation getConstructLoc() const {
924 const SharingMapTy *Top = getTopOfStackOrNull();
925 return Top ? Top->ConstructLoc : SourceLocation();
926 }
927
928 /// Do the check specified in \a Check to all component lists and return true
929 /// if any issue is found.
930 bool checkMappableExprComponentListsForDecl(
931 const ValueDecl *VD, bool CurrentRegionOnly,
932 const llvm::function_ref<
933 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
934 OpenMPClauseKind)>
935 Check) const {
936 if (isStackEmpty())
937 return false;
938 auto SI = begin();
939 auto SE = end();
940
941 if (SI == SE)
942 return false;
943
944 if (CurrentRegionOnly)
945 SE = std::next(SI);
946 else
947 std::advance(SI, 1);
948
949 for (; SI != SE; ++SI) {
950 auto MI = SI->MappedExprComponents.find(VD);
951 if (MI != SI->MappedExprComponents.end())
952 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
953 MI->second.Components)
954 if (Check(L, MI->second.Kind))
955 return true;
956 }
957 return false;
958 }
959
960 /// Do the check specified in \a Check to all component lists at a given level
961 /// and return true if any issue is found.
962 bool checkMappableExprComponentListsForDeclAtLevel(
963 const ValueDecl *VD, unsigned Level,
964 const llvm::function_ref<
965 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
966 OpenMPClauseKind)>
967 Check) const {
968 if (getStackSize() <= Level)
969 return false;
970
971 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
972 auto MI = StackElem.MappedExprComponents.find(VD);
973 if (MI != StackElem.MappedExprComponents.end())
974 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
975 MI->second.Components)
976 if (Check(L, MI->second.Kind))
977 return true;
978 return false;
979 }
980
981 /// Create a new mappable expression component list associated with a given
982 /// declaration and initialize it with the provided list of components.
983 void addMappableExpressionComponents(
984 const ValueDecl *VD,
985 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
986 OpenMPClauseKind WhereFoundClauseKind) {
987 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
988 // Create new entry and append the new components there.
989 MEC.Components.resize(MEC.Components.size() + 1);
990 MEC.Components.back().append(Components.begin(), Components.end());
991 MEC.Kind = WhereFoundClauseKind;
992 }
993
994 unsigned getNestingLevel() const {
995 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 995, __PRETTY_FUNCTION__))
;
996 return getStackSize() - 1;
997 }
998 void addDoacrossDependClause(OMPDependClause *C,
999 const OperatorOffsetTy &OpsOffs) {
1000 SharingMapTy *Parent = getSecondOnStackOrNull();
1001 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1001, __PRETTY_FUNCTION__))
;
1002 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1003 }
1004 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1005 getDoacrossDependClauses() const {
1006 const SharingMapTy &StackElem = getTopOfStack();
1007 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1008 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1009 return llvm::make_range(Ref.begin(), Ref.end());
1010 }
1011 return llvm::make_range(StackElem.DoacrossDepends.end(),
1012 StackElem.DoacrossDepends.end());
1013 }
1014
1015 // Store types of classes which have been explicitly mapped
1016 void addMappedClassesQualTypes(QualType QT) {
1017 SharingMapTy &StackElem = getTopOfStack();
1018 StackElem.MappedClassesQualTypes.insert(QT);
1019 }
1020
1021 // Return set of mapped classes types
1022 bool isClassPreviouslyMapped(QualType QT) const {
1023 const SharingMapTy &StackElem = getTopOfStack();
1024 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1025 }
1026
1027 /// Adds global declare target to the parent target region.
1028 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1029 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1031, __PRETTY_FUNCTION__))
1030 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1031, __PRETTY_FUNCTION__))
1031 "Expected declare target link global.")((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1031, __PRETTY_FUNCTION__))
;
1032 for (auto &Elem : *this) {
1033 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1034 Elem.DeclareTargetLinkVarDecls.push_back(E);
1035 return;
1036 }
1037 }
1038 }
1039
1040 /// Returns the list of globals with declare target link if current directive
1041 /// is target.
1042 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1043 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1044, __PRETTY_FUNCTION__))
1044 "Expected target executable directive.")((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1044, __PRETTY_FUNCTION__))
;
1045 return getTopOfStack().DeclareTargetLinkVarDecls;
1046 }
1047
1048 /// Adds list of allocators expressions.
1049 void addInnerAllocatorExpr(Expr *E) {
1050 getTopOfStack().InnerUsedAllocators.push_back(E);
1051 }
1052 /// Return list of used allocators.
1053 ArrayRef<Expr *> getInnerAllocators() const {
1054 return getTopOfStack().InnerUsedAllocators;
1055 }
1056 /// Marks the declaration as implicitly firstprivate nin the task-based
1057 /// regions.
1058 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1059 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1060 }
1061 /// Checks if the decl is implicitly firstprivate in the task-based region.
1062 bool isImplicitTaskFirstprivate(Decl *D) const {
1063 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1064 }
1065
1066 /// Marks decl as used in uses_allocators clause as the allocator.
1067 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1068 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1069 }
1070 /// Checks if specified decl is used in uses allocator clause as the
1071 /// allocator.
1072 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1073 const Decl *D) const {
1074 const SharingMapTy &StackElem = getTopOfStack();
1075 auto I = StackElem.UsesAllocatorsDecls.find(D);
1076 if (I == StackElem.UsesAllocatorsDecls.end())
1077 return None;
1078 return I->getSecond();
1079 }
1080 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1081 const SharingMapTy &StackElem = getTopOfStack();
1082 auto I = StackElem.UsesAllocatorsDecls.find(D);
1083 if (I == StackElem.UsesAllocatorsDecls.end())
1084 return None;
1085 return I->getSecond();
1086 }
1087
1088 void addDeclareMapperVarRef(Expr *Ref) {
1089 SharingMapTy &StackElem = getTopOfStack();
1090 StackElem.DeclareMapperVar = Ref;
1091 }
1092 const Expr *getDeclareMapperVarRef() const {
1093 const SharingMapTy *Top = getTopOfStackOrNull();
1094 return Top ? Top->DeclareMapperVar : nullptr;
1095 }
1096};
1097
1098bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1099 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1100}
1101
1102bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1103 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1104 DKind == OMPD_unknown;
1105}
1106
1107} // namespace
1108
1109static const Expr *getExprAsWritten(const Expr *E) {
1110 if (const auto *FE = dyn_cast<FullExpr>(E))
1111 E = FE->getSubExpr();
1112
1113 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1114 E = MTE->getSubExpr();
1115
1116 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1117 E = Binder->getSubExpr();
1118
1119 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1120 E = ICE->getSubExprAsWritten();
1121 return E->IgnoreParens();
1122}
1123
1124static Expr *getExprAsWritten(Expr *E) {
1125 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1126}
1127
1128static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1129 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1130 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1131 D = ME->getMemberDecl();
1132 const auto *VD = dyn_cast<VarDecl>(D);
1133 const auto *FD = dyn_cast<FieldDecl>(D);
1134 if (VD != nullptr) {
1135 VD = VD->getCanonicalDecl();
1136 D = VD;
1137 } else {
1138 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1138, __PRETTY_FUNCTION__))
;
1139 FD = FD->getCanonicalDecl();
1140 D = FD;
1141 }
1142 return D;
1143}
1144
1145static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1146 return const_cast<ValueDecl *>(
1147 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1148}
1149
1150DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1151 ValueDecl *D) const {
1152 D = getCanonicalDecl(D);
1153 auto *VD = dyn_cast<VarDecl>(D);
1154 const auto *FD = dyn_cast<FieldDecl>(D);
1155 DSAVarData DVar;
1156 if (Iter == end()) {
1157 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1158 // in a region but not in construct]
1159 // File-scope or namespace-scope variables referenced in called routines
1160 // in the region are shared unless they appear in a threadprivate
1161 // directive.
1162 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1163 DVar.CKind = OMPC_shared;
1164
1165 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1166 // in a region but not in construct]
1167 // Variables with static storage duration that are declared in called
1168 // routines in the region are shared.
1169 if (VD && VD->hasGlobalStorage())
1170 DVar.CKind = OMPC_shared;
1171
1172 // Non-static data members are shared by default.
1173 if (FD)
1174 DVar.CKind = OMPC_shared;
1175
1176 return DVar;
1177 }
1178
1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1180 // in a Construct, C/C++, predetermined, p.1]
1181 // Variables with automatic storage duration that are declared in a scope
1182 // inside the construct are private.
1183 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1184 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1185 DVar.CKind = OMPC_private;
1186 return DVar;
1187 }
1188
1189 DVar.DKind = Iter->Directive;
1190 // Explicitly specified attributes and local variables with predetermined
1191 // attributes.
1192 if (Iter->SharingMap.count(D)) {
1193 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1194 DVar.RefExpr = Data.RefExpr.getPointer();
1195 DVar.PrivateCopy = Data.PrivateCopy;
1196 DVar.CKind = Data.Attributes;
1197 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1198 DVar.Modifier = Data.Modifier;
1199 DVar.AppliedToPointee = Data.AppliedToPointee;
1200 return DVar;
1201 }
1202
1203 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1204 // in a Construct, C/C++, implicitly determined, p.1]
1205 // In a parallel or task construct, the data-sharing attributes of these
1206 // variables are determined by the default clause, if present.
1207 switch (Iter->DefaultAttr) {
1208 case DSA_shared:
1209 DVar.CKind = OMPC_shared;
1210 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1211 return DVar;
1212 case DSA_none:
1213 return DVar;
1214 case DSA_firstprivate:
1215 if (VD->getStorageDuration() == SD_Static &&
1216 VD->getDeclContext()->isFileContext()) {
1217 DVar.CKind = OMPC_unknown;
1218 } else {
1219 DVar.CKind = OMPC_firstprivate;
1220 }
1221 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1222 return DVar;
1223 case DSA_unspecified:
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225 // in a Construct, implicitly determined, p.2]
1226 // In a parallel construct, if no default clause is present, these
1227 // variables are shared.
1228 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1229 if ((isOpenMPParallelDirective(DVar.DKind) &&
1230 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1231 isOpenMPTeamsDirective(DVar.DKind)) {
1232 DVar.CKind = OMPC_shared;
1233 return DVar;
1234 }
1235
1236 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1237 // in a Construct, implicitly determined, p.4]
1238 // In a task construct, if no default clause is present, a variable that in
1239 // the enclosing context is determined to be shared by all implicit tasks
1240 // bound to the current team is shared.
1241 if (isOpenMPTaskingDirective(DVar.DKind)) {
1242 DSAVarData DVarTemp;
1243 const_iterator I = Iter, E = end();
1244 do {
1245 ++I;
1246 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1247 // Referenced in a Construct, implicitly determined, p.6]
1248 // In a task construct, if no default clause is present, a variable
1249 // whose data-sharing attribute is not determined by the rules above is
1250 // firstprivate.
1251 DVarTemp = getDSA(I, D);
1252 if (DVarTemp.CKind != OMPC_shared) {
1253 DVar.RefExpr = nullptr;
1254 DVar.CKind = OMPC_firstprivate;
1255 return DVar;
1256 }
1257 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1258 DVar.CKind =
1259 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1260 return DVar;
1261 }
1262 }
1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1264 // in a Construct, implicitly determined, p.3]
1265 // For constructs other than task, if no default clause is present, these
1266 // variables inherit their data-sharing attributes from the enclosing
1267 // context.
1268 return getDSA(++Iter, D);
1269}
1270
1271const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1272 const Expr *NewDE) {
1273 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1273, __PRETTY_FUNCTION__))
;
1274 D = getCanonicalDecl(D);
1275 SharingMapTy &StackElem = getTopOfStack();
1276 auto It = StackElem.AlignedMap.find(D);
1277 if (It == StackElem.AlignedMap.end()) {
1278 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1278, __PRETTY_FUNCTION__))
;
1279 StackElem.AlignedMap[D] = NewDE;
1280 return nullptr;
1281 }
1282 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1282, __PRETTY_FUNCTION__))
;
1283 return It->second;
1284}
1285
1286const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1287 const Expr *NewDE) {
1288 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1288, __PRETTY_FUNCTION__))
;
1289 D = getCanonicalDecl(D);
1290 SharingMapTy &StackElem = getTopOfStack();
1291 auto It = StackElem.NontemporalMap.find(D);
1292 if (It == StackElem.NontemporalMap.end()) {
1293 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1293, __PRETTY_FUNCTION__))
;
1294 StackElem.NontemporalMap[D] = NewDE;
1295 return nullptr;
1296 }
1297 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1297, __PRETTY_FUNCTION__))
;
1298 return It->second;
1299}
1300
1301void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1302 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1302, __PRETTY_FUNCTION__))
;
1303 D = getCanonicalDecl(D);
1304 SharingMapTy &StackElem = getTopOfStack();
1305 StackElem.LCVMap.try_emplace(
1306 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1307}
1308
1309const DSAStackTy::LCDeclInfo
1310DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1311 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1311, __PRETTY_FUNCTION__))
;
1312 D = getCanonicalDecl(D);
1313 const SharingMapTy &StackElem = getTopOfStack();
1314 auto It = StackElem.LCVMap.find(D);
1315 if (It != StackElem.LCVMap.end())
1316 return It->second;
1317 return {0, nullptr};
1318}
1319
1320const DSAStackTy::LCDeclInfo
1321DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1322 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1322, __PRETTY_FUNCTION__))
;
1323 D = getCanonicalDecl(D);
1324 for (unsigned I = Level + 1; I > 0; --I) {
1325 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1326 auto It = StackElem.LCVMap.find(D);
1327 if (It != StackElem.LCVMap.end())
1328 return It->second;
1329 }
1330 return {0, nullptr};
1331}
1332
1333const DSAStackTy::LCDeclInfo
1334DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1335 const SharingMapTy *Parent = getSecondOnStackOrNull();
1336 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1336, __PRETTY_FUNCTION__))
;
1337 D = getCanonicalDecl(D);
1338 auto It = Parent->LCVMap.find(D);
1339 if (It != Parent->LCVMap.end())
1340 return It->second;
1341 return {0, nullptr};
1342}
1343
1344const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1345 const SharingMapTy *Parent = getSecondOnStackOrNull();
1346 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1346, __PRETTY_FUNCTION__))
;
1347 if (Parent->LCVMap.size() < I)
1348 return nullptr;
1349 for (const auto &Pair : Parent->LCVMap)
1350 if (Pair.second.first == I)
1351 return Pair.first;
1352 return nullptr;
1353}
1354
1355void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1356 DeclRefExpr *PrivateCopy, unsigned Modifier,
1357 bool AppliedToPointee) {
1358 D = getCanonicalDecl(D);
1359 if (A == OMPC_threadprivate) {
1360 DSAInfo &Data = Threadprivates[D];
1361 Data.Attributes = A;
1362 Data.RefExpr.setPointer(E);
1363 Data.PrivateCopy = nullptr;
1364 Data.Modifier = Modifier;
1365 } else {
1366 DSAInfo &Data = getTopOfStack().SharingMap[D];
1367 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1370, __PRETTY_FUNCTION__))
1368 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1370, __PRETTY_FUNCTION__))
1369 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1370, __PRETTY_FUNCTION__))
1370 (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1370, __PRETTY_FUNCTION__))
;
1371 Data.Modifier = Modifier;
1372 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1373 Data.RefExpr.setInt(/*IntVal=*/true);
1374 return;
1375 }
1376 const bool IsLastprivate =
1377 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1378 Data.Attributes = A;
1379 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1380 Data.PrivateCopy = PrivateCopy;
1381 Data.AppliedToPointee = AppliedToPointee;
1382 if (PrivateCopy) {
1383 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1384 Data.Modifier = Modifier;
1385 Data.Attributes = A;
1386 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1387 Data.PrivateCopy = nullptr;
1388 Data.AppliedToPointee = AppliedToPointee;
1389 }
1390 }
1391}
1392
1393/// Build a variable declaration for OpenMP loop iteration variable.
1394static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1395 StringRef Name, const AttrVec *Attrs = nullptr,
1396 DeclRefExpr *OrigRef = nullptr) {
1397 DeclContext *DC = SemaRef.CurContext;
1398 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1399 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1400 auto *Decl =
1401 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1402 if (Attrs) {
1403 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1404 I != E; ++I)
1405 Decl->addAttr(*I);
1406 }
1407 Decl->setImplicit();
1408 if (OrigRef) {
1409 Decl->addAttr(
1410 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1411 }
1412 return Decl;
1413}
1414
1415static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1416 SourceLocation Loc,
1417 bool RefersToCapture = false) {
1418 D->setReferenced();
1419 D->markUsed(S.Context);
1420 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1421 SourceLocation(), D, RefersToCapture, Loc, Ty,
1422 VK_LValue);
1423}
1424
1425void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1426 BinaryOperatorKind BOK) {
1427 D = getCanonicalDecl(D);
1428 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1428, __PRETTY_FUNCTION__))
;
1429 assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1431, __PRETTY_FUNCTION__))
1430 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1431, __PRETTY_FUNCTION__))
1431 "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1431, __PRETTY_FUNCTION__))
;
1432 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1433 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1434 (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1435 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1436 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1437 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1438 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
1439 "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1439, __PRETTY_FUNCTION__))
;
1440 ReductionData.set(BOK, SR);
1441 Expr *&TaskgroupReductionRef =
1442 getTopOfStack().TaskgroupReductionRef;
1443 if (!TaskgroupReductionRef) {
1444 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1445 SemaRef.Context.VoidPtrTy, ".task_red.");
1446 TaskgroupReductionRef =
1447 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1448 }
1449}
1450
1451void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1452 const Expr *ReductionRef) {
1453 D = getCanonicalDecl(D);
1454 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1454, __PRETTY_FUNCTION__))
;
1455 assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1457, __PRETTY_FUNCTION__))
1456 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1457, __PRETTY_FUNCTION__))
1457 "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1457, __PRETTY_FUNCTION__))
;
1458 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1459 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1460 (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1461 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1462 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1463 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1464 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
1465 "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1465, __PRETTY_FUNCTION__))
;
1466 ReductionData.set(ReductionRef, SR);
1467 Expr *&TaskgroupReductionRef =
1468 getTopOfStack().TaskgroupReductionRef;
1469 if (!TaskgroupReductionRef) {
1470 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1471 SemaRef.Context.VoidPtrTy, ".task_red.");
1472 TaskgroupReductionRef =
1473 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1474 }
1475}
1476
1477const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1478 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1479 Expr *&TaskgroupDescriptor) const {
1480 D = getCanonicalDecl(D);
1481 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1481, __PRETTY_FUNCTION__))
;
1482 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1483 const DSAInfo &Data = I->SharingMap.lookup(D);
1484 if (Data.Attributes != OMPC_reduction ||
1485 Data.Modifier != OMPC_REDUCTION_task)
1486 continue;
1487 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1488 if (!ReductionData.ReductionOp ||
1489 ReductionData.ReductionOp.is<const Expr *>())
1490 return DSAVarData();
1491 SR = ReductionData.ReductionRange;
1492 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1493 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1495, __PRETTY_FUNCTION__))
1494 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1495, __PRETTY_FUNCTION__))
1495 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1495, __PRETTY_FUNCTION__))
;
1496 TaskgroupDescriptor = I->TaskgroupReductionRef;
1497 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1498 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1499 /*AppliedToPointee=*/false);
1500 }
1501 return DSAVarData();
1502}
1503
1504const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1505 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1506 Expr *&TaskgroupDescriptor) const {
1507 D = getCanonicalDecl(D);
1508 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1508, __PRETTY_FUNCTION__))
;
1509 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1510 const DSAInfo &Data = I->SharingMap.lookup(D);
1511 if (Data.Attributes != OMPC_reduction ||
1512 Data.Modifier != OMPC_REDUCTION_task)
1513 continue;
1514 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1515 if (!ReductionData.ReductionOp ||
1516 !ReductionData.ReductionOp.is<const Expr *>())
1517 return DSAVarData();
1518 SR = ReductionData.ReductionRange;
1519 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1520 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1522, __PRETTY_FUNCTION__))
1521 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1522, __PRETTY_FUNCTION__))
1522 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1522, __PRETTY_FUNCTION__))
;
1523 TaskgroupDescriptor = I->TaskgroupReductionRef;
1524 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1525 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1526 /*AppliedToPointee=*/false);
1527 }
1528 return DSAVarData();
1529}
1530
1531bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1532 D = D->getCanonicalDecl();
1533 for (const_iterator E = end(); I != E; ++I) {
1534 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1535 isOpenMPTargetExecutionDirective(I->Directive)) {
1536 if (I->CurScope) {
1537 Scope *TopScope = I->CurScope->getParent();
1538 Scope *CurScope = getCurScope();
1539 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1540 CurScope = CurScope->getParent();
1541 return CurScope != TopScope;
1542 }
1543 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1544 if (I->Context == DC)
1545 return true;
1546 return false;
1547 }
1548 }
1549 return false;
1550}
1551
1552static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1553 bool AcceptIfMutable = true,
1554 bool *IsClassType = nullptr) {
1555 ASTContext &Context = SemaRef.getASTContext();
1556 Type = Type.getNonReferenceType().getCanonicalType();
1557 bool IsConstant = Type.isConstant(Context);
1558 Type = Context.getBaseElementType(Type);
1559 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1560 ? Type->getAsCXXRecordDecl()
1561 : nullptr;
1562 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1563 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1564 RD = CTD->getTemplatedDecl();
1565 if (IsClassType)
1566 *IsClassType = RD;
1567 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1568 RD->hasDefinition() && RD->hasMutableFields());
1569}
1570
1571static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1572 QualType Type, OpenMPClauseKind CKind,
1573 SourceLocation ELoc,
1574 bool AcceptIfMutable = true,
1575 bool ListItemNotVar = false) {
1576 ASTContext &Context = SemaRef.getASTContext();
1577 bool IsClassType;
1578 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1579 unsigned Diag = ListItemNotVar
1580 ? diag::err_omp_const_list_item
1581 : IsClassType ? diag::err_omp_const_not_mutable_variable
1582 : diag::err_omp_const_variable;
1583 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1584 if (!ListItemNotVar && D) {
1585 const VarDecl *VD = dyn_cast<VarDecl>(D);
1586 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1587 VarDecl::DeclarationOnly;
1588 SemaRef.Diag(D->getLocation(),
1589 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1590 << D;
1591 }
1592 return true;
1593 }
1594 return false;
1595}
1596
1597const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1598 bool FromParent) {
1599 D = getCanonicalDecl(D);
1600 DSAVarData DVar;
1601
1602 auto *VD = dyn_cast<VarDecl>(D);
1603 auto TI = Threadprivates.find(D);
1604 if (TI != Threadprivates.end()) {
1605 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1606 DVar.CKind = OMPC_threadprivate;
1607 DVar.Modifier = TI->getSecond().Modifier;
1608 return DVar;
1609 }
1610 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1611 DVar.RefExpr = buildDeclRefExpr(
1612 SemaRef, VD, D->getType().getNonReferenceType(),
1613 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1614 DVar.CKind = OMPC_threadprivate;
1615 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1616 return DVar;
1617 }
1618 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1619 // in a Construct, C/C++, predetermined, p.1]
1620 // Variables appearing in threadprivate directives are threadprivate.
1621 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1622 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1623 SemaRef.getLangOpts().OpenMPUseTLS &&
1624 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1625 (VD && VD->getStorageClass() == SC_Register &&
1626 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1627 DVar.RefExpr = buildDeclRefExpr(
1628 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1629 DVar.CKind = OMPC_threadprivate;
1630 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1631 return DVar;
1632 }
1633 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1634 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1635 !isLoopControlVariable(D).first) {
1636 const_iterator IterTarget =
1637 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1638 return isOpenMPTargetExecutionDirective(Data.Directive);
1639 });
1640 if (IterTarget != end()) {
1641 const_iterator ParentIterTarget = IterTarget + 1;
1642 for (const_iterator Iter = begin();
1643 Iter != ParentIterTarget; ++Iter) {
1644 if (isOpenMPLocal(VD, Iter)) {
1645 DVar.RefExpr =
1646 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1647 D->getLocation());
1648 DVar.CKind = OMPC_threadprivate;
1649 return DVar;
1650 }
1651 }
1652 if (!isClauseParsingMode() || IterTarget != begin()) {
1653 auto DSAIter = IterTarget->SharingMap.find(D);
1654 if (DSAIter != IterTarget->SharingMap.end() &&
1655 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1656 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1657 DVar.CKind = OMPC_threadprivate;
1658 return DVar;
1659 }
1660 const_iterator End = end();
1661 if (!SemaRef.isOpenMPCapturedByRef(
1662 D, std::distance(ParentIterTarget, End),
1663 /*OpenMPCaptureLevel=*/0)) {
1664 DVar.RefExpr =
1665 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1666 IterTarget->ConstructLoc);
1667 DVar.CKind = OMPC_threadprivate;
1668 return DVar;
1669 }
1670 }
1671 }
1672 }
1673
1674 if (isStackEmpty())
1675 // Not in OpenMP execution region and top scope was already checked.
1676 return DVar;
1677
1678 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1679 // in a Construct, C/C++, predetermined, p.4]
1680 // Static data members are shared.
1681 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1682 // in a Construct, C/C++, predetermined, p.7]
1683 // Variables with static storage duration that are declared in a scope
1684 // inside the construct are shared.
1685 if (VD && VD->isStaticDataMember()) {
1686 // Check for explicitly specified attributes.
1687 const_iterator I = begin();
1688 const_iterator EndI = end();
1689 if (FromParent && I != EndI)
1690 ++I;
1691 if (I != EndI) {
1692 auto It = I->SharingMap.find(D);
1693 if (It != I->SharingMap.end()) {
1694 const DSAInfo &Data = It->getSecond();
1695 DVar.RefExpr = Data.RefExpr.getPointer();
1696 DVar.PrivateCopy = Data.PrivateCopy;
1697 DVar.CKind = Data.Attributes;
1698 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1699 DVar.DKind = I->Directive;
1700 DVar.Modifier = Data.Modifier;
1701 DVar.AppliedToPointee = Data.AppliedToPointee;
1702 return DVar;
1703 }
1704 }
1705
1706 DVar.CKind = OMPC_shared;
1707 return DVar;
1708 }
1709
1710 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1711 // The predetermined shared attribute for const-qualified types having no
1712 // mutable members was removed after OpenMP 3.1.
1713 if (SemaRef.LangOpts.OpenMP <= 31) {
1714 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1715 // in a Construct, C/C++, predetermined, p.6]
1716 // Variables with const qualified type having no mutable member are
1717 // shared.
1718 if (isConstNotMutableType(SemaRef, D->getType())) {
1719 // Variables with const-qualified type having no mutable member may be
1720 // listed in a firstprivate clause, even if they are static data members.
1721 DSAVarData DVarTemp = hasInnermostDSA(
1722 D,
1723 [](OpenMPClauseKind C, bool) {
1724 return C == OMPC_firstprivate || C == OMPC_shared;
1725 },
1726 MatchesAlways, FromParent);
1727 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1728 return DVarTemp;
1729
1730 DVar.CKind = OMPC_shared;
1731 return DVar;
1732 }
1733 }
1734
1735 // Explicitly specified attributes and local variables with predetermined
1736 // attributes.
1737 const_iterator I = begin();
1738 const_iterator EndI = end();
1739 if (FromParent && I != EndI)
1740 ++I;
1741 if (I == EndI)
1742 return DVar;
1743 auto It = I->SharingMap.find(D);
1744 if (It != I->SharingMap.end()) {
1745 const DSAInfo &Data = It->getSecond();
1746 DVar.RefExpr = Data.RefExpr.getPointer();
1747 DVar.PrivateCopy = Data.PrivateCopy;
1748 DVar.CKind = Data.Attributes;
1749 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1750 DVar.DKind = I->Directive;
1751 DVar.Modifier = Data.Modifier;
1752 DVar.AppliedToPointee = Data.AppliedToPointee;
1753 }
1754
1755 return DVar;
1756}
1757
1758const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1759 bool FromParent) const {
1760 if (isStackEmpty()) {
1761 const_iterator I;
1762 return getDSA(I, D);
1763 }
1764 D = getCanonicalDecl(D);
1765 const_iterator StartI = begin();
1766 const_iterator EndI = end();
1767 if (FromParent && StartI != EndI)
1768 ++StartI;
1769 return getDSA(StartI, D);
1770}
1771
1772const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1773 unsigned Level) const {
1774 if (getStackSize() <= Level)
1775 return DSAVarData();
1776 D = getCanonicalDecl(D);
1777 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1778 return getDSA(StartI, D);
1779}
1780
1781const DSAStackTy::DSAVarData
1782DSAStackTy::hasDSA(ValueDecl *D,
1783 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1784 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1785 bool FromParent) const {
1786 if (isStackEmpty())
1787 return {};
1788 D = getCanonicalDecl(D);
1789 const_iterator I = begin();
1790 const_iterator EndI = end();
1791 if (FromParent && I != EndI)
1792 ++I;
1793 for (; I != EndI; ++I) {
1794 if (!DPred(I->Directive) &&
1795 !isImplicitOrExplicitTaskingRegion(I->Directive))
1796 continue;
1797 const_iterator NewI = I;
1798 DSAVarData DVar = getDSA(NewI, D);
1799 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1800 return DVar;
1801 }
1802 return {};
1803}
1804
1805const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1806 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1807 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1808 bool FromParent) const {
1809 if (isStackEmpty())
1810 return {};
1811 D = getCanonicalDecl(D);
1812 const_iterator StartI = begin();
1813 const_iterator EndI = end();
1814 if (FromParent && StartI != EndI)
1815 ++StartI;
1816 if (StartI == EndI || !DPred(StartI->Directive))
1817 return {};
1818 const_iterator NewI = StartI;
1819 DSAVarData DVar = getDSA(NewI, D);
1820 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1821 ? DVar
1822 : DSAVarData();
1823}
1824
1825bool DSAStackTy::hasExplicitDSA(
1826 const ValueDecl *D,
1827 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1828 unsigned Level, bool NotLastprivate) const {
1829 if (getStackSize() <= Level)
1830 return false;
1831 D = getCanonicalDecl(D);
1832 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1833 auto I = StackElem.SharingMap.find(D);
1834 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1835 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1836 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1837 return true;
1838 // Check predetermined rules for the loop control variables.
1839 auto LI = StackElem.LCVMap.find(D);
1840 if (LI != StackElem.LCVMap.end())
1841 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1842 return false;
1843}
1844
1845bool DSAStackTy::hasExplicitDirective(
1846 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1847 unsigned Level) const {
1848 if (getStackSize() <= Level)
1849 return false;
1850 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1851 return DPred(StackElem.Directive);
1852}
1853
1854bool DSAStackTy::hasDirective(
1855 const llvm::function_ref<bool(OpenMPDirectiveKind,
1856 const DeclarationNameInfo &, SourceLocation)>
1857 DPred,
1858 bool FromParent) const {
1859 // We look only in the enclosing region.
1860 size_t Skip = FromParent ? 2 : 1;
1861 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1862 I != E; ++I) {
1863 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1864 return true;
1865 }
1866 return false;
1867}
1868
1869void Sema::InitDataSharingAttributesStack() {
1870 VarDataSharingAttributesStack = new DSAStackTy(*this);
1871}
1872
1873#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1874
1875void Sema::pushOpenMPFunctionRegion() {
1876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1877}
1878
1879void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1880 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1881}
1882
1883static bool isOpenMPDeviceDelayedContext(Sema &S) {
1884 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1885, __PRETTY_FUNCTION__))
1885 "Expected OpenMP device compilation.")((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1885, __PRETTY_FUNCTION__))
;
1886 return !S.isInOpenMPTargetExecutionDirective() &&
1887 !S.isInOpenMPDeclareTargetContext();
1888}
1889
1890namespace {
1891/// Status of the function emission on the host/device.
1892enum class FunctionEmissionStatus {
1893 Emitted,
1894 Discarded,
1895 Unknown,
1896};
1897} // anonymous namespace
1898
1899Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900 unsigned DiagID) {
1901 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1902, __PRETTY_FUNCTION__))
1902 "Expected OpenMP device compilation.")((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1902, __PRETTY_FUNCTION__))
;
1903
1904 FunctionDecl *FD = getCurFunctionDecl();
1905 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1906 if (FD) {
1907 FunctionEmissionStatus FES = getEmissionStatus(FD);
1908 switch (FES) {
1909 case FunctionEmissionStatus::Emitted:
1910 Kind = DeviceDiagBuilder::K_Immediate;
1911 break;
1912 case FunctionEmissionStatus::Unknown:
1913 Kind = isOpenMPDeviceDelayedContext(*this)
1914 ? DeviceDiagBuilder::K_Deferred
1915 : DeviceDiagBuilder::K_Immediate;
1916 break;
1917 case FunctionEmissionStatus::TemplateDiscarded:
1918 case FunctionEmissionStatus::OMPDiscarded:
1919 Kind = DeviceDiagBuilder::K_Nop;
1920 break;
1921 case FunctionEmissionStatus::CUDADiscarded:
1922 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1922)
;
1923 break;
1924 }
1925 }
1926
1927 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1928}
1929
1930Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1931 unsigned DiagID) {
1932 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
"Expected OpenMP host compilation.") ? static_cast<void>
(0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1933, __PRETTY_FUNCTION__))
1933 "Expected OpenMP host compilation.")((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
"Expected OpenMP host compilation.") ? static_cast<void>
(0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1933, __PRETTY_FUNCTION__))
;
1934 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1935 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1936 switch (FES) {
1937 case FunctionEmissionStatus::Emitted:
1938 Kind = DeviceDiagBuilder::K_Immediate;
1939 break;
1940 case FunctionEmissionStatus::Unknown:
1941 Kind = DeviceDiagBuilder::K_Deferred;
1942 break;
1943 case FunctionEmissionStatus::TemplateDiscarded:
1944 case FunctionEmissionStatus::OMPDiscarded:
1945 case FunctionEmissionStatus::CUDADiscarded:
1946 Kind = DeviceDiagBuilder::K_Nop;
1947 break;
1948 }
1949
1950 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1951}
1952
1953static OpenMPDefaultmapClauseKind
1954getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1955 if (LO.OpenMP <= 45) {
1956 if (VD->getType().getNonReferenceType()->isScalarType())
1957 return OMPC_DEFAULTMAP_scalar;
1958 return OMPC_DEFAULTMAP_aggregate;
1959 }
1960 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1961 return OMPC_DEFAULTMAP_pointer;
1962 if (VD->getType().getNonReferenceType()->isScalarType())
1963 return OMPC_DEFAULTMAP_scalar;
1964 return OMPC_DEFAULTMAP_aggregate;
1965}
1966
1967bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1968 unsigned OpenMPCaptureLevel) const {
1969 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 1969, __PRETTY_FUNCTION__))
;
1970
1971 ASTContext &Ctx = getASTContext();
1972 bool IsByRef = true;
1973
1974 // Find the directive that is associated with the provided scope.
1975 D = cast<ValueDecl>(D->getCanonicalDecl());
1976 QualType Ty = D->getType();
1977
1978 bool IsVariableUsedInMapClause = false;
1979 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1980 // This table summarizes how a given variable should be passed to the device
1981 // given its type and the clauses where it appears. This table is based on
1982 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1983 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1984 //
1985 // =========================================================================
1986 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1987 // | |(tofrom:scalar)| | pvt | | | |
1988 // =========================================================================
1989 // | scl | | | | - | | bycopy|
1990 // | scl | | - | x | - | - | bycopy|
1991 // | scl | | x | - | - | - | null |
1992 // | scl | x | | | - | | byref |
1993 // | scl | x | - | x | - | - | bycopy|
1994 // | scl | x | x | - | - | - | null |
1995 // | scl | | - | - | - | x | byref |
1996 // | scl | x | - | - | - | x | byref |
1997 //
1998 // | agg | n.a. | | | - | | byref |
1999 // | agg | n.a. | - | x | - | - | byref |
2000 // | agg | n.a. | x | - | - | - | null |
2001 // | agg | n.a. | - | - | - | x | byref |
2002 // | agg | n.a. | - | - | - | x[] | byref |
2003 //
2004 // | ptr | n.a. | | | - | | bycopy|
2005 // | ptr | n.a. | - | x | - | - | bycopy|
2006 // | ptr | n.a. | x | - | - | - | null |
2007 // | ptr | n.a. | - | - | - | x | byref |
2008 // | ptr | n.a. | - | - | - | x[] | bycopy|
2009 // | ptr | n.a. | - | - | x | | bycopy|
2010 // | ptr | n.a. | - | - | x | x | bycopy|
2011 // | ptr | n.a. | - | - | x | x[] | bycopy|
2012 // =========================================================================
2013 // Legend:
2014 // scl - scalar
2015 // ptr - pointer
2016 // agg - aggregate
2017 // x - applies
2018 // - - invalid in this combination
2019 // [] - mapped with an array section
2020 // byref - should be mapped by reference
2021 // byval - should be mapped by value
2022 // null - initialize a local variable to null on the device
2023 //
2024 // Observations:
2025 // - All scalar declarations that show up in a map clause have to be passed
2026 // by reference, because they may have been mapped in the enclosing data
2027 // environment.
2028 // - If the scalar value does not fit the size of uintptr, it has to be
2029 // passed by reference, regardless the result in the table above.
2030 // - For pointers mapped by value that have either an implicit map or an
2031 // array section, the runtime library may pass the NULL value to the
2032 // device instead of the value passed to it by the compiler.
2033
2034 if (Ty->isReferenceType())
2035 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2036
2037 // Locate map clauses and see if the variable being captured is referred to
2038 // in any of those clauses. Here we only care about variables, not fields,
2039 // because fields are part of aggregates.
2040 bool IsVariableAssociatedWithSection = false;
2041
2042 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2043 D, Level,
2044 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2045 OMPClauseMappableExprCommon::MappableExprComponentListRef
2046 MapExprComponents,
2047 OpenMPClauseKind WhereFoundClauseKind) {
2048 // Only the map clause information influences how a variable is
2049 // captured. E.g. is_device_ptr does not require changing the default
2050 // behavior.
2051 if (WhereFoundClauseKind != OMPC_map)
2052 return false;
2053
2054 auto EI = MapExprComponents.rbegin();
2055 auto EE = MapExprComponents.rend();
2056
2057 assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast
<void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2057, __PRETTY_FUNCTION__))
;
2058
2059 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2060 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2061
2062 ++EI;
2063 if (EI == EE)
2064 return false;
2065
2066 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2067 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2068 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2069 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2070 IsVariableAssociatedWithSection = true;
2071 // There is nothing more we need to know about this variable.
2072 return true;
2073 }
2074
2075 // Keep looking for more map info.
2076 return false;
2077 });
2078
2079 if (IsVariableUsedInMapClause) {
2080 // If variable is identified in a map clause it is always captured by
2081 // reference except if it is a pointer that is dereferenced somehow.
2082 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2083 } else {
2084 // By default, all the data that has a scalar type is mapped by copy
2085 // (except for reduction variables).
2086 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2087 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2088 !Ty->isAnyPointerType()) ||
2089 !Ty->isScalarType() ||
2090 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2091 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2092 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2093 D,
2094 [](OpenMPClauseKind K, bool AppliedToPointee) {
2095 return K == OMPC_reduction && !AppliedToPointee;
2096 },
2097 Level);
2098 }
2099 }
2100
2101 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2102 IsByRef =
2103 ((IsVariableUsedInMapClause &&
2104 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2105 OMPD_target) ||
2106 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2107 D,
2108 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2109 return K == OMPC_firstprivate ||
2110 (K == OMPC_reduction && AppliedToPointee);
2111 },
2112 Level, /*NotLastprivate=*/true) ||
2113 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2114 // If the variable is artificial and must be captured by value - try to
2115 // capture by value.
2116 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2117 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2118 // If the variable is implicitly firstprivate and scalar - capture by
2119 // copy
2120 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2121 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2122 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2123 Level) &&
2124 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2125 }
2126
2127 // When passing data by copy, we need to make sure it fits the uintptr size
2128 // and alignment, because the runtime library only deals with uintptr types.
2129 // If it does not fit the uintptr size, we need to pass the data by reference
2130 // instead.
2131 if (!IsByRef &&
2132 (Ctx.getTypeSizeInChars(Ty) >
2133 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2134 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2135 IsByRef = true;
2136 }
2137
2138 return IsByRef;
2139}
2140
2141unsigned Sema::getOpenMPNestingLevel() const {
2142 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2142, __PRETTY_FUNCTION__))
;
2143 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2144}
2145
2146bool Sema::isInOpenMPTargetExecutionDirective() const {
2147 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2148 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2149 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2150 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2151 SourceLocation) -> bool {
2152 return isOpenMPTargetExecutionDirective(K);
2153 },
2154 false);
2155}
2156
2157VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2158 unsigned StopAt) {
2159 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2159, __PRETTY_FUNCTION__))
;
2160 D = getCanonicalDecl(D);
2161
2162 auto *VD = dyn_cast<VarDecl>(D);
2163 // Do not capture constexpr variables.
2164 if (VD && VD->isConstexpr())
2165 return nullptr;
2166
2167 // If we want to determine whether the variable should be captured from the
2168 // perspective of the current capturing scope, and we've already left all the
2169 // capturing scopes of the top directive on the stack, check from the
2170 // perspective of its parent directive (if any) instead.
2171 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2172 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2173
2174 // If we are attempting to capture a global variable in a directive with
2175 // 'target' we return true so that this global is also mapped to the device.
2176 //
2177 if (VD && !VD->hasLocalStorage() &&
2178 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2179 if (isInOpenMPDeclareTargetContext()) {
2180 // Try to mark variable as declare target if it is used in capturing
2181 // regions.
2182 if (LangOpts.OpenMP <= 45 &&
2183 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2184 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2185 return nullptr;
2186 }
2187 if (isInOpenMPTargetExecutionDirective()) {
2188 // If the declaration is enclosed in a 'declare target' directive,
2189 // then it should not be captured.
2190 //
2191 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192 return nullptr;
2193 CapturedRegionScopeInfo *CSI = nullptr;
2194 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2195 llvm::reverse(FunctionScopes),
2196 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2197 if (!isa<CapturingScopeInfo>(FSI))
2198 return nullptr;
2199 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2200 if (RSI->CapRegionKind == CR_OpenMP) {
2201 CSI = RSI;
2202 break;
2203 }
2204 }
2205 assert(CSI && "Failed to find CapturedRegionScopeInfo")((CSI && "Failed to find CapturedRegionScopeInfo") ? static_cast
<void> (0) : __assert_fail ("CSI && \"Failed to find CapturedRegionScopeInfo\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2205, __PRETTY_FUNCTION__))
;
2206 SmallVector<OpenMPDirectiveKind, 4> Regions;
2207 getOpenMPCaptureRegions(Regions,
2208 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2209 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2210 return VD;
2211 }
2212 }
2213
2214 if (CheckScopeInfo) {
2215 bool OpenMPFound = false;
2216 for (unsigned I = StopAt + 1; I > 0; --I) {
2217 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2218 if(!isa<CapturingScopeInfo>(FSI))
2219 return nullptr;
2220 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2221 if (RSI->CapRegionKind == CR_OpenMP) {
2222 OpenMPFound = true;
2223 break;
2224 }
2225 }
2226 if (!OpenMPFound)
2227 return nullptr;
2228 }
2229
2230 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2231 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2233 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2234 if (Info.first ||
2235 (VD && VD->hasLocalStorage() &&
2236 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2237 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2238 return VD ? VD : Info.second;
2239 DSAStackTy::DSAVarData DVarTop =
2240 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2241 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2242 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2243 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2244 // Threadprivate variables must not be captured.
2245 if (isOpenMPThreadPrivate(DVarTop.CKind))
2246 return nullptr;
2247 // The variable is not private or it is the variable in the directive with
2248 // default(none) clause and not used in any clause.
2249 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2250 D,
2251 [](OpenMPClauseKind C, bool AppliedToPointee) {
2252 return isOpenMPPrivate(C) && !AppliedToPointee;
2253 },
2254 [](OpenMPDirectiveKind) { return true; },
2255 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2256 // Global shared must not be captured.
2257 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2258 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2259 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2260 DVarTop.CKind == OMPC_shared))
2261 return nullptr;
2262 if (DVarPrivate.CKind != OMPC_unknown ||
2263 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2264 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2265 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2266 }
2267 return nullptr;
2268}
2269
2270void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2271 unsigned Level) const {
2272 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2273}
2274
2275void Sema::startOpenMPLoop() {
2276 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2276, __PRETTY_FUNCTION__))
;
2277 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2278 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2279}
2280
2281void Sema::startOpenMPCXXRangeFor() {
2282 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2282, __PRETTY_FUNCTION__))
;
2283 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2284 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2285 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2286 }
2287}
2288
2289OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2290 unsigned CapLevel) const {
2291 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2291, __PRETTY_FUNCTION__))
;
2292 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2293 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2294 Level)) {
2295 bool IsTriviallyCopyable =
2296 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2297 !D->getType()
2298 .getNonReferenceType()
2299 .getCanonicalType()
2300 ->getAsCXXRecordDecl();
2301 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2302 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2303 getOpenMPCaptureRegions(CaptureRegions, DKind);
2304 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2305 (IsTriviallyCopyable ||
2306 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2307 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2308 D,
2309 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2310 Level, /*NotLastprivate=*/true))
2311 return OMPC_firstprivate;
2312 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2313 if (DVar.CKind != OMPC_shared &&
2314 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2315 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2316 return OMPC_firstprivate;
2317 }
2318 }
2319 }
2320 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2321 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2322 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2323 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2324 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2325 return OMPC_private;
2326 }
2327 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2328 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2329 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2330 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2331 Level) &&
2332 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2333 return OMPC_private;
2334 }
2335 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2336 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2337 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2338 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2339 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2340 Level))
2341 return OMPC_private;
2342 }
2343 // User-defined allocators are private since they must be defined in the
2344 // context of target region.
2345 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2346 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2347 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2348 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2349 return OMPC_private;
2350 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2351 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2352 Level) ||
2353 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2354 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2355 // Consider taskgroup reduction descriptor variable a private
2356 // to avoid possible capture in the region.
2357 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2358 [](OpenMPDirectiveKind K) {
2359 return K == OMPD_taskgroup ||
2360 ((isOpenMPParallelDirective(K) ||
2361 isOpenMPWorksharingDirective(K)) &&
2362 !isOpenMPSimdDirective(K));
2363 },
2364 Level) &&
2365 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2366 ? OMPC_private
2367 : OMPC_unknown;
2368}
2369
2370void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2371 unsigned Level) {
2372 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2372, __PRETTY_FUNCTION__))
;
2373 D = getCanonicalDecl(D);
2374 OpenMPClauseKind OMPC = OMPC_unknown;
2375 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2376 const unsigned NewLevel = I - 1;
2377 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2378 D,
2379 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2380 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2381 OMPC = K;
2382 return true;
2383 }
2384 return false;
2385 },
2386 NewLevel))
2387 break;
2388 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2389 D, NewLevel,
2390 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2391 OpenMPClauseKind) { return true; })) {
2392 OMPC = OMPC_map;
2393 break;
2394 }
2395 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2396 NewLevel)) {
2397 OMPC = OMPC_map;
2398 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2399 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2400 OMPC = OMPC_firstprivate;
2401 break;
2402 }
2403 }
2404 if (OMPC != OMPC_unknown)
2405 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2406}
2407
2408bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2409 unsigned CaptureLevel) const {
2410 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2410, __PRETTY_FUNCTION__))
;
2411 // Return true if the current level is no longer enclosed in a target region.
2412
2413 SmallVector<OpenMPDirectiveKind, 4> Regions;
2414 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2415 const auto *VD = dyn_cast<VarDecl>(D);
2416 return VD && !VD->hasLocalStorage() &&
2417 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2418 Level) &&
2419 Regions[CaptureLevel] != OMPD_task;
2420}
2421
2422bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2423 unsigned CaptureLevel) const {
2424 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2424, __PRETTY_FUNCTION__))
;
2425 // Return true if the current level is no longer enclosed in a target region.
2426
2427 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2428 if (!VD->hasLocalStorage()) {
2429 if (isInOpenMPTargetExecutionDirective())
2430 return true;
2431 DSAStackTy::DSAVarData TopDVar =
2432 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2433 unsigned NumLevels =
2434 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2435 if (Level == 0)
2436 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2437 do {
2438 --Level;
2439 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2440 if (DVar.CKind != OMPC_shared)
2441 return true;
2442 } while (Level > 0);
2443 }
2444 }
2445 return true;
2446}
2447
2448void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2449
2450void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2451 OMPTraitInfo &TI) {
2452 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2453}
2454
2455void Sema::ActOnOpenMPEndDeclareVariant() {
2456 assert(isInOpenMPDeclareVariantScope() &&((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2457, __PRETTY_FUNCTION__))
2457 "Not in OpenMP declare variant scope!")((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2457, __PRETTY_FUNCTION__))
;
2458
2459 OMPDeclareVariantScopes.pop_back();
2460}
2461
2462void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2463 const FunctionDecl *Callee,
2464 SourceLocation Loc) {
2465 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")((LangOpts.OpenMP && "Expected OpenMP compilation mode."
) ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2465, __PRETTY_FUNCTION__))
;
2466 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2467 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2468 // Ignore host functions during device analyzis.
2469 if (LangOpts.OpenMPIsDevice && DevTy &&
2470 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2471 return;
2472 // Ignore nohost functions during host analyzis.
2473 if (!LangOpts.OpenMPIsDevice && DevTy &&
2474 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2475 return;
2476 const FunctionDecl *FD = Callee->getMostRecentDecl();
2477 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2478 if (LangOpts.OpenMPIsDevice && DevTy &&
2479 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2480 // Diagnose host function called during device codegen.
2481 StringRef HostDevTy =
2482 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2483 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2484 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2485 diag::note_omp_marked_device_type_here)
2486 << HostDevTy;
2487 return;
2488 }
2489 if (!LangOpts.OpenMPIsDevice && DevTy &&
2490 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2491 // Diagnose nohost function called during host codegen.
2492 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2493 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2494 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2495 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2496 diag::note_omp_marked_device_type_here)
2497 << NoHostDevTy;
2498 }
2499}
2500
2501void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2502 const DeclarationNameInfo &DirName,
2503 Scope *CurScope, SourceLocation Loc) {
2504 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2505 PushExpressionEvaluationContext(
2506 ExpressionEvaluationContext::PotentiallyEvaluated);
2507}
2508
2509void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2510 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2511}
2512
2513void Sema::EndOpenMPClause() {
2514 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2515}
2516
2517static std::pair<ValueDecl *, bool>
2518getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2519 SourceRange &ERange, bool AllowArraySection = false);
2520
2521/// Check consistency of the reduction clauses.
2522static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2523 ArrayRef<OMPClause *> Clauses) {
2524 bool InscanFound = false;
2525 SourceLocation InscanLoc;
2526 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2527 // A reduction clause without the inscan reduction-modifier may not appear on
2528 // a construct on which a reduction clause with the inscan reduction-modifier
2529 // appears.
2530 for (OMPClause *C : Clauses) {
2531 if (C->getClauseKind() != OMPC_reduction)
2532 continue;
2533 auto *RC = cast<OMPReductionClause>(C);
2534 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2535 InscanFound = true;
2536 InscanLoc = RC->getModifierLoc();
2537 continue;
2538 }
2539 if (RC->getModifier() == OMPC_REDUCTION_task) {
2540 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2541 // A reduction clause with the task reduction-modifier may only appear on
2542 // a parallel construct, a worksharing construct or a combined or
2543 // composite construct for which any of the aforementioned constructs is a
2544 // constituent construct and simd or loop are not constituent constructs.
2545 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2546 if (!(isOpenMPParallelDirective(CurDir) ||
2547 isOpenMPWorksharingDirective(CurDir)) ||
2548 isOpenMPSimdDirective(CurDir))
2549 S.Diag(RC->getModifierLoc(),
2550 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2551 continue;
2552 }
2553 }
2554 if (InscanFound) {
2555 for (OMPClause *C : Clauses) {
2556 if (C->getClauseKind() != OMPC_reduction)
2557 continue;
2558 auto *RC = cast<OMPReductionClause>(C);
2559 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2560 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2561 ? RC->getBeginLoc()
2562 : RC->getModifierLoc(),
2563 diag::err_omp_inscan_reduction_expected);
2564 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2565 continue;
2566 }
2567 for (Expr *Ref : RC->varlists()) {
2568 assert(Ref && "NULL expr in OpenMP nontemporal clause.")((Ref && "NULL expr in OpenMP nontemporal clause.") ?
static_cast<void> (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2568, __PRETTY_FUNCTION__))
;
2569 SourceLocation ELoc;
2570 SourceRange ERange;
2571 Expr *SimpleRefExpr = Ref;
2572 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2573 /*AllowArraySection=*/true);
2574 ValueDecl *D = Res.first;
2575 if (!D)
2576 continue;
2577 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2578 S.Diag(Ref->getExprLoc(),
2579 diag::err_omp_reduction_not_inclusive_exclusive)
2580 << Ref->getSourceRange();
2581 }
2582 }
2583 }
2584 }
2585}
2586
2587static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2588 ArrayRef<OMPClause *> Clauses);
2589static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2590 bool WithInit);
2591
2592static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2593 const ValueDecl *D,
2594 const DSAStackTy::DSAVarData &DVar,
2595 bool IsLoopIterVar = false);
2596
2597void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2598 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2599 // A variable of class type (or array thereof) that appears in a lastprivate
2600 // clause requires an accessible, unambiguous default constructor for the
2601 // class type, unless the list item is also specified in a firstprivate
2602 // clause.
2603 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2604 for (OMPClause *C : D->clauses()) {
2605 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2606 SmallVector<Expr *, 8> PrivateCopies;
2607 for (Expr *DE : Clause->varlists()) {
2608 if (DE->isValueDependent() || DE->isTypeDependent()) {
2609 PrivateCopies.push_back(nullptr);
2610 continue;
2611 }
2612 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2613 auto *VD = cast<VarDecl>(DRE->getDecl());
2614 QualType Type = VD->getType().getNonReferenceType();
2615 const DSAStackTy::DSAVarData DVar =
2616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2617 if (DVar.CKind == OMPC_lastprivate) {
2618 // Generate helper private variable and initialize it with the
2619 // default value. The address of the original variable is replaced
2620 // by the address of the new private variable in CodeGen. This new
2621 // variable is not added to IdResolver, so the code in the OpenMP
2622 // region uses original variable for proper diagnostics.
2623 VarDecl *VDPrivate = buildVarDecl(
2624 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2625 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2626 ActOnUninitializedDecl(VDPrivate);
2627 if (VDPrivate->isInvalidDecl()) {
2628 PrivateCopies.push_back(nullptr);
2629 continue;
2630 }
2631 PrivateCopies.push_back(buildDeclRefExpr(
2632 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2633 } else {
2634 // The variable is also a firstprivate, so initialization sequence
2635 // for private copy is generated already.
2636 PrivateCopies.push_back(nullptr);
2637 }
2638 }
2639 Clause->setPrivateCopies(PrivateCopies);
2640 continue;
2641 }
2642 // Finalize nontemporal clause by handling private copies, if any.
2643 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2644 SmallVector<Expr *, 8> PrivateRefs;
2645 for (Expr *RefExpr : Clause->varlists()) {
2646 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 2646, __PRETTY_FUNCTION__))
;
2647 SourceLocation ELoc;
2648 SourceRange ERange;
2649 Expr *SimpleRefExpr = RefExpr;
2650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2651 if (Res.second)
2652 // It will be analyzed later.
2653 PrivateRefs.push_back(RefExpr);
2654 ValueDecl *D = Res.first;
2655 if (!D)
2656 continue;
2657
2658 const DSAStackTy::DSAVarData DVar =
2659 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2660 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2661 : SimpleRefExpr);
2662 }
2663 Clause->setPrivateRefs(PrivateRefs);
2664 continue;
2665 }
2666 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2667 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2668 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2669 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2670 if (!DRE)
2671 continue;
2672 ValueDecl *VD = DRE->getDecl();
2673 if (!VD || !isa<VarDecl>(VD))
2674 continue;
2675 DSAStackTy::DSAVarData DVar =
2676 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2677 // OpenMP [2.12.5, target Construct]
2678 // Memory allocators that appear in a uses_allocators clause cannot
2679 // appear in other data-sharing attribute clauses or data-mapping
2680 // attribute clauses in the same construct.
2681 Expr *MapExpr = nullptr;
2682 if (DVar.RefExpr ||
2683 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2684 VD, /*CurrentRegionOnly=*/true,
2685 [VD, &MapExpr](
2686 OMPClauseMappableExprCommon::MappableExprComponentListRef
2687 MapExprComponents,
2688 OpenMPClauseKind C) {
2689 auto MI = MapExprComponents.rbegin();
2690 auto ME = MapExprComponents.rend();
2691 if (MI != ME &&
2692 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2693 VD->getCanonicalDecl()) {
2694 MapExpr = MI->getAssociatedExpression();
2695 return true;
2696 }
2697 return false;
2698 })) {
2699 Diag(D.Allocator->getExprLoc(),
2700 diag::err_omp_allocator_used_in_clauses)
2701 << D.Allocator->getSourceRange();
2702 if (DVar.RefExpr)
2703 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2704 else
2705 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2706 << MapExpr->getSourceRange();
2707 }
2708 }
2709 continue;
2710 }
2711 }
2712 // Check allocate clauses.
2713 if (!CurContext->isDependentContext())
2714 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2715 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2716 }
2717
2718 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2719 DiscardCleanupsInEvaluationContext();
2720 PopExpressionEvaluationContext();
2721}
2722
2723static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2724 Expr *NumIterations, Sema &SemaRef,
2725 Scope *S, DSAStackTy *Stack);
2726
2727namespace {
2728
2729class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2730private:
2731 Sema &SemaRef;
2732
2733public:
2734 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2735 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2736 NamedDecl *ND = Candidate.getCorrectionDecl();
2737 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2738 return VD->hasGlobalStorage() &&
2739 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2740 SemaRef.getCurScope());
2741 }
2742 return false;
2743 }
2744
2745 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2746 return std::make_unique<VarDeclFilterCCC>(*this);
2747 }
2748
2749};
2750
2751class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2752private:
2753 Sema &SemaRef;
2754
2755public:
2756 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2757 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2758 NamedDecl *ND = Candidate.getCorrectionDecl();
2759 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2760 isa<FunctionDecl>(ND))) {
2761 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2762 SemaRef.getCurScope());
2763 }
2764 return false;
2765 }
2766
2767 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2768 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2769 }
2770};
2771
2772} // namespace
2773
2774ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2775 CXXScopeSpec &ScopeSpec,
2776 const DeclarationNameInfo &Id,
2777 OpenMPDirectiveKind Kind) {
2778 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2779 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2780
2781 if (Lookup.isAmbiguous())
2782 return ExprError();
2783
2784 VarDecl *VD;
2785 if (!Lookup.isSingleResult()) {
2786 VarDeclFilterCCC CCC(*this);
2787 if (TypoCorrection Corrected =
2788 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2789 CTK_ErrorRecovery)) {
2790 diagnoseTypo(Corrected,
2791 PDiag(Lookup.empty()
2792 ? diag::err_undeclared_var_use_suggest
2793 : diag::err_omp_expected_var_arg_suggest)
2794 << Id.getName());
2795 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2796 } else {
2797 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2798 : diag::err_omp_expected_var_arg)
2799 << Id.getName();
2800 return ExprError();
2801 }
2802 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2803 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2804 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2805 return ExprError();
2806 }
2807 Lookup.suppressDiagnostics();
2808
2809 // OpenMP [2.9.2, Syntax, C/C++]
2810 // Variables must be file-scope, namespace-scope, or static block-scope.
2811 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2812 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2813 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2814 bool IsDecl =
2815 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2816 Diag(VD->getLocation(),
2817 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2818 << VD;
2819 return ExprError();
2820 }
2821
2822 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2823 NamedDecl *ND = CanonicalVD;
2824 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2825 // A threadprivate directive for file-scope variables must appear outside
2826 // any definition or declaration.
2827 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2828 !getCurLexicalContext()->isTranslationUnit()) {
2829 Diag(Id.getLoc(), diag::err_omp_var_scope)
2830 << getOpenMPDirectiveName(Kind) << VD;
2831 bool IsDecl =
2832 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2833 Diag(VD->getLocation(),
2834 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2835 << VD;
2836 return ExprError();
2837 }
2838 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2839 // A threadprivate directive for static class member variables must appear
2840 // in the class definition, in the same scope in which the member
2841 // variables are declared.
2842 if (CanonicalVD->isStaticDataMember() &&
2843 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2844 Diag(Id.getLoc(), diag::err_omp_var_scope)
2845 << getOpenMPDirectiveName(Kind) << VD;
2846 bool IsDecl =
2847 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2848 Diag(VD->getLocation(),
2849 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2850 << VD;
2851 return ExprError();
2852 }
2853 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2854 // A threadprivate directive for namespace-scope variables must appear
2855 // outside any definition or declaration other than the namespace
2856 // definition itself.
2857 if (CanonicalVD->getDeclContext()->isNamespace() &&
2858 (!getCurLexicalContext()->isFileContext() ||
2859 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2860 Diag(Id.getLoc(), diag::err_omp_var_scope)
2861 << getOpenMPDirectiveName(Kind) << VD;
2862 bool IsDecl =
2863 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2864 Diag(VD->getLocation(),
2865 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2866 << VD;
2867 return ExprError();
2868 }
2869 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2870 // A threadprivate directive for static block-scope variables must appear
2871 // in the scope of the variable and not in a nested scope.
2872 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2873 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2874 Diag(Id.getLoc(), diag::err_omp_var_scope)
2875 << getOpenMPDirectiveName(Kind) << VD;
2876 bool IsDecl =
2877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2878 Diag(VD->getLocation(),
2879 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2880 << VD;
2881 return ExprError();
2882 }
2883
2884 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2885 // A threadprivate directive must lexically precede all references to any
2886 // of the variables in its list.
2887 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2888 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2889 Diag(Id.getLoc(), diag::err_omp_var_used)
2890 << getOpenMPDirectiveName(Kind) << VD;
2891 return ExprError();
2892 }
2893
2894 QualType ExprType = VD->getType().getNonReferenceType();
2895 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2896 SourceLocation(), VD,
2897 /*RefersToEnclosingVariableOrCapture=*/false,
2898 Id.getLoc(), ExprType, VK_LValue);
2899}
2900
2901Sema::DeclGroupPtrTy
2902Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2903 ArrayRef<Expr *> VarList) {
2904 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2905 CurContext->addDecl(D);
2906 return DeclGroupPtrTy::make(DeclGroupRef(D));
2907 }
2908 return nullptr;
2909}
2910
2911namespace {
2912class LocalVarRefChecker final
2913 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2914 Sema &SemaRef;
2915
2916public:
2917 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2918 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2919 if (VD->hasLocalStorage()) {
2920 SemaRef.Diag(E->getBeginLoc(),
2921 diag::err_omp_local_var_in_threadprivate_init)
2922 << E->getSourceRange();
2923 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2924 << VD << VD->getSourceRange();
2925 return true;
2926 }
2927 }
2928 return false;
2929 }
2930 bool VisitStmt(const Stmt *S) {
2931 for (const Stmt *Child : S->children()) {
2932 if (Child && Visit(Child))
2933 return true;
2934 }
2935 return false;
2936 }
2937 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2938};
2939} // namespace
2940
2941OMPThreadPrivateDecl *
2942Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2943 SmallVector<Expr *, 8> Vars;
2944 for (Expr *RefExpr : VarList) {
2945 auto *DE = cast<DeclRefExpr>(RefExpr);
2946 auto *VD = cast<VarDecl>(DE->getDecl());
2947 SourceLocation ILoc = DE->getExprLoc();
2948
2949 // Mark variable as used.
2950 VD->setReferenced();
2951 VD->markUsed(Context);
2952
2953 QualType QType = VD->getType();
2954 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2955 // It will be analyzed later.
2956 Vars.push_back(DE);
2957 continue;
2958 }
2959
2960 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2961 // A threadprivate variable must not have an incomplete type.
2962 if (RequireCompleteType(ILoc, VD->getType(),
2963 diag::err_omp_threadprivate_incomplete_type)) {
2964 continue;
2965 }
2966
2967 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2968 // A threadprivate variable must not have a reference type.
2969 if (VD->getType()->isReferenceType()) {
2970 Diag(ILoc, diag::err_omp_ref_type_arg)
2971 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2972 bool IsDecl =
2973 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2974 Diag(VD->getLocation(),
2975 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2976 << VD;
2977 continue;
2978 }
2979
2980 // Check if this is a TLS variable. If TLS is not being supported, produce
2981 // the corresponding diagnostic.
2982 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2983 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2984 getLangOpts().OpenMPUseTLS &&
2985 getASTContext().getTargetInfo().isTLSSupported())) ||
2986 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2987 !VD->isLocalVarDecl())) {
2988 Diag(ILoc, diag::err_omp_var_thread_local)
2989 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2990 bool IsDecl =
2991 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2992 Diag(VD->getLocation(),
2993 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2994 << VD;
2995 continue;
2996 }
2997
2998 // Check if initial value of threadprivate variable reference variable with
2999 // local storage (it is not supported by runtime).
3000 if (const Expr *Init = VD->getAnyInitializer()) {
3001 LocalVarRefChecker Checker(*this);
3002 if (Checker.Visit(Init))
3003 continue;
3004 }
3005
3006 Vars.push_back(RefExpr);
3007 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3008 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3009 Context, SourceRange(Loc, Loc)));
3010 if (ASTMutationListener *ML = Context.getASTMutationListener())
3011 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3012 }
3013 OMPThreadPrivateDecl *D = nullptr;
3014 if (!Vars.empty()) {
3015 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3016 Vars);
3017 D->setAccess(AS_public);
3018 }
3019 return D;
3020}
3021
3022static OMPAllocateDeclAttr::AllocatorTypeTy
3023getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3024 if (!Allocator)
3025 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3026 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3027 Allocator->isInstantiationDependent() ||
3028 Allocator->containsUnexpandedParameterPack())
3029 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3030 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3031 const Expr *AE = Allocator->IgnoreParenImpCasts();
3032 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3033 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3034 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3035 llvm::FoldingSetNodeID AEId, DAEId;
3036 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3037 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3038 if (AEId == DAEId) {
3039 AllocatorKindRes = AllocatorKind;
3040 break;
3041 }
3042 }
3043 return AllocatorKindRes;
3044}
3045
3046static bool checkPreviousOMPAllocateAttribute(
3047 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3048 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3049 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3050 return false;
3051 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3052 Expr *PrevAllocator = A->getAllocator();
3053 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3054 getAllocatorKind(S, Stack, PrevAllocator);
3055 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3056 if (AllocatorsMatch &&
3057 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3058 Allocator && PrevAllocator) {
3059 const Expr *AE = Allocator->IgnoreParenImpCasts();
3060 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3061 llvm::FoldingSetNodeID AEId, PAEId;
3062 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3063 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3064 AllocatorsMatch = AEId == PAEId;
3065 }
3066 if (!AllocatorsMatch) {
3067 SmallString<256> AllocatorBuffer;
3068 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3069 if (Allocator)
3070 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3071 SmallString<256> PrevAllocatorBuffer;
3072 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3073 if (PrevAllocator)
3074 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3075 S.getPrintingPolicy());
3076
3077 SourceLocation AllocatorLoc =
3078 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3079 SourceRange AllocatorRange =
3080 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3081 SourceLocation PrevAllocatorLoc =
3082 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3083 SourceRange PrevAllocatorRange =
3084 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3085 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3086 << (Allocator ? 1 : 0) << AllocatorStream.str()
3087 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3088 << AllocatorRange;
3089 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3090 << PrevAllocatorRange;
3091 return true;
3092 }
3093 return false;
3094}
3095
3096static void
3097applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3098 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3099 Expr *Allocator, SourceRange SR) {
3100 if (VD->hasAttr<OMPAllocateDeclAttr>())
3101 return;
3102 if (Allocator &&
3103 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3104 Allocator->isInstantiationDependent() ||
3105 Allocator->containsUnexpandedParameterPack()))
3106 return;
3107 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3108 Allocator, SR);
3109 VD->addAttr(A);
3110 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3111 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3112}
3113
3114Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3115 SourceLocation Loc, ArrayRef<Expr *> VarList,
3116 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3117 assert(Clauses.size() <= 1 && "Expected at most one clause.")((Clauses.size() <= 1 && "Expected at most one clause."
) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 3117, __PRETTY_FUNCTION__))
;
3118 Expr *Allocator = nullptr;
3119 if (Clauses.empty()) {
3120 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3121 // allocate directives that appear in a target region must specify an
3122 // allocator clause unless a requires directive with the dynamic_allocators
3123 // clause is present in the same compilation unit.
3124 if (LangOpts.OpenMPIsDevice &&
3125 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3126 targetDiag(Loc, diag::err_expected_allocator_clause);
3127 } else {
3128 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3129 }
3130 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3131 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3132 SmallVector<Expr *, 8> Vars;
3133 for (Expr *RefExpr : VarList) {
3134 auto *DE = cast<DeclRefExpr>(RefExpr);
3135 auto *VD = cast<VarDecl>(DE->getDecl());
3136
3137 // Check if this is a TLS variable or global register.
3138 if (VD->getTLSKind() != VarDecl::TLS_None ||
3139 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3140 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3141 !VD->isLocalVarDecl()))
3142 continue;
3143
3144 // If the used several times in the allocate directive, the same allocator
3145 // must be used.
3146 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3147 AllocatorKind, Allocator))
3148 continue;
3149
3150 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3151 // If a list item has a static storage type, the allocator expression in the
3152 // allocator clause must be a constant expression that evaluates to one of
3153 // the predefined memory allocator values.
3154 if (Allocator && VD->hasGlobalStorage()) {
3155 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3156 Diag(Allocator->getExprLoc(),
3157 diag::err_omp_expected_predefined_allocator)
3158 << Allocator->getSourceRange();
3159 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3160 VarDecl::DeclarationOnly;
3161 Diag(VD->getLocation(),
3162 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163 << VD;
3164 continue;
3165 }
3166 }
3167
3168 Vars.push_back(RefExpr);
3169 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3170 DE->getSourceRange());
3171 }
3172 if (Vars.empty())
3173 return nullptr;
3174 if (!Owner)
3175 Owner = getCurLexicalContext();
3176 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3177 D->setAccess(AS_public);
3178 Owner->addDecl(D);
3179 return DeclGroupPtrTy::make(DeclGroupRef(D));
3180}
3181
3182Sema::DeclGroupPtrTy
3183Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3184 ArrayRef<OMPClause *> ClauseList) {
3185 OMPRequiresDecl *D = nullptr;
3186 if (!CurContext->isFileContext()) {
3187 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3188 } else {
3189 D = CheckOMPRequiresDecl(Loc, ClauseList);
3190 if (D) {
3191 CurContext->addDecl(D);
3192 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3193 }
3194 }
3195 return DeclGroupPtrTy::make(DeclGroupRef(D));
3196}
3197
3198OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3199 ArrayRef<OMPClause *> ClauseList) {
3200 /// For target specific clauses, the requires directive cannot be
3201 /// specified after the handling of any of the target regions in the
3202 /// current compilation unit.
3203 ArrayRef<SourceLocation> TargetLocations =
3204 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3205 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3206 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3207 for (const OMPClause *CNew : ClauseList) {
3208 // Check if any of the requires clauses affect target regions.
3209 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3210 isa<OMPUnifiedAddressClause>(CNew) ||
3211 isa<OMPReverseOffloadClause>(CNew) ||
3212 isa<OMPDynamicAllocatorsClause>(CNew)) {
3213 Diag(Loc, diag::err_omp_directive_before_requires)
3214 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3215 for (SourceLocation TargetLoc : TargetLocations) {
3216 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3217 << "target";
3218 }
3219 } else if (!AtomicLoc.isInvalid() &&
3220 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3221 Diag(Loc, diag::err_omp_directive_before_requires)
3222 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3223 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3224 << "atomic";
3225 }
3226 }
3227 }
3228
3229 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3230 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3231 ClauseList);
3232 return nullptr;
3233}
3234
3235static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3236 const ValueDecl *D,
3237 const DSAStackTy::DSAVarData &DVar,
3238 bool IsLoopIterVar) {
3239 if (DVar.RefExpr) {
3240 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3241 << getOpenMPClauseName(DVar.CKind);
3242 return;
3243 }
3244 enum {
3245 PDSA_StaticMemberShared,
3246 PDSA_StaticLocalVarShared,
3247 PDSA_LoopIterVarPrivate,
3248 PDSA_LoopIterVarLinear,
3249 PDSA_LoopIterVarLastprivate,
3250 PDSA_ConstVarShared,
3251 PDSA_GlobalVarShared,
3252 PDSA_TaskVarFirstprivate,
3253 PDSA_LocalVarPrivate,
3254 PDSA_Implicit
3255 } Reason = PDSA_Implicit;
3256 bool ReportHint = false;
3257 auto ReportLoc = D->getLocation();
3258 auto *VD = dyn_cast<VarDecl>(D);
3259 if (IsLoopIterVar) {
3260 if (DVar.CKind == OMPC_private)
3261 Reason = PDSA_LoopIterVarPrivate;
3262 else if (DVar.CKind == OMPC_lastprivate)
3263 Reason = PDSA_LoopIterVarLastprivate;
3264 else
3265 Reason = PDSA_LoopIterVarLinear;
3266 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3267 DVar.CKind == OMPC_firstprivate) {
3268 Reason = PDSA_TaskVarFirstprivate;
3269 ReportLoc = DVar.ImplicitDSALoc;
3270 } else if (VD && VD->isStaticLocal())
3271 Reason = PDSA_StaticLocalVarShared;
3272 else if (VD && VD->isStaticDataMember())
3273 Reason = PDSA_StaticMemberShared;
3274 else if (VD && VD->isFileVarDecl())
3275 Reason = PDSA_GlobalVarShared;
3276 else if (D->getType().isConstant(SemaRef.getASTContext()))
3277 Reason = PDSA_ConstVarShared;
3278 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3279 ReportHint = true;
3280 Reason = PDSA_LocalVarPrivate;
3281 }
3282 if (Reason != PDSA_Implicit) {
3283 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3284 << Reason << ReportHint
3285 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3286 } else if (DVar.ImplicitDSALoc.isValid()) {
3287 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3288 << getOpenMPClauseName(DVar.CKind);
3289 }
3290}
3291
3292static OpenMPMapClauseKind
3293getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3294 bool IsAggregateOrDeclareTarget) {
3295 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3296 switch (M) {
3297 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3298 Kind = OMPC_MAP_alloc;
3299 break;
3300 case OMPC_DEFAULTMAP_MODIFIER_to:
3301 Kind = OMPC_MAP_to;
3302 break;
3303 case OMPC_DEFAULTMAP_MODIFIER_from:
3304 Kind = OMPC_MAP_from;
3305 break;
3306 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3307 Kind = OMPC_MAP_tofrom;
3308 break;
3309 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3310 case OMPC_DEFAULTMAP_MODIFIER_last:
3311 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 3311)
;
3312 case OMPC_DEFAULTMAP_MODIFIER_none:
3313 case OMPC_DEFAULTMAP_MODIFIER_default:
3314 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3315 // IsAggregateOrDeclareTarget could be true if:
3316 // 1. the implicit behavior for aggregate is tofrom
3317 // 2. it's a declare target link
3318 if (IsAggregateOrDeclareTarget) {
3319 Kind = OMPC_MAP_tofrom;
3320 break;
3321 }
3322 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 3322)
;
3323 }
3324 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")((Kind != OMPC_MAP_unknown && "Expect map kind to be known"
) ? static_cast<void> (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 3324, __PRETTY_FUNCTION__))
;
3325 return Kind;
3326}
3327
3328namespace {
3329class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3330 DSAStackTy *Stack;
3331 Sema &SemaRef;
3332 bool ErrorFound = false;
3333 bool TryCaptureCXXThisMembers = false;
3334 CapturedStmt *CS = nullptr;
3335 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3336 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3337 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3338 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3339
3340 void VisitSubCaptures(OMPExecutableDirective *S) {
3341 // Check implicitly captured variables.
3342 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() ||
3343 S->getDirectiveKind() == OMPD_atomic ||
3344 S->getDirectiveKind() == OMPD_critical ||
3345 S->getDirectiveKind() == OMPD_section ||
3346 S->getDirectiveKind() == OMPD_master)
3347 return;
3348 visitSubCaptures(S->getInnermostCapturedStmt());
3349 // Try to capture inner this->member references to generate correct mappings
3350 // and diagnostics.
3351 if (TryCaptureCXXThisMembers ||
3352 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3353 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3354 [](const CapturedStmt::Capture &C) {
3355 return C.capturesThis();
3356 }))) {
3357 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3358 TryCaptureCXXThisMembers = true;
3359 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3360 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3361 }
3362 // In tasks firstprivates are not captured anymore, need to analyze them
3363 // explicitly.
3364 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3365 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3366 for (OMPClause *C : S->clauses())
3367 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3368 for (Expr *Ref : FC->varlists())
3369 Visit(Ref);
3370 }
3371 }
3372 }
3373
3374public:
3375 void VisitDeclRefExpr(DeclRefExpr *E) {
3376 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3377 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3378 E->isInstantiationDependent())
3379 return;
3380 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3381 // Check the datasharing rules for the expressions in the clauses.
3382 if (!CS) {
3383 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3384 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3385 Visit(CED->getInit());
3386 return;
3387 }
3388 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3389 // Do not analyze internal variables and do not enclose them into
3390 // implicit clauses.
3391 return;
3392 VD = VD->getCanonicalDecl();
3393 // Skip internally declared variables.
3394 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3395 !Stack->isImplicitTaskFirstprivate(VD))
3396 return;
3397 // Skip allocators in uses_allocators clauses.
3398 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3399 return;
3400
3401 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3402 // Check if the variable has explicit DSA set and stop analysis if it so.
3403 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3404 return;
3405
3406 // Skip internally declared static variables.
3407 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3408 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3409 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3410 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3411 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3412 !Stack->isImplicitTaskFirstprivate(VD))
3413 return;
3414
3415 SourceLocation ELoc = E->getExprLoc();
3416 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3417 // The default(none) clause requires that each variable that is referenced
3418 // in the construct, and does not have a predetermined data-sharing
3419 // attribute, must have its data-sharing attribute explicitly determined
3420 // by being listed in a data-sharing attribute clause.
3421 if (DVar.CKind == OMPC_unknown &&
3422 (Stack->getDefaultDSA() == DSA_none ||
3423 Stack->getDefaultDSA() == DSA_firstprivate) &&
3424 isImplicitOrExplicitTaskingRegion(DKind) &&
3425 VarsWithInheritedDSA.count(VD) == 0) {
3426 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3427 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3428 DSAStackTy::DSAVarData DVar =
3429 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3430 InheritedDSA = DVar.CKind == OMPC_unknown;
3431 }
3432 if (InheritedDSA)
3433 VarsWithInheritedDSA[VD] = E;
3434 return;
3435 }
3436
3437 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3438 // If implicit-behavior is none, each variable referenced in the
3439 // construct that does not have a predetermined data-sharing attribute
3440 // and does not appear in a to or link clause on a declare target
3441 // directive must be listed in a data-mapping attribute clause, a
3442 // data-haring attribute clause (including a data-sharing attribute
3443 // clause on a combined construct where target. is one of the
3444 // constituent constructs), or an is_device_ptr clause.
3445 OpenMPDefaultmapClauseKind ClauseKind =
3446 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3447 if (SemaRef.getLangOpts().OpenMP >= 50) {
3448 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3449 OMPC_DEFAULTMAP_MODIFIER_none;
3450 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3451 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3452 // Only check for data-mapping attribute and is_device_ptr here
3453 // since we have already make sure that the declaration does not
3454 // have a data-sharing attribute above
3455 if (!Stack->checkMappableExprComponentListsForDecl(
3456 VD, /*CurrentRegionOnly=*/true,
3457 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3458 MapExprComponents,
3459 OpenMPClauseKind) {
3460 auto MI = MapExprComponents.rbegin();
3461 auto ME = MapExprComponents.rend();
3462 return MI != ME && MI->getAssociatedDeclaration() == VD;
3463 })) {
3464 VarsWithInheritedDSA[VD] = E;
3465 return;
3466 }
3467 }
3468 }
3469
3470 if (isOpenMPTargetExecutionDirective(DKind) &&
3471 !Stack->isLoopControlVariable(VD).first) {
3472 if (!Stack->checkMappableExprComponentListsForDecl(
3473 VD, /*CurrentRegionOnly=*/true,
3474 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3475 StackComponents,
3476 OpenMPClauseKind) {
3477 // Variable is used if it has been marked as an array, array
3478 // section, array shaping or the variable iself.
3479 return StackComponents.size() == 1 ||
3480 std::all_of(
3481 std::next(StackComponents.rbegin()),
3482 StackComponents.rend(),
3483 [](const OMPClauseMappableExprCommon::
3484 MappableComponent &MC) {
3485 return MC.getAssociatedDeclaration() ==
3486 nullptr &&
3487 (isa<OMPArraySectionExpr>(
3488 MC.getAssociatedExpression()) ||
3489 isa<OMPArrayShapingExpr>(
3490 MC.getAssociatedExpression()) ||
3491 isa<ArraySubscriptExpr>(
3492 MC.getAssociatedExpression()));
3493 });
3494 })) {
3495 bool IsFirstprivate = false;
3496 // By default lambdas are captured as firstprivates.
3497 if (const auto *RD =
3498 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3499 IsFirstprivate = RD->isLambda();
3500 IsFirstprivate =
3501 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3502 if (IsFirstprivate) {
3503 ImplicitFirstprivate.emplace_back(E);
3504 } else {
3505 OpenMPDefaultmapClauseModifier M =
3506 Stack->getDefaultmapModifier(ClauseKind);
3507 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3508 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3509 ImplicitMap[Kind].emplace_back(E);
3510 }
3511 return;
3512 }
3513 }
3514
3515 // OpenMP [2.9.3.6, Restrictions, p.2]
3516 // A list item that appears in a reduction clause of the innermost
3517 // enclosing worksharing or parallel construct may not be accessed in an
3518 // explicit task.
3519 DVar = Stack->hasInnermostDSA(
3520 VD,
3521 [](OpenMPClauseKind C, bool AppliedToPointee) {
3522 return C == OMPC_reduction && !AppliedToPointee;
3523 },
3524 [](OpenMPDirectiveKind K) {
3525 return isOpenMPParallelDirective(K) ||
3526 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3527 },
3528 /*FromParent=*/true);
3529 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3530 ErrorFound = true;
3531 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3532 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3533 return;
3534 }
3535
3536 // Define implicit data-sharing attributes for task.
3537 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3538 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3539 (Stack->getDefaultDSA() == DSA_firstprivate &&
3540 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3541 !Stack->isLoopControlVariable(VD).first) {
3542 ImplicitFirstprivate.push_back(E);
3543 return;
3544 }
3545
3546 // Store implicitly used globals with declare target link for parent
3547 // target.
3548 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3549 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3550 Stack->addToParentTargetRegionLinkGlobals(E);
3551 return;
3552 }
3553 }
3554 }
3555 void VisitMemberExpr(MemberExpr *E) {
3556 if (E->isTypeDependent() || E->isValueDependent() ||
3557 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3558 return;
3559 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3560 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3561 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3562 if (!FD)
3563 return;
3564 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3565 // Check if the variable has explicit DSA set and stop analysis if it
3566 // so.
3567 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3568 return;
3569
3570 if (isOpenMPTargetExecutionDirective(DKind) &&
3571 !Stack->isLoopControlVariable(FD).first &&
3572 !Stack->checkMappableExprComponentListsForDecl(
3573 FD, /*CurrentRegionOnly=*/true,
3574 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3575 StackComponents,
3576 OpenMPClauseKind) {
3577 return isa<CXXThisExpr>(
3578 cast<MemberExpr>(
3579 StackComponents.back().getAssociatedExpression())
3580 ->getBase()
3581 ->IgnoreParens());
3582 })) {
3583 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3584 // A bit-field cannot appear in a map clause.
3585 //
3586 if (FD->isBitField())
3587 return;
3588
3589 // Check to see if the member expression is referencing a class that
3590 // has already been explicitly mapped
3591 if (Stack->isClassPreviouslyMapped(TE->getType()))
3592 return;
3593
3594 OpenMPDefaultmapClauseModifier Modifier =
3595 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3596 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3597 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3598 ImplicitMap[Kind].emplace_back(E);
3599 return;
3600 }
3601
3602 SourceLocation ELoc = E->getExprLoc();
3603 // OpenMP [2.9.3.6, Restrictions, p.2]
3604 // A list item that appears in a reduction clause of the innermost
3605 // enclosing worksharing or parallel construct may not be accessed in
3606 // an explicit task.
3607 DVar = Stack->hasInnermostDSA(
3608 FD,
3609 [](OpenMPClauseKind C, bool AppliedToPointee) {
3610 return C == OMPC_reduction && !AppliedToPointee;
3611 },
3612 [](OpenMPDirectiveKind K) {
3613 return isOpenMPParallelDirective(K) ||
3614 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3615 },
3616 /*FromParent=*/true);
3617 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3618 ErrorFound = true;
3619 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3620 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3621 return;
3622 }
3623
3624 // Define implicit data-sharing attributes for task.
3625 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3626 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3627 !Stack->isLoopControlVariable(FD).first) {
3628 // Check if there is a captured expression for the current field in the
3629 // region. Do not mark it as firstprivate unless there is no captured
3630 // expression.
3631 // TODO: try to make it firstprivate.
3632 if (DVar.CKind != OMPC_unknown)
3633 ImplicitFirstprivate.push_back(E);
3634 }
3635 return;
3636 }
3637 if (isOpenMPTargetExecutionDirective(DKind)) {
3638 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3639 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3640 /*NoDiagnose=*/true))
3641 return;
3642 const auto *VD = cast<ValueDecl>(
3643 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3644 if (!Stack->checkMappableExprComponentListsForDecl(
3645 VD, /*CurrentRegionOnly=*/true,
3646 [&CurComponents](
3647 OMPClauseMappableExprCommon::MappableExprComponentListRef
3648 StackComponents,
3649 OpenMPClauseKind) {
3650 auto CCI = CurComponents.rbegin();
3651 auto CCE = CurComponents.rend();
3652 for (const auto &SC : llvm::reverse(StackComponents)) {
3653 // Do both expressions have the same kind?
3654 if (CCI->getAssociatedExpression()->getStmtClass() !=
3655 SC.getAssociatedExpression()->getStmtClass())
3656 if (!((isa<OMPArraySectionExpr>(
3657 SC.getAssociatedExpression()) ||
3658 isa<OMPArrayShapingExpr>(
3659 SC.getAssociatedExpression())) &&
3660 isa<ArraySubscriptExpr>(
3661 CCI->getAssociatedExpression())))
3662 return false;
3663
3664 const Decl *CCD = CCI->getAssociatedDeclaration();
3665 const Decl *SCD = SC.getAssociatedDeclaration();
3666 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3667 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3668 if (SCD != CCD)
3669 return false;
3670 std::advance(CCI, 1);
3671 if (CCI == CCE)
3672 break;
3673 }
3674 return true;
3675 })) {
3676 Visit(E->getBase());
3677 }
3678 } else if (!TryCaptureCXXThisMembers) {
3679 Visit(E->getBase());
3680 }
3681 }
3682 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3683 for (OMPClause *C : S->clauses()) {
3684 // Skip analysis of arguments of implicitly defined firstprivate clause
3685 // for task|target directives.
3686 // Skip analysis of arguments of implicitly defined map clause for target
3687 // directives.
3688 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3689 C->isImplicit())) {
3690 for (Stmt *CC : C->children()) {
3691 if (CC)
3692 Visit(CC);
3693 }
3694 }
3695 }
3696 // Check implicitly captured variables.
3697 VisitSubCaptures(S);
3698 }
3699 void VisitStmt(Stmt *S) {
3700 for (Stmt *C : S->children()) {
3701 if (C) {
3702 // Check implicitly captured variables in the task-based directives to
3703 // check if they must be firstprivatized.
3704 Visit(C);
3705 }
3706 }
3707 }
3708
3709 void visitSubCaptures(CapturedStmt *S) {
3710 for (const CapturedStmt::Capture &Cap : S->captures()) {
3711 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3712 continue;
3713 VarDecl *VD = Cap.getCapturedVar();
3714 // Do not try to map the variable if it or its sub-component was mapped
3715 // already.
3716 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3717 Stack->checkMappableExprComponentListsForDecl(
3718 VD, /*CurrentRegionOnly=*/true,
3719 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3720 OpenMPClauseKind) { return true; }))
3721 continue;
3722 DeclRefExpr *DRE = buildDeclRefExpr(
3723 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3724 Cap.getLocation(), /*RefersToCapture=*/true);
3725 Visit(DRE);
3726 }
3727 }
3728 bool isErrorFound() const { return ErrorFound; }
3729 ArrayRef<Expr *> getImplicitFirstprivate() const {
3730 return ImplicitFirstprivate;
3731 }
3732 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3733 return ImplicitMap[Kind];
3734 }
3735 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3736 return VarsWithInheritedDSA;
3737 }
3738
3739 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3740 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3741 // Process declare target link variables for the target directives.
3742 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3743 for (DeclRefExpr *E : Stack->getLinkGlobals())
3744 Visit(E);
3745 }
3746 }
3747};
3748} // namespace
3749
3750void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3751 switch (DKind) {
3752 case OMPD_parallel:
3753 case OMPD_parallel_for:
3754 case OMPD_parallel_for_simd:
3755 case OMPD_parallel_sections:
3756 case OMPD_parallel_master:
3757 case OMPD_teams:
3758 case OMPD_teams_distribute:
3759 case OMPD_teams_distribute_simd: {
3760 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3761 QualType KmpInt32PtrTy =
3762 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3763 Sema::CapturedParamNameType Params[] = {
3764 std::make_pair(".global_tid.", KmpInt32PtrTy),
3765 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3766 std::make_pair(StringRef(), QualType()) // __context with shared vars
3767 };
3768 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3769 Params);
3770 break;
3771 }
3772 case OMPD_target_teams:
3773 case OMPD_target_parallel:
3774 case OMPD_target_parallel_for:
3775 case OMPD_target_parallel_for_simd:
3776 case OMPD_target_teams_distribute:
3777 case OMPD_target_teams_distribute_simd: {
3778 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3779 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3780 QualType KmpInt32PtrTy =
3781 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3782 QualType Args[] = {VoidPtrTy};
3783 FunctionProtoType::ExtProtoInfo EPI;
3784 EPI.Variadic = true;
3785 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3786 Sema::CapturedParamNameType Params[] = {
3787 std::make_pair(".global_tid.", KmpInt32Ty),
3788 std::make_pair(".part_id.", KmpInt32PtrTy),
3789 std::make_pair(".privates.", VoidPtrTy),
3790 std::make_pair(
3791 ".copy_fn.",
3792 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3793 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3794 std::make_pair(StringRef(), QualType()) // __context with shared vars
3795 };
3796 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3797 Params, /*OpenMPCaptureLevel=*/0);
3798 // Mark this captured region as inlined, because we don't use outlined
3799 // function directly.
3800 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3801 AlwaysInlineAttr::CreateImplicit(
3802 Context, {}, AttributeCommonInfo::AS_Keyword,
3803 AlwaysInlineAttr::Keyword_forceinline));
3804 Sema::CapturedParamNameType ParamsTarget[] = {
3805 std::make_pair(StringRef(), QualType()) // __context with shared vars
3806 };
3807 // Start a captured region for 'target' with no implicit parameters.
3808 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3809 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3810 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3811 std::make_pair(".global_tid.", KmpInt32PtrTy),
3812 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3813 std::make_pair(StringRef(), QualType()) // __context with shared vars
3814 };
3815 // Start a captured region for 'teams' or 'parallel'. Both regions have
3816 // the same implicit parameters.
3817 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3818 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3819 break;
3820 }
3821 case OMPD_target:
3822 case OMPD_target_simd: {
3823 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3824 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3825 QualType KmpInt32PtrTy =
3826 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3827 QualType Args[] = {VoidPtrTy};
3828 FunctionProtoType::ExtProtoInfo EPI;
3829 EPI.Variadic = true;
3830 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3831 Sema::CapturedParamNameType Params[] = {
3832 std::make_pair(".global_tid.", KmpInt32Ty),
3833 std::make_pair(".part_id.", KmpInt32PtrTy),
3834 std::make_pair(".privates.", VoidPtrTy),
3835 std::make_pair(
3836 ".copy_fn.",
3837 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3838 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3839 std::make_pair(StringRef(), QualType()) // __context with shared vars
3840 };
3841 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3842 Params, /*OpenMPCaptureLevel=*/0);
3843 // Mark this captured region as inlined, because we don't use outlined
3844 // function directly.
3845 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3846 AlwaysInlineAttr::CreateImplicit(
3847 Context, {}, AttributeCommonInfo::AS_Keyword,
3848 AlwaysInlineAttr::Keyword_forceinline));
3849 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3850 std::make_pair(StringRef(), QualType()),
3851 /*OpenMPCaptureLevel=*/1);
3852 break;
3853 }
3854 case OMPD_atomic:
3855 case OMPD_critical:
3856 case OMPD_section:
3857 case OMPD_master:
3858 break;
3859 case OMPD_simd:
3860 case OMPD_for:
3861 case OMPD_for_simd:
3862 case OMPD_sections:
3863 case OMPD_single:
3864 case OMPD_taskgroup:
3865 case OMPD_distribute:
3866 case OMPD_distribute_simd:
3867 case OMPD_ordered:
3868 case OMPD_target_data: {
3869 Sema::CapturedParamNameType Params[] = {
3870 std::make_pair(StringRef(), QualType()) // __context with shared vars
3871 };
3872 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3873 Params);
3874 break;
3875 }
3876 case OMPD_task: {
3877 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3878 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3879 QualType KmpInt32PtrTy =
3880 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3881 QualType Args[] = {VoidPtrTy};
3882 FunctionProtoType::ExtProtoInfo EPI;
3883 EPI.Variadic = true;
3884 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3885 Sema::CapturedParamNameType Params[] = {
3886 std::make_pair(".global_tid.", KmpInt32Ty),
3887 std::make_pair(".part_id.", KmpInt32PtrTy),
3888 std::make_pair(".privates.", VoidPtrTy),
3889 std::make_pair(
3890 ".copy_fn.",
3891 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3892 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3893 std::make_pair(StringRef(), QualType()) // __context with shared vars
3894 };
3895 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3896 Params);
3897 // Mark this captured region as inlined, because we don't use outlined
3898 // function directly.
3899 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3900 AlwaysInlineAttr::CreateImplicit(
3901 Context, {}, AttributeCommonInfo::AS_Keyword,
3902 AlwaysInlineAttr::Keyword_forceinline));
3903 break;
3904 }
3905 case OMPD_taskloop:
3906 case OMPD_taskloop_simd:
3907 case OMPD_master_taskloop:
3908 case OMPD_master_taskloop_simd: {
3909 QualType KmpInt32Ty =
3910 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3911 .withConst();
3912 QualType KmpUInt64Ty =
3913 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3914 .withConst();
3915 QualType KmpInt64Ty =
3916 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3917 .withConst();
3918 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3919 QualType KmpInt32PtrTy =
3920 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3921 QualType Args[] = {VoidPtrTy};
3922 FunctionProtoType::ExtProtoInfo EPI;
3923 EPI.Variadic = true;
3924 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3925 Sema::CapturedParamNameType Params[] = {
3926 std::make_pair(".global_tid.", KmpInt32Ty),
3927 std::make_pair(".part_id.", KmpInt32PtrTy),
3928 std::make_pair(".privates.", VoidPtrTy),
3929 std::make_pair(
3930 ".copy_fn.",
3931 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3932 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3933 std::make_pair(".lb.", KmpUInt64Ty),
3934 std::make_pair(".ub.", KmpUInt64Ty),
3935 std::make_pair(".st.", KmpInt64Ty),
3936 std::make_pair(".liter.", KmpInt32Ty),
3937 std::make_pair(".reductions.", VoidPtrTy),
3938 std::make_pair(StringRef(), QualType()) // __context with shared vars
3939 };
3940 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3941 Params);
3942 // Mark this captured region as inlined, because we don't use outlined
3943 // function directly.
3944 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3945 AlwaysInlineAttr::CreateImplicit(
3946 Context, {}, AttributeCommonInfo::AS_Keyword,
3947 AlwaysInlineAttr::Keyword_forceinline));
3948 break;
3949 }
3950 case OMPD_parallel_master_taskloop:
3951 case OMPD_parallel_master_taskloop_simd: {
3952 QualType KmpInt32Ty =
3953 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3954 .withConst();
3955 QualType KmpUInt64Ty =
3956 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3957 .withConst();
3958 QualType KmpInt64Ty =
3959 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3960 .withConst();
3961 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3962 QualType KmpInt32PtrTy =
3963 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3964 Sema::CapturedParamNameType ParamsParallel[] = {
3965 std::make_pair(".global_tid.", KmpInt32PtrTy),
3966 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3967 std::make_pair(StringRef(), QualType()) // __context with shared vars
3968 };
3969 // Start a captured region for 'parallel'.
3970 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3971 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3972 QualType Args[] = {VoidPtrTy};
3973 FunctionProtoType::ExtProtoInfo EPI;
3974 EPI.Variadic = true;
3975 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3976 Sema::CapturedParamNameType Params[] = {
3977 std::make_pair(".global_tid.", KmpInt32Ty),
3978 std::make_pair(".part_id.", KmpInt32PtrTy),
3979 std::make_pair(".privates.", VoidPtrTy),
3980 std::make_pair(
3981 ".copy_fn.",
3982 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3983 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3984 std::make_pair(".lb.", KmpUInt64Ty),
3985 std::make_pair(".ub.", KmpUInt64Ty),
3986 std::make_pair(".st.", KmpInt64Ty),
3987 std::make_pair(".liter.", KmpInt32Ty),
3988 std::make_pair(".reductions.", VoidPtrTy),
3989 std::make_pair(StringRef(), QualType()) // __context with shared vars
3990 };
3991 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3992 Params, /*OpenMPCaptureLevel=*/1);
3993 // Mark this captured region as inlined, because we don't use outlined
3994 // function directly.
3995 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3996 AlwaysInlineAttr::CreateImplicit(
3997 Context, {}, AttributeCommonInfo::AS_Keyword,
3998 AlwaysInlineAttr::Keyword_forceinline));
3999 break;
4000 }
4001 case OMPD_distribute_parallel_for_simd:
4002 case OMPD_distribute_parallel_for: {
4003 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4004 QualType KmpInt32PtrTy =
4005 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4006 Sema::CapturedParamNameType Params[] = {
4007 std::make_pair(".global_tid.", KmpInt32PtrTy),
4008 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4009 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4010 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4011 std::make_pair(StringRef(), QualType()) // __context with shared vars
4012 };
4013 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4014 Params);
4015 break;
4016 }
4017 case OMPD_target_teams_distribute_parallel_for:
4018 case OMPD_target_teams_distribute_parallel_for_simd: {
4019 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4020 QualType KmpInt32PtrTy =
4021 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4022 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4023
4024 QualType Args[] = {VoidPtrTy};
4025 FunctionProtoType::ExtProtoInfo EPI;
4026 EPI.Variadic = true;
4027 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4028 Sema::CapturedParamNameType Params[] = {
4029 std::make_pair(".global_tid.", KmpInt32Ty),
4030 std::make_pair(".part_id.", KmpInt32PtrTy),
4031 std::make_pair(".privates.", VoidPtrTy),
4032 std::make_pair(
4033 ".copy_fn.",
4034 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4035 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4036 std::make_pair(StringRef(), QualType()) // __context with shared vars
4037 };
4038 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4039 Params, /*OpenMPCaptureLevel=*/0);
4040 // Mark this captured region as inlined, because we don't use outlined
4041 // function directly.
4042 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4043 AlwaysInlineAttr::CreateImplicit(
4044 Context, {}, AttributeCommonInfo::AS_Keyword,
4045 AlwaysInlineAttr::Keyword_forceinline));
4046 Sema::CapturedParamNameType ParamsTarget[] = {
4047 std::make_pair(StringRef(), QualType()) // __context with shared vars
4048 };
4049 // Start a captured region for 'target' with no implicit parameters.
4050 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4051 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4052
4053 Sema::CapturedParamNameType ParamsTeams[] = {
4054 std::make_pair(".global_tid.", KmpInt32PtrTy),
4055 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4056 std::make_pair(StringRef(), QualType()) // __context with shared vars
4057 };
4058 // Start a captured region for 'target' with no implicit parameters.
4059 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4060 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4061
4062 Sema::CapturedParamNameType ParamsParallel[] = {
4063 std::make_pair(".global_tid.", KmpInt32PtrTy),
4064 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4065 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4066 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4067 std::make_pair(StringRef(), QualType()) // __context with shared vars
4068 };
4069 // Start a captured region for 'teams' or 'parallel'. Both regions have
4070 // the same implicit parameters.
4071 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4072 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4073 break;
4074 }
4075
4076 case OMPD_teams_distribute_parallel_for:
4077 case OMPD_teams_distribute_parallel_for_simd: {
4078 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4079 QualType KmpInt32PtrTy =
4080 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4081
4082 Sema::CapturedParamNameType ParamsTeams[] = {
4083 std::make_pair(".global_tid.", KmpInt32PtrTy),
4084 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4085 std::make_pair(StringRef(), QualType()) // __context with shared vars
4086 };
4087 // Start a captured region for 'target' with no implicit parameters.
4088 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4089 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4090
4091 Sema::CapturedParamNameType ParamsParallel[] = {
4092 std::make_pair(".global_tid.", KmpInt32PtrTy),
4093 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4094 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4095 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4096 std::make_pair(StringRef(), QualType()) // __context with shared vars
4097 };
4098 // Start a captured region for 'teams' or 'parallel'. Both regions have
4099 // the same implicit parameters.
4100 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4101 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4102 break;
4103 }
4104 case OMPD_target_update:
4105 case OMPD_target_enter_data:
4106 case OMPD_target_exit_data: {
4107 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4108 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4109 QualType KmpInt32PtrTy =
4110 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4111 QualType Args[] = {VoidPtrTy};
4112 FunctionProtoType::ExtProtoInfo EPI;
4113 EPI.Variadic = true;
4114 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4115 Sema::CapturedParamNameType Params[] = {
4116 std::make_pair(".global_tid.", KmpInt32Ty),
4117 std::make_pair(".part_id.", KmpInt32PtrTy),
4118 std::make_pair(".privates.", VoidPtrTy),
4119 std::make_pair(
4120 ".copy_fn.",
4121 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4122 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4123 std::make_pair(StringRef(), QualType()) // __context with shared vars
4124 };
4125 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4126 Params);
4127 // Mark this captured region as inlined, because we don't use outlined
4128 // function directly.
4129 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4130 AlwaysInlineAttr::CreateImplicit(
4131 Context, {}, AttributeCommonInfo::AS_Keyword,
4132 AlwaysInlineAttr::Keyword_forceinline));
4133 break;
4134 }
4135 case OMPD_threadprivate:
4136 case OMPD_allocate:
4137 case OMPD_taskyield:
4138 case OMPD_barrier:
4139 case OMPD_taskwait:
4140 case OMPD_cancellation_point:
4141 case OMPD_cancel:
4142 case OMPD_flush:
4143 case OMPD_depobj:
4144 case OMPD_scan:
4145 case OMPD_declare_reduction:
4146 case OMPD_declare_mapper:
4147 case OMPD_declare_simd:
4148 case OMPD_declare_target:
4149 case OMPD_end_declare_target:
4150 case OMPD_requires:
4151 case OMPD_declare_variant:
4152 case OMPD_begin_declare_variant:
4153 case OMPD_end_declare_variant:
4154 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4154)
;
4155 case OMPD_unknown:
4156 default:
4157 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4157)
;
4158 }
4159 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4160}
4161
4162int Sema::getNumberOfConstructScopes(unsigned Level) const {
4163 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4164}
4165
4166int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4167 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4168 getOpenMPCaptureRegions(CaptureRegions, DKind);
4169 return CaptureRegions.size();
4170}
4171
4172static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4173 Expr *CaptureExpr, bool WithInit,
4174 bool AsExpression) {
4175 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4175, __PRETTY_FUNCTION__))
;
4176 ASTContext &C = S.getASTContext();
4177 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4178 QualType Ty = Init->getType();
4179 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4180 if (S.getLangOpts().CPlusPlus) {
4181 Ty = C.getLValueReferenceType(Ty);
4182 } else {
4183 Ty = C.getPointerType(Ty);
4184 ExprResult Res =
4185 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4186 if (!Res.isUsable())
4187 return nullptr;
4188 Init = Res.get();
4189 }
4190 WithInit = true;
4191 }
4192 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4193 CaptureExpr->getBeginLoc());
4194 if (!WithInit)
4195 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4196 S.CurContext->addHiddenDecl(CED);
4197 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4198 return CED;
4199}
4200
4201static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4202 bool WithInit) {
4203 OMPCapturedExprDecl *CD;
4204 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4205 CD = cast<OMPCapturedExprDecl>(VD);
4206 else
4207 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4208 /*AsExpression=*/false);
4209 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4210 CaptureExpr->getExprLoc());
4211}
4212
4213static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4214 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4215 if (!Ref) {
4216 OMPCapturedExprDecl *CD = buildCaptureDecl(
4217 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4218 /*WithInit=*/true, /*AsExpression=*/true);
4219 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4220 CaptureExpr->getExprLoc());
4221 }
4222 ExprResult Res = Ref;
4223 if (!S.getLangOpts().CPlusPlus &&
4224 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4225 Ref->getType()->isPointerType()) {
4226 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4227 if (!Res.isUsable())
4228 return ExprError();
4229 }
4230 return S.DefaultLvalueConversion(Res.get());
4231}
4232
4233namespace {
4234// OpenMP directives parsed in this section are represented as a
4235// CapturedStatement with an associated statement. If a syntax error
4236// is detected during the parsing of the associated statement, the
4237// compiler must abort processing and close the CapturedStatement.
4238//
4239// Combined directives such as 'target parallel' have more than one
4240// nested CapturedStatements. This RAII ensures that we unwind out
4241// of all the nested CapturedStatements when an error is found.
4242class CaptureRegionUnwinderRAII {
4243private:
4244 Sema &S;
4245 bool &ErrorFound;
4246 OpenMPDirectiveKind DKind = OMPD_unknown;
4247
4248public:
4249 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4250 OpenMPDirectiveKind DKind)
4251 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4252 ~CaptureRegionUnwinderRAII() {
4253 if (ErrorFound) {
4254 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4255 while (--ThisCaptureLevel >= 0)
4256 S.ActOnCapturedRegionError();
4257 }
4258 }
4259};
4260} // namespace
4261
4262void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4263 // Capture variables captured by reference in lambdas for target-based
4264 // directives.
4265 if (!CurContext->isDependentContext() &&
4266 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4267 isOpenMPTargetDataManagementDirective(
4268 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4269 QualType Type = V->getType();
4270 if (const auto *RD = Type.getCanonicalType()
4271 .getNonReferenceType()
4272 ->getAsCXXRecordDecl()) {
4273 bool SavedForceCaptureByReferenceInTargetExecutable =
4274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4275 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4276 /*V=*/true);
4277 if (RD->isLambda()) {
4278 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4279 FieldDecl *ThisCapture;
4280 RD->getCaptureFields(Captures, ThisCapture);
4281 for (const LambdaCapture &LC : RD->captures()) {
4282 if (LC.getCaptureKind() == LCK_ByRef) {
4283 VarDecl *VD = LC.getCapturedVar();
4284 DeclContext *VDC = VD->getDeclContext();
4285 if (!VDC->Encloses(CurContext))
4286 continue;
4287 MarkVariableReferenced(LC.getLocation(), VD);
4288 } else if (LC.getCaptureKind() == LCK_This) {
4289 QualType ThisTy = getCurrentThisType();
4290 if (!ThisTy.isNull() &&
4291 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4292 CheckCXXThisCapture(LC.getLocation());
4293 }
4294 }
4295 }
4296 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4297 SavedForceCaptureByReferenceInTargetExecutable);
4298 }
4299 }
4300}
4301
4302static bool checkOrderedOrderSpecified(Sema &S,
4303 const ArrayRef<OMPClause *> Clauses) {
4304 const OMPOrderedClause *Ordered = nullptr;
4305 const OMPOrderClause *Order = nullptr;
4306
4307 for (const OMPClause *Clause : Clauses) {
4308 if (Clause->getClauseKind() == OMPC_ordered)
4309 Ordered = cast<OMPOrderedClause>(Clause);
4310 else if (Clause->getClauseKind() == OMPC_order) {
4311 Order = cast<OMPOrderClause>(Clause);
4312 if (Order->getKind() != OMPC_ORDER_concurrent)
4313 Order = nullptr;
4314 }
4315 if (Ordered && Order)
4316 break;
4317 }
4318
4319 if (Ordered && Order) {
4320 S.Diag(Order->getKindKwLoc(),
4321 diag::err_omp_simple_clause_incompatible_with_ordered)
4322 << getOpenMPClauseName(OMPC_order)
4323 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4324 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4325 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4326 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4327 return true;
4328 }
4329 return false;
4330}
4331
4332StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4333 ArrayRef<OMPClause *> Clauses) {
4334 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4335 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4336 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4337 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master)
4338 return S;
4339
4340 bool ErrorFound = false;
4341 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4342 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4343 if (!S.isUsable()) {
4344 ErrorFound = true;
4345 return StmtError();
4346 }
4347
4348 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4349 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4350 OMPOrderedClause *OC = nullptr;
4351 OMPScheduleClause *SC = nullptr;
4352 SmallVector<const OMPLinearClause *, 4> LCs;
4353 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4354 // This is required for proper codegen.
4355 for (OMPClause *Clause : Clauses) {
4356 if (!LangOpts.OpenMPSimd &&
4357 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4358 Clause->getClauseKind() == OMPC_in_reduction) {
4359 // Capture taskgroup task_reduction descriptors inside the tasking regions
4360 // with the corresponding in_reduction items.
4361 auto *IRC = cast<OMPInReductionClause>(Clause);
4362 for (Expr *E : IRC->taskgroup_descriptors())
4363 if (E)
4364 MarkDeclarationsReferencedInExpr(E);
4365 }
4366 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4367 Clause->getClauseKind() == OMPC_copyprivate ||
4368 (getLangOpts().OpenMPUseTLS &&
4369 getASTContext().getTargetInfo().isTLSSupported() &&
4370 Clause->getClauseKind() == OMPC_copyin)) {
4371 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4372 // Mark all variables in private list clauses as used in inner region.
4373 for (Stmt *VarRef : Clause->children()) {
4374 if (auto *E = cast_or_null<Expr>(VarRef)) {
4375 MarkDeclarationsReferencedInExpr(E);
4376 }
4377 }
4378 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4379 } else if (CaptureRegions.size() > 1 ||
4380 CaptureRegions.back() != OMPD_unknown) {
4381 if (auto *C = OMPClauseWithPreInit::get(Clause))
4382 PICs.push_back(C);
4383 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4384 if (Expr *E = C->getPostUpdateExpr())
4385 MarkDeclarationsReferencedInExpr(E);
4386 }
4387 }
4388 if (Clause->getClauseKind() == OMPC_schedule)
4389 SC = cast<OMPScheduleClause>(Clause);
4390 else if (Clause->getClauseKind() == OMPC_ordered)
4391 OC = cast<OMPOrderedClause>(Clause);
4392 else if (Clause->getClauseKind() == OMPC_linear)
4393 LCs.push_back(cast<OMPLinearClause>(Clause));
4394 }
4395 // Capture allocator expressions if used.
4396 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4397 MarkDeclarationsReferencedInExpr(E);
4398 // OpenMP, 2.7.1 Loop Construct, Restrictions
4399 // The nonmonotonic modifier cannot be specified if an ordered clause is
4400 // specified.
4401 if (SC &&
4402 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4403 SC->getSecondScheduleModifier() ==
4404 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4405 OC) {
4406 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4407 ? SC->getFirstScheduleModifierLoc()
4408 : SC->getSecondScheduleModifierLoc(),
4409 diag::err_omp_simple_clause_incompatible_with_ordered)
4410 << getOpenMPClauseName(OMPC_schedule)
4411 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4412 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4413 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4414 ErrorFound = true;
4415 }
4416 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4417 // If an order(concurrent) clause is present, an ordered clause may not appear
4418 // on the same directive.
4419 if (checkOrderedOrderSpecified(*this, Clauses))
4420 ErrorFound = true;
4421 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4422 for (const OMPLinearClause *C : LCs) {
4423 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4424 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4425 }
4426 ErrorFound = true;
4427 }
4428 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4429 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4430 OC->getNumForLoops()) {
4431 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4432 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4433 ErrorFound = true;
4434 }
4435 if (ErrorFound) {
4436 return StmtError();
4437 }
4438 StmtResult SR = S;
4439 unsigned CompletedRegions = 0;
4440 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4441 // Mark all variables in private list clauses as used in inner region.
4442 // Required for proper codegen of combined directives.
4443 // TODO: add processing for other clauses.
4444 if (ThisCaptureRegion != OMPD_unknown) {
4445 for (const clang::OMPClauseWithPreInit *C : PICs) {
4446 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4447 // Find the particular capture region for the clause if the
4448 // directive is a combined one with multiple capture regions.
4449 // If the directive is not a combined one, the capture region
4450 // associated with the clause is OMPD_unknown and is generated
4451 // only once.
4452 if (CaptureRegion == ThisCaptureRegion ||
4453 CaptureRegion == OMPD_unknown) {
4454 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4455 for (Decl *D : DS->decls())
4456 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4457 }
4458 }
4459 }
4460 }
4461 if (ThisCaptureRegion == OMPD_target) {
4462 // Capture allocator traits in the target region. They are used implicitly
4463 // and, thus, are not captured by default.
4464 for (OMPClause *C : Clauses) {
4465 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4466 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4467 ++I) {
4468 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4469 if (Expr *E = D.AllocatorTraits)
4470 MarkDeclarationsReferencedInExpr(E);
4471 }
4472 continue;
4473 }
4474 }
4475 }
4476 if (++CompletedRegions == CaptureRegions.size())
4477 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4478 SR = ActOnCapturedRegionEnd(SR.get());
4479 }
4480 return SR;
4481}
4482
4483static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4484 OpenMPDirectiveKind CancelRegion,
4485 SourceLocation StartLoc) {
4486 // CancelRegion is only needed for cancel and cancellation_point.
4487 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4488 return false;
4489
4490 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4491 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4492 return false;
4493
4494 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4495 << getOpenMPDirectiveName(CancelRegion);
4496 return true;
4497}
4498
4499static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4500 OpenMPDirectiveKind CurrentRegion,
4501 const DeclarationNameInfo &CurrentName,
4502 OpenMPDirectiveKind CancelRegion,
4503 SourceLocation StartLoc) {
4504 if (Stack->getCurScope()) {
4505 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4506 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4507 bool NestingProhibited = false;
4508 bool CloseNesting = true;
4509 bool OrphanSeen = false;
4510 enum {
4511 NoRecommend,
4512 ShouldBeInParallelRegion,
4513 ShouldBeInOrderedRegion,
4514 ShouldBeInTargetRegion,
4515 ShouldBeInTeamsRegion,
4516 ShouldBeInLoopSimdRegion,
4517 } Recommend = NoRecommend;
4518 if (isOpenMPSimdDirective(ParentRegion) &&
4519 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4520 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4521 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4522 CurrentRegion != OMPD_scan))) {
4523 // OpenMP [2.16, Nesting of Regions]
4524 // OpenMP constructs may not be nested inside a simd region.
4525 // OpenMP [2.8.1,simd Construct, Restrictions]
4526 // An ordered construct with the simd clause is the only OpenMP
4527 // construct that can appear in the simd region.
4528 // Allowing a SIMD construct nested in another SIMD construct is an
4529 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4530 // message.
4531 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4532 // The only OpenMP constructs that can be encountered during execution of
4533 // a simd region are the atomic construct, the loop construct, the simd
4534 // construct and the ordered construct with the simd clause.
4535 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4536 ? diag::err_omp_prohibited_region_simd
4537 : diag::warn_omp_nesting_simd)
4538 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4539 return CurrentRegion != OMPD_simd;
4540 }
4541 if (ParentRegion == OMPD_atomic) {
4542 // OpenMP [2.16, Nesting of Regions]
4543 // OpenMP constructs may not be nested inside an atomic region.
4544 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4545 return true;
4546 }
4547 if (CurrentRegion == OMPD_section) {
4548 // OpenMP [2.7.2, sections Construct, Restrictions]
4549 // Orphaned section directives are prohibited. That is, the section
4550 // directives must appear within the sections construct and must not be
4551 // encountered elsewhere in the sections region.
4552 if (ParentRegion != OMPD_sections &&
4553 ParentRegion != OMPD_parallel_sections) {
4554 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4555 << (ParentRegion != OMPD_unknown)
4556 << getOpenMPDirectiveName(ParentRegion);
4557 return true;
4558 }
4559 return false;
4560 }
4561 // Allow some constructs (except teams and cancellation constructs) to be
4562 // orphaned (they could be used in functions, called from OpenMP regions
4563 // with the required preconditions).
4564 if (ParentRegion == OMPD_unknown &&
4565 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4566 CurrentRegion != OMPD_cancellation_point &&
4567 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4568 return false;
4569 if (CurrentRegion == OMPD_cancellation_point ||
4570 CurrentRegion == OMPD_cancel) {
4571 // OpenMP [2.16, Nesting of Regions]
4572 // A cancellation point construct for which construct-type-clause is
4573 // taskgroup must be nested inside a task construct. A cancellation
4574 // point construct for which construct-type-clause is not taskgroup must
4575 // be closely nested inside an OpenMP construct that matches the type
4576 // specified in construct-type-clause.
4577 // A cancel construct for which construct-type-clause is taskgroup must be
4578 // nested inside a task construct. A cancel construct for which
4579 // construct-type-clause is not taskgroup must be closely nested inside an
4580 // OpenMP construct that matches the type specified in
4581 // construct-type-clause.
4582 NestingProhibited =
4583 !((CancelRegion == OMPD_parallel &&
4584 (ParentRegion == OMPD_parallel ||
4585 ParentRegion == OMPD_target_parallel)) ||
4586 (CancelRegion == OMPD_for &&
4587 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4588 ParentRegion == OMPD_target_parallel_for ||
4589 ParentRegion == OMPD_distribute_parallel_for ||
4590 ParentRegion == OMPD_teams_distribute_parallel_for ||
4591 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4592 (CancelRegion == OMPD_taskgroup &&
4593 (ParentRegion == OMPD_task ||
4594 (SemaRef.getLangOpts().OpenMP >= 50 &&
4595 (ParentRegion == OMPD_taskloop ||
4596 ParentRegion == OMPD_master_taskloop ||
4597 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4598 (CancelRegion == OMPD_sections &&
4599 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4600 ParentRegion == OMPD_parallel_sections)));
4601 OrphanSeen = ParentRegion == OMPD_unknown;
4602 } else if (CurrentRegion == OMPD_master) {
4603 // OpenMP [2.16, Nesting of Regions]
4604 // A master region may not be closely nested inside a worksharing,
4605 // atomic, or explicit task region.
4606 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4607 isOpenMPTaskingDirective(ParentRegion);
4608 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4609 // OpenMP [2.16, Nesting of Regions]
4610 // A critical region may not be nested (closely or otherwise) inside a
4611 // critical region with the same name. Note that this restriction is not
4612 // sufficient to prevent deadlock.
4613 SourceLocation PreviousCriticalLoc;
4614 bool DeadLock = Stack->hasDirective(
4615 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4616 const DeclarationNameInfo &DNI,
4617 SourceLocation Loc) {
4618 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4619 PreviousCriticalLoc = Loc;
4620 return true;
4621 }
4622 return false;
4623 },
4624 false /* skip top directive */);
4625 if (DeadLock) {
4626 SemaRef.Diag(StartLoc,
4627 diag::err_omp_prohibited_region_critical_same_name)
4628 << CurrentName.getName();
4629 if (PreviousCriticalLoc.isValid())
4630 SemaRef.Diag(PreviousCriticalLoc,
4631 diag::note_omp_previous_critical_region);
4632 return true;
4633 }
4634 } else if (CurrentRegion == OMPD_barrier) {
4635 // OpenMP [2.16, Nesting of Regions]
4636 // A barrier region may not be closely nested inside a worksharing,
4637 // explicit task, critical, ordered, atomic, or master region.
4638 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4639 isOpenMPTaskingDirective(ParentRegion) ||
4640 ParentRegion == OMPD_master ||
4641 ParentRegion == OMPD_parallel_master ||
4642 ParentRegion == OMPD_critical ||
4643 ParentRegion == OMPD_ordered;
4644 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4645 !isOpenMPParallelDirective(CurrentRegion) &&
4646 !isOpenMPTeamsDirective(CurrentRegion)) {
4647 // OpenMP [2.16, Nesting of Regions]
4648 // A worksharing region may not be closely nested inside a worksharing,
4649 // explicit task, critical, ordered, atomic, or master region.
4650 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4651 isOpenMPTaskingDirective(ParentRegion) ||
4652 ParentRegion == OMPD_master ||
4653 ParentRegion == OMPD_parallel_master ||
4654 ParentRegion == OMPD_critical ||
4655 ParentRegion == OMPD_ordered;
4656 Recommend = ShouldBeInParallelRegion;
4657 } else if (CurrentRegion == OMPD_ordered) {
4658 // OpenMP [2.16, Nesting of Regions]
4659 // An ordered region may not be closely nested inside a critical,
4660 // atomic, or explicit task region.
4661 // An ordered region must be closely nested inside a loop region (or
4662 // parallel loop region) with an ordered clause.
4663 // OpenMP [2.8.1,simd Construct, Restrictions]
4664 // An ordered construct with the simd clause is the only OpenMP construct
4665 // that can appear in the simd region.
4666 NestingProhibited = ParentRegion == OMPD_critical ||
4667 isOpenMPTaskingDirective(ParentRegion) ||
4668 !(isOpenMPSimdDirective(ParentRegion) ||
4669 Stack->isParentOrderedRegion());
4670 Recommend = ShouldBeInOrderedRegion;
4671 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4672 // OpenMP [2.16, Nesting of Regions]
4673 // If specified, a teams construct must be contained within a target
4674 // construct.
4675 NestingProhibited =
4676 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4677 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4678 ParentRegion != OMPD_target);
4679 OrphanSeen = ParentRegion == OMPD_unknown;
4680 Recommend = ShouldBeInTargetRegion;
4681 } else if (CurrentRegion == OMPD_scan) {
4682 // OpenMP [2.16, Nesting of Regions]
4683 // If specified, a teams construct must be contained within a target
4684 // construct.
4685 NestingProhibited =
4686 SemaRef.LangOpts.OpenMP < 50 ||
4687 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4688 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4689 ParentRegion != OMPD_parallel_for_simd);
4690 OrphanSeen = ParentRegion == OMPD_unknown;
4691 Recommend = ShouldBeInLoopSimdRegion;
4692 }
4693 if (!NestingProhibited &&
4694 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4695 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4696 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4697 // OpenMP [2.16, Nesting of Regions]
4698 // distribute, parallel, parallel sections, parallel workshare, and the
4699 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4700 // constructs that can be closely nested in the teams region.
4701 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4702 !isOpenMPDistributeDirective(CurrentRegion);
4703 Recommend = ShouldBeInParallelRegion;
4704 }
4705 if (!NestingProhibited &&
4706 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4707 // OpenMP 4.5 [2.17 Nesting of Regions]
4708 // The region associated with the distribute construct must be strictly
4709 // nested inside a teams region
4710 NestingProhibited =
4711 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4712 Recommend = ShouldBeInTeamsRegion;
4713 }
4714 if (!NestingProhibited &&
4715 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4716 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4717 // OpenMP 4.5 [2.17 Nesting of Regions]
4718 // If a target, target update, target data, target enter data, or
4719 // target exit data construct is encountered during execution of a
4720 // target region, the behavior is unspecified.
4721 NestingProhibited = Stack->hasDirective(
4722 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4723 SourceLocation) {
4724 if (isOpenMPTargetExecutionDirective(K)) {
4725 OffendingRegion = K;
4726 return true;
4727 }
4728 return false;
4729 },
4730 false /* don't skip top directive */);
4731 CloseNesting = false;
4732 }
4733 if (NestingProhibited) {
4734 if (OrphanSeen) {
4735 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4736 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4737 } else {
4738 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4739 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4740 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4741 }
4742 return true;
4743 }
4744 }
4745 return false;
4746}
4747
4748struct Kind2Unsigned {
4749 using argument_type = OpenMPDirectiveKind;
4750 unsigned operator()(argument_type DK) { return unsigned(DK); }
4751};
4752static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4753 ArrayRef<OMPClause *> Clauses,
4754 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4755 bool ErrorFound = false;
4756 unsigned NamedModifiersNumber = 0;
4757 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4758 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4759 SmallVector<SourceLocation, 4> NameModifierLoc;
4760 for (const OMPClause *C : Clauses) {
4761 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4762 // At most one if clause without a directive-name-modifier can appear on
4763 // the directive.
4764 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4765 if (FoundNameModifiers[CurNM]) {
4766 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4767 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4768 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4769 ErrorFound = true;
4770 } else if (CurNM != OMPD_unknown) {
4771 NameModifierLoc.push_back(IC->getNameModifierLoc());
4772 ++NamedModifiersNumber;
4773 }
4774 FoundNameModifiers[CurNM] = IC;
4775 if (CurNM == OMPD_unknown)
4776 continue;
4777 // Check if the specified name modifier is allowed for the current
4778 // directive.
4779 // At most one if clause with the particular directive-name-modifier can
4780 // appear on the directive.
4781 bool MatchFound = false;
4782 for (auto NM : AllowedNameModifiers) {
4783 if (CurNM == NM) {
4784 MatchFound = true;
4785 break;
4786 }
4787 }
4788 if (!MatchFound) {
4789 S.Diag(IC->getNameModifierLoc(),
4790 diag::err_omp_wrong_if_directive_name_modifier)
4791 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4792 ErrorFound = true;
4793 }
4794 }
4795 }
4796 // If any if clause on the directive includes a directive-name-modifier then
4797 // all if clauses on the directive must include a directive-name-modifier.
4798 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4799 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4800 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4801 diag::err_omp_no_more_if_clause);
4802 } else {
4803 std::string Values;
4804 std::string Sep(", ");
4805 unsigned AllowedCnt = 0;
4806 unsigned TotalAllowedNum =
4807 AllowedNameModifiers.size() - NamedModifiersNumber;
4808 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4809 ++Cnt) {
4810 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4811 if (!FoundNameModifiers[NM]) {
4812 Values += "'";
4813 Values += getOpenMPDirectiveName(NM);
4814 Values += "'";
4815 if (AllowedCnt + 2 == TotalAllowedNum)
4816 Values += " or ";
4817 else if (AllowedCnt + 1 != TotalAllowedNum)
4818 Values += Sep;
4819 ++AllowedCnt;
4820 }
4821 }
4822 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4823 diag::err_omp_unnamed_if_clause)
4824 << (TotalAllowedNum > 1) << Values;
4825 }
4826 for (SourceLocation Loc : NameModifierLoc) {
4827 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4828 }
4829 ErrorFound = true;
4830 }
4831 return ErrorFound;
4832}
4833
4834static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4835 SourceLocation &ELoc,
4836 SourceRange &ERange,
4837 bool AllowArraySection) {
4838 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4839 RefExpr->containsUnexpandedParameterPack())
4840 return std::make_pair(nullptr, true);
4841
4842 // OpenMP [3.1, C/C++]
4843 // A list item is a variable name.
4844 // OpenMP [2.9.3.3, Restrictions, p.1]
4845 // A variable that is part of another variable (as an array or
4846 // structure element) cannot appear in a private clause.
4847 RefExpr = RefExpr->IgnoreParens();
4848 enum {
4849 NoArrayExpr = -1,
4850 ArraySubscript = 0,
4851 OMPArraySection = 1
4852 } IsArrayExpr = NoArrayExpr;
4853 if (AllowArraySection) {
4854 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4855 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4856 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4857 Base = TempASE->getBase()->IgnoreParenImpCasts();
4858 RefExpr = Base;
4859 IsArrayExpr = ArraySubscript;
4860 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4861 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4862 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4863 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4864 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4865 Base = TempASE->getBase()->IgnoreParenImpCasts();
4866 RefExpr = Base;
4867 IsArrayExpr = OMPArraySection;
4868 }
4869 }
4870 ELoc = RefExpr->getExprLoc();
4871 ERange = RefExpr->getSourceRange();
4872 RefExpr = RefExpr->IgnoreParenImpCasts();
4873 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4874 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4875 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4876 (S.getCurrentThisType().isNull() || !ME ||
4877 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4878 !isa<FieldDecl>(ME->getMemberDecl()))) {
4879 if (IsArrayExpr != NoArrayExpr) {
4880 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4881 << ERange;
4882 } else {
4883 S.Diag(ELoc,
4884 AllowArraySection
4885 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4886 : diag::err_omp_expected_var_name_member_expr)
4887 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4888 }
4889 return std::make_pair(nullptr, false);
4890 }
4891 return std::make_pair(
4892 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4893}
4894
4895namespace {
4896/// Checks if the allocator is used in uses_allocators clause to be allowed in
4897/// target regions.
4898class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4899 DSAStackTy *S = nullptr;
4900
4901public:
4902 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4903 return S->isUsesAllocatorsDecl(E->getDecl())
4904 .getValueOr(
4905 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4906 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4907 }
4908 bool VisitStmt(const Stmt *S) {
4909 for (const Stmt *Child : S->children()) {
4910 if (Child && Visit(Child))
4911 return true;
4912 }
4913 return false;
4914 }
4915 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4916};
4917} // namespace
4918
4919static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4920 ArrayRef<OMPClause *> Clauses) {
4921 assert(!S.CurContext->isDependentContext() &&((!S.CurContext->isDependentContext() && "Expected non-dependent context."
) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4922, __PRETTY_FUNCTION__))
4922 "Expected non-dependent context.")((!S.CurContext->isDependentContext() && "Expected non-dependent context."
) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4922, __PRETTY_FUNCTION__))
;
4923 auto AllocateRange =
4924 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4925 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4926 DeclToCopy;
4927 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4928 return isOpenMPPrivate(C->getClauseKind());
4929 });
4930 for (OMPClause *Cl : PrivateRange) {
4931 MutableArrayRef<Expr *>::iterator I, It, Et;
4932 if (Cl->getClauseKind() == OMPC_private) {
4933 auto *PC = cast<OMPPrivateClause>(Cl);
4934 I = PC->private_copies().begin();
4935 It = PC->varlist_begin();
4936 Et = PC->varlist_end();
4937 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4938 auto *PC = cast<OMPFirstprivateClause>(Cl);
4939 I = PC->private_copies().begin();
4940 It = PC->varlist_begin();
4941 Et = PC->varlist_end();
4942 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4943 auto *PC = cast<OMPLastprivateClause>(Cl);
4944 I = PC->private_copies().begin();
4945 It = PC->varlist_begin();
4946 Et = PC->varlist_end();
4947 } else if (Cl->getClauseKind() == OMPC_linear) {
4948 auto *PC = cast<OMPLinearClause>(Cl);
4949 I = PC->privates().begin();
4950 It = PC->varlist_begin();
4951 Et = PC->varlist_end();
4952 } else if (Cl->getClauseKind() == OMPC_reduction) {
4953 auto *PC = cast<OMPReductionClause>(Cl);
4954 I = PC->privates().begin();
4955 It = PC->varlist_begin();
4956 Et = PC->varlist_end();
4957 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4958 auto *PC = cast<OMPTaskReductionClause>(Cl);
4959 I = PC->privates().begin();
4960 It = PC->varlist_begin();
4961 Et = PC->varlist_end();
4962 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4963 auto *PC = cast<OMPInReductionClause>(Cl);
4964 I = PC->privates().begin();
4965 It = PC->varlist_begin();
4966 Et = PC->varlist_end();
4967 } else {
4968 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 4968)
;
4969 }
4970 for (Expr *E : llvm::make_range(It, Et)) {
4971 if (!*I) {
4972 ++I;
4973 continue;
4974 }
4975 SourceLocation ELoc;
4976 SourceRange ERange;
4977 Expr *SimpleRefExpr = E;
4978 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4979 /*AllowArraySection=*/true);
4980 DeclToCopy.try_emplace(Res.first,
4981 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4982 ++I;
4983 }
4984 }
4985 for (OMPClause *C : AllocateRange) {
4986 auto *AC = cast<OMPAllocateClause>(C);
4987 if (S.getLangOpts().OpenMP >= 50 &&
4988 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4989 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4990 AC->getAllocator()) {
4991 Expr *Allocator = AC->getAllocator();
4992 // OpenMP, 2.12.5 target Construct
4993 // Memory allocators that do not appear in a uses_allocators clause cannot
4994 // appear as an allocator in an allocate clause or be used in the target
4995 // region unless a requires directive with the dynamic_allocators clause
4996 // is present in the same compilation unit.
4997 AllocatorChecker Checker(Stack);
4998 if (Checker.Visit(Allocator))
4999 S.Diag(Allocator->getExprLoc(),
5000 diag::err_omp_allocator_not_in_uses_allocators)
5001 << Allocator->getSourceRange();
5002 }
5003 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5004 getAllocatorKind(S, Stack, AC->getAllocator());
5005 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5006 // For task, taskloop or target directives, allocation requests to memory
5007 // allocators with the trait access set to thread result in unspecified
5008 // behavior.
5009 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5010 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5011 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5012 S.Diag(AC->getAllocator()->getExprLoc(),
5013 diag::warn_omp_allocate_thread_on_task_target_directive)
5014 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5015 }
5016 for (Expr *E : AC->varlists()) {
5017 SourceLocation ELoc;
5018 SourceRange ERange;
5019 Expr *SimpleRefExpr = E;
5020 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5021 ValueDecl *VD = Res.first;
5022 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5023 if (!isOpenMPPrivate(Data.CKind)) {
5024 S.Diag(E->getExprLoc(),
5025 diag::err_omp_expected_private_copy_for_allocate);
5026 continue;
5027 }
5028 VarDecl *PrivateVD = DeclToCopy[VD];
5029 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5030 AllocatorKind, AC->getAllocator()))
5031 continue;
5032 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5033 E->getSourceRange());
5034 }
5035 }
5036}
5037
5038StmtResult Sema::ActOnOpenMPExecutableDirective(
5039 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5040 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5041 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5042 StmtResult Res = StmtError();
5043 // First check CancelRegion which is then used in checkNestingOfRegions.
5044 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5045 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
5046 StartLoc))
5047 return StmtError();
5048
5049 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5050 VarsWithInheritedDSAType VarsWithInheritedDSA;
5051 bool ErrorFound = false;
5052 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5053 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5054 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5055 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5055, __PRETTY_FUNCTION__))
;
5056
5057 // Check default data sharing attributes for referenced variables.
5058 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
5059 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5060 Stmt *S = AStmt;
5061 while (--ThisCaptureLevel >= 0)
5062 S = cast<CapturedStmt>(S)->getCapturedStmt();
5063 DSAChecker.Visit(S);
5064 if (!isOpenMPTargetDataManagementDirective(Kind) &&
5065 !isOpenMPTaskingDirective(Kind)) {
5066 // Visit subcaptures to generate implicit clauses for captured vars.
5067 auto *CS = cast<CapturedStmt>(AStmt);
5068 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5069 getOpenMPCaptureRegions(CaptureRegions, Kind);
5070 // Ignore outer tasking regions for target directives.
5071 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5072 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5073 DSAChecker.visitSubCaptures(CS);
5074 }
5075 if (DSAChecker.isErrorFound())
5076 return StmtError();
5077 // Generate list of implicitly defined firstprivate variables.
5078 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5079
5080 SmallVector<Expr *, 4> ImplicitFirstprivates(
5081 DSAChecker.getImplicitFirstprivate().begin(),
5082 DSAChecker.getImplicitFirstprivate().end());
5083 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5084 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5085 ArrayRef<Expr *> ImplicitMap =
5086 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5087 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5088 }
5089 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5090 for (OMPClause *C : Clauses) {
5091 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5092 for (Expr *E : IRC->taskgroup_descriptors())
5093 if (E)
5094 ImplicitFirstprivates.emplace_back(E);
5095 }
5096 // OpenMP 5.0, 2.10.1 task Construct
5097 // [detach clause]... The event-handle will be considered as if it was
5098 // specified on a firstprivate clause.
5099 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5100 ImplicitFirstprivates.push_back(DC->getEventHandler());
5101 }
5102 if (!ImplicitFirstprivates.empty()) {
5103 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5104 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5105 SourceLocation())) {
5106 ClausesWithImplicit.push_back(Implicit);
5107 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5108 ImplicitFirstprivates.size();
5109 } else {
5110 ErrorFound = true;
5111 }
5112 }
5113 int ClauseKindCnt = -1;
5114 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5115 ++ClauseKindCnt;
5116 if (ImplicitMap.empty())
5117 continue;
5118 CXXScopeSpec MapperIdScopeSpec;
5119 DeclarationNameInfo MapperId;
5120 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5121 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5122 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5123 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5124 ImplicitMap, OMPVarListLocTy())) {
5125 ClausesWithImplicit.emplace_back(Implicit);
5126 ErrorFound |=
5127 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5128 } else {
5129 ErrorFound = true;
5130 }
5131 }
5132 }
5133
5134 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5135 switch (Kind) {
5136 case OMPD_parallel:
5137 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5138 EndLoc);
5139 AllowedNameModifiers.push_back(OMPD_parallel);
5140 break;
5141 case OMPD_simd:
5142 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5143 VarsWithInheritedDSA);
5144 if (LangOpts.OpenMP >= 50)
5145 AllowedNameModifiers.push_back(OMPD_simd);
5146 break;
5147 case OMPD_for:
5148 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5149 VarsWithInheritedDSA);
5150 break;
5151 case OMPD_for_simd:
5152 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5153 EndLoc, VarsWithInheritedDSA);
5154 if (LangOpts.OpenMP >= 50)
5155 AllowedNameModifiers.push_back(OMPD_simd);
5156 break;
5157 case OMPD_sections:
5158 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5159 EndLoc);
5160 break;
5161 case OMPD_section:
5162 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5163, __PRETTY_FUNCTION__))
5163 "No clauses are allowed for 'omp section' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5163, __PRETTY_FUNCTION__))
;
5164 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5165 break;
5166 case OMPD_single:
5167 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5168 EndLoc);
5169 break;
5170 case OMPD_master:
5171 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5172, __PRETTY_FUNCTION__))
5172 "No clauses are allowed for 'omp master' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5172, __PRETTY_FUNCTION__))
;
5173 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5174 break;
5175 case OMPD_critical:
5176 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5177 StartLoc, EndLoc);
5178 break;
5179 case OMPD_parallel_for:
5180 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5181 EndLoc, VarsWithInheritedDSA);
5182 AllowedNameModifiers.push_back(OMPD_parallel);
5183 break;
5184 case OMPD_parallel_for_simd:
5185 Res = ActOnOpenMPParallelForSimdDirective(
5186 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5187 AllowedNameModifiers.push_back(OMPD_parallel);
5188 if (LangOpts.OpenMP >= 50)
5189 AllowedNameModifiers.push_back(OMPD_simd);
5190 break;
5191 case OMPD_parallel_master:
5192 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5193 StartLoc, EndLoc);
5194 AllowedNameModifiers.push_back(OMPD_parallel);
5195 break;
5196 case OMPD_parallel_sections:
5197 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5198 StartLoc, EndLoc);
5199 AllowedNameModifiers.push_back(OMPD_parallel);
5200 break;
5201 case OMPD_task:
5202 Res =
5203 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5204 AllowedNameModifiers.push_back(OMPD_task);
5205 break;
5206 case OMPD_taskyield:
5207 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5208, __PRETTY_FUNCTION__))
5208 "No clauses are allowed for 'omp taskyield' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5208, __PRETTY_FUNCTION__))
;
5209 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5210, __PRETTY_FUNCTION__))
5210 "No associated statement allowed for 'omp taskyield' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5210, __PRETTY_FUNCTION__))
;
5211 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5212 break;
5213 case OMPD_barrier:
5214 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5215, __PRETTY_FUNCTION__))
5215 "No clauses are allowed for 'omp barrier' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5215, __PRETTY_FUNCTION__))
;
5216 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5217, __PRETTY_FUNCTION__))
5217 "No associated statement allowed for 'omp barrier' directive")((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5217, __PRETTY_FUNCTION__))
;
5218 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5219 break;
5220 case OMPD_taskwait:
5221 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5222, __PRETTY_FUNCTION__))
5222 "No clauses are allowed for 'omp taskwait' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5222, __PRETTY_FUNCTION__))
;
5223 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __PRETTY_FUNCTION__))
5224 "No associated statement allowed for 'omp taskwait' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __PRETTY_FUNCTION__))
;
5225 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5226 break;
5227 case OMPD_taskgroup:
5228 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5229 EndLoc);
5230 break;
5231 case OMPD_flush:
5232 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5233, __PRETTY_FUNCTION__))
5233 "No associated statement allowed for 'omp flush' directive")((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5233, __PRETTY_FUNCTION__))
;
5234 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5235 break;
5236 case OMPD_depobj:
5237 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5238, __PRETTY_FUNCTION__))
5238 "No associated statement allowed for 'omp depobj' directive")((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5238, __PRETTY_FUNCTION__))
;
5239 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5240 break;
5241 case OMPD_scan:
5242 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5243, __PRETTY_FUNCTION__))
5243 "No associated statement allowed for 'omp scan' directive")((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5243, __PRETTY_FUNCTION__))
;
5244 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5245 break;
5246 case OMPD_ordered:
5247 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5248 EndLoc);
5249 break;
5250 case OMPD_atomic:
5251 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5252 EndLoc);
5253 break;
5254 case OMPD_teams:
5255 Res =
5256 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5257 break;
5258 case OMPD_target:
5259 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5260 EndLoc);
5261 AllowedNameModifiers.push_back(OMPD_target);
5262 break;
5263 case OMPD_target_parallel:
5264 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5265 StartLoc, EndLoc);
5266 AllowedNameModifiers.push_back(OMPD_target);
5267 AllowedNameModifiers.push_back(OMPD_parallel);
5268 break;
5269 case OMPD_target_parallel_for:
5270 Res = ActOnOpenMPTargetParallelForDirective(
5271 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5272 AllowedNameModifiers.push_back(OMPD_target);
5273 AllowedNameModifiers.push_back(OMPD_parallel);
5274 break;
5275 case OMPD_cancellation_point:
5276 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5277, __PRETTY_FUNCTION__))
5277 "No clauses are allowed for 'omp cancellation point' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5277, __PRETTY_FUNCTION__))
;
5278 assert(AStmt == nullptr && "No associated statement allowed for 'omp "((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5279, __PRETTY_FUNCTION__))
5279 "cancellation point' directive")((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5279, __PRETTY_FUNCTION__))
;
5280 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5281 break;
5282 case OMPD_cancel:
5283 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5284, __PRETTY_FUNCTION__))
5284 "No associated statement allowed for 'omp cancel' directive")((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5284, __PRETTY_FUNCTION__))
;
5285 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5286 CancelRegion);
5287 AllowedNameModifiers.push_back(OMPD_cancel);
5288 break;
5289 case OMPD_target_data:
5290 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5291 EndLoc);
5292 AllowedNameModifiers.push_back(OMPD_target_data);
5293 break;
5294 case OMPD_target_enter_data:
5295 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5296 EndLoc, AStmt);
5297 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5298 break;
5299 case OMPD_target_exit_data:
5300 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5301 EndLoc, AStmt);
5302 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5303 break;
5304 case OMPD_taskloop:
5305 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5306 EndLoc, VarsWithInheritedDSA);
5307 AllowedNameModifiers.push_back(OMPD_taskloop);
5308 break;
5309 case OMPD_taskloop_simd:
5310 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5311 EndLoc, VarsWithInheritedDSA);
5312 AllowedNameModifiers.push_back(OMPD_taskloop);
5313 if (LangOpts.OpenMP >= 50)
5314 AllowedNameModifiers.push_back(OMPD_simd);
5315 break;
5316 case OMPD_master_taskloop:
5317 Res = ActOnOpenMPMasterTaskLoopDirective(
5318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5319 AllowedNameModifiers.push_back(OMPD_taskloop);
5320 break;
5321 case OMPD_master_taskloop_simd:
5322 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5323 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5324 AllowedNameModifiers.push_back(OMPD_taskloop);
5325 if (LangOpts.OpenMP >= 50)
5326 AllowedNameModifiers.push_back(OMPD_simd);
5327 break;
5328 case OMPD_parallel_master_taskloop:
5329 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5330 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5331 AllowedNameModifiers.push_back(OMPD_taskloop);
5332 AllowedNameModifiers.push_back(OMPD_parallel);
5333 break;
5334 case OMPD_parallel_master_taskloop_simd:
5335 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5336 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5337 AllowedNameModifiers.push_back(OMPD_taskloop);
5338 AllowedNameModifiers.push_back(OMPD_parallel);
5339 if (LangOpts.OpenMP >= 50)
5340 AllowedNameModifiers.push_back(OMPD_simd);
5341 break;
5342 case OMPD_distribute:
5343 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5344 EndLoc, VarsWithInheritedDSA);
5345 break;
5346 case OMPD_target_update:
5347 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5348 EndLoc, AStmt);
5349 AllowedNameModifiers.push_back(OMPD_target_update);
5350 break;
5351 case OMPD_distribute_parallel_for:
5352 Res = ActOnOpenMPDistributeParallelForDirective(
5353 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5354 AllowedNameModifiers.push_back(OMPD_parallel);
5355 break;
5356 case OMPD_distribute_parallel_for_simd:
5357 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5358 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5359 AllowedNameModifiers.push_back(OMPD_parallel);
5360 if (LangOpts.OpenMP >= 50)
5361 AllowedNameModifiers.push_back(OMPD_simd);
5362 break;
5363 case OMPD_distribute_simd:
5364 Res = ActOnOpenMPDistributeSimdDirective(
5365 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5366 if (LangOpts.OpenMP >= 50)
5367 AllowedNameModifiers.push_back(OMPD_simd);
5368 break;
5369 case OMPD_target_parallel_for_simd:
5370 Res = ActOnOpenMPTargetParallelForSimdDirective(
5371 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5372 AllowedNameModifiers.push_back(OMPD_target);
5373 AllowedNameModifiers.push_back(OMPD_parallel);
5374 if (LangOpts.OpenMP >= 50)
5375 AllowedNameModifiers.push_back(OMPD_simd);
5376 break;
5377 case OMPD_target_simd:
5378 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5379 EndLoc, VarsWithInheritedDSA);
5380 AllowedNameModifiers.push_back(OMPD_target);
5381 if (LangOpts.OpenMP >= 50)
5382 AllowedNameModifiers.push_back(OMPD_simd);
5383 break;
5384 case OMPD_teams_distribute:
5385 Res = ActOnOpenMPTeamsDistributeDirective(
5386 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5387 break;
5388 case OMPD_teams_distribute_simd:
5389 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5390 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5391 if (LangOpts.OpenMP >= 50)
5392 AllowedNameModifiers.push_back(OMPD_simd);
5393 break;
5394 case OMPD_teams_distribute_parallel_for_simd:
5395 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5396 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5397 AllowedNameModifiers.push_back(OMPD_parallel);
5398 if (LangOpts.OpenMP >= 50)
5399 AllowedNameModifiers.push_back(OMPD_simd);
5400 break;
5401 case OMPD_teams_distribute_parallel_for:
5402 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5403 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5404 AllowedNameModifiers.push_back(OMPD_parallel);
5405 break;
5406 case OMPD_target_teams:
5407 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5408 EndLoc);
5409 AllowedNameModifiers.push_back(OMPD_target);
5410 break;
5411 case OMPD_target_teams_distribute:
5412 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5413 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5414 AllowedNameModifiers.push_back(OMPD_target);
5415 break;
5416 case OMPD_target_teams_distribute_parallel_for:
5417 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5418 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5419 AllowedNameModifiers.push_back(OMPD_target);
5420 AllowedNameModifiers.push_back(OMPD_parallel);
5421 break;
5422 case OMPD_target_teams_distribute_parallel_for_simd:
5423 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5424 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5425 AllowedNameModifiers.push_back(OMPD_target);
5426 AllowedNameModifiers.push_back(OMPD_parallel);
5427 if (LangOpts.OpenMP >= 50)
5428 AllowedNameModifiers.push_back(OMPD_simd);
5429 break;
5430 case OMPD_target_teams_distribute_simd:
5431 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5432 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5433 AllowedNameModifiers.push_back(OMPD_target);
5434 if (LangOpts.OpenMP >= 50)
5435 AllowedNameModifiers.push_back(OMPD_simd);
5436 break;
5437 case OMPD_declare_target:
5438 case OMPD_end_declare_target:
5439 case OMPD_threadprivate:
5440 case OMPD_allocate:
5441 case OMPD_declare_reduction:
5442 case OMPD_declare_mapper:
5443 case OMPD_declare_simd:
5444 case OMPD_requires:
5445 case OMPD_declare_variant:
5446 case OMPD_begin_declare_variant:
5447 case OMPD_end_declare_variant:
5448 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5448)
;
5449 case OMPD_unknown:
5450 default:
5451 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5451)
;
5452 }
5453
5454 ErrorFound = Res.isInvalid() || ErrorFound;
5455
5456 // Check variables in the clauses if default(none) or
5457 // default(firstprivate) was specified.
5458 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5459 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5460 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5461 for (OMPClause *C : Clauses) {
5462 switch (C->getClauseKind()) {
5463 case OMPC_num_threads:
5464 case OMPC_dist_schedule:
5465 // Do not analyse if no parent teams directive.
5466 if (isOpenMPTeamsDirective(Kind))
5467 break;
5468 continue;
5469 case OMPC_if:
5470 if (isOpenMPTeamsDirective(Kind) &&
5471 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5472 break;
5473 if (isOpenMPParallelDirective(Kind) &&
5474 isOpenMPTaskLoopDirective(Kind) &&
5475 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5476 break;
5477 continue;
5478 case OMPC_schedule:
5479 case OMPC_detach:
5480 break;
5481 case OMPC_grainsize:
5482 case OMPC_num_tasks:
5483 case OMPC_final:
5484 case OMPC_priority:
5485 // Do not analyze if no parent parallel directive.
5486 if (isOpenMPParallelDirective(Kind))
5487 break;
5488 continue;
5489 case OMPC_ordered:
5490 case OMPC_device:
5491 case OMPC_num_teams:
5492 case OMPC_thread_limit:
5493 case OMPC_hint:
5494 case OMPC_collapse:
5495 case OMPC_safelen:
5496 case OMPC_simdlen:
5497 case OMPC_default:
5498 case OMPC_proc_bind:
5499 case OMPC_private:
5500 case OMPC_firstprivate:
5501 case OMPC_lastprivate:
5502 case OMPC_shared:
5503 case OMPC_reduction:
5504 case OMPC_task_reduction:
5505 case OMPC_in_reduction:
5506 case OMPC_linear:
5507 case OMPC_aligned:
5508 case OMPC_copyin:
5509 case OMPC_copyprivate:
5510 case OMPC_nowait:
5511 case OMPC_untied:
5512 case OMPC_mergeable:
5513 case OMPC_allocate:
5514 case OMPC_read:
5515 case OMPC_write:
5516 case OMPC_update:
5517 case OMPC_capture:
5518 case OMPC_seq_cst:
5519 case OMPC_acq_rel:
5520 case OMPC_acquire:
5521 case OMPC_release:
5522 case OMPC_relaxed:
5523 case OMPC_depend:
5524 case OMPC_threads:
5525 case OMPC_simd:
5526 case OMPC_map:
5527 case OMPC_nogroup:
5528 case OMPC_defaultmap:
5529 case OMPC_to:
5530 case OMPC_from:
5531 case OMPC_use_device_ptr:
5532 case OMPC_use_device_addr:
5533 case OMPC_is_device_ptr:
5534 case OMPC_nontemporal:
5535 case OMPC_order:
5536 case OMPC_destroy:
5537 case OMPC_inclusive:
5538 case OMPC_exclusive:
5539 case OMPC_uses_allocators:
5540 case OMPC_affinity:
5541 continue;
5542 case OMPC_allocator:
5543 case OMPC_flush:
5544 case OMPC_depobj:
5545 case OMPC_threadprivate:
5546 case OMPC_uniform:
5547 case OMPC_unknown:
5548 case OMPC_unified_address:
5549 case OMPC_unified_shared_memory:
5550 case OMPC_reverse_offload:
5551 case OMPC_dynamic_allocators:
5552 case OMPC_atomic_default_mem_order:
5553 case OMPC_device_type:
5554 case OMPC_match:
5555 default:
5556 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5556)
;
5557 }
5558 for (Stmt *CC : C->children()) {
5559 if (CC)
5560 DSAChecker.Visit(CC);
5561 }
5562 }
5563 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5564 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5565 }
5566 for (const auto &P : VarsWithInheritedDSA) {
5567 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5568 continue;
5569 ErrorFound = true;
5570 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5571 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5572 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5573 << P.first << P.second->getSourceRange();
5574 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5575 } else if (getLangOpts().OpenMP >= 50) {
5576 Diag(P.second->getExprLoc(),
5577 diag::err_omp_defaultmap_no_attr_for_variable)
5578 << P.first << P.second->getSourceRange();
5579 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5580 diag::note_omp_defaultmap_attr_none);
5581 }
5582 }
5583
5584 if (!AllowedNameModifiers.empty())
5585 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5586 ErrorFound;
5587
5588 if (ErrorFound)
5589 return StmtError();
5590
5591 if (!CurContext->isDependentContext() &&
5592 isOpenMPTargetExecutionDirective(Kind) &&
5593 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5594 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5595 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5596 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5597 // Register target to DSA Stack.
5598 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5599 }
5600
5601 return Res;
5602}
5603
5604Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5605 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5606 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5607 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5608 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5609 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5609, __PRETTY_FUNCTION__))
;
5610 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5610, __PRETTY_FUNCTION__))
;
5611 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5611, __PRETTY_FUNCTION__))
;
5612 if (!DG || DG.get().isNull())
5613 return DeclGroupPtrTy();
5614
5615 const int SimdId = 0;
5616 if (!DG.get().isSingleDecl()) {
5617 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5618 << SimdId;
5619 return DG;
5620 }
5621 Decl *ADecl = DG.get().getSingleDecl();
5622 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5623 ADecl = FTD->getTemplatedDecl();
5624
5625 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5626 if (!FD) {
5627 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5628 return DeclGroupPtrTy();
5629 }
5630
5631 // OpenMP [2.8.2, declare simd construct, Description]
5632 // The parameter of the simdlen clause must be a constant positive integer
5633 // expression.
5634 ExprResult SL;
5635 if (Simdlen)
5636 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5637 // OpenMP [2.8.2, declare simd construct, Description]
5638 // The special this pointer can be used as if was one of the arguments to the
5639 // function in any of the linear, aligned, or uniform clauses.
5640 // The uniform clause declares one or more arguments to have an invariant
5641 // value for all concurrent invocations of the function in the execution of a
5642 // single SIMD loop.
5643 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5644 const Expr *UniformedLinearThis = nullptr;
5645 for (const Expr *E : Uniforms) {
5646 E = E->IgnoreParenImpCasts();
5647 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5648 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5649 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5650 FD->getParamDecl(PVD->getFunctionScopeIndex())
5651 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5652 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5653 continue;
5654 }
5655 if (isa<CXXThisExpr>(E)) {
5656 UniformedLinearThis = E;
5657 continue;
5658 }
5659 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5660 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5661 }
5662 // OpenMP [2.8.2, declare simd construct, Description]
5663 // The aligned clause declares that the object to which each list item points
5664 // is aligned to the number of bytes expressed in the optional parameter of
5665 // the aligned clause.
5666 // The special this pointer can be used as if was one of the arguments to the
5667 // function in any of the linear, aligned, or uniform clauses.
5668 // The type of list items appearing in the aligned clause must be array,
5669 // pointer, reference to array, or reference to pointer.
5670 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5671 const Expr *AlignedThis = nullptr;
5672 for (const Expr *E : Aligneds) {
5673 E = E->IgnoreParenImpCasts();
5674 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5675 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5676 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5677 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5678 FD->getParamDecl(PVD->getFunctionScopeIndex())
5679 ->getCanonicalDecl() == CanonPVD) {
5680 // OpenMP [2.8.1, simd construct, Restrictions]
5681 // A list-item cannot appear in more than one aligned clause.
5682 if (AlignedArgs.count(CanonPVD) > 0) {
5683 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5684 << 1 << getOpenMPClauseName(OMPC_aligned)
5685 << E->getSourceRange();
5686 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5687 diag::note_omp_explicit_dsa)
5688 << getOpenMPClauseName(OMPC_aligned);
5689 continue;
5690 }
5691 AlignedArgs[CanonPVD] = E;
5692 QualType QTy = PVD->getType()
5693 .getNonReferenceType()
5694 .getUnqualifiedType()
5695 .getCanonicalType();
5696 const Type *Ty = QTy.getTypePtrOrNull();
5697 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5698 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5699 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5700 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5701 }
5702 continue;
5703 }
5704 }
5705 if (isa<CXXThisExpr>(E)) {
5706 if (AlignedThis) {
5707 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5708 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5709 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5710 << getOpenMPClauseName(OMPC_aligned);
5711 }
5712 AlignedThis = E;
5713 continue;
5714 }
5715 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5716 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5717 }
5718 // The optional parameter of the aligned clause, alignment, must be a constant
5719 // positive integer expression. If no optional parameter is specified,
5720 // implementation-defined default alignments for SIMD instructions on the
5721 // target platforms are assumed.
5722 SmallVector<const Expr *, 4> NewAligns;
5723 for (Expr *E : Alignments) {
5724 ExprResult Align;
5725 if (E)
5726 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5727 NewAligns.push_back(Align.get());
5728 }
5729 // OpenMP [2.8.2, declare simd construct, Description]
5730 // The linear clause declares one or more list items to be private to a SIMD
5731 // lane and to have a linear relationship with respect to the iteration space
5732 // of a loop.
5733 // The special this pointer can be used as if was one of the arguments to the
5734 // function in any of the linear, aligned, or uniform clauses.
5735 // When a linear-step expression is specified in a linear clause it must be
5736 // either a constant integer expression or an integer-typed parameter that is
5737 // specified in a uniform clause on the directive.
5738 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5739 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5740 auto MI = LinModifiers.begin();
5741 for (const Expr *E : Linears) {
5742 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5743 ++MI;
5744 E = E->IgnoreParenImpCasts();
5745 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5746 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5747 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5748 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5749 FD->getParamDecl(PVD->getFunctionScopeIndex())
5750 ->getCanonicalDecl() == CanonPVD) {
5751 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5752 // A list-item cannot appear in more than one linear clause.
5753 if (LinearArgs.count(CanonPVD) > 0) {
5754 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5755 << getOpenMPClauseName(OMPC_linear)
5756 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5757 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5758 diag::note_omp_explicit_dsa)
5759 << getOpenMPClauseName(OMPC_linear);
5760 continue;
5761 }
5762 // Each argument can appear in at most one uniform or linear clause.
5763 if (UniformedArgs.count(CanonPVD) > 0) {
5764 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5765 << getOpenMPClauseName(OMPC_linear)
5766 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5767 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5768 diag::note_omp_explicit_dsa)
5769 << getOpenMPClauseName(OMPC_uniform);
5770 continue;
5771 }
5772 LinearArgs[CanonPVD] = E;
5773 if (E->isValueDependent() || E->isTypeDependent() ||
5774 E->isInstantiationDependent() ||
5775 E->containsUnexpandedParameterPack())
5776 continue;
5777 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5778 PVD->getOriginalType(),
5779 /*IsDeclareSimd=*/true);
5780 continue;
5781 }
5782 }
5783 if (isa<CXXThisExpr>(E)) {
5784 if (UniformedLinearThis) {
5785 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5786 << getOpenMPClauseName(OMPC_linear)
5787 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5788 << E->getSourceRange();
5789 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5790 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5791 : OMPC_linear);
5792 continue;
5793 }
5794 UniformedLinearThis = E;
5795 if (E->isValueDependent() || E->isTypeDependent() ||
5796 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5797 continue;
5798 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5799 E->getType(), /*IsDeclareSimd=*/true);
5800 continue;
5801 }
5802 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5803 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5804 }
5805 Expr *Step = nullptr;
5806 Expr *NewStep = nullptr;
5807 SmallVector<Expr *, 4> NewSteps;
5808 for (Expr *E : Steps) {
5809 // Skip the same step expression, it was checked already.
5810 if (Step == E || !E) {
5811 NewSteps.push_back(E ? NewStep : nullptr);
5812 continue;
5813 }
5814 Step = E;
5815 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5816 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5817 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5818 if (UniformedArgs.count(CanonPVD) == 0) {
5819 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5820 << Step->getSourceRange();
5821 } else if (E->isValueDependent() || E->isTypeDependent() ||
5822 E->isInstantiationDependent() ||
5823 E->containsUnexpandedParameterPack() ||
5824 CanonPVD->getType()->hasIntegerRepresentation()) {
5825 NewSteps.push_back(Step);
5826 } else {
5827 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5828 << Step->getSourceRange();
5829 }
5830 continue;
5831 }
5832 NewStep = Step;
5833 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5834 !Step->isInstantiationDependent() &&
5835 !Step->containsUnexpandedParameterPack()) {
5836 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5837 .get();
5838 if (NewStep)
5839 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5840 }
5841 NewSteps.push_back(NewStep);
5842 }
5843 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5844 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5845 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5846 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5847 const_cast<Expr **>(Linears.data()), Linears.size(),
5848 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5849 NewSteps.data(), NewSteps.size(), SR);
5850 ADecl->addAttr(NewAttr);
5851 return DG;
5852}
5853
5854static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5855 QualType NewType) {
5856 assert(NewType->isFunctionProtoType() &&((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5857, __PRETTY_FUNCTION__))
5857 "Expected function type with prototype.")((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5857, __PRETTY_FUNCTION__))
;
5858 assert(FD->getType()->isFunctionNoProtoType() &&((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5859, __PRETTY_FUNCTION__))
5859 "Expected function with type with no prototype.")((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5859, __PRETTY_FUNCTION__))
;
5860 assert(FDWithProto->getType()->isFunctionProtoType() &&((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5861, __PRETTY_FUNCTION__))
5861 "Expected function with prototype.")((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 5861, __PRETTY_FUNCTION__))
;
5862 // Synthesize parameters with the same types.
5863 FD->setType(NewType);
5864 SmallVector<ParmVarDecl *, 16> Params;
5865 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5866 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5867 SourceLocation(), nullptr, P->getType(),
5868 /*TInfo=*/nullptr, SC_None, nullptr);
5869 Param->setScopeInfo(0, Params.size());
5870 Param->setImplicit();
5871 Params.push_back(Param);
5872 }
5873
5874 FD->setParams(Params);
5875}
5876
5877Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5878 : TI(&TI), NameSuffix(TI.getMangledName()) {}
5879
5880void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
5881 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
5882 SmallVectorImpl<FunctionDecl *> &Bases) {
5883 if (!D.getIdentifier())
5884 return;
5885
5886 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5887
5888 // Template specialization is an extension, check if we do it.
5889 bool IsTemplated = !TemplateParamLists.empty();
5890 if (IsTemplated &
5891 !DVScope.TI->isExtensionActive(
5892 llvm::omp::TraitProperty::implementation_extension_allow_templates))
5893 return;
5894
5895 IdentifierInfo *BaseII = D.getIdentifier();
5896 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5897 LookupOrdinaryName);
5898 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5899
5900 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5901 QualType FType = TInfo->getType();
5902
5903 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr;
5904 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval;
5905
5906 for (auto *Candidate : Lookup) {
5907 auto *CandidateDecl = Candidate->getUnderlyingDecl();
5908 FunctionDecl *UDecl = nullptr;
5909 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
5910 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
5911 else if (!IsTemplated)
5912 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
5913 if (!UDecl)
5914 continue;
5915
5916 // Don't specialize constexpr/consteval functions with
5917 // non-constexpr/consteval functions.
5918 if (UDecl->isConstexpr() && !IsConstexpr)
5919 continue;
5920 if (UDecl->isConsteval() && !IsConsteval)
5921 continue;
5922
5923 QualType UDeclTy = UDecl->getType();
5924 // TODO: Verify types for templates eventually.
5925 if (!UDeclTy->isDependentType()) {
5926 QualType NewType = Context.mergeFunctionTypes(
5927 FType, UDeclTy, /* OfBlockPointer */ false,
5928 /* Unqualified */ false, /* AllowCXX */ true);
5929 if (NewType.isNull())
5930 continue;
5931 }
5932
5933 // Found a base!
5934 Bases.push_back(UDecl);
5935 }
5936
5937 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
5938 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
5939 // If no base was found we create a declaration that we use as base.
5940 if (Bases.empty() && UseImplicitBase) {
5941 D.setFunctionDefinitionKind(FDK_Declaration);
5942 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
5943 BaseD->setImplicit(true);
5944 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
5945 Bases.push_back(BaseTemplD->getTemplatedDecl());
5946 else
5947 Bases.push_back(cast<FunctionDecl>(BaseD));
5948 }
5949
5950 std::string MangledName;
5951 MangledName += D.getIdentifier()->getName();
5952 MangledName += getOpenMPVariantManglingSeparatorStr();
5953 MangledName += DVScope.NameSuffix;
5954 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5955
5956 VariantII.setMangledOpenMPVariantName(true);
5957 D.SetIdentifier(&VariantII, D.getBeginLoc());
5958}
5959
5960void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5961 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
5962 // Do not mark function as is used to prevent its emission if this is the
5963 // only place where it is used.
5964 EnterExpressionEvaluationContext Unevaluated(
5965 *this, Sema::ExpressionEvaluationContext::Unevaluated);
5966
5967 FunctionDecl *FD = nullptr;
5968 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
5969 FD = UTemplDecl->getTemplatedDecl();
5970 else
5971 FD = cast<FunctionDecl>(D);
5972 auto *VariantFuncRef = DeclRefExpr::Create(
5973 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5974 /* RefersToEnclosingVariableOrCapture */ false,
5975 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5976
5977 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5978 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5979 Context, VariantFuncRef, DVScope.TI);
5980 for (FunctionDecl *BaseFD : Bases)
5981 BaseFD->addAttr(OMPDeclareVariantA);
5982}
5983
5984ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5985 SourceLocation LParenLoc,
5986 MultiExprArg ArgExprs,
5987 SourceLocation RParenLoc, Expr *ExecConfig) {
5988 // The common case is a regular call we do not want to specialize at all. Try
5989 // to make that case fast by bailing early.
5990 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
1
Assuming the object is a 'CallExpr'
5991 if (!CE
1.1
'CE' is non-null
1.1
'CE' is non-null
)
2
Taking false branch
5992 return Call;
5993
5994 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
5995 if (!CalleeFnDecl
2.1
'CalleeFnDecl' is non-null
2.1
'CalleeFnDecl' is non-null
)
3
Taking false branch
5996 return Call;
5997
5998 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
4
Calling 'Decl::hasAttr'
7
Returning from 'Decl::hasAttr'
8
Taking false branch
5999 return Call;
6000
6001 ASTContext &Context = getASTContext();
6002 std::function<void(StringRef)> DiagUnknownTrait = [this,
6003 CE](StringRef ISATrait) {
6004 // TODO Track the selector locations in a way that is accessible here to
6005 // improve the diagnostic location.
6006 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6007 << ISATrait;
6008 };
6009 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6010 getCurFunctionDecl());
6011
6012 SmallVector<Expr *, 4> Exprs;
6013 SmallVector<VariantMatchInfo, 4> VMIs;
6014 while (CalleeFnDecl) {
9
Loop condition is true. Entering loop body
10
Loop condition is false. Execution jumps to the end of the function
6015 for (OMPDeclareVariantAttr *A :
6016 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6017 Expr *VariantRef = A->getVariantFuncRef();
6018
6019 VariantMatchInfo VMI;
6020 OMPTraitInfo &TI = A->getTraitInfo();
6021 TI.getAsVariantMatchInfo(Context, VMI);
6022 if (!isVariantApplicableInContext(VMI, OMPCtx,
6023 /* DeviceSetOnly */ false))
6024 continue;
6025
6026 VMIs.push_back(VMI);
6027 Exprs.push_back(VariantRef);
6028 }
6029
6030 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6031 }
6032
6033 ExprResult NewCall;
6034 do {
6035 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6036 if (BestIdx < 0)
11
Assuming 'BestIdx' is >= 0
12
Taking false branch
6037 return Call;
6038 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
13
The object is a 'DeclRefExpr'
6039 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
14
'BestExpr' is a 'DeclRefExpr'
6040
6041 {
6042 // Try to build a (member) call expression for the current best applicable
6043 // variant expression. We allow this to fail in which case we continue
6044 // with the next best variant expression. The fail case is part of the
6045 // implementation defined behavior in the OpenMP standard when it talks
6046 // about what differences in the function prototypes: "Any differences
6047 // that the specific OpenMP context requires in the prototype of the
6048 // variant from the base function prototype are implementation defined."
6049 // This wording is there to allow the specialized variant to have a
6050 // different type than the base function. This is intended and OK but if
6051 // we cannot create a call the difference is not in the "implementation
6052 // defined range" we allow.
6053 Sema::TentativeAnalysisScope Trap(*this);
6054
6055 if (auto *SpecializedMethod
15.1
'SpecializedMethod' is non-null
15.1
'SpecializedMethod' is non-null
= dyn_cast<CXXMethodDecl>(BestDecl)) {
15
Assuming 'BestDecl' is a 'CXXMethodDecl'
16
Taking true branch
6056 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
17
Assuming 'CE' is not a 'CXXMemberCallExpr'
18
'MemberCall' initialized to a null pointer value
6057 BestExpr = MemberExpr::CreateImplicit(
6058 Context, MemberCall->getImplicitObjectArgument(),
19
Called C++ object pointer is null
6059 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6060 MemberCall->getValueKind(), MemberCall->getObjectKind());
6061 }
6062 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6063 ExecConfig);
6064 if (NewCall.isUsable())
6065 break;
6066 }
6067
6068 VMIs.erase(VMIs.begin() + BestIdx);
6069 Exprs.erase(Exprs.begin() + BestIdx);
6070 } while (!VMIs.empty());
6071
6072 if (!NewCall.isUsable())
6073 return Call;
6074 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6075}
6076
6077Optional<std::pair<FunctionDecl *, Expr *>>
6078Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6079 Expr *VariantRef, OMPTraitInfo &TI,
6080 SourceRange SR) {
6081 if (!DG || DG.get().isNull())
6082 return None;
6083
6084 const int VariantId = 1;
6085 // Must be applied only to single decl.
6086 if (!DG.get().isSingleDecl()) {
6087 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6088 << VariantId << SR;
6089 return None;
6090 }
6091 Decl *ADecl = DG.get().getSingleDecl();
6092 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6093 ADecl = FTD->getTemplatedDecl();
6094
6095 // Decl must be a function.
6096 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6097 if (!FD) {
6098 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6099 << VariantId << SR;
6100 return None;
6101 }
6102
6103 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6104 return FD->hasAttrs() &&
6105 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6106 FD->hasAttr<TargetAttr>());
6107 };
6108 // OpenMP is not compatible with CPU-specific attributes.
6109 if (HasMultiVersionAttributes(FD)) {
6110 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6111 << SR;
6112 return None;
6113 }
6114
6115 // Allow #pragma omp declare variant only if the function is not used.
6116 if (FD->isUsed(false))
6117 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6118 << FD->getLocation();
6119
6120 // Check if the function was emitted already.
6121 const FunctionDecl *Definition;
6122 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6123 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6124 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6125 << FD->getLocation();
6126
6127 // The VariantRef must point to function.
6128 if (!VariantRef) {
6129 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6130 return None;
6131 }
6132
6133 auto ShouldDelayChecks = [](Expr *&E, bool) {
6134 return E && (E->isTypeDependent() || E->isValueDependent() ||
6135 E->containsUnexpandedParameterPack() ||
6136 E->isInstantiationDependent());
6137 };
6138 // Do not check templates, wait until instantiation.
6139 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6140 TI.anyScoreOrCondition(ShouldDelayChecks))
6141 return std::make_pair(FD, VariantRef);
6142
6143 // Deal with non-constant score and user condition expressions.
6144 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6145 bool IsScore) -> bool {
6146 if (!E || E->isIntegerConstantExpr(Context))
6147 return false;
6148
6149 if (IsScore) {
6150 // We warn on non-constant scores and pretend they were not present.
6151 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6152 << E;
6153 E = nullptr;
6154 } else {
6155 // We could replace a non-constant user condition with "false" but we
6156 // will soon need to handle these anyway for the dynamic version of
6157 // OpenMP context selectors.
6158 Diag(E->getExprLoc(),
6159 diag::err_omp_declare_variant_user_condition_not_constant)
6160 << E;
6161 }
6162 return true;
6163 };
6164 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6165 return None;
6166
6167 // Convert VariantRef expression to the type of the original function to
6168 // resolve possible conflicts.
6169 ExprResult VariantRefCast = VariantRef;
6170 if (LangOpts.CPlusPlus) {
6171 QualType FnPtrType;
6172 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6173 if (Method && !Method->isStatic()) {
6174 const Type *ClassType =
6175 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6176 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6177 ExprResult ER;
6178 {
6179 // Build adrr_of unary op to correctly handle type checks for member
6180 // functions.
6181 Sema::TentativeAnalysisScope Trap(*this);
6182 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6183 VariantRef);
6184 }
6185 if (!ER.isUsable()) {
6186 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6187 << VariantId << VariantRef->getSourceRange();
6188 return None;
6189 }
6190 VariantRef = ER.get();
6191 } else {
6192 FnPtrType = Context.getPointerType(FD->getType());
6193 }
6194 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6195 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6196 ImplicitConversionSequence ICS = TryImplicitConversion(
6197 VariantRef, FnPtrType.getUnqualifiedType(),
6198 /*SuppressUserConversions=*/false, AllowedExplicit::None,
6199 /*InOverloadResolution=*/false,
6200 /*CStyle=*/false,
6201 /*AllowObjCWritebackConversion=*/false);
6202 if (ICS.isFailure()) {
6203 Diag(VariantRef->getExprLoc(),
6204 diag::err_omp_declare_variant_incompat_types)
6205 << VariantRef->getType()
6206 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6207 << VariantRef->getSourceRange();
6208 return None;
6209 }
6210 VariantRefCast = PerformImplicitConversion(
6211 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6212 if (!VariantRefCast.isUsable())
6213 return None;
6214 }
6215 // Drop previously built artificial addr_of unary op for member functions.
6216 if (Method && !Method->isStatic()) {
6217 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6218 if (auto *UO = dyn_cast<UnaryOperator>(
6219 PossibleAddrOfVariantRef->IgnoreImplicit()))
6220 VariantRefCast = UO->getSubExpr();
6221 }
6222 }
6223
6224 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6225 if (!ER.isUsable() ||
6226 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6227 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6228 << VariantId << VariantRef->getSourceRange();
6229 return None;
6230 }
6231
6232 // The VariantRef must point to function.
6233 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6234 if (!DRE) {
6235 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6236 << VariantId << VariantRef->getSourceRange();
6237 return None;
6238 }
6239 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6240 if (!NewFD) {
6241 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6242 << VariantId << VariantRef->getSourceRange();
6243 return None;
6244 }
6245
6246 // Check if function types are compatible in C.
6247 if (!LangOpts.CPlusPlus) {
6248 QualType NewType =
6249 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6250 if (NewType.isNull()) {
6251 Diag(VariantRef->getExprLoc(),
6252 diag::err_omp_declare_variant_incompat_types)
6253 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6254 return None;
6255 }
6256 if (NewType->isFunctionProtoType()) {
6257 if (FD->getType()->isFunctionNoProtoType())
6258 setPrototype(*this, FD, NewFD, NewType);
6259 else if (NewFD->getType()->isFunctionNoProtoType())
6260 setPrototype(*this, NewFD, FD, NewType);
6261 }
6262 }
6263
6264 // Check if variant function is not marked with declare variant directive.
6265 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6266 Diag(VariantRef->getExprLoc(),
6267 diag::warn_omp_declare_variant_marked_as_declare_variant)
6268 << VariantRef->getSourceRange();
6269 SourceRange SR =
6270 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6271 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6272 return None;
6273 }
6274
6275 enum DoesntSupport {
6276 VirtFuncs = 1,
6277 Constructors = 3,
6278 Destructors = 4,
6279 DeletedFuncs = 5,
6280 DefaultedFuncs = 6,
6281 ConstexprFuncs = 7,
6282 ConstevalFuncs = 8,
6283 };
6284 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6285 if (CXXFD->isVirtual()) {
6286 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6287 << VirtFuncs;
6288 return None;
6289 }
6290
6291 if (isa<CXXConstructorDecl>(FD)) {
6292 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6293 << Constructors;
6294 return None;
6295 }
6296
6297 if (isa<CXXDestructorDecl>(FD)) {
6298 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6299 << Destructors;
6300 return None;
6301 }
6302 }
6303
6304 if (FD->isDeleted()) {
6305 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6306 << DeletedFuncs;
6307 return None;
6308 }
6309
6310 if (FD->isDefaulted()) {
6311 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6312 << DefaultedFuncs;
6313 return None;
6314 }
6315
6316 if (FD->isConstexpr()) {
6317 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6318 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6319 return None;
6320 }
6321
6322 // Check general compatibility.
6323 if (areMultiversionVariantFunctionsCompatible(
6324 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6325 PartialDiagnosticAt(SourceLocation(),
6326 PartialDiagnostic::NullDiagnostic()),
6327 PartialDiagnosticAt(
6328 VariantRef->getExprLoc(),
6329 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6330 PartialDiagnosticAt(VariantRef->getExprLoc(),
6331 PDiag(diag::err_omp_declare_variant_diff)
6332 << FD->getLocation()),
6333 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6334 /*CLinkageMayDiffer=*/true))
6335 return None;
6336 return std::make_pair(FD, cast<Expr>(DRE));
6337}
6338
6339void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6340 Expr *VariantRef,
6341 OMPTraitInfo &TI,
6342 SourceRange SR) {
6343 auto *NewAttr =
6344 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6345 FD->addAttr(NewAttr);
6346}
6347
6348StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6349 Stmt *AStmt,
6350 SourceLocation StartLoc,
6351 SourceLocation EndLoc) {
6352 if (!AStmt)
6353 return StmtError();
6354
6355 auto *CS = cast<CapturedStmt>(AStmt);
6356 // 1.2.2 OpenMP Language Terminology
6357 // Structured block - An executable statement with a single entry at the
6358 // top and a single exit at the bottom.
6359 // The point of exit cannot be a branch out of the structured block.
6360 // longjmp() and throw() must not violate the entry/exit criteria.
6361 CS->getCapturedDecl()->setNothrow();
6362
6363 setFunctionHasBranchProtectedScope();
6364
6365 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6366 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
6367 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6368}
6369
6370namespace {
6371/// Iteration space of a single for loop.
6372struct LoopIterationSpace final {
6373 /// True if the condition operator is the strict compare operator (<, > or
6374 /// !=).
6375 bool IsStrictCompare = false;
6376 /// Condition of the loop.
6377 Expr *PreCond = nullptr;
6378 /// This expression calculates the number of iterations in the loop.
6379 /// It is always possible to calculate it before starting the loop.
6380 Expr *NumIterations = nullptr;
6381 /// The loop counter variable.
6382 Expr *CounterVar = nullptr;
6383 /// Private loop counter variable.
6384 Expr *PrivateCounterVar = nullptr;
6385 /// This is initializer for the initial value of #CounterVar.
6386 Expr *CounterInit = nullptr;
6387 /// This is step for the #CounterVar used to generate its update:
6388 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6389 Expr *CounterStep = nullptr;
6390 /// Should step be subtracted?
6391 bool Subtract = false;
6392 /// Source range of the loop init.
6393 SourceRange InitSrcRange;
6394 /// Source range of the loop condition.
6395 SourceRange CondSrcRange;
6396 /// Source range of the loop increment.
6397 SourceRange IncSrcRange;
6398 /// Minimum value that can have the loop control variable. Used to support
6399 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6400 /// since only such variables can be used in non-loop invariant expressions.
6401 Expr *MinValue = nullptr;
6402 /// Maximum value that can have the loop control variable. Used to support
6403 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6404 /// since only such variables can be used in non-loop invariant expressions.
6405 Expr *MaxValue = nullptr;
6406 /// true, if the lower bound depends on the outer loop control var.
6407 bool IsNonRectangularLB = false;
6408 /// true, if the upper bound depends on the outer loop control var.
6409 bool IsNonRectangularUB = false;
6410 /// Index of the loop this loop depends on and forms non-rectangular loop
6411 /// nest.
6412 unsigned LoopDependentIdx = 0;
6413 /// Final condition for the non-rectangular loop nest support. It is used to
6414 /// check that the number of iterations for this particular counter must be
6415 /// finished.
6416 Expr *FinalCondition = nullptr;
6417};
6418
6419/// Helper class for checking canonical form of the OpenMP loops and
6420/// extracting iteration space of each loop in the loop nest, that will be used
6421/// for IR generation.
6422class OpenMPIterationSpaceChecker {
6423 /// Reference to Sema.
6424 Sema &SemaRef;
6425 /// Data-sharing stack.
6426 DSAStackTy &Stack;
6427 /// A location for diagnostics (when there is no some better location).
6428 SourceLocation DefaultLoc;
6429 /// A location for diagnostics (when increment is not compatible).
6430 SourceLocation ConditionLoc;
6431 /// A source location for referring to loop init later.
6432 SourceRange InitSrcRange;
6433 /// A source location for referring to condition later.
6434 SourceRange ConditionSrcRange;
6435 /// A source location for referring to increment later.
6436 SourceRange IncrementSrcRange;
6437 /// Loop variable.
6438 ValueDecl *LCDecl = nullptr;
6439 /// Reference to loop variable.
6440 Expr *LCRef = nullptr;
6441 /// Lower bound (initializer for the var).
6442 Expr *LB = nullptr;
6443 /// Upper bound.
6444 Expr *UB = nullptr;
6445 /// Loop step (increment).
6446 Expr *Step = nullptr;
6447 /// This flag is true when condition is one of:
6448 /// Var < UB
6449 /// Var <= UB
6450 /// UB > Var
6451 /// UB >= Var
6452 /// This will have no value when the condition is !=
6453 llvm::Optional<bool> TestIsLessOp;
6454 /// This flag is true when condition is strict ( < or > ).
6455 bool TestIsStrictOp = false;
6456 /// This flag is true when step is subtracted on each iteration.
6457 bool SubtractStep = false;
6458 /// The outer loop counter this loop depends on (if any).
6459 const ValueDecl *DepDecl = nullptr;
6460 /// Contains number of loop (starts from 1) on which loop counter init
6461 /// expression of this loop depends on.
6462 Optional<unsigned> InitDependOnLC;
6463 /// Contains number of loop (starts from 1) on which loop counter condition
6464 /// expression of this loop depends on.
6465 Optional<unsigned> CondDependOnLC;
6466 /// Checks if the provide statement depends on the loop counter.
6467 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6468 /// Original condition required for checking of the exit condition for
6469 /// non-rectangular loop.
6470 Expr *Condition = nullptr;
6471
6472public:
6473 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6474 SourceLocation DefaultLoc)
6475 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6476 ConditionLoc(DefaultLoc) {}
6477 /// Check init-expr for canonical loop form and save loop counter
6478 /// variable - #Var and its initialization value - #LB.
6479 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6480 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6481 /// for less/greater and for strict/non-strict comparison.
6482 bool checkAndSetCond(Expr *S);
6483 /// Check incr-expr for canonical loop form and return true if it
6484 /// does not conform, otherwise save loop step (#Step).
6485 bool checkAndSetInc(Expr *S);
6486 /// Return the loop counter variable.
6487 ValueDecl *getLoopDecl() const { return LCDecl; }
6488 /// Return the reference expression to loop counter variable.
6489 Expr *getLoopDeclRefExpr() const { return LCRef; }
6490 /// Source range of the loop init.
6491 SourceRange getInitSrcRange() const { return InitSrcRange; }
6492 /// Source range of the loop condition.
6493 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6494 /// Source range of the loop increment.
6495 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6496 /// True if the step should be subtracted.
6497 bool shouldSubtractStep() const { return SubtractStep; }
6498 /// True, if the compare operator is strict (<, > or !=).
6499 bool isStrictTestOp() const { return TestIsStrictOp; }
6500 /// Build the expression to calculate the number of iterations.
6501 Expr *buildNumIterations(
6502 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6503 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6504 /// Build the precondition expression for the loops.
6505 Expr *
6506 buildPreCond(Scope *S, Expr *Cond,
6507 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6508 /// Build reference expression to the counter be used for codegen.
6509 DeclRefExpr *
6510 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6511 DSAStackTy &DSA) const;
6512 /// Build reference expression to the private counter be used for
6513 /// codegen.
6514 Expr *buildPrivateCounterVar() const;
6515 /// Build initialization of the counter be used for codegen.
6516 Expr *buildCounterInit() const;
6517 /// Build step of the counter be used for codegen.
6518 Expr *buildCounterStep() const;
6519 /// Build loop data with counter value for depend clauses in ordered
6520 /// directives.
6521 Expr *
6522 buildOrderedLoopData(Scope *S, Expr *Counter,
6523 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6524 SourceLocation Loc, Expr *Inc = nullptr,
6525 OverloadedOperatorKind OOK = OO_Amp);
6526 /// Builds the minimum value for the loop counter.
6527 std::pair<Expr *, Expr *> buildMinMaxValues(
6528 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6529 /// Builds final condition for the non-rectangular loops.
6530 Expr *buildFinalCondition(Scope *S) const;
6531 /// Return true if any expression is dependent.
6532 bool dependent() const;
6533 /// Returns true if the initializer forms non-rectangular loop.
6534 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6535 /// Returns true if the condition forms non-rectangular loop.
6536 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6537 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6538 unsigned getLoopDependentIdx() const {
6539 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6540 }
6541
6542private:
6543 /// Check the right-hand side of an assignment in the increment
6544 /// expression.
6545 bool checkAndSetIncRHS(Expr *RHS);
6546 /// Helper to set loop counter variable and its initializer.
6547 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6548 bool EmitDiags);
6549 /// Helper to set upper bound.
6550 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6551 SourceRange SR, SourceLocation SL);
6552 /// Helper to set loop increment.
6553 bool setStep(Expr *NewStep, bool Subtract);
6554};
6555
6556bool OpenMPIterationSpaceChecker::dependent() const {
6557 if (!LCDecl) {
6558 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6558, __PRETTY_FUNCTION__))
;
6559 return false;
6560 }
6561 return LCDecl->getType()->isDependentType() ||
6562 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6563 (Step && Step->isValueDependent());
6564}
6565
6566bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6567 Expr *NewLCRefExpr,
6568 Expr *NewLB, bool EmitDiags) {
6569 // State consistency checking to ensure correct usage.
6570 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6571, __PRETTY_FUNCTION__))
6571 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6571, __PRETTY_FUNCTION__))
;
6572 if (!NewLCDecl || !NewLB)
6573 return true;
6574 LCDecl = getCanonicalDecl(NewLCDecl);
6575 LCRef = NewLCRefExpr;
6576 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6577 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6578 if ((Ctor->isCopyOrMoveConstructor() ||
6579 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6580 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6581 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6582 LB = NewLB;
6583 if (EmitDiags)
6584 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6585 return false;
6586}
6587
6588bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6589 llvm::Optional<bool> LessOp,
6590 bool StrictOp, SourceRange SR,
6591 SourceLocation SL) {
6592 // State consistency checking to ensure correct usage.
6593 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6594, __PRETTY_FUNCTION__))
6594 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6594, __PRETTY_FUNCTION__))
;
6595 if (!NewUB)
6596 return true;
6597 UB = NewUB;
6598 if (LessOp)
6599 TestIsLessOp = LessOp;
6600 TestIsStrictOp = StrictOp;
6601 ConditionSrcRange = SR;
6602 ConditionLoc = SL;
6603 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6604 return false;
6605}
6606
6607bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6608 // State consistency checking to ensure correct usage.
6609 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step ==
nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6609, __PRETTY_FUNCTION__))
;
6610 if (!NewStep)
6611 return true;
6612 if (!NewStep->isValueDependent()) {
6613 // Check that the step is integer expression.
6614 SourceLocation StepLoc = NewStep->getBeginLoc();
6615 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6616 StepLoc, getExprAsWritten(NewStep));
6617 if (Val.isInvalid())
6618 return true;
6619 NewStep = Val.get();
6620
6621 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6622 // If test-expr is of form var relational-op b and relational-op is < or
6623 // <= then incr-expr must cause var to increase on each iteration of the
6624 // loop. If test-expr is of form var relational-op b and relational-op is
6625 // > or >= then incr-expr must cause var to decrease on each iteration of
6626 // the loop.
6627 // If test-expr is of form b relational-op var and relational-op is < or
6628 // <= then incr-expr must cause var to decrease on each iteration of the
6629 // loop. If test-expr is of form b relational-op var and relational-op is
6630 // > or >= then incr-expr must cause var to increase on each iteration of
6631 // the loop.
6632 Optional<llvm::APSInt> Result =
6633 NewStep->getIntegerConstantExpr(SemaRef.Context);
6634 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6635 bool IsConstNeg =
6636 Result && Result->isSigned() && (Subtract != Result->isNegative());
6637 bool IsConstPos =
6638 Result && Result->isSigned() && (Subtract == Result->isNegative());
6639 bool IsConstZero = Result && !Result->getBoolValue();
6640
6641 // != with increment is treated as <; != with decrement is treated as >
6642 if (!TestIsLessOp.hasValue())
6643 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6644 if (UB && (IsConstZero ||
6645 (TestIsLessOp.getValue() ?
6646 (IsConstNeg || (IsUnsigned && Subtract)) :
6647 (IsConstPos || (IsUnsigned && !Subtract))))) {
6648 SemaRef.Diag(NewStep->getExprLoc(),
6649 diag::err_omp_loop_incr_not_compatible)
6650 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6651 SemaRef.Diag(ConditionLoc,
6652 diag::note_omp_loop_cond_requres_compatible_incr)
6653 << TestIsLessOp.getValue() << ConditionSrcRange;
6654 return true;
6655 }
6656 if (TestIsLessOp.getValue() == Subtract) {
6657 NewStep =
6658 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6659 .get();
6660 Subtract = !Subtract;
6661 }
6662 }
6663
6664 Step = NewStep;
6665 SubtractStep = Subtract;
6666 return false;
6667}
6668
6669namespace {
6670/// Checker for the non-rectangular loops. Checks if the initializer or
6671/// condition expression references loop counter variable.
6672class LoopCounterRefChecker final
6673 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6674 Sema &SemaRef;
6675 DSAStackTy &Stack;
6676 const ValueDecl *CurLCDecl = nullptr;
6677 const ValueDecl *DepDecl = nullptr;
6678 const ValueDecl *PrevDepDecl = nullptr;
6679 bool IsInitializer = true;
6680 unsigned BaseLoopId = 0;
6681 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6682 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6683 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6684 << (IsInitializer ? 0 : 1);
6685 return false;
6686 }
6687 const auto &&Data = Stack.isLoopControlVariable(VD);
6688 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6689 // The type of the loop iterator on which we depend may not have a random
6690 // access iterator type.
6691 if (Data.first && VD->getType()->isRecordType()) {
6692 SmallString<128> Name;
6693 llvm::raw_svector_ostream OS(Name);
6694 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6695 /*Qualified=*/true);
6696 SemaRef.Diag(E->getExprLoc(),
6697 diag::err_omp_wrong_dependency_iterator_type)
6698 << OS.str();
6699 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6700 return false;
6701 }
6702 if (Data.first &&
6703 (DepDecl || (PrevDepDecl &&
6704 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6705 if (!DepDecl && PrevDepDecl)
6706 DepDecl = PrevDepDecl;
6707 SmallString<128> Name;
6708 llvm::raw_svector_ostream OS(Name);
6709 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6710 /*Qualified=*/true);
6711 SemaRef.Diag(E->getExprLoc(),
6712 diag::err_omp_invariant_or_linear_dependency)
6713 << OS.str();
6714 return false;
6715 }
6716 if (Data.first) {
6717 DepDecl = VD;
6718 BaseLoopId = Data.first;
6719 }
6720 return Data.first;
6721 }
6722
6723public:
6724 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6725 const ValueDecl *VD = E->getDecl();
6726 if (isa<VarDecl>(VD))
6727 return checkDecl(E, VD);
6728 return false;
6729 }
6730 bool VisitMemberExpr(const MemberExpr *E) {
6731 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6732 const ValueDecl *VD = E->getMemberDecl();
6733 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6734 return checkDecl(E, VD);
6735 }
6736 return false;
6737 }
6738 bool VisitStmt(const Stmt *S) {
6739 bool Res = false;
6740 for (const Stmt *Child : S->children())
6741 Res = (Child && Visit(Child)) || Res;
6742 return Res;
6743 }
6744 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6745 const ValueDecl *CurLCDecl, bool IsInitializer,
6746 const ValueDecl *PrevDepDecl = nullptr)
6747 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6748 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6749 unsigned getBaseLoopId() const {
6750 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6750, __PRETTY_FUNCTION__))
;
6751 return BaseLoopId;
6752 }
6753 const ValueDecl *getDepDecl() const {
6754 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 6754, __PRETTY_FUNCTION__))
;
6755 return DepDecl;
6756 }
6757};
6758} // namespace
6759
6760Optional<unsigned>
6761OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6762 bool IsInitializer) {
6763 // Check for the non-rectangular loops.
6764 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6765 DepDecl);
6766 if (LoopStmtChecker.Visit(S)) {
6767 DepDecl = LoopStmtChecker.getDepDecl();
6768 return LoopStmtChecker.getBaseLoopId();
6769 }
6770 return llvm::None;
6771}
6772
6773bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6774 // Check init-expr for canonical loop form and save loop counter
6775 // variable - #Var and its initialization value - #LB.
6776 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6777 // var = lb
6778 // integer-type var = lb
6779 // random-access-iterator-type var = lb
6780 // pointer-type var = lb
6781 //
6782 if (!S) {
6783 if (EmitDiags) {
6784 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6785 }
6786 return true;
6787 }
6788 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6789 if (!ExprTemp->cleanupsHaveSideEffects())
6790 S = ExprTemp->getSubExpr();
6791
6792 InitSrcRange = S->getSourceRange();
6793 if (Expr *E = dyn_cast<Expr>(S))
6794 S = E->IgnoreParens();
6795 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6796 if (BO->getOpcode() == BO_Assign) {
6797 Expr *LHS = BO->getLHS()->IgnoreParens();
6798 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6799 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6800 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6801 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6802 EmitDiags);
6803 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6804 }
6805 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6806 if (ME->isArrow() &&
6807 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6808 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6809 EmitDiags);
6810 }
6811 }
6812 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6813 if (DS->isSingleDecl()) {
6814 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6815 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6816 // Accept non-canonical init form here but emit ext. warning.
6817 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6818 SemaRef.Diag(S->getBeginLoc(),
6819 diag::ext_omp_loop_not_canonical_init)
6820 << S->getSourceRange();
6821 return setLCDeclAndLB(
6822 Var,
6823 buildDeclRefExpr(SemaRef, Var,
6824 Var->getType().getNonReferenceType(),
6825 DS->getBeginLoc()),
6826 Var->getInit(), EmitDiags);
6827 }
6828 }
6829 }
6830 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6831 if (CE->getOperator() == OO_Equal) {
6832 Expr *LHS = CE->getArg(0);
6833 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6834 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6835 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6836 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6837 EmitDiags);
6838 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6839 }
6840 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6841 if (ME->isArrow() &&
6842 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6843 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6844 EmitDiags);
6845 }
6846 }
6847 }
6848
6849 if (dependent() || SemaRef.CurContext->isDependentContext())
6850 return false;
6851 if (EmitDiags) {
6852 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6853 << S->getSourceRange();
6854 }
6855 return true;
6856}
6857
6858/// Ignore parenthesizes, implicit casts, copy constructor and return the
6859/// variable (which may be the loop variable) if possible.
6860static const ValueDecl *getInitLCDecl(const Expr *E) {
6861 if (!E)
6862 return nullptr;
6863 E = getExprAsWritten(E);
6864 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6865 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6866 if ((Ctor->isCopyOrMoveConstructor() ||
6867 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6868 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6869 E = CE->getArg(0)->IgnoreParenImpCasts();
6870 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6871 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6872 return getCanonicalDecl(VD);
6873 }
6874 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6875 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6876 return getCanonicalDecl(ME->getMemberDecl());
6877 return nullptr;
6878}
6879
6880bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6881 // Check test-expr for canonical form, save upper-bound UB, flags for
6882 // less/greater and for strict/non-strict comparison.
6883 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6884 // var relational-op b
6885 // b relational-op var
6886 //
6887 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6888 if (!S) {
6889 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6890 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6891 return true;
6892 }
6893 Condition = S;
6894 S = getExprAsWritten(S);
6895 SourceLocation CondLoc = S->getBeginLoc();
6896 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6897 if (BO->isRelationalOp()) {
6898 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6899 return setUB(BO->getRHS(),
6900 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6901 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6902 BO->getSourceRange(), BO->getOperatorLoc());
6903 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6904 return setUB(BO->getLHS(),
6905 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6906 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6907 BO->getSourceRange(), BO->getOperatorLoc());
6908 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6909 return setUB(
6910 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6911 /*LessOp=*/llvm::None,
6912 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6913 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6914 if (CE->getNumArgs() == 2) {
6915 auto Op = CE->getOperator();
6916 switch (Op) {
6917 case OO_Greater:
6918 case OO_GreaterEqual:
6919 case OO_Less:
6920 case OO_LessEqual:
6921 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6922 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6923 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6924 CE->getOperatorLoc());
6925 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6926 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6927 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6928 CE->getOperatorLoc());
6929 break;
6930 case OO_ExclaimEqual:
6931 if (IneqCondIsCanonical)
6932 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6933 : CE->getArg(0),
6934 /*LessOp=*/llvm::None,
6935 /*StrictOp=*/true, CE->getSourceRange(),
6936 CE->getOperatorLoc());
6937 break;
6938 default:
6939 break;
6940 }
6941 }
6942 }
6943 if (dependent() || SemaRef.CurContext->isDependentContext())
6944 return false;
6945 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6946 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6947 return true;
6948}
6949
6950bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6951 // RHS of canonical loop form increment can be:
6952 // var + incr
6953 // incr + var
6954 // var - incr
6955 //
6956 RHS = RHS->IgnoreParenImpCasts();
6957 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6958 if (BO->isAdditiveOp()) {
6959 bool IsAdd = BO->getOpcode() == BO_Add;
6960 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6961 return setStep(BO->getRHS(), !IsAdd);
6962 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6963 return setStep(BO->getLHS(), /*Subtract=*/false);
6964 }
6965 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6966 bool IsAdd = CE->getOperator() == OO_Plus;
6967 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6968 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6969 return setStep(CE->getArg(1), !IsAdd);
6970 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6971 return setStep(CE->getArg(0), /*Subtract=*/false);
6972 }
6973 }
6974 if (dependent() || SemaRef.CurContext->isDependentContext())
6975 return false;
6976 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6977 << RHS->getSourceRange() << LCDecl;
6978 return true;
6979}
6980
6981bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6982 // Check incr-expr for canonical loop form and return true if it
6983 // does not conform.
6984 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6985 // ++var
6986 // var++
6987 // --var
6988 // var--
6989 // var += incr
6990 // var -= incr
6991 // var = var + incr
6992 // var = incr + var
6993 // var = var - incr
6994 //
6995 if (!S) {
6996 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6997 return true;
6998 }
6999 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7000 if (!ExprTemp->cleanupsHaveSideEffects())
7001 S = ExprTemp->getSubExpr();
7002
7003 IncrementSrcRange = S->getSourceRange();
7004 S = S->IgnoreParens();
7005 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7006 if (UO->isIncrementDecrementOp() &&
7007 getInitLCDecl(UO->getSubExpr()) == LCDecl)
7008 return setStep(SemaRef
7009 .ActOnIntegerConstant(UO->getBeginLoc(),
7010 (UO->isDecrementOp() ? -1 : 1))
7011 .get(),
7012 /*Subtract=*/false);
7013 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7014 switch (BO->getOpcode()) {
7015 case BO_AddAssign:
7016 case BO_SubAssign:
7017 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7018 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7019 break;
7020 case BO_Assign:
7021 if (getInitLCDecl(BO->getLHS()) == LCDecl)
7022 return checkAndSetIncRHS(BO->getRHS());
7023 break;
7024 default:
7025 break;
7026 }
7027 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7028 switch (CE->getOperator()) {
7029 case OO_PlusPlus:
7030 case OO_MinusMinus:
7031 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7032 return setStep(SemaRef
7033 .ActOnIntegerConstant(
7034 CE->getBeginLoc(),
7035 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7036 .get(),
7037 /*Subtract=*/false);
7038 break;
7039 case OO_PlusEqual:
7040 case OO_MinusEqual:
7041 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7042 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7043 break;
7044 case OO_Equal:
7045 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7046 return checkAndSetIncRHS(CE->getArg(1));
7047 break;
7048 default:
7049 break;
7050 }
7051 }
7052 if (dependent() || SemaRef.CurContext->isDependentContext())
7053 return false;
7054 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7055 << S->getSourceRange() << LCDecl;
7056 return true;
7057}
7058
7059static ExprResult
7060tryBuildCapture(Sema &SemaRef, Expr *Capture,
7061 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7062 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7063 return Capture;
7064 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7065 return SemaRef.PerformImplicitConversion(
7066 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7067 /*AllowExplicit=*/true);
7068 auto I = Captures.find(Capture);
7069 if (I != Captures.end())
7070 return buildCapture(SemaRef, Capture, I->second);
7071 DeclRefExpr *Ref = nullptr;
7072 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7073 Captures[Capture] = Ref;
7074 return Res;
7075}
7076
7077/// Calculate number of iterations, transforming to unsigned, if number of
7078/// iterations may be larger than the original type.
7079static Expr *
7080calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7081 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7082 bool TestIsStrictOp, bool RoundToStep,
7083 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7084 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7085 if (!NewStep.isUsable())
7086 return nullptr;
7087 llvm::APSInt LRes, SRes;
7088 bool IsLowerConst = false, IsStepConst = false;
7089 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7090 LRes = *Res;
7091 IsLowerConst = true;
7092 }
7093 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7094 SRes = *Res;
7095 IsStepConst = true;
7096 }
7097 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7098 ((!TestIsStrictOp && LRes.isNonNegative()) ||
7099 (TestIsStrictOp && LRes.isStrictlyPositive()));
7100 bool NeedToReorganize = false;
7101 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7102 if (!NoNeedToConvert && IsLowerConst &&
7103 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7104 NoNeedToConvert = true;
7105 if (RoundToStep) {
7106 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7107 ? LRes.getBitWidth()
7108 : SRes.getBitWidth();
7109 LRes = LRes.extend(BW + 1);
7110 LRes.setIsSigned(true);
7111 SRes = SRes.extend(BW + 1);
7112 SRes.setIsSigned(true);
7113 LRes -= SRes;
7114 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7115 LRes = LRes.trunc(BW);
7116 }
7117 if (TestIsStrictOp) {
7118 unsigned BW = LRes.getBitWidth();
7119 LRes = LRes.extend(BW + 1);
7120 LRes.setIsSigned(true);
7121 ++LRes;
7122 NoNeedToConvert =
7123 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7124 // truncate to the original bitwidth.
7125 LRes = LRes.trunc(BW);
7126 }
7127 NeedToReorganize = NoNeedToConvert;
7128 }
7129 llvm::APSInt URes;
7130 bool IsUpperConst = false;
7131 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7132 URes = *Res;
7133 IsUpperConst = true;
7134 }
7135 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7136 (!RoundToStep || IsStepConst)) {
7137 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7138 : URes.getBitWidth();
7139 LRes = LRes.extend(BW + 1);
7140 LRes.setIsSigned(true);
7141 URes = URes.extend(BW + 1);
7142 URes.setIsSigned(true);
7143 URes -= LRes;
7144 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7145 NeedToReorganize = NoNeedToConvert;
7146 }
7147 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7148 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7149 // unsigned.
7150 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7151 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7152 QualType LowerTy = Lower->getType();
7153 QualType UpperTy = Upper->getType();
7154 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7155 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7156 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7157 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7158 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7159 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7160 Upper =
7161 SemaRef
7162 .PerformImplicitConversion(
7163 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7164 CastType, Sema::AA_Converting)
7165 .get();
7166 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7167 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7168 }
7169 }
7170 if (!Lower || !Upper || NewStep.isInvalid())
7171 return nullptr;
7172
7173 ExprResult Diff;
7174 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7175 // 1]).
7176 if (NeedToReorganize) {
7177 Diff = Lower;
7178
7179 if (RoundToStep) {
7180 // Lower - Step
7181 Diff =
7182 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7183 if (!Diff.isUsable())
7184 return nullptr;
7185 }
7186
7187 // Lower - Step [+ 1]
7188 if (TestIsStrictOp)
7189 Diff = SemaRef.BuildBinOp(
7190 S, DefaultLoc, BO_Add, Diff.get(),
7191 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7192 if (!Diff.isUsable())
7193 return nullptr;
7194
7195 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7196 if (!Diff.isUsable())
7197 return nullptr;
7198
7199 // Upper - (Lower - Step [+ 1]).
7200 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7201 if (!Diff.isUsable())
7202 return nullptr;
7203 } else {
7204 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7205
7206 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7207 // BuildBinOp already emitted error, this one is to point user to upper
7208 // and lower bound, and to tell what is passed to 'operator-'.
7209 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7210 << Upper->getSourceRange() << Lower->getSourceRange();
7211 return nullptr;
7212 }
7213
7214 if (!Diff.isUsable())
7215 return nullptr;
7216
7217 // Upper - Lower [- 1]
7218 if (TestIsStrictOp)
7219 Diff = SemaRef.BuildBinOp(
7220 S, DefaultLoc, BO_Sub, Diff.get(),
7221 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7222 if (!Diff.isUsable())
7223 return nullptr;
7224
7225 if (RoundToStep) {
7226 // Upper - Lower [- 1] + Step
7227 Diff =
7228 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7229 if (!Diff.isUsable())
7230 return nullptr;
7231 }
7232 }
7233
7234 // Parentheses (for dumping/debugging purposes only).
7235 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7236 if (!Diff.isUsable())
7237 return nullptr;
7238
7239 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7240 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7241 if (!Diff.isUsable())
7242 return nullptr;
7243
7244 return Diff.get();
7245}
7246
7247/// Build the expression to calculate the number of iterations.
7248Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7249 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7250 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7251 QualType VarType = LCDecl->getType().getNonReferenceType();
7252 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7253 !SemaRef.getLangOpts().CPlusPlus)
7254 return nullptr;
7255 Expr *LBVal = LB;
7256 Expr *UBVal = UB;
7257 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7258 // max(LB(MinVal), LB(MaxVal))
7259 if (InitDependOnLC) {
7260 const LoopIterationSpace &IS =
7261 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7262 InitDependOnLC.getValueOr(
7263 CondDependOnLC.getValueOr(0))];
7264 if (!IS.MinValue || !IS.MaxValue)
7265 return nullptr;
7266 // OuterVar = Min
7267 ExprResult MinValue =
7268 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7269 if (!MinValue.isUsable())
7270 return nullptr;
7271
7272 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7273 IS.CounterVar, MinValue.get());
7274 if (!LBMinVal.isUsable())
7275 return nullptr;
7276 // OuterVar = Min, LBVal
7277 LBMinVal =
7278 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7279 if (!LBMinVal.isUsable())
7280 return nullptr;
7281 // (OuterVar = Min, LBVal)
7282 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7283 if (!LBMinVal.isUsable())
7284 return nullptr;
7285
7286 // OuterVar = Max
7287 ExprResult MaxValue =
7288 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7289 if (!MaxValue.isUsable())
7290 return nullptr;
7291
7292 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7293 IS.CounterVar, MaxValue.get());
7294 if (!LBMaxVal.isUsable())
7295 return nullptr;
7296 // OuterVar = Max, LBVal
7297 LBMaxVal =
7298 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7299 if (!LBMaxVal.isUsable())
7300 return nullptr;
7301 // (OuterVar = Max, LBVal)
7302 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7303 if (!LBMaxVal.isUsable())
7304 return nullptr;
7305
7306 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7307 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7308 if (!LBMin || !LBMax)
7309 return nullptr;
7310 // LB(MinVal) < LB(MaxVal)
7311 ExprResult MinLessMaxRes =
7312 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7313 if (!MinLessMaxRes.isUsable())
7314 return nullptr;
7315 Expr *MinLessMax =
7316 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7317 if (!MinLessMax)
7318 return nullptr;
7319 if (TestIsLessOp.getValue()) {
7320 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7321 // LB(MaxVal))
7322 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7323 MinLessMax, LBMin, LBMax);
7324 if (!MinLB.isUsable())
7325 return nullptr;
7326 LBVal = MinLB.get();
7327 } else {
7328 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7329 // LB(MaxVal))
7330 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7331 MinLessMax, LBMax, LBMin);
7332 if (!MaxLB.isUsable())
7333 return nullptr;
7334 LBVal = MaxLB.get();
7335 }
7336 }
7337 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7338 // min(UB(MinVal), UB(MaxVal))
7339 if (CondDependOnLC) {
7340 const LoopIterationSpace &IS =
7341 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7342 InitDependOnLC.getValueOr(
7343 CondDependOnLC.getValueOr(0))];
7344 if (!IS.MinValue || !IS.MaxValue)
7345 return nullptr;
7346 // OuterVar = Min
7347 ExprResult MinValue =
7348 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7349 if (!MinValue.isUsable())
7350 return nullptr;
7351
7352 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7353 IS.CounterVar, MinValue.get());
7354 if (!UBMinVal.isUsable())
7355 return nullptr;
7356 // OuterVar = Min, UBVal
7357 UBMinVal =
7358 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7359 if (!UBMinVal.isUsable())
7360 return nullptr;
7361 // (OuterVar = Min, UBVal)
7362 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7363 if (!UBMinVal.isUsable())
7364 return nullptr;
7365
7366 // OuterVar = Max
7367 ExprResult MaxValue =
7368 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7369 if (!MaxValue.isUsable())
7370 return nullptr;
7371
7372 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7373 IS.CounterVar, MaxValue.get());
7374 if (!UBMaxVal.isUsable())
7375 return nullptr;
7376 // OuterVar = Max, UBVal
7377 UBMaxVal =
7378 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7379 if (!UBMaxVal.isUsable())
7380 return nullptr;
7381 // (OuterVar = Max, UBVal)
7382 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7383 if (!UBMaxVal.isUsable())
7384 return nullptr;
7385
7386 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7387 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7388 if (!UBMin || !UBMax)
7389 return nullptr;
7390 // UB(MinVal) > UB(MaxVal)
7391 ExprResult MinGreaterMaxRes =
7392 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7393 if (!MinGreaterMaxRes.isUsable())
7394 return nullptr;
7395 Expr *MinGreaterMax =
7396 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7397 if (!MinGreaterMax)
7398 return nullptr;
7399 if (TestIsLessOp.getValue()) {
7400 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7401 // UB(MaxVal))
7402 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7403 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7404 if (!MaxUB.isUsable())
7405 return nullptr;
7406 UBVal = MaxUB.get();
7407 } else {
7408 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7409 // UB(MaxVal))
7410 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7411 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7412 if (!MinUB.isUsable())
7413 return nullptr;
7414 UBVal = MinUB.get();
7415 }
7416 }
7417 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7418 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7419 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7420 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7421 if (!Upper || !Lower)
7422 return nullptr;
7423
7424 ExprResult Diff =
7425 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7426 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7427 if (!Diff.isUsable())
7428 return nullptr;
7429
7430 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7431 QualType Type = Diff.get()->getType();
7432 ASTContext &C = SemaRef.Context;
7433 bool UseVarType = VarType->hasIntegerRepresentation() &&
7434 C.getTypeSize(Type) > C.getTypeSize(VarType);
7435 if (!Type->isIntegerType() || UseVarType) {
7436 unsigned NewSize =
7437 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7438 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7439 : Type->hasSignedIntegerRepresentation();
7440 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7441 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7442 Diff = SemaRef.PerformImplicitConversion(
7443 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7444 if (!Diff.isUsable())
7445 return nullptr;
7446 }
7447 }
7448 if (LimitedType) {
7449 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7450 if (NewSize != C.getTypeSize(Type)) {
7451 if (NewSize < C.getTypeSize(Type)) {
7452 assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast
<void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7452, __PRETTY_FUNCTION__))
;
7453 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7454 << InitSrcRange << ConditionSrcRange;
7455 }
7456 QualType NewType = C.getIntTypeForBitwidth(
7457 NewSize, Type->hasSignedIntegerRepresentation() ||
7458 C.getTypeSize(Type) < NewSize);
7459 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7460 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7461 Sema::AA_Converting, true);
7462 if (!Diff.isUsable())
7463 return nullptr;
7464 }
7465 }
7466 }
7467
7468 return Diff.get();
7469}
7470
7471std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7472 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7473 // Do not build for iterators, they cannot be used in non-rectangular loop
7474 // nests.
7475 if (LCDecl->getType()->isRecordType())
7476 return std::make_pair(nullptr, nullptr);
7477 // If we subtract, the min is in the condition, otherwise the min is in the
7478 // init value.
7479 Expr *MinExpr = nullptr;
7480 Expr *MaxExpr = nullptr;
7481 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7482 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7483 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7484 : CondDependOnLC.hasValue();
7485 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7486 : InitDependOnLC.hasValue();
7487 Expr *Lower =
7488 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7489 Expr *Upper =
7490 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7491 if (!Upper || !Lower)
7492 return std::make_pair(nullptr, nullptr);
7493
7494 if (TestIsLessOp.getValue())
7495 MinExpr = Lower;
7496 else
7497 MaxExpr = Upper;
7498
7499 // Build minimum/maximum value based on number of iterations.
7500 QualType VarType = LCDecl->getType().getNonReferenceType();
7501
7502 ExprResult Diff =
7503 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7504 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7505 if (!Diff.isUsable())
7506 return std::make_pair(nullptr, nullptr);
7507
7508 // ((Upper - Lower [- 1]) / Step) * Step
7509 // Parentheses (for dumping/debugging purposes only).
7510 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7511 if (!Diff.isUsable())
7512 return std::make_pair(nullptr, nullptr);
7513
7514 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7515 if (!NewStep.isUsable())
7516 return std::make_pair(nullptr, nullptr);
7517 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7518 if (!Diff.isUsable())
7519 return std::make_pair(nullptr, nullptr);
7520
7521 // Parentheses (for dumping/debugging purposes only).
7522 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7523 if (!Diff.isUsable())
7524 return std::make_pair(nullptr, nullptr);
7525
7526 // Convert to the ptrdiff_t, if original type is pointer.
7527 if (VarType->isAnyPointerType() &&
7528 !SemaRef.Context.hasSameType(
7529 Diff.get()->getType(),
7530 SemaRef.Context.getUnsignedPointerDiffType())) {
7531 Diff = SemaRef.PerformImplicitConversion(
7532 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7533 Sema::AA_Converting, /*AllowExplicit=*/true);
7534 }
7535 if (!Diff.isUsable())
7536 return std::make_pair(nullptr, nullptr);
7537
7538 if (TestIsLessOp.getValue()) {
7539 // MinExpr = Lower;
7540 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7541 Diff = SemaRef.BuildBinOp(
7542 S, DefaultLoc, BO_Add,
7543 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7544 Diff.get());
7545 if (!Diff.isUsable())
7546 return std::make_pair(nullptr, nullptr);
7547 } else {
7548 // MaxExpr = Upper;
7549 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7550 Diff = SemaRef.BuildBinOp(
7551 S, DefaultLoc, BO_Sub,
7552 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7553 Diff.get());
7554 if (!Diff.isUsable())
7555 return std::make_pair(nullptr, nullptr);
7556 }
7557
7558 // Convert to the original type.
7559 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7560 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7561 Sema::AA_Converting,
7562 /*AllowExplicit=*/true);
7563 if (!Diff.isUsable())
7564 return std::make_pair(nullptr, nullptr);
7565
7566 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7567 if (!Diff.isUsable())
7568 return std::make_pair(nullptr, nullptr);
7569
7570 if (TestIsLessOp.getValue())
7571 MaxExpr = Diff.get();
7572 else
7573 MinExpr = Diff.get();
7574
7575 return std::make_pair(MinExpr, MaxExpr);
7576}
7577
7578Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7579 if (InitDependOnLC || CondDependOnLC)
7580 return Condition;
7581 return nullptr;
7582}
7583
7584Expr *OpenMPIterationSpaceChecker::buildPreCond(
7585 Scope *S, Expr *Cond,
7586 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7587 // Do not build a precondition when the condition/initialization is dependent
7588 // to prevent pessimistic early loop exit.
7589 // TODO: this can be improved by calculating min/max values but not sure that
7590 // it will be very effective.
7591 if (CondDependOnLC || InitDependOnLC)
7592 return SemaRef.PerformImplicitConversion(
7593 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7594 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7595 /*AllowExplicit=*/true).get();
7596
7597 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7598 Sema::TentativeAnalysisScope Trap(SemaRef);
7599
7600 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7601 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7602 if (!NewLB.isUsable() || !NewUB.isUsable())
7603 return nullptr;
7604
7605 ExprResult CondExpr =
7606 SemaRef.BuildBinOp(S, DefaultLoc,
7607 TestIsLessOp.getValue() ?
7608 (TestIsStrictOp ? BO_LT : BO_LE) :
7609 (TestIsStrictOp ? BO_GT : BO_GE),
7610 NewLB.get(), NewUB.get());
7611 if (CondExpr.isUsable()) {
7612 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7613 SemaRef.Context.BoolTy))
7614 CondExpr = SemaRef.PerformImplicitConversion(
7615 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7616 /*AllowExplicit=*/true);
7617 }
7618
7619 // Otherwise use original loop condition and evaluate it in runtime.
7620 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7621}
7622
7623/// Build reference expression to the counter be used for codegen.
7624DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7625 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7626 DSAStackTy &DSA) const {
7627 auto *VD = dyn_cast<VarDecl>(LCDecl);
7628 if (!VD) {
7629 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7630 DeclRefExpr *Ref = buildDeclRefExpr(
7631 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7632 const DSAStackTy::DSAVarData Data =
7633 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7634 // If the loop control decl is explicitly marked as private, do not mark it
7635 // as captured again.
7636 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7637 Captures.insert(std::make_pair(LCRef, Ref));
7638 return Ref;
7639 }
7640 return cast<DeclRefExpr>(LCRef);
7641}
7642
7643Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7644 if (LCDecl && !LCDecl->isInvalidDecl()) {
7645 QualType Type = LCDecl->getType().getNonReferenceType();
7646 VarDecl *PrivateVar = buildVarDecl(
7647 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7648 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7649 isa<VarDecl>(LCDecl)
7650 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7651 : nullptr);
7652 if (PrivateVar->isInvalidDecl())
7653 return nullptr;
7654 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7655 }
7656 return nullptr;
7657}
7658
7659/// Build initialization of the counter to be used for codegen.
7660Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7661
7662/// Build step of the counter be used for codegen.
7663Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7664
7665Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7666 Scope *S, Expr *Counter,
7667 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7668 Expr *Inc, OverloadedOperatorKind OOK) {
7669 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7670 if (!Cnt)
7671 return nullptr;
7672 if (Inc) {
7673 assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7674, __PRETTY_FUNCTION__))
7674 "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7674, __PRETTY_FUNCTION__))
;
7675 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7676 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7677 if (!Cnt)
7678 return nullptr;
7679 }
7680 QualType VarType = LCDecl->getType().getNonReferenceType();
7681 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7682 !SemaRef.getLangOpts().CPlusPlus)
7683 return nullptr;
7684 // Upper - Lower
7685 Expr *Upper = TestIsLessOp.getValue()
7686 ? Cnt
7687 : tryBuildCapture(SemaRef, LB, Captures).get();
7688 Expr *Lower = TestIsLessOp.getValue()
7689 ? tryBuildCapture(SemaRef, LB, Captures).get()
7690 : Cnt;
7691 if (!Upper || !Lower)
7692 return nullptr;
7693
7694 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7695 Step, VarType, /*TestIsStrictOp=*/false,
7696 /*RoundToStep=*/false, Captures);
7697 if (!Diff.isUsable())
7698 return nullptr;
7699
7700 return Diff.get();
7701}
7702} // namespace
7703
7704void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7705 assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7705, __PRETTY_FUNCTION__))
;
7706 assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast
<void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7706, __PRETTY_FUNCTION__))
;
7707 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
7708 if (AssociatedLoops > 0 &&
7709 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
7710 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
7711 OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
7712 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7713 if (ValueDecl *D = ISC.getLoopDecl()) {
7714 auto *VD = dyn_cast<VarDecl>(D);
7715 DeclRefExpr *PrivateRef = nullptr;
7716 if (!VD) {
7717 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7718 VD = Private;
7719 } else {
7720 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7721 /*WithInit=*/false);
7722 VD = cast<VarDecl>(PrivateRef->getDecl());
7723 }
7724 }
7725 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
7726 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
7727 if (LD != D->getCanonicalDecl()) {
7728 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
7729 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7730 MarkDeclarationsReferencedInExpr(
7731 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7732 Var->getType().getNonLValueExprType(Context),
7733 ForLoc, /*RefersToCapture=*/true));
7734 }
7735 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
7736 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7737 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7738 // associated for-loop of a simd construct with just one associated
7739 // for-loop may be listed in a linear clause with a constant-linear-step
7740 // that is the increment of the associated for-loop. The loop iteration
7741 // variable(s) in the associated for-loop(s) of a for or parallel for
7742 // construct may be listed in a private or lastprivate clause.
7743 DSAStackTy::DSAVarData DVar =
7744 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
7745 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7746 // is declared in the loop and it is predetermined as a private.
7747 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7748 OpenMPClauseKind PredeterminedCKind =
7749 isOpenMPSimdDirective(DKind)
7750 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7751 : OMPC_private;
7752 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7753 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7754 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7755 DVar.CKind != OMPC_private))) ||
7756 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7757 DKind == OMPD_master_taskloop ||
7758 DKind == OMPD_parallel_master_taskloop ||
7759 isOpenMPDistributeDirective(DKind)) &&
7760 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7761 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7762 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7763 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7764 << getOpenMPClauseName(DVar.CKind)
7765 << getOpenMPDirectiveName(DKind)
7766 << getOpenMPClauseName(PredeterminedCKind);
7767 if (DVar.RefExpr == nullptr)
7768 DVar.CKind = PredeterminedCKind;
7769 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
7770 /*IsLoopIterVar=*/true);
7771 } else if (LoopDeclRefExpr) {
7772 // Make the loop iteration variable private (for worksharing
7773 // constructs), linear (for simd directives with the only one
7774 // associated loop) or lastprivate (for simd directives with several
7775 // collapsed or ordered loops).
7776 if (DVar.CKind == OMPC_unknown)
7777 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7778 PrivateRef);
7779 }
7780 }
7781 }
7782 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
7783 }
7784}
7785
7786/// Called on a for stmt to check and extract its iteration space
7787/// for further processing (such as collapsing).
7788static bool checkOpenMPIterationSpace(
7789 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7790 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7791 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7792 Expr *OrderedLoopCountExpr,
7793 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7794 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7795 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7796 // OpenMP [2.9.1, Canonical Loop Form]
7797 // for (init-expr; test-expr; incr-expr) structured-block
7798 // for (range-decl: range-expr) structured-block
7799 auto *For = dyn_cast_or_null<ForStmt>(S);
7800 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7801 // Ranged for is supported only in OpenMP 5.0.
7802 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7803 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7804 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7805 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7806 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7807 if (TotalNestedLoopCount > 1) {
7808 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7809 SemaRef.Diag(DSA.getConstructLoc(),
7810 diag::note_omp_collapse_ordered_expr)
7811 << 2 << CollapseLoopCountExpr->getSourceRange()
7812 << OrderedLoopCountExpr->getSourceRange();
7813 else if (CollapseLoopCountExpr)
7814 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7815 diag::note_omp_collapse_ordered_expr)
7816 << 0 << CollapseLoopCountExpr->getSourceRange();
7817 else
7818 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7819 diag::note_omp_collapse_ordered_expr)
7820 << 1 << OrderedLoopCountExpr->getSourceRange();
7821 }
7822 return true;
7823 }
7824 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7825, __PRETTY_FUNCTION__))
7825 "No loop body.")((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7825, __PRETTY_FUNCTION__))
;
7826
7827 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7828 For ? For->getForLoc() : CXXFor->getForLoc());
7829
7830 // Check init.
7831 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7832 if (ISC.checkAndSetInit(Init))
7833 return true;
7834
7835 bool HasErrors = false;
7836
7837 // Check loop variable's type.
7838 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7839 // OpenMP [2.6, Canonical Loop Form]
7840 // Var is one of the following:
7841 // A variable of signed or unsigned integer type.
7842 // For C++, a variable of a random access iterator type.
7843 // For C, a variable of a pointer type.
7844 QualType VarType = LCDecl->getType().getNonReferenceType();
7845 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7846 !VarType->isPointerType() &&
7847 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7848 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7849 << SemaRef.getLangOpts().CPlusPlus;
7850 HasErrors = true;
7851 }
7852
7853 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7854 // a Construct
7855 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7856 // parallel for construct is (are) private.
7857 // The loop iteration variable in the associated for-loop of a simd
7858 // construct with just one associated for-loop is linear with a
7859 // constant-linear-step that is the increment of the associated for-loop.
7860 // Exclude loop var from the list of variables with implicitly defined data
7861 // sharing attributes.
7862 VarsWithImplicitDSA.erase(LCDecl);
7863
7864 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 7864, __PRETTY_FUNCTION__))
;
7865
7866 // Check test-expr.
7867 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7868
7869 // Check incr-expr.
7870 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7871 }
7872
7873 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7874 return HasErrors;
7875
7876 // Build the loop's iteration space representation.
7877 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7878 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7879 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7880 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7881 (isOpenMPWorksharingDirective(DKind) ||
7882 isOpenMPTaskLoopDirective(DKind) ||
7883 isOpenMPDistributeDirective(DKind)),
7884 Captures);
7885 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7886 ISC.buildCounterVar(Captures, DSA);
7887 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7888 ISC.buildPrivateCounterVar();
7889 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7890 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7891 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7892 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7893 ISC.getConditionSrcRange();
7894 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7895 ISC.getIncrementSrcRange();
7896 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7897 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7898 ISC.isStrictTestOp();
7899 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7900 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7901 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7902 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7903 ISC.buildFinalCondition(DSA.getCurScope());
7904 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7905 ISC.doesInitDependOnLC();
7906 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7907 ISC.doesCondDependOnLC();
7908 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7909 ISC.getLoopDependentIdx();
7910
7911 HasErrors |=
7912 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7913 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7914 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7915 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7916 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7917 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7918 if (!HasErrors && DSA.isOrderedRegion()) {
7919 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7920 if (CurrentNestedLoopCount <
7921 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7922 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7923 CurrentNestedLoopCount,
7924 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7925 DSA.getOrderedRegionParam().second->setLoopCounter(
7926 CurrentNestedLoopCount,
7927 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7928 }
7929 }
7930 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7931 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7932 // Erroneous case - clause has some problems.
7933 continue;
7934 }
7935 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7936 Pair.second.size() <= CurrentNestedLoopCount) {
7937 // Erroneous case - clause has some problems.
7938 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7939 continue;
7940 }
7941 Expr *CntValue;
7942 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7943 CntValue = ISC.buildOrderedLoopData(
7944 DSA.getCurScope(),
7945 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7946 Pair.first->getDependencyLoc());
7947 else
7948 CntValue = ISC.buildOrderedLoopData(
7949 DSA.getCurScope(),
7950 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7951 Pair.first->getDependencyLoc(),
7952 Pair.second[CurrentNestedLoopCount].first,
7953 Pair.second[CurrentNestedLoopCount].second);
7954 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7955 }
7956 }
7957
7958 return HasErrors;
7959}
7960
7961/// Build 'VarRef = Start.
7962static ExprResult
7963buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7964 ExprResult Start, bool IsNonRectangularLB,
7965 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7966 // Build 'VarRef = Start.
7967 ExprResult NewStart = IsNonRectangularLB
7968 ? Start.get()
7969 : tryBuildCapture(SemaRef, Start.get(), Captures);
7970 if (!NewStart.isUsable())
7971 return ExprError();
7972 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7973 VarRef.get()->getType())) {
7974 NewStart = SemaRef.PerformImplicitConversion(
7975 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7976 /*AllowExplicit=*/true);
7977 if (!NewStart.isUsable())
7978 return ExprError();
7979 }
7980
7981 ExprResult Init =
7982 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7983 return Init;
7984}
7985
7986/// Build 'VarRef = Start + Iter * Step'.
7987static ExprResult buildCounterUpdate(
7988 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7989 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7990 bool IsNonRectangularLB,
7991 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7992 // Add parentheses (for debugging purposes only).
7993 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7994 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7995 !Step.isUsable())
7996 return ExprError();
7997
7998 ExprResult NewStep = Step;
7999 if (Captures)
8000 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8001 if (NewStep.isInvalid())
8002 return ExprError();
8003 ExprResult Update =
8004 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8005 if (!Update.isUsable())
8006 return ExprError();
8007
8008 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8009 // 'VarRef = Start (+|-) Iter * Step'.
8010 if (!Start.isUsable())
8011 return ExprError();
8012 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8013 if (!NewStart.isUsable())
8014 return ExprError();
8015 if (Captures && !IsNonRectangularLB)
8016 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8017 if (NewStart.isInvalid())
8018 return ExprError();
8019
8020 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8021 ExprResult SavedUpdate = Update;
8022 ExprResult UpdateVal;
8023 if (VarRef.get()->getType()->isOverloadableType() ||
8024 NewStart.get()->getType()->isOverloadableType() ||
8025 Update.get()->getType()->isOverloadableType()) {
8026 Sema::TentativeAnalysisScope Trap(SemaRef);
8027
8028 Update =
8029 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8030 if (Update.isUsable()) {
8031 UpdateVal =
8032 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8033 VarRef.get(), SavedUpdate.get());
8034 if (UpdateVal.isUsable()) {
8035 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8036 UpdateVal.get());
8037 }
8038 }
8039 }
8040
8041 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8042 if (!Update.isUsable() || !UpdateVal.isUsable()) {
8043 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8044 NewStart.get(), SavedUpdate.get());
8045 if (!Update.isUsable())
8046 return ExprError();
8047
8048 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8049 VarRef.get()->getType())) {
8050 Update = SemaRef.PerformImplicitConversion(
8051 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8052 if (!Update.isUsable())
8053 return ExprError();
8054 }
8055
8056 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8057 }
8058 return Update;
8059}
8060
8061/// Convert integer expression \a E to make it have at least \a Bits
8062/// bits.
8063static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8064 if (E == nullptr)
8065 return ExprError();
8066 ASTContext &C = SemaRef.Context;
8067 QualType OldType = E->getType();
8068 unsigned HasBits = C.getTypeSize(OldType);
8069 if (HasBits >= Bits)
8070 return ExprResult(E);
8071 // OK to convert to signed, because new type has more bits than old.
8072 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8073 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8074 true);
8075}
8076
8077/// Check if the given expression \a E is a constant integer that fits
8078/// into \a Bits bits.
8079static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8080 if (E == nullptr)
8081 return false;
8082 if (Optional<llvm::APSInt> Result =
8083 E->getIntegerConstantExpr(SemaRef.Context))
8084 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8085 return false;
8086}
8087
8088/// Build preinits statement for the given declarations.
8089static Stmt *buildPreInits(ASTContext &Context,
8090 MutableArrayRef<Decl *> PreInits) {
8091 if (!PreInits.empty()) {
8092 return new (Context) DeclStmt(
8093 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8094 SourceLocation(), SourceLocation());
8095 }
8096 return nullptr;
8097}
8098
8099/// Build preinits statement for the given declarations.
8100static Stmt *
8101buildPreInits(ASTContext &Context,
8102 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8103 if (!Captures.empty()) {
8104 SmallVector<Decl *, 16> PreInits;
8105 for (const auto &Pair : Captures)
8106 PreInits.push_back(Pair.second->getDecl());
8107 return buildPreInits(Context, PreInits);
8108 }
8109 return nullptr;
8110}
8111
8112/// Build postupdate expression for the given list of postupdates expressions.
8113static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8114 Expr *PostUpdate = nullptr;
8115 if (!PostUpdates.empty()) {
8116 for (Expr *E : PostUpdates) {
8117 Expr *ConvE = S.BuildCStyleCastExpr(
8118 E->getExprLoc(),
8119 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8120 E->getExprLoc(), E)
8121 .get();
8122 PostUpdate = PostUpdate
8123 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8124 PostUpdate, ConvE)
8125 .get()
8126 : ConvE;
8127 }
8128 }
8129 return PostUpdate;
8130}
8131
8132/// Called on a for stmt to check itself and nested loops (if any).
8133/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8134/// number of collapsed loops otherwise.
8135static unsigned
8136checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8137 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8138 DSAStackTy &DSA,
8139 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8140 OMPLoopDirective::HelperExprs &Built) {
8141 unsigned NestedLoopCount = 1;
8142 if (CollapseLoopCountExpr) {
8143 // Found 'collapse' clause - calculate collapse number.
8144 Expr::EvalResult Result;
8145 if (!CollapseLoopCountExpr->isValueDependent() &&
8146 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8147 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8148 } else {
8149 Built.clear(/*Size=*/1);
8150 return 1;
8151 }
8152 }
8153 unsigned OrderedLoopCount = 1;
8154 if (OrderedLoopCountExpr) {
8155 // Found 'ordered' clause - calculate collapse number.
8156 Expr::EvalResult EVResult;
8157 if (!OrderedLoopCountExpr->isValueDependent() &&
8158 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8159 SemaRef.getASTContext())) {
8160 llvm::APSInt Result = EVResult.Val.getInt();
8161 if (Result.getLimitedValue() < NestedLoopCount) {
8162 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8163 diag::err_omp_wrong_ordered_loop_count)
8164 << OrderedLoopCountExpr->getSourceRange();
8165 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8166 diag::note_collapse_loop_count)
8167 << CollapseLoopCountExpr->getSourceRange();
8168 }
8169 OrderedLoopCount = Result.getLimitedValue();
8170 } else {
8171 Built.clear(/*Size=*/1);
8172 return 1;
8173 }
8174 }
8175 // This is helper routine for loop directives (e.g., 'for', 'simd',
8176 // 'for simd', etc.).
8177 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8178 SmallVector<LoopIterationSpace, 4> IterSpaces(
8179 std::max(OrderedLoopCount, NestedLoopCount));
8180 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8181 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8182 if (checkOpenMPIterationSpace(
8183 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8184 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8185 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8186 return 0;
8187 // Move on to the next nested for loop, or to the loop body.
8188 // OpenMP [2.8.1, simd construct, Restrictions]
8189 // All loops associated with the construct must be perfectly nested; that
8190 // is, there must be no intervening code nor any OpenMP directive between
8191 // any two loops.
8192 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8193 CurStmt = For->getBody();
8194 } else {
8195 assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8196, __PRETTY_FUNCTION__))
8196 "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8196, __PRETTY_FUNCTION__))
;
8197 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8198 }
8199 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8200 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8201 }
8202 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8203 if (checkOpenMPIterationSpace(
8204 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8205 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8206 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8207 return 0;
8208 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8209 // Handle initialization of captured loop iterator variables.
8210 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8211 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8212 Captures[DRE] = DRE;
8213 }
8214 }
8215 // Move on to the next nested for loop, or to the loop body.
8216 // OpenMP [2.8.1, simd construct, Restrictions]
8217 // All loops associated with the construct must be perfectly nested; that
8218 // is, there must be no intervening code nor any OpenMP directive between
8219 // any two loops.
8220 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8221 CurStmt = For->getBody();
8222 } else {
8223 assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8224, __PRETTY_FUNCTION__))
8224 "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8224, __PRETTY_FUNCTION__))
;
8225 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8226 }
8227 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8228 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8229 }
8230
8231 Built.clear(/* size */ NestedLoopCount);
8232
8233 if (SemaRef.CurContext->isDependentContext())
8234 return NestedLoopCount;
8235
8236 // An example of what is generated for the following code:
8237 //
8238 // #pragma omp simd collapse(2) ordered(2)
8239 // for (i = 0; i < NI; ++i)
8240 // for (k = 0; k < NK; ++k)
8241 // for (j = J0; j < NJ; j+=2) {
8242 // <loop body>
8243 // }
8244 //
8245 // We generate the code below.
8246 // Note: the loop body may be outlined in CodeGen.
8247 // Note: some counters may be C++ classes, operator- is used to find number of
8248 // iterations and operator+= to calculate counter value.
8249 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8250 // or i64 is currently supported).
8251 //
8252 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8253 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8254 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8255 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8256 // // similar updates for vars in clauses (e.g. 'linear')
8257 // <loop body (using local i and j)>
8258 // }
8259 // i = NI; // assign final values of counters
8260 // j = NJ;
8261 //
8262
8263 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8264 // the iteration counts of the collapsed for loops.
8265 // Precondition tests if there is at least one iteration (all conditions are
8266 // true).
8267 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8268 Expr *N0 = IterSpaces[0].NumIterations;
8269 ExprResult LastIteration32 =
8270 widenIterationCount(/*Bits=*/32,
8271 SemaRef
8272 .PerformImplicitConversion(
8273 N0->IgnoreImpCasts(), N0->getType(),
8274 Sema::AA_Converting, /*AllowExplicit=*/true)
8275 .get(),
8276 SemaRef);
8277 ExprResult LastIteration64 = widenIterationCount(
8278 /*Bits=*/64,
8279 SemaRef
8280 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8281 Sema::AA_Converting,
8282 /*AllowExplicit=*/true)
8283 .get(),
8284 SemaRef);
8285
8286 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8287 return NestedLoopCount;
8288
8289 ASTContext &C = SemaRef.Context;
8290 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8291
8292 Scope *CurScope = DSA.getCurScope();
8293 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8294 if (PreCond.isUsable()) {
8295 PreCond =
8296 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8297 PreCond.get(), IterSpaces[Cnt].PreCond);
8298 }
8299 Expr *N = IterSpaces[Cnt].NumIterations;
8300 SourceLocation Loc = N->getExprLoc();
8301 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8302 if (LastIteration32.isUsable())
8303 LastIteration32 = SemaRef.BuildBinOp(
8304 CurScope, Loc, BO_Mul, LastIteration32.get(),
8305 SemaRef
8306 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8307 Sema::AA_Converting,
8308 /*AllowExplicit=*/true)
8309 .get());
8310 if (LastIteration64.isUsable())
8311 LastIteration64 = SemaRef.BuildBinOp(
8312 CurScope, Loc, BO_Mul, LastIteration64.get(),
8313 SemaRef
8314 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8315 Sema::AA_Converting,
8316 /*AllowExplicit=*/true)
8317 .get());
8318 }
8319
8320 // Choose either the 32-bit or 64-bit version.
8321 ExprResult LastIteration = LastIteration64;
8322 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8323 (LastIteration32.isUsable() &&
8324 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8325 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8326 fitsInto(
8327 /*Bits=*/32,
8328 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8329 LastIteration64.get(), SemaRef))))
8330 LastIteration = LastIteration32;
8331 QualType VType = LastIteration.get()->getType();
8332 QualType RealVType = VType;
8333 QualType StrideVType = VType;
8334 if (isOpenMPTaskLoopDirective(DKind)) {
8335 VType =
8336 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8337 StrideVType =
8338 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8339 }
8340
8341 if (!LastIteration.isUsable())
8342 return 0;
8343
8344 // Save the number of iterations.
8345 ExprResult NumIterations = LastIteration;
8346 {
8347 LastIteration = SemaRef.BuildBinOp(
8348 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8349 LastIteration.get(),
8350 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8351 if (!LastIteration.isUsable())
8352 return 0;
8353 }
8354
8355 // Calculate the last iteration number beforehand instead of doing this on
8356 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8357 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8358 ExprResult CalcLastIteration;
8359 if (!IsConstant) {
8360 ExprResult SaveRef =
8361 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8362 LastIteration = SaveRef;
8363
8364 // Prepare SaveRef + 1.
8365 NumIterations = SemaRef.BuildBinOp(
8366 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8367 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8368 if (!NumIterations.isUsable())
8369 return 0;
8370 }
8371
8372 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8373
8374 // Build variables passed into runtime, necessary for worksharing directives.
8375 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8376 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8377 isOpenMPDistributeDirective(DKind)) {
8378 // Lower bound variable, initialized with zero.
8379 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8380 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8381 SemaRef.AddInitializerToDecl(LBDecl,
8382 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8383 /*DirectInit*/ false);
8384
8385 // Upper bound variable, initialized with last iteration number.
8386 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8387 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8388 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8389 /*DirectInit*/ false);
8390
8391 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8392 // This will be used to implement clause 'lastprivate'.
8393 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8394 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8395 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8396 SemaRef.AddInitializerToDecl(ILDecl,
8397 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8398 /*DirectInit*/ false);
8399
8400 // Stride variable returned by runtime (we initialize it to 1 by default).
8401 VarDecl *STDecl =
8402 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8403 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8404 SemaRef.AddInitializerToDecl(STDecl,
8405 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8406 /*DirectInit*/ false);
8407
8408 // Build expression: UB = min(UB, LastIteration)
8409 // It is necessary for CodeGen of directives with static scheduling.
8410 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8411 UB.get(), LastIteration.get());
8412 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8413 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8414 LastIteration.get(), UB.get());
8415 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8416 CondOp.get());
8417 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8418
8419 // If we have a combined directive that combines 'distribute', 'for' or
8420 // 'simd' we need to be able to access the bounds of the schedule of the
8421 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8422 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8423 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8424 // Lower bound variable, initialized with zero.
8425 VarDecl *CombLBDecl =
8426 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8427 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8428 SemaRef.AddInitializerToDecl(
8429 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8430 /*DirectInit*/ false);
8431
8432 // Upper bound variable, initialized with last iteration number.
8433 VarDecl *CombUBDecl =
8434 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8435 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8436 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8437 /*DirectInit*/ false);
8438
8439 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8440 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8441 ExprResult CombCondOp =
8442 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8443 LastIteration.get(), CombUB.get());
8444 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8445 CombCondOp.get());
8446 CombEUB =
8447 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8448
8449 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8450 // We expect to have at least 2 more parameters than the 'parallel'
8451 // directive does - the lower and upper bounds of the previous schedule.
8452 assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8453, __PRETTY_FUNCTION__))
8453 "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8453, __PRETTY_FUNCTION__))
;
8454
8455 // Set the proper type for the bounds given what we learned from the
8456 // enclosed loops.
8457 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8458 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8459
8460 // Previous lower and upper bounds are obtained from the region
8461 // parameters.
8462 PrevLB =
8463 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8464 PrevUB =
8465 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8466 }
8467 }
8468
8469 // Build the iteration variable and its initialization before loop.
8470 ExprResult IV;
8471 ExprResult Init, CombInit;
8472 {
8473 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8474 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8475 Expr *RHS =
8476 (isOpenMPWorksharingDirective(DKind) ||
8477 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8478 ? LB.get()
8479 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8480 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8481 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8482
8483 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8484 Expr *CombRHS =
8485 (isOpenMPWorksharingDirective(DKind) ||
8486 isOpenMPTaskLoopDirective(DKind) ||
8487 isOpenMPDistributeDirective(DKind))
8488 ? CombLB.get()
8489 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8490 CombInit =
8491 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8492 CombInit =
8493 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8494 }
8495 }
8496
8497 bool UseStrictCompare =
8498 RealVType->hasUnsignedIntegerRepresentation() &&
8499 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8500 return LIS.IsStrictCompare;
8501 });
8502 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8503 // unsigned IV)) for worksharing loops.
8504 SourceLocation CondLoc = AStmt->getBeginLoc();
8505 Expr *BoundUB = UB.get();
8506 if (UseStrictCompare) {
8507 BoundUB =
8508 SemaRef
8509 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8510 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8511 .get();
8512 BoundUB =
8513 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8514 }
8515 ExprResult Cond =
8516 (isOpenMPWorksharingDirective(DKind) ||
8517 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8518 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8519 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8520 BoundUB)
8521 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8522 NumIterations.get());
8523 ExprResult CombDistCond;
8524 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8525 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8526 NumIterations.get());
8527 }
8528
8529 ExprResult CombCond;
8530 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8531 Expr *BoundCombUB = CombUB.get();
8532 if (UseStrictCompare) {
8533 BoundCombUB =
8534 SemaRef
8535 .BuildBinOp(
8536 CurScope, CondLoc, BO_Add, BoundCombUB,
8537 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8538 .get();
8539 BoundCombUB =
8540 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8541 .get();
8542 }
8543 CombCond =
8544 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8545 IV.get(), BoundCombUB);
8546 }
8547 // Loop increment (IV = IV + 1)
8548 SourceLocation IncLoc = AStmt->getBeginLoc();
8549 ExprResult Inc =
8550 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8551 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8552 if (!Inc.isUsable())
8553 return 0;
8554 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8555 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8556 if (!Inc.isUsable())
8557 return 0;
8558
8559 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8560 // Used for directives with static scheduling.
8561 // In combined construct, add combined version that use CombLB and CombUB
8562 // base variables for the update
8563 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8564 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8565 isOpenMPDistributeDirective(DKind)) {
8566 // LB + ST
8567 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8568 if (!NextLB.isUsable())
8569 return 0;
8570 // LB = LB + ST
8571 NextLB =
8572 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8573 NextLB =
8574 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8575 if (!NextLB.isUsable())
8576 return 0;
8577 // UB + ST
8578 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8579 if (!NextUB.isUsable())
8580 return 0;
8581 // UB = UB + ST
8582 NextUB =
8583 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8584 NextUB =
8585 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8586 if (!NextUB.isUsable())
8587 return 0;
8588 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8589 CombNextLB =
8590 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8591 if (!NextLB.isUsable())
8592 return 0;
8593 // LB = LB + ST
8594 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8595 CombNextLB.get());
8596 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8597 /*DiscardedValue*/ false);
8598 if (!CombNextLB.isUsable())
8599 return 0;
8600 // UB + ST
8601 CombNextUB =
8602 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8603 if (!CombNextUB.isUsable())
8604 return 0;
8605 // UB = UB + ST
8606 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8607 CombNextUB.get());
8608 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8609 /*DiscardedValue*/ false);
8610 if (!CombNextUB.isUsable())
8611 return 0;
8612 }
8613 }
8614
8615 // Create increment expression for distribute loop when combined in a same
8616 // directive with for as IV = IV + ST; ensure upper bound expression based
8617 // on PrevUB instead of NumIterations - used to implement 'for' when found
8618 // in combination with 'distribute', like in 'distribute parallel for'
8619 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8620 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8621 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8622 DistCond = SemaRef.BuildBinOp(
8623 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8624 assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8624, __PRETTY_FUNCTION__))
;
8625
8626 DistInc =
8627 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8628 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8628, __PRETTY_FUNCTION__))
;
8629 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8630 DistInc.get());
8631 DistInc =
8632 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8633 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8633, __PRETTY_FUNCTION__))
;
8634
8635 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8636 // construct
8637 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8638 ExprResult IsUBGreater =
8639 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8640 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8641 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8642 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8643 CondOp.get());
8644 PrevEUB =
8645 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8646
8647 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8648 // parallel for is in combination with a distribute directive with
8649 // schedule(static, 1)
8650 Expr *BoundPrevUB = PrevUB.get();
8651 if (UseStrictCompare) {
8652 BoundPrevUB =
8653 SemaRef
8654 .BuildBinOp(
8655 CurScope, CondLoc, BO_Add, BoundPrevUB,
8656 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8657 .get();
8658 BoundPrevUB =
8659 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8660 .get();
8661 }
8662 ParForInDistCond =
8663 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8664 IV.get(), BoundPrevUB);
8665 }
8666
8667 // Build updates and final values of the loop counters.
8668 bool HasErrors = false;
8669 Built.Counters.resize(NestedLoopCount);
8670 Built.Inits.resize(NestedLoopCount);
8671 Built.Updates.resize(NestedLoopCount);
8672 Built.Finals.resize(NestedLoopCount);
8673 Built.DependentCounters.resize(NestedLoopCount);
8674 Built.DependentInits.resize(NestedLoopCount);
8675 Built.FinalsConditions.resize(NestedLoopCount);
8676 {
8677 // We implement the following algorithm for obtaining the
8678 // original loop iteration variable values based on the
8679 // value of the collapsed loop iteration variable IV.
8680 //
8681 // Let n+1 be the number of collapsed loops in the nest.
8682 // Iteration variables (I0, I1, .... In)
8683 // Iteration counts (N0, N1, ... Nn)
8684 //
8685 // Acc = IV;
8686 //
8687 // To compute Ik for loop k, 0 <= k <= n, generate:
8688 // Prod = N(k+1) * N(k+2) * ... * Nn;
8689 // Ik = Acc / Prod;
8690 // Acc -= Ik * Prod;
8691 //
8692 ExprResult Acc = IV;
8693 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8694 LoopIterationSpace &IS = IterSpaces[Cnt];
8695 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8696 ExprResult Iter;
8697
8698 // Compute prod
8699 ExprResult Prod =
8700 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8701 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8702 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8703 IterSpaces[K].NumIterations);
8704
8705 // Iter = Acc / Prod
8706 // If there is at least one more inner loop to avoid
8707 // multiplication by 1.
8708 if (Cnt + 1 < NestedLoopCount)
8709 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8710 Acc.get(), Prod.get());
8711 else
8712 Iter = Acc;
8713 if (!Iter.isUsable()) {
8714 HasErrors = true;
8715 break;
8716 }
8717
8718 // Update Acc:
8719 // Acc -= Iter * Prod
8720 // Check if there is at least one more inner loop to avoid
8721 // multiplication by 1.
8722 if (Cnt + 1 < NestedLoopCount)
8723 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8724 Iter.get(), Prod.get());
8725 else
8726 Prod = Iter;
8727 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8728 Acc.get(), Prod.get());
8729
8730 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8731 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8732 DeclRefExpr *CounterVar = buildDeclRefExpr(
8733 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8734 /*RefersToCapture=*/true);
8735 ExprResult Init =
8736 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8737 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8738 if (!Init.isUsable()) {
8739 HasErrors = true;
8740 break;
8741 }
8742 ExprResult Update = buildCounterUpdate(
8743 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8744 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8745 if (!Update.isUsable()) {
8746 HasErrors = true;
8747 break;
8748 }
8749
8750 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8751 ExprResult Final =
8752 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8753 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8754 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8755 if (!Final.isUsable()) {
8756 HasErrors = true;
8757 break;
8758 }
8759
8760 if (!Update.isUsable() || !Final.isUsable()) {
8761 HasErrors = true;
8762 break;
8763 }
8764 // Save results
8765 Built.Counters[Cnt] = IS.CounterVar;
8766 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8767 Built.Inits[Cnt] = Init.get();
8768 Built.Updates[Cnt] = Update.get();
8769 Built.Finals[Cnt] = Final.get();
8770 Built.DependentCounters[Cnt] = nullptr;
8771 Built.DependentInits[Cnt] = nullptr;
8772 Built.FinalsConditions[Cnt] = nullptr;
8773 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8774 Built.DependentCounters[Cnt] =
8775 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8776 Built.DependentInits[Cnt] =
8777 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8778 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8779 }
8780 }
8781 }
8782
8783 if (HasErrors)
8784 return 0;
8785
8786 // Save results
8787 Built.IterationVarRef = IV.get();
8788 Built.LastIteration = LastIteration.get();
8789 Built.NumIterations = NumIterations.get();
8790 Built.CalcLastIteration = SemaRef
8791 .ActOnFinishFullExpr(CalcLastIteration.get(),
8792 /*DiscardedValue=*/false)
8793 .get();
8794 Built.PreCond = PreCond.get();
8795 Built.PreInits = buildPreInits(C, Captures);
8796 Built.Cond = Cond.get();
8797 Built.Init = Init.get();
8798 Built.Inc = Inc.get();
8799 Built.LB = LB.get();
8800 Built.UB = UB.get();
8801 Built.IL = IL.get();
8802 Built.ST = ST.get();
8803 Built.EUB = EUB.get();
8804 Built.NLB = NextLB.get();
8805 Built.NUB = NextUB.get();
8806 Built.PrevLB = PrevLB.get();
8807 Built.PrevUB = PrevUB.get();
8808 Built.DistInc = DistInc.get();
8809 Built.PrevEUB = PrevEUB.get();
8810 Built.DistCombinedFields.LB = CombLB.get();
8811 Built.DistCombinedFields.UB = CombUB.get();
8812 Built.DistCombinedFields.EUB = CombEUB.get();
8813 Built.DistCombinedFields.Init = CombInit.get();
8814 Built.DistCombinedFields.Cond = CombCond.get();
8815 Built.DistCombinedFields.NLB = CombNextLB.get();
8816 Built.DistCombinedFields.NUB = CombNextUB.get();
8817 Built.DistCombinedFields.DistCond = CombDistCond.get();
8818 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8819
8820 return NestedLoopCount;
8821}
8822
8823static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8824 auto CollapseClauses =
8825 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8826 if (CollapseClauses.begin() != CollapseClauses.end())
8827 return (*CollapseClauses.begin())->getNumForLoops();
8828 return nullptr;
8829}
8830
8831static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8832 auto OrderedClauses =
8833 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8834 if (OrderedClauses.begin() != OrderedClauses.end())
8835 return (*OrderedClauses.begin())->getNumForLoops();
8836 return nullptr;
8837}
8838
8839static bool checkSimdlenSafelenSpecified(Sema &S,
8840 const ArrayRef<OMPClause *> Clauses) {
8841 const OMPSafelenClause *Safelen = nullptr;
8842 const OMPSimdlenClause *Simdlen = nullptr;
8843
8844 for (const OMPClause *Clause : Clauses) {
8845 if (Clause->getClauseKind() == OMPC_safelen)
8846 Safelen = cast<OMPSafelenClause>(Clause);
8847 else if (Clause->getClauseKind() == OMPC_simdlen)
8848 Simdlen = cast<OMPSimdlenClause>(Clause);
8849 if (Safelen && Simdlen)
8850 break;
8851 }
8852
8853 if (Simdlen && Safelen) {
8854 const Expr *SimdlenLength = Simdlen->getSimdlen();
8855 const Expr *SafelenLength = Safelen->getSafelen();
8856 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8857 SimdlenLength->isInstantiationDependent() ||
8858 SimdlenLength->containsUnexpandedParameterPack())
8859 return false;
8860 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8861 SafelenLength->isInstantiationDependent() ||
8862 SafelenLength->containsUnexpandedParameterPack())
8863 return false;
8864 Expr::EvalResult SimdlenResult, SafelenResult;
8865 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8866 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8867 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8868 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8869 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8870 // If both simdlen and safelen clauses are specified, the value of the
8871 // simdlen parameter must be less than or equal to the value of the safelen
8872 // parameter.
8873 if (SimdlenRes > SafelenRes) {
8874 S.Diag(SimdlenLength->getExprLoc(),
8875 diag::err_omp_wrong_simdlen_safelen_values)
8876 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8877 return true;
8878 }
8879 }
8880 return false;
8881}
8882
8883StmtResult
8884Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8885 SourceLocation StartLoc, SourceLocation EndLoc,
8886 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8887 if (!AStmt)
8888 return StmtError();
8889
8890 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8890, __PRETTY_FUNCTION__))
;
8891 OMPLoopDirective::HelperExprs B;
8892 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8893 // define the nested loops number.
8894 unsigned NestedLoopCount = checkOpenMPLoop(
8895 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8896 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8897 if (NestedLoopCount == 0)
8898 return StmtError();
8899
8900 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8901, __PRETTY_FUNCTION__))
8901 "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8901, __PRETTY_FUNCTION__))
;
8902
8903 if (!CurContext->isDependentContext()) {
8904 // Finalize the clauses that need pre-built expressions for CodeGen.
8905 for (OMPClause *C : Clauses) {
8906 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8907 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8908 B.NumIterations, *this, CurScope,
8909 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8910 return StmtError();
8911 }
8912 }
8913
8914 if (checkSimdlenSafelenSpecified(*this, Clauses))
8915 return StmtError();
8916
8917 setFunctionHasBranchProtectedScope();
8918 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8919 Clauses, AStmt, B);
8920}
8921
8922StmtResult
8923Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8924 SourceLocation StartLoc, SourceLocation EndLoc,
8925 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8926 if (!AStmt)
8927 return StmtError();
8928
8929 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8929, __PRETTY_FUNCTION__))
;
8930 OMPLoopDirective::HelperExprs B;
8931 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8932 // define the nested loops number.
8933 unsigned NestedLoopCount = checkOpenMPLoop(
8934 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8935 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8936 if (NestedLoopCount == 0)
8937 return StmtError();
8938
8939 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8940, __PRETTY_FUNCTION__))
8940 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8940, __PRETTY_FUNCTION__))
;
8941
8942 if (!CurContext->isDependentContext()) {
8943 // Finalize the clauses that need pre-built expressions for CodeGen.
8944 for (OMPClause *C : Clauses) {
8945 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8946 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8947 B.NumIterations, *this, CurScope,
8948 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8949 return StmtError();
8950 }
8951 }
8952
8953 setFunctionHasBranchProtectedScope();
8954 return OMPForDirective::Create(
8955 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8956 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8957}
8958
8959StmtResult Sema::ActOnOpenMPForSimdDirective(
8960 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8961 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8962 if (!AStmt)
8963 return StmtError();
8964
8965 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8965, __PRETTY_FUNCTION__))
;
8966 OMPLoopDirective::HelperExprs B;
8967 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8968 // define the nested loops number.
8969 unsigned NestedLoopCount =
8970 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8971 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
8972 VarsWithImplicitDSA, B);
8973 if (NestedLoopCount == 0)
8974 return StmtError();
8975
8976 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8977, __PRETTY_FUNCTION__))
8977 "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 8977, __PRETTY_FUNCTION__))
;
8978
8979 if (!CurContext->isDependentContext()) {
8980 // Finalize the clauses that need pre-built expressions for CodeGen.
8981 for (OMPClause *C : Clauses) {
8982 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8983 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8984 B.NumIterations, *this, CurScope,
8985 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8986 return StmtError();
8987 }
8988 }
8989
8990 if (checkSimdlenSafelenSpecified(*this, Clauses))
8991 return StmtError();
8992
8993 setFunctionHasBranchProtectedScope();
8994 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8995 Clauses, AStmt, B);
8996}
8997
8998StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
8999 Stmt *AStmt,
9000 SourceLocation StartLoc,
9001 SourceLocation EndLoc) {
9002 if (!AStmt)
9003 return StmtError();
9004
9005 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9005, __PRETTY_FUNCTION__))
;
9006 auto BaseStmt = AStmt;
9007 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9008 BaseStmt = CS->getCapturedStmt();
9009 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9010 auto S = C->children();
9011 if (S.begin() == S.end())
9012 return StmtError();
9013 // All associated statements must be '#pragma omp section' except for
9014 // the first one.
9015 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9016 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9017 if (SectionStmt)
9018 Diag(SectionStmt->getBeginLoc(),
9019 diag::err_omp_sections_substmt_not_section);
9020 return StmtError();
9021 }
9022 cast<OMPSectionDirective>(SectionStmt)
9023 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9024 }
9025 } else {
9026 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9027 return StmtError();
9028 }
9029
9030 setFunctionHasBranchProtectedScope();
9031
9032 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9033 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
9034 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9035}
9036
9037StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9038 SourceLocation StartLoc,
9039 SourceLocation EndLoc) {
9040 if (!AStmt)
9041 return StmtError();
9042
9043 setFunctionHasBranchProtectedScope();
9044 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9045
9046 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9047 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9048}
9049
9050StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9051 Stmt *AStmt,
9052 SourceLocation StartLoc,
9053 SourceLocation EndLoc) {
9054 if (!AStmt)
9055 return StmtError();
9056
9057 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9057, __PRETTY_FUNCTION__))
;
9058
9059 setFunctionHasBranchProtectedScope();
9060
9061 // OpenMP [2.7.3, single Construct, Restrictions]
9062 // The copyprivate clause must not be used with the nowait clause.
9063 const OMPClause *Nowait = nullptr;
9064 const OMPClause *Copyprivate = nullptr;
9065 for (const OMPClause *Clause : Clauses) {
9066 if (Clause->getClauseKind() == OMPC_nowait)
9067 Nowait = Clause;
9068 else if (Clause->getClauseKind() == OMPC_copyprivate)
9069 Copyprivate = Clause;
9070 if (Copyprivate && Nowait) {
9071 Diag(Copyprivate->getBeginLoc(),
9072 diag::err_omp_single_copyprivate_with_nowait);
9073 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9074 return StmtError();
9075 }
9076 }
9077
9078 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9079}
9080
9081StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9082 SourceLocation StartLoc,
9083 SourceLocation EndLoc) {
9084 if (!AStmt)
9085 return StmtError();
9086
9087 setFunctionHasBranchProtectedScope();
9088
9089 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9090}
9091
9092StmtResult Sema::ActOnOpenMPCriticalDirective(
9093 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9094 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9095 if (!AStmt)
9096 return StmtError();
9097
9098 bool ErrorFound = false;
9099 llvm::APSInt Hint;
9100 SourceLocation HintLoc;
9101 bool DependentHint = false;
9102 for (const OMPClause *C : Clauses) {
9103 if (C->getClauseKind() == OMPC_hint) {
9104 if (!DirName.getName()) {
9105 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9106 ErrorFound = true;
9107 }
9108 Expr *E = cast<OMPHintClause>(C)->getHint();
9109 if (E->isTypeDependent() || E->isValueDependent() ||
9110 E->isInstantiationDependent()) {
9111 DependentHint = true;
9112 } else {
9113 Hint = E->EvaluateKnownConstInt(Context);
9114 HintLoc = C->getBeginLoc();
9115 }
9116 }
9117 }
9118 if (ErrorFound)
9119 return StmtError();
9120 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9121 if (Pair.first && DirName.getName() && !DependentHint) {
9122 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9123 Diag(StartLoc, diag::err_omp_critical_with_hint);
9124 if (HintLoc.isValid())
9125 Diag(HintLoc, diag::note_omp_critical_hint_here)
9126 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9127 else
9128 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9129 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9130 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9131 << 1
9132 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9133 /*Radix=*/10, /*Signed=*/false);
9134 } else {
9135 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9136 }
9137 }
9138 }
9139
9140 setFunctionHasBranchProtectedScope();
9141
9142 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9143 Clauses, AStmt);
9144 if (!Pair.first && DirName.getName() && !DependentHint)
9145 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9146 return Dir;
9147}
9148
9149StmtResult Sema::ActOnOpenMPParallelForDirective(
9150 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9151 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9152 if (!AStmt)
9153 return StmtError();
9154
9155 auto *CS = cast<CapturedStmt>(AStmt);
9156 // 1.2.2 OpenMP Language Terminology
9157 // Structured block - An executable statement with a single entry at the
9158 // top and a single exit at the bottom.
9159 // The point of exit cannot be a branch out of the structured block.
9160 // longjmp() and throw() must not violate the entry/exit criteria.
9161 CS->getCapturedDecl()->setNothrow();
9162
9163 OMPLoopDirective::HelperExprs B;
9164 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9165 // define the nested loops number.
9166 unsigned NestedLoopCount =
9167 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9168 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9169 VarsWithImplicitDSA, B);
9170 if (NestedLoopCount == 0)
9171 return StmtError();
9172
9173 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9174, __PRETTY_FUNCTION__))
9174 "omp parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9174, __PRETTY_FUNCTION__))
;
9175
9176 if (!CurContext->isDependentContext()) {
9177 // Finalize the clauses that need pre-built expressions for CodeGen.
9178 for (OMPClause *C : Clauses) {
9179 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9180 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9181 B.NumIterations, *this, CurScope,
9182 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9183 return StmtError();
9184 }
9185 }
9186
9187 setFunctionHasBranchProtectedScope();
9188 return OMPParallelForDirective::Create(
9189 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9190 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9191}
9192
9193StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9194 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9195 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9196 if (!AStmt)
9197 return StmtError();
9198
9199 auto *CS = cast<CapturedStmt>(AStmt);
9200 // 1.2.2 OpenMP Language Terminology
9201 // Structured block - An executable statement with a single entry at the
9202 // top and a single exit at the bottom.
9203 // The point of exit cannot be a branch out of the structured block.
9204 // longjmp() and throw() must not violate the entry/exit criteria.
9205 CS->getCapturedDecl()->setNothrow();
9206
9207 OMPLoopDirective::HelperExprs B;
9208 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9209 // define the nested loops number.
9210 unsigned NestedLoopCount =
9211 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9212 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9213 VarsWithImplicitDSA, B);
9214 if (NestedLoopCount == 0)
9215 return StmtError();
9216
9217 if (!CurContext->isDependentContext()) {
9218 // Finalize the clauses that need pre-built expressions for CodeGen.
9219 for (OMPClause *C : Clauses) {
9220 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9221 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9222 B.NumIterations, *this, CurScope,
9223 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9224 return StmtError();
9225 }
9226 }
9227
9228 if (checkSimdlenSafelenSpecified(*this, Clauses))
9229 return StmtError();
9230
9231 setFunctionHasBranchProtectedScope();
9232 return OMPParallelForSimdDirective::Create(
9233 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9234}
9235
9236StmtResult
9237Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9238 Stmt *AStmt, SourceLocation StartLoc,
9239 SourceLocation EndLoc) {
9240 if (!AStmt)
9241 return StmtError();
9242
9243 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9243, __PRETTY_FUNCTION__))
;
9244 auto *CS = cast<CapturedStmt>(AStmt);
9245 // 1.2.2 OpenMP Language Terminology
9246 // Structured block - An executable statement with a single entry at the
9247 // top and a single exit at the bottom.
9248 // The point of exit cannot be a branch out of the structured block.
9249 // longjmp() and throw() must not violate the entry/exit criteria.
9250 CS->getCapturedDecl()->setNothrow();
9251
9252 setFunctionHasBranchProtectedScope();
9253
9254 return OMPParallelMasterDirective::Create(
9255 Context, StartLoc, EndLoc, Clauses, AStmt,
9256 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9257}
9258
9259StmtResult
9260Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9261 Stmt *AStmt, SourceLocation StartLoc,
9262 SourceLocation EndLoc) {
9263 if (!AStmt)
9264 return StmtError();
9265
9266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9266, __PRETTY_FUNCTION__))
;
9267 auto BaseStmt = AStmt;
9268 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9269 BaseStmt = CS->getCapturedStmt();
9270 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9271 auto S = C->children();
9272 if (S.begin() == S.end())
9273 return StmtError();
9274 // All associated statements must be '#pragma omp section' except for
9275 // the first one.
9276 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9277 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9278 if (SectionStmt)
9279 Diag(SectionStmt->getBeginLoc(),
9280 diag::err_omp_parallel_sections_substmt_not_section);
9281 return StmtError();
9282 }
9283 cast<OMPSectionDirective>(SectionStmt)
9284 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9285 }
9286 } else {
9287 Diag(AStmt->getBeginLoc(),
9288 diag::err_omp_parallel_sections_not_compound_stmt);
9289 return StmtError();
9290 }
9291
9292 setFunctionHasBranchProtectedScope();
9293
9294 return OMPParallelSectionsDirective::Create(
9295 Context, StartLoc, EndLoc, Clauses, AStmt,
9296 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9297}
9298
9299/// detach and mergeable clauses are mutially exclusive, check for it.
9300static bool checkDetachMergeableClauses(Sema &S,
9301 ArrayRef<OMPClause *> Clauses) {
9302 const OMPClause *PrevClause = nullptr;
9303 bool ErrorFound = false;
9304 for (const OMPClause *C : Clauses) {
9305 if (C->getClauseKind() == OMPC_detach ||
9306 C->getClauseKind() == OMPC_mergeable) {
9307 if (!PrevClause) {
9308 PrevClause = C;
9309 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9310 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9311 << getOpenMPClauseName(C->getClauseKind())
9312 << getOpenMPClauseName(PrevClause->getClauseKind());
9313 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9314 << getOpenMPClauseName(PrevClause->getClauseKind());
9315 ErrorFound = true;
9316 }
9317 }
9318 }
9319 return ErrorFound;
9320}
9321
9322StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9323 Stmt *AStmt, SourceLocation StartLoc,
9324 SourceLocation EndLoc) {
9325 if (!AStmt)
9326 return StmtError();
9327
9328 // OpenMP 5.0, 2.10.1 task Construct
9329 // If a detach clause appears on the directive, then a mergeable clause cannot
9330 // appear on the same directive.
9331 if (checkDetachMergeableClauses(*this, Clauses))
9332 return StmtError();
9333
9334 auto *CS = cast<CapturedStmt>(AStmt);
9335 // 1.2.2 OpenMP Language Terminology
9336 // Structured block - An executable statement with a single entry at the
9337 // top and a single exit at the bottom.
9338 // The point of exit cannot be a branch out of the structured block.
9339 // longjmp() and throw() must not violate the entry/exit criteria.
9340 CS->getCapturedDecl()->setNothrow();
9341
9342 setFunctionHasBranchProtectedScope();
9343
9344 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9346}
9347
9348StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9349 SourceLocation EndLoc) {
9350 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9351}
9352
9353StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9354 SourceLocation EndLoc) {
9355 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9356}
9357
9358StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9359 SourceLocation EndLoc) {
9360 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9361}
9362
9363StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9364 Stmt *AStmt,
9365 SourceLocation StartLoc,
9366 SourceLocation EndLoc) {
9367 if (!AStmt)
9368 return StmtError();
9369
9370 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9370, __PRETTY_FUNCTION__))
;
9371
9372 setFunctionHasBranchProtectedScope();
9373
9374 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9375 AStmt,
9376 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9377}
9378
9379StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9380 SourceLocation StartLoc,
9381 SourceLocation EndLoc) {
9382 OMPFlushClause *FC = nullptr;
9383 OMPClause *OrderClause = nullptr;
9384 for (OMPClause *C : Clauses) {
9385 if (C->getClauseKind() == OMPC_flush)
9386 FC = cast<OMPFlushClause>(C);
9387 else
9388 OrderClause = C;
9389 }
9390 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9391 SourceLocation MemOrderLoc;
9392 for (const OMPClause *C : Clauses) {
9393 if (C->getClauseKind() == OMPC_acq_rel ||
9394 C->getClauseKind() == OMPC_acquire ||
9395 C->getClauseKind() == OMPC_release) {
9396 if (MemOrderKind != OMPC_unknown) {
9397 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9398 << getOpenMPDirectiveName(OMPD_flush) << 1
9399 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9400 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9401 << getOpenMPClauseName(MemOrderKind);
9402 } else {
9403 MemOrderKind = C->getClauseKind();
9404 MemOrderLoc = C->getBeginLoc();
9405 }
9406 }
9407 }
9408 if (FC && OrderClause) {
9409 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9410 << getOpenMPClauseName(OrderClause->getClauseKind());
9411 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9412 << getOpenMPClauseName(OrderClause->getClauseKind());
9413 return StmtError();
9414 }
9415 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9416}
9417
9418StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9419 SourceLocation StartLoc,
9420 SourceLocation EndLoc) {
9421 if (Clauses.empty()) {
9422 Diag(StartLoc, diag::err_omp_depobj_expected);
9423 return StmtError();
9424 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9425 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9426 return StmtError();
9427 }
9428 // Only depobj expression and another single clause is allowed.
9429 if (Clauses.size() > 2) {
9430 Diag(Clauses[2]->getBeginLoc(),
9431 diag::err_omp_depobj_single_clause_expected);
9432 return StmtError();
9433 } else if (Clauses.size() < 1) {
9434 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9435 return StmtError();
9436 }
9437 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9438}
9439
9440StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9441 SourceLocation StartLoc,
9442 SourceLocation EndLoc) {
9443 // Check that exactly one clause is specified.
9444 if (Clauses.size() != 1) {
9445 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9446 diag::err_omp_scan_single_clause_expected);
9447 return StmtError();
9448 }
9449 // Check that scan directive is used in the scopeof the OpenMP loop body.
9450 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
9451 Scope *ParentS = S->getParent();
9452 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9453 !ParentS->getBreakParent()->isOpenMPLoopScope())
9454 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9455 << getOpenMPDirectiveName(OMPD_scan) << 5);
9456 }
9457 // Check that only one instance of scan directives is used in the same outer
9458 // region.
9459 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
9460 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9461 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
9462 diag::note_omp_previous_directive)
9463 << "scan";
9464 return StmtError();
9465 }
9466 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
9467 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9468}
9469
9470StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9471 Stmt *AStmt,
9472 SourceLocation StartLoc,
9473 SourceLocation EndLoc) {
9474 const OMPClause *DependFound = nullptr;
9475 const OMPClause *DependSourceClause = nullptr;
9476 const OMPClause *DependSinkClause = nullptr;
9477 bool ErrorFound = false;
9478 const OMPThreadsClause *TC = nullptr;
9479 const OMPSIMDClause *SC = nullptr;
9480 for (const OMPClause *C : Clauses) {
9481 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9482 DependFound = C;
9483 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9484 if (DependSourceClause) {
9485 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9486 << getOpenMPDirectiveName(OMPD_ordered)
9487 << getOpenMPClauseName(OMPC_depend) << 2;
9488 ErrorFound = true;
9489 } else {
9490 DependSourceClause = C;
9491 }
9492 if (DependSinkClause) {
9493 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9494 << 0;
9495 ErrorFound = true;
9496 }
9497 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9498 if (DependSourceClause) {
9499 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9500 << 1;
9501 ErrorFound = true;
9502 }
9503 DependSinkClause = C;
9504 }
9505 } else if (C->getClauseKind() == OMPC_threads) {
9506 TC = cast<OMPThreadsClause>(C);
9507 } else if (C->getClauseKind() == OMPC_simd) {
9508 SC = cast<OMPSIMDClause>(C);
9509 }
9510 }
9511 if (!ErrorFound && !SC &&
9512 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
9513 // OpenMP [2.8.1,simd Construct, Restrictions]
9514 // An ordered construct with the simd clause is the only OpenMP construct
9515 // that can appear in the simd region.
9516 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9517 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9518 ErrorFound = true;
9519 } else if (DependFound && (TC || SC)) {
9520 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9521 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9522 ErrorFound = true;
9523 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9524 Diag(DependFound->getBeginLoc(),
9525 diag::err_omp_ordered_directive_without_param);
9526 ErrorFound = true;
9527 } else if (TC || Clauses.empty()) {
9528 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9529 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9530 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9531 << (TC != nullptr);
9532 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9533 ErrorFound = true;
9534 }
9535 }
9536 if ((!AStmt && !DependFound) || ErrorFound)
9537 return StmtError();
9538
9539 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9540 // During execution of an iteration of a worksharing-loop or a loop nest
9541 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9542 // must not execute more than one ordered region corresponding to an ordered
9543 // construct without a depend clause.
9544 if (!DependFound) {
9545 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
9546 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9547 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
9548 diag::note_omp_previous_directive)
9549 << "ordered";
9550 return StmtError();
9551 }
9552 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
9553 }
9554
9555 if (AStmt) {
9556 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 9556, __PRETTY_FUNCTION__))
;
9557
9558 setFunctionHasBranchProtectedScope();
9559 }
9560
9561 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9562}
9563
9564namespace {
9565/// Helper class for checking expression in 'omp atomic [update]'
9566/// construct.
9567class OpenMPAtomicUpdateChecker {
9568 /// Error results for atomic update expressions.
9569 enum ExprAnalysisErrorCode {
9570 /// A statement is not an expression statement.
9571 NotAnExpression,
9572 /// Expression is not builtin binary or unary operation.
9573 NotABinaryOrUnaryExpression,
9574 /// Unary operation is not post-/pre- increment/decrement operation.
9575 NotAnUnaryIncDecExpression,
9576 /// An expression is not of scalar type.
9577 NotAScalarType,
9578 /// A binary operation is not an assignment operation.
9579 NotAnAssignmentOp,
9580 /// RHS part of the binary operation is not a binary expression.
9581 NotABinaryExpression,
9582 /// RHS part is not additive/multiplicative/shift/biwise binary
9583 /// expression.
9584 NotABinaryOperator,
9585 /// RHS binary operation does not have reference to the updated LHS
9586 /// part.
9587 NotAnUpdateExpression,
9588 /// No errors is found.
9589 NoError
9590 };
9591 /// Reference to Sema.
9592 Sema &SemaRef;
9593 /// A location for note diagnostics (when error is found).
9594 SourceLocation NoteLoc;
9595 /// 'x' lvalue part of the source atomic expression.
9596 Expr *X;
9597 /// 'expr' rvalue part of the source atomic expression.
9598 Expr *E;
9599 /// Helper expression of the form
9600 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9601 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9602 Expr *UpdateExpr;
9603 /// Is 'x' a LHS in a RHS part of full update expression. It is
9604 /// important for non-associative operations.
9605 bool IsXLHSInRHSPart;
9606 BinaryOperatorKind Op;
9607 SourceLocation OpLoc;
9608 /// true if the source expression is a postfix unary operation, false
9609 /// if it is a prefix unary operation.
9610 bool IsPostfixUpdate;
9611
9612public:
9613 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9614 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9615 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9616 /// Check specified statement that it is suitable for 'atomic update'
9617 /// constructs and extract 'x', 'expr' and Operation from the original
9618 /// expression. If DiagId and NoteId == 0, then only check is performed
9619 /// without error notification.
9620 /// \param DiagId Diagnostic which should be emitted if error is found.
9621 /// \param NoteId Diagnostic note for the main error message.
9622 /// \return true if statement is not an update expression, false otherwise.
9623 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9624 /// Return the 'x' lvalue part of the source atomic expression.
9625 Expr *getX() const { return X; }
9626 /// Return the 'expr' rvalue part of the source atomic expression.
9627 Expr *getExpr() const { return E; }
9628 /// Return the update expression used in calculation of the updated
9629 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9630 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9631 Expr *getUpdateExpr() const { return UpdateExpr; }
9632 /// Return true if 'x' is LHS in RHS part of full update expression,
9633 /// false otherwise.
9634 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9635
9636 /// true if the source expression is a postfix unary operation, false
9637 /// if it is a prefix unary operation.
9638 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9639
9640private:
9641 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9642 unsigned NoteId = 0);
9643};
9644} // namespace
9645
9646bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9647 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9648 ExprAnalysisErrorCode ErrorFound = NoError;
9649 SourceLocation ErrorLoc, NoteLoc;
9650 SourceRange ErrorRange, NoteRange;
9651 // Allowed constructs are:
9652 // x = x binop expr;
9653 // x = expr binop x;
9654 if (AtomicBinOp->getOpcode() == BO_Assign) {
9655 X = AtomicBinOp->getLHS();
9656 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9657 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9658 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9659 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9660 AtomicInnerBinOp->isBitwiseOp()) {
9661 Op = AtomicInnerBinOp->getOpcode();
9662 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9663 Expr *LHS = AtomicInnerBinOp->getLHS();
9664 Expr *RHS = AtomicInnerBinOp->getRHS();
9665 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9666 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9667 /*Canonical=*/true);
9668 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9669 /*Canonical=*/true);
9670 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9671 /*Canonical=*/true);
9672 if (XId == LHSId) {
9673 E = RHS;
9674 IsXLHSInRHSPart = true;
9675 } else if (XId == RHSId) {
9676 E = LHS;
9677 IsXLHSInRHSPart = false;
9678 } else {
9679 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9680 ErrorRange = AtomicInnerBinOp->getSourceRange();
9681 NoteLoc = X->getExprLoc();
9682 NoteRange = X->getSourceRange();
9683 ErrorFound = NotAnUpdateExpression;
9684 }
9685 } else {
9686 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9687 ErrorRange = AtomicInnerBinOp->getSourceRange();
9688 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9689 NoteRange = SourceRange(NoteLoc, NoteLoc);
9690 ErrorFound = NotABinaryOperator;
9691 }
9692 } else {
9693 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9694 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9695 ErrorFound = NotABinaryExpression;
9696 }
9697 } else {
9698 ErrorLoc = AtomicBinOp->getExprLoc();
9699 ErrorRange = AtomicBinOp->getSourceRange();
9700 NoteLoc = AtomicBinOp->getOperatorLoc();
9701 NoteRange = SourceRange(NoteLoc, NoteLoc);
9702 ErrorFound = NotAnAssignmentOp;
9703 }
9704 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9705 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9706 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9707 return true;
9708 }
9709 if (SemaRef.CurContext->isDependentContext())
9710 E = X = UpdateExpr = nullptr;
9711 return ErrorFound != NoError;
9712}
9713
9714bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9715 unsigned NoteId) {
9716 ExprAnalysisErrorCode ErrorFound = NoError;
9717 SourceLocation ErrorLoc, NoteLoc;
9718 SourceRange ErrorRange, NoteRange;
9719 // Allowed constructs are:
9720 // x++;
9721 // x--;
9722 // ++x;
9723 // --x;
9724 // x binop= expr;
9725 // x = x binop expr;
9726 // x = expr binop x;
9727 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9728 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9729 if (AtomicBody->getType()->isScalarType() ||
9730 AtomicBody->isInstantiationDependent()) {
9731 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9732 AtomicBody->IgnoreParenImpCasts())) {
9733 // Check for Compound Assignment Operation
9734 Op = BinaryOperator::getOpForCompoundAssignment(
9735 AtomicCompAssignOp->getOpcode());
9736 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9737 E = AtomicCompAssignOp->getRHS();
9738 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9739 IsXLHSInRHSPart = true;
9740 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9741 AtomicBody->IgnoreParenImpCasts())) {
9742 // Check for Binary Operation
9743 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9744 return true;
9745 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9746 AtomicBody->IgnoreParenImpCasts())) {
9747 // Check for Unary Operation
9748 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9749 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9750 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9751 OpLoc = AtomicUnaryOp->getOperatorLoc();
9752 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9753 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9754 IsXLHSInRHSPart = true;
9755 } else {
9756 ErrorFound = NotAnUnaryIncDecExpression;
9757 ErrorLoc = AtomicUnaryOp->getExprLoc();
9758 ErrorRange = AtomicUnaryOp->getSourceRange();
9759 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9760 NoteRange = SourceRange(NoteLoc, NoteLoc);
9761 }
9762 } else if (!AtomicBody->isInstantiationDependent()) {
9763 ErrorFound = NotABinaryOrUnaryExpression;
9764 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9765 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9766 }
9767 } else {
9768 ErrorFound = NotAScalarType;
9769 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9770 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9771 }
9772 } else {
9773 ErrorFound = NotAnExpression;
9774 NoteLoc = ErrorLoc = S->getBeginLoc();
9775 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9776 }
9777 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9778 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9779 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9780 return true;
9781 }
9782 if (SemaRef.CurContext->isDependentContext())
9783 E = X = UpdateExpr = nullptr;
9784 if (ErrorFound == NoError && E && X) {
9785 // Build an update expression of form 'OpaqueValueExpr(x) binop
9786 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9787 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9788 auto *OVEX = new (SemaRef.getASTContext())
9789 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9790 auto *OVEExpr = new (SemaRef.getASTContext())
9791 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9792 ExprResult Update =
9793 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9794 IsXLHSInRHSPart ? OVEExpr : OVEX);
9795 if (Update.isInvalid())
9796 return true;
9797 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9798 Sema::AA_Casting);
9799 if (Update.isInvalid())
9800 return true;
9801 UpdateExpr = Update.get();
9802 }
9803 return ErrorFound != NoError;
9804}
9805
9806StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9807 Stmt *AStmt,
9808 SourceLocation StartLoc,
9809 SourceLocation EndLoc) {
9810 // Register location of the first atomic directive.
9811 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
9812 if (!AStmt)
9813 return StmtError();
9814
9815 // 1.2.2 OpenMP Language Terminology
9816 // Structured block - An executable statement with a single entry at the
9817 // top and a single exit at the bottom.
9818 // The point of exit cannot be a branch out of the structured block.
9819 // longjmp() and throw() must not violate the entry/exit criteria.
9820 OpenMPClauseKind AtomicKind = OMPC_unknown;
9821 SourceLocation AtomicKindLoc;
9822 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9823 SourceLocation MemOrderLoc;
9824 for (const OMPClause *C : Clauses) {
9825 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9826 C->getClauseKind() == OMPC_update ||
9827 C->getClauseKind() == OMPC_capture) {
9828 if (AtomicKind != OMPC_unknown) {
9829 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9830 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9831 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9832 << getOpenMPClauseName(AtomicKind);
9833 } else {
9834 AtomicKind = C->getClauseKind();
9835 AtomicKindLoc = C->getBeginLoc();
9836 }
9837 }
9838 if (C->getClauseKind() == OMPC_seq_cst ||
9839 C->getClauseKind() == OMPC_acq_rel ||
9840 C->getClauseKind() == OMPC_acquire ||
9841 C->getClauseKind() == OMPC_release ||
9842 C->getClauseKind() == OMPC_relaxed) {
9843 if (MemOrderKind != OMPC_unknown) {
9844 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9845 << getOpenMPDirectiveName(OMPD_atomic) << 0
9846 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9847 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9848 << getOpenMPClauseName(MemOrderKind);
9849 } else {
9850 MemOrderKind = C->getClauseKind();
9851 MemOrderLoc = C->getBeginLoc();
9852 }
9853 }
9854 }
9855 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9856 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9857 // release.
9858 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9859 // acquire.
9860 // If atomic-clause is update or not present then memory-order-clause must not
9861 // be acq_rel or acquire.
9862 if ((AtomicKind == OMPC_read &&
9863 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9864 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9865 AtomicKind == OMPC_unknown) &&
9866 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9867 SourceLocation Loc = AtomicKindLoc;
9868 if (AtomicKind == OMPC_unknown)
9869 Loc = StartLoc;
9870 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9871 << getOpenMPClauseName(AtomicKind)
9872 << (AtomicKind == OMPC_unknown ? 1 : 0)
9873 << getOpenMPClauseName(MemOrderKind);
9874 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9875 << getOpenMPClauseName(MemOrderKind);
9876 }
9877
9878 Stmt *Body = AStmt;
9879 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9880 Body = EWC->getSubExpr();
9881
9882 Expr *X = nullptr;
9883 Expr *V = nullptr;
9884 Expr *E = nullptr;
9885 Expr *UE = nullptr;
9886 bool IsXLHSInRHSPart = false;
9887 bool IsPostfixUpdate = false;
9888 // OpenMP [2.12.6, atomic Construct]
9889 // In the next expressions:
9890 // * x and v (as applicable) are both l-value expressions with scalar type.
9891 // * During the execution of an atomic region, multiple syntactic
9892 // occurrences of x must designate the same storage location.
9893 // * Neither of v and expr (as applicable) may access the storage location
9894 // designated by x.
9895 // * Neither of x and expr (as applicable) may access the storage location
9896 // designated by v.
9897 // * expr is an expression with scalar type.
9898 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9899 // * binop, binop=, ++, and -- are not overloaded operators.
9900 // * The expression x binop expr must be numerically equivalent to x binop
9901 // (expr). This requirement is satisfied if the operators in expr have
9902 // precedence greater than binop, or by using parentheses around expr or
9903 // subexpressions of expr.
9904 // * The expression expr binop x must be numerically equivalent to (expr)
9905 // binop x. This requirement is satisfied if the operators in expr have
9906 // precedence equal to or greater than binop, or by using parentheses around
9907 // expr or subexpressions of expr.
9908 // * For forms that allow multiple occurrences of x, the number of times
9909 // that x is evaluated is unspecified.
9910 if (AtomicKind == OMPC_read) {
9911 enum {
9912 NotAnExpression,
9913 NotAnAssignmentOp,
9914 NotAScalarType,
9915 NotAnLValue,
9916 NoError
9917 } ErrorFound = NoError;
9918 SourceLocation ErrorLoc, NoteLoc;
9919 SourceRange ErrorRange, NoteRange;
9920 // If clause is read:
9921 // v = x;
9922 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9923 const auto *AtomicBinOp =
9924 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9925 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9926 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9927 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9928 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9929 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9930 if (!X->isLValue() || !V->isLValue()) {
9931 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9932 ErrorFound = NotAnLValue;
9933 ErrorLoc = AtomicBinOp->getExprLoc();
9934 ErrorRange = AtomicBinOp->getSourceRange();
9935 NoteLoc = NotLValueExpr->getExprLoc();
9936 NoteRange = NotLValueExpr->getSourceRange();
9937 }
9938 } else if (!X->isInstantiationDependent() ||
9939 !V->isInstantiationDependent()) {
9940 const Expr *NotScalarExpr =
9941 (X->isInstantiationDependent() || X->getType()->isScalarType())
9942 ? V
9943 : X;
9944 ErrorFound = NotAScalarType;
9945 ErrorLoc = AtomicBinOp->getExprLoc();
9946 ErrorRange = AtomicBinOp->getSourceRange();
9947 NoteLoc = NotScalarExpr->getExprLoc();
9948 NoteRange = NotScalarExpr->getSourceRange();
9949 }
9950 } else if (!AtomicBody->isInstantiationDependent()) {
9951 ErrorFound = NotAnAssignmentOp;
9952 ErrorLoc = AtomicBody->getExprLoc();
9953 ErrorRange = AtomicBody->getSourceRange();
9954 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9955 : AtomicBody->getExprLoc();
9956 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9957 : AtomicBody->getSourceRange();
9958 }
9959 } else {
9960 ErrorFound = NotAnExpression;
9961 NoteLoc = ErrorLoc = Body->getBeginLoc();
9962 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9963 }
9964 if (ErrorFound != NoError) {
9965 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9966 << ErrorRange;
9967 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9968 << NoteRange;
9969 return StmtError();
9970 }
9971 if (CurContext->isDependentContext())
9972 V = X = nullptr;
9973 } else if (AtomicKind == OMPC_write) {
9974 enum {
9975 NotAnExpression,
9976 NotAnAssignmentOp,
9977 NotAScalarType,
9978 NotAnLValue,
9979 NoError
9980 } ErrorFound = NoError;
9981 SourceLocation ErrorLoc, NoteLoc;
9982 SourceRange ErrorRange, NoteRange;
9983 // If clause is write:
9984 // x = expr;
9985 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9986 const auto *AtomicBinOp =
9987 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9988 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9989 X = AtomicBinOp->getLHS();
9990 E = AtomicBinOp->getRHS();
9991 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9992 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
9993 if (!X->isLValue()) {
9994 ErrorFound = NotAnLValue;
9995 ErrorLoc = AtomicBinOp->getExprLoc();
9996 ErrorRange = AtomicBinOp->getSourceRange();
9997 NoteLoc = X->getExprLoc();
9998 NoteRange = X->getSourceRange();
9999 }
10000 } else if (!X->isInstantiationDependent() ||
10001 !E->isInstantiationDependent()) {
10002 const Expr *NotScalarExpr =
10003 (X->isInstantiationDependent() || X->getType()->isScalarType())
10004 ? E
10005 : X;
10006 ErrorFound = NotAScalarType;
10007 ErrorLoc = AtomicBinOp->getExprLoc();
10008 ErrorRange = AtomicBinOp->getSourceRange();
10009 NoteLoc = NotScalarExpr->getExprLoc();
10010 NoteRange = NotScalarExpr->getSourceRange();
10011 }
10012 } else if (!AtomicBody->isInstantiationDependent()) {
10013 ErrorFound = NotAnAssignmentOp;
10014 ErrorLoc = AtomicBody->getExprLoc();
10015 ErrorRange = AtomicBody->getSourceRange();
10016 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10017 : AtomicBody->getExprLoc();
10018 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10019 : AtomicBody->getSourceRange();
10020 }
10021 } else {
10022 ErrorFound = NotAnExpression;
10023 NoteLoc = ErrorLoc = Body->getBeginLoc();
10024 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10025 }
10026 if (ErrorFound != NoError) {
10027 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10028 << ErrorRange;
10029 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10030 << NoteRange;
10031 return StmtError();
10032 }
10033 if (CurContext->isDependentContext())
10034 E = X = nullptr;
10035 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10036 // If clause is update:
10037 // x++;
10038 // x--;
10039 // ++x;
10040 // --x;
10041 // x binop= expr;
10042 // x = x binop expr;
10043 // x = expr binop x;
10044 OpenMPAtomicUpdateChecker Checker(*this);
10045 if (Checker.checkStatement(
10046 Body, (AtomicKind == OMPC_update)
10047 ? diag::err_omp_atomic_update_not_expression_statement
10048 : diag::err_omp_atomic_not_expression_statement,
10049 diag::note_omp_atomic_update))
10050 return StmtError();
10051 if (!CurContext->isDependentContext()) {
10052 E = Checker.getExpr();
10053 X = Checker.getX();
10054 UE = Checker.getUpdateExpr();
10055 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10056 }
10057 } else if (AtomicKind == OMPC_capture) {
10058 enum {
10059 NotAnAssignmentOp,
10060 NotACompoundStatement,
10061 NotTwoSubstatements,
10062 NotASpecificExpression,
10063 NoError
10064 } ErrorFound = NoError;
10065 SourceLocation ErrorLoc, NoteLoc;
10066 SourceRange ErrorRange, NoteRange;
10067 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10068 // If clause is a capture:
10069 // v = x++;
10070 // v = x--;
10071 // v = ++x;
10072 // v = --x;
10073 // v = x binop= expr;
10074 // v = x = x binop expr;
10075 // v = x = expr binop x;
10076 const auto *AtomicBinOp =
10077 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10078 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10079 V = AtomicBinOp->getLHS();
10080 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10081 OpenMPAtomicUpdateChecker Checker(*this);
10082 if (Checker.checkStatement(
10083 Body, diag::err_omp_atomic_capture_not_expression_statement,
10084 diag::note_omp_atomic_update))
10085 return StmtError();
10086 E = Checker.getExpr();
10087 X = Checker.getX();
10088 UE = Checker.getUpdateExpr();
10089 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10090 IsPostfixUpdate = Checker.isPostfixUpdate();
10091 } else if (!AtomicBody->isInstantiationDependent()) {
10092 ErrorLoc = AtomicBody->getExprLoc();
10093 ErrorRange = AtomicBody->getSourceRange();
10094 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10095 : AtomicBody->getExprLoc();
10096 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10097 : AtomicBody->getSourceRange();
10098 ErrorFound = NotAnAssignmentOp;
10099 }
10100 if (ErrorFound != NoError) {
10101 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10102 << ErrorRange;
10103 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10104 return StmtError();
10105 }
10106 if (CurContext->isDependentContext())
10107 UE = V = E = X = nullptr;
10108 } else {
10109 // If clause is a capture:
10110 // { v = x; x = expr; }
10111 // { v = x; x++; }
10112 // { v = x; x--; }
10113 // { v = x; ++x; }
10114 // { v = x; --x; }
10115 // { v = x; x binop= expr; }
10116 // { v = x; x = x binop expr; }
10117 // { v = x; x = expr binop x; }
10118 // { x++; v = x; }
10119 // { x--; v = x; }
10120 // { ++x; v = x; }
10121 // { --x; v = x; }
10122 // { x binop= expr; v = x; }
10123 // { x = x binop expr; v = x; }
10124 // { x = expr binop x; v = x; }
10125 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10126 // Check that this is { expr1; expr2; }
10127 if (CS->size() == 2) {
10128 Stmt *First = CS->body_front();
10129 Stmt *Second = CS->body_back();
10130 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10131 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10132 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10133 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10134 // Need to find what subexpression is 'v' and what is 'x'.
10135 OpenMPAtomicUpdateChecker Checker(*this);
10136 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10137 BinaryOperator *BinOp = nullptr;
10138 if (IsUpdateExprFound) {
10139 BinOp = dyn_cast<BinaryOperator>(First);
10140 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10141 }
10142 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10143 // { v = x; x++; }
10144 // { v = x; x--; }
10145 // { v = x; ++x; }
10146 // { v = x; --x; }
10147 // { v = x; x binop= expr; }
10148 // { v = x; x = x binop expr; }
10149 // { v = x; x = expr binop x; }
10150 // Check that the first expression has form v = x.
10151 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10152 llvm::FoldingSetNodeID XId, PossibleXId;
10153 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10154 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10155 IsUpdateExprFound = XId == PossibleXId;
10156 if (IsUpdateExprFound) {
10157 V = BinOp->getLHS();
10158 X = Checker.getX();
10159 E = Checker.getExpr();
10160 UE = Checker.getUpdateExpr();
10161 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10162 IsPostfixUpdate = true;
10163 }
10164 }
10165 if (!IsUpdateExprFound) {
10166 IsUpdateExprFound = !Checker.checkStatement(First);
10167 BinOp = nullptr;
10168 if (IsUpdateExprFound) {
10169 BinOp = dyn_cast<BinaryOperator>(Second);
10170 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10171 }
10172 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10173 // { x++; v = x; }
10174 // { x--; v = x; }
10175 // { ++x; v = x; }
10176 // { --x; v = x; }
10177 // { x binop= expr; v = x; }
10178 // { x = x binop expr; v = x; }
10179 // { x = expr binop x; v = x; }
10180 // Check that the second expression has form v = x.
10181 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10182 llvm::FoldingSetNodeID XId, PossibleXId;
10183 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10184 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10185 IsUpdateExprFound = XId == PossibleXId;
10186 if (IsUpdateExprFound) {
10187 V = BinOp->getLHS();
10188 X = Checker.getX();
10189 E = Checker.getExpr();
10190 UE = Checker.getUpdateExpr();
10191 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10192 IsPostfixUpdate = false;
10193 }
10194 }
10195 }
10196 if (!IsUpdateExprFound) {
10197 // { v = x; x = expr; }
10198 auto *FirstExpr = dyn_cast<Expr>(First);
10199 auto *SecondExpr = dyn_cast<Expr>(Second);
10200 if (!FirstExpr || !SecondExpr ||
10201 !(FirstExpr->isInstantiationDependent() ||
10202 SecondExpr->isInstantiationDependent())) {
10203 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10204 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10205 ErrorFound = NotAnAssignmentOp;
10206 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10207 : First->getBeginLoc();
10208 NoteRange = ErrorRange = FirstBinOp
10209 ? FirstBinOp->getSourceRange()
10210 : SourceRange(ErrorLoc, ErrorLoc);
10211 } else {
10212 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10213 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10214 ErrorFound = NotAnAssignmentOp;
10215 NoteLoc = ErrorLoc = SecondBinOp
10216 ? SecondBinOp->getOperatorLoc()
10217 : Second->getBeginLoc();
10218 NoteRange = ErrorRange =
10219 SecondBinOp ? SecondBinOp->getSourceRange()
10220 : SourceRange(ErrorLoc, ErrorLoc);
10221 } else {
10222 Expr *PossibleXRHSInFirst =
10223 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10224 Expr *PossibleXLHSInSecond =
10225 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10226 llvm::FoldingSetNodeID X1Id, X2Id;
10227 PossibleXRHSInFirst->Profile(X1Id, Context,
10228 /*Canonical=*/true);
10229 PossibleXLHSInSecond->Profile(X2Id, Context,
10230 /*Canonical=*/true);
10231 IsUpdateExprFound = X1Id == X2Id;
10232 if (IsUpdateExprFound) {
10233 V = FirstBinOp->getLHS();
10234 X = SecondBinOp->getLHS();
10235 E = SecondBinOp->getRHS();
10236 UE = nullptr;
10237 IsXLHSInRHSPart = false;
10238 IsPostfixUpdate = true;
10239 } else {
10240 ErrorFound = NotASpecificExpression;
10241 ErrorLoc = FirstBinOp->getExprLoc();
10242 ErrorRange = FirstBinOp->getSourceRange();
10243 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10244 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10245 }
10246 }
10247 }
10248 }
10249 }
10250 } else {
10251 NoteLoc = ErrorLoc = Body->getBeginLoc();
10252 NoteRange = ErrorRange =
10253 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10254 ErrorFound = NotTwoSubstatements;
10255 }
10256 } else {
10257 NoteLoc = ErrorLoc = Body->getBeginLoc();
10258 NoteRange = ErrorRange =
10259 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10260 ErrorFound = NotACompoundStatement;
10261 }
10262 if (ErrorFound != NoError) {
10263 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10264 << ErrorRange;
10265 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10266 return StmtError();
10267 }
10268 if (CurContext->isDependentContext())
10269 UE = V = E = X = nullptr;
10270 }
10271 }
10272
10273 setFunctionHasBranchProtectedScope();
10274
10275 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10276 X, V, E, UE, IsXLHSInRHSPart,
10277 IsPostfixUpdate);
10278}
10279
10280StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10281 Stmt *AStmt,
10282 SourceLocation StartLoc,
10283 SourceLocation EndLoc) {
10284 if (!AStmt)
10285 return StmtError();
10286
10287 auto *CS = cast<CapturedStmt>(AStmt);
10288 // 1.2.2 OpenMP Language Terminology
10289 // Structured block - An executable statement with a single entry at the
10290 // top and a single exit at the bottom.
10291 // The point of exit cannot be a branch out of the structured block.
10292 // longjmp() and throw() must not violate the entry/exit criteria.
10293 CS->getCapturedDecl()->setNothrow();
10294 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10295 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10296 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10297 // 1.2.2 OpenMP Language Terminology
10298 // Structured block - An executable statement with a single entry at the
10299 // top and a single exit at the bottom.
10300 // The point of exit cannot be a branch out of the structured block.
10301 // longjmp() and throw() must not violate the entry/exit criteria.
10302 CS->getCapturedDecl()->setNothrow();
10303 }
10304
10305 // OpenMP [2.16, Nesting of Regions]
10306 // If specified, a teams construct must be contained within a target
10307 // construct. That target construct must contain no statements or directives
10308 // outside of the teams construct.
10309 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
10310 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10311 bool OMPTeamsFound = true;
10312 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10313 auto I = CS->body_begin();
10314 while (I != CS->body_end()) {
10315 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10316 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10317 OMPTeamsFound) {
10318
10319 OMPTeamsFound = false;
10320 break;
10321 }
10322 ++I;
10323 }
10324 assert(I != CS->body_end() && "Not found statement")((I != CS->body_end() && "Not found statement") ? static_cast
<void> (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10324, __PRETTY_FUNCTION__))
;
10325 S = *I;
10326 } else {
10327 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10328 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10329 }
10330 if (!OMPTeamsFound) {
10331 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10332 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
10333 diag::note_omp_nested_teams_construct_here);
10334 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10335 << isa<OMPExecutableDirective>(S);
10336 return StmtError();
10337 }
10338 }
10339
10340 setFunctionHasBranchProtectedScope();
10341
10342 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10343}
10344
10345StmtResult
10346Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10347 Stmt *AStmt, SourceLocation StartLoc,
10348 SourceLocation EndLoc) {
10349 if (!AStmt)
10350 return StmtError();
10351
10352 auto *CS = cast<CapturedStmt>(AStmt);
10353 // 1.2.2 OpenMP Language Terminology
10354 // Structured block - An executable statement with a single entry at the
10355 // top and a single exit at the bottom.
10356 // The point of exit cannot be a branch out of the structured block.
10357 // longjmp() and throw() must not violate the entry/exit criteria.
10358 CS->getCapturedDecl()->setNothrow();
10359 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10360 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10361 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10362 // 1.2.2 OpenMP Language Terminology
10363 // Structured block - An executable statement with a single entry at the
10364 // top and a single exit at the bottom.
10365 // The point of exit cannot be a branch out of the structured block.
10366 // longjmp() and throw() must not violate the entry/exit criteria.
10367 CS->getCapturedDecl()->setNothrow();
10368 }
10369
10370 setFunctionHasBranchProtectedScope();
10371
10372 return OMPTargetParallelDirective::Create(
10373 Context, StartLoc, EndLoc, Clauses, AStmt,
10374 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10375}
10376
10377StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10379 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10380 if (!AStmt)
10381 return StmtError();
10382
10383 auto *CS = cast<CapturedStmt>(AStmt);
10384 // 1.2.2 OpenMP Language Terminology
10385 // Structured block - An executable statement with a single entry at the
10386 // top and a single exit at the bottom.
10387 // The point of exit cannot be a branch out of the structured block.
10388 // longjmp() and throw() must not violate the entry/exit criteria.
10389 CS->getCapturedDecl()->setNothrow();
10390 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10391 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10392 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10393 // 1.2.2 OpenMP Language Terminology
10394 // Structured block - An executable statement with a single entry at the
10395 // top and a single exit at the bottom.
10396 // The point of exit cannot be a branch out of the structured block.
10397 // longjmp() and throw() must not violate the entry/exit criteria.
10398 CS->getCapturedDecl()->setNothrow();
10399 }
10400
10401 OMPLoopDirective::HelperExprs B;
10402 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10403 // define the nested loops number.
10404 unsigned NestedLoopCount =
10405 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10406 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10407 VarsWithImplicitDSA, B);
10408 if (NestedLoopCount == 0)
10409 return StmtError();
10410
10411 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10412, __PRETTY_FUNCTION__))
10412 "omp target parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10412, __PRETTY_FUNCTION__))
;
10413
10414 if (!CurContext->isDependentContext()) {
10415 // Finalize the clauses that need pre-built expressions for CodeGen.
10416 for (OMPClause *C : Clauses) {
10417 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10418 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10419 B.NumIterations, *this, CurScope,
10420 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10421 return StmtError();
10422 }
10423 }
10424
10425 setFunctionHasBranchProtectedScope();
10426 return OMPTargetParallelForDirective::Create(
10427 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10428 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10429}
10430
10431/// Check for existence of a map clause in the list of clauses.
10432static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10433 const OpenMPClauseKind K) {
10434 return llvm::any_of(
10435 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10436}
10437
10438template <typename... Params>
10439static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10440 const Params... ClauseTypes) {
10441 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10442}
10443
10444StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10445 Stmt *AStmt,
10446 SourceLocation StartLoc,
10447 SourceLocation EndLoc) {
10448 if (!AStmt)
10449 return StmtError();
10450
10451 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10451, __PRETTY_FUNCTION__))
;
10452
10453 // OpenMP [2.12.2, target data Construct, Restrictions]
10454 // At least one map, use_device_addr or use_device_ptr clause must appear on
10455 // the directive.
10456 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10457 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10458 StringRef Expected;
10459 if (LangOpts.OpenMP < 50)
10460 Expected = "'map' or 'use_device_ptr'";
10461 else
10462 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10463 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10464 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10465 return StmtError();
10466 }
10467
10468 setFunctionHasBranchProtectedScope();
10469
10470 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10471 AStmt);
10472}
10473
10474StmtResult
10475Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10476 SourceLocation StartLoc,
10477 SourceLocation EndLoc, Stmt *AStmt) {
10478 if (!AStmt)
10479 return StmtError();
10480
10481 auto *CS = cast<CapturedStmt>(AStmt);
10482 // 1.2.2 OpenMP Language Terminology
10483 // Structured block - An executable statement with a single entry at the
10484 // top and a single exit at the bottom.
10485 // The point of exit cannot be a branch out of the structured block.
10486 // longjmp() and throw() must not violate the entry/exit criteria.
10487 CS->getCapturedDecl()->setNothrow();
10488 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10489 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10490 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10491 // 1.2.2 OpenMP Language Terminology
10492 // Structured block - An executable statement with a single entry at the
10493 // top and a single exit at the bottom.
10494 // The point of exit cannot be a branch out of the structured block.
10495 // longjmp() and throw() must not violate the entry/exit criteria.
10496 CS->getCapturedDecl()->setNothrow();
10497 }
10498
10499 // OpenMP [2.10.2, Restrictions, p. 99]
10500 // At least one map clause must appear on the directive.
10501 if (!hasClauses(Clauses, OMPC_map)) {
10502 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10503 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10504 return StmtError();
10505 }
10506
10507 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10508 AStmt);
10509}
10510
10511StmtResult
10512Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10513 SourceLocation StartLoc,
10514 SourceLocation EndLoc, Stmt *AStmt) {
10515 if (!AStmt)
10516 return StmtError();
10517
10518 auto *CS = cast<CapturedStmt>(AStmt);
10519 // 1.2.2 OpenMP Language Terminology
10520 // Structured block - An executable statement with a single entry at the
10521 // top and a single exit at the bottom.
10522 // The point of exit cannot be a branch out of the structured block.
10523 // longjmp() and throw() must not violate the entry/exit criteria.
10524 CS->getCapturedDecl()->setNothrow();
10525 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10526 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10527 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10528 // 1.2.2 OpenMP Language Terminology
10529 // Structured block - An executable statement with a single entry at the
10530 // top and a single exit at the bottom.
10531 // The point of exit cannot be a branch out of the structured block.
10532 // longjmp() and throw() must not violate the entry/exit criteria.
10533 CS->getCapturedDecl()->setNothrow();
10534 }
10535
10536 // OpenMP [2.10.3, Restrictions, p. 102]
10537 // At least one map clause must appear on the directive.
10538 if (!hasClauses(Clauses, OMPC_map)) {
10539 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10540 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10541 return StmtError();
10542 }
10543
10544 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10545 AStmt);
10546}
10547
10548StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10549 SourceLocation StartLoc,
10550 SourceLocation EndLoc,
10551 Stmt *AStmt) {
10552 if (!AStmt)
10553 return StmtError();
10554
10555 auto *CS = cast<CapturedStmt>(AStmt);
10556 // 1.2.2 OpenMP Language Terminology
10557 // Structured block - An executable statement with a single entry at the
10558 // top and a single exit at the bottom.
10559 // The point of exit cannot be a branch out of the structured block.
10560 // longjmp() and throw() must not violate the entry/exit criteria.
10561 CS->getCapturedDecl()->setNothrow();
10562 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10563 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10564 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10565 // 1.2.2 OpenMP Language Terminology
10566 // Structured block - An executable statement with a single entry at the
10567 // top and a single exit at the bottom.
10568 // The point of exit cannot be a branch out of the structured block.
10569 // longjmp() and throw() must not violate the entry/exit criteria.
10570 CS->getCapturedDecl()->setNothrow();
10571 }
10572
10573 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10574 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10575 return StmtError();
10576 }
10577 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10578 AStmt);
10579}
10580
10581StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10582 Stmt *AStmt, SourceLocation StartLoc,
10583 SourceLocation EndLoc) {
10584 if (!AStmt)
10585 return StmtError();
10586
10587 auto *CS = cast<CapturedStmt>(AStmt);
10588 // 1.2.2 OpenMP Language Terminology
10589 // Structured block - An executable statement with a single entry at the
10590 // top and a single exit at the bottom.
10591 // The point of exit cannot be a branch out of the structured block.
10592 // longjmp() and throw() must not violate the entry/exit criteria.
10593 CS->getCapturedDecl()->setNothrow();
10594
10595 setFunctionHasBranchProtectedScope();
10596
10597 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10598
10599 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10600}
10601
10602StmtResult
10603Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10604 SourceLocation EndLoc,
10605 OpenMPDirectiveKind CancelRegion) {
10606 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10607 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10608 return StmtError();
10609 }
10610 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10611 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10612 return StmtError();
10613 }
10614 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10615 CancelRegion);
10616}
10617
10618StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10619 SourceLocation StartLoc,
10620 SourceLocation EndLoc,
10621 OpenMPDirectiveKind CancelRegion) {
10622 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10623 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10624 return StmtError();
10625 }
10626 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10627 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10628 return StmtError();
10629 }
10630 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
10631 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10632 CancelRegion);
10633}
10634
10635static bool checkGrainsizeNumTasksClauses(Sema &S,
10636 ArrayRef<OMPClause *> Clauses) {
10637 const OMPClause *PrevClause = nullptr;
10638 bool ErrorFound = false;
10639 for (const OMPClause *C : Clauses) {
10640 if (C->getClauseKind() == OMPC_grainsize ||
10641 C->getClauseKind() == OMPC_num_tasks) {
10642 if (!PrevClause)
10643 PrevClause = C;
10644 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10645 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10646 << getOpenMPClauseName(C->getClauseKind())
10647 << getOpenMPClauseName(PrevClause->getClauseKind());
10648 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10649 << getOpenMPClauseName(PrevClause->getClauseKind());
10650 ErrorFound = true;
10651 }
10652 }
10653 }
10654 return ErrorFound;
10655}
10656
10657static bool checkReductionClauseWithNogroup(Sema &S,
10658 ArrayRef<OMPClause *> Clauses) {
10659 const OMPClause *ReductionClause = nullptr;
10660 const OMPClause *NogroupClause = nullptr;
10661 for (const OMPClause *C : Clauses) {
10662 if (C->getClauseKind() == OMPC_reduction) {
10663 ReductionClause = C;
10664 if (NogroupClause)
10665 break;
10666 continue;
10667 }
10668 if (C->getClauseKind() == OMPC_nogroup) {
10669 NogroupClause = C;
10670 if (ReductionClause)
10671 break;
10672 continue;
10673 }
10674 }
10675 if (ReductionClause && NogroupClause) {
10676 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10677 << SourceRange(NogroupClause->getBeginLoc(),
10678 NogroupClause->getEndLoc());
10679 return true;
10680 }
10681 return false;
10682}
10683
10684StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10685 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10686 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10687 if (!AStmt)
10688 return StmtError();
10689
10690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10690, __PRETTY_FUNCTION__))
;
10691 OMPLoopDirective::HelperExprs B;
10692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10693 // define the nested loops number.
10694 unsigned NestedLoopCount =
10695 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10696 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10697 VarsWithImplicitDSA, B);
10698 if (NestedLoopCount == 0)
10699 return StmtError();
10700
10701 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10702, __PRETTY_FUNCTION__))
10702 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10702, __PRETTY_FUNCTION__))
;
10703
10704 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10705 // The grainsize clause and num_tasks clause are mutually exclusive and may
10706 // not appear on the same taskloop directive.
10707 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10708 return StmtError();
10709 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10710 // If a reduction clause is present on the taskloop directive, the nogroup
10711 // clause must not be specified.
10712 if (checkReductionClauseWithNogroup(*this, Clauses))
10713 return StmtError();
10714
10715 setFunctionHasBranchProtectedScope();
10716 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10717 NestedLoopCount, Clauses, AStmt, B,
10718 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10719}
10720
10721StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10722 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10723 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10724 if (!AStmt)
10725 return StmtError();
10726
10727 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10727, __PRETTY_FUNCTION__))
;
10728 OMPLoopDirective::HelperExprs B;
10729 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10730 // define the nested loops number.
10731 unsigned NestedLoopCount =
10732 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10733 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10734 VarsWithImplicitDSA, B);
10735 if (NestedLoopCount == 0)
10736 return StmtError();
10737
10738 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10739, __PRETTY_FUNCTION__))
10739 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10739, __PRETTY_FUNCTION__))
;
10740
10741 if (!CurContext->isDependentContext()) {
10742 // Finalize the clauses that need pre-built expressions for CodeGen.
10743 for (OMPClause *C : Clauses) {
10744 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10745 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10746 B.NumIterations, *this, CurScope,
10747 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10748 return StmtError();
10749 }
10750 }
10751
10752 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10753 // The grainsize clause and num_tasks clause are mutually exclusive and may
10754 // not appear on the same taskloop directive.
10755 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10756 return StmtError();
10757 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10758 // If a reduction clause is present on the taskloop directive, the nogroup
10759 // clause must not be specified.
10760 if (checkReductionClauseWithNogroup(*this, Clauses))
10761 return StmtError();
10762 if (checkSimdlenSafelenSpecified(*this, Clauses))
10763 return StmtError();
10764
10765 setFunctionHasBranchProtectedScope();
10766 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10767 NestedLoopCount, Clauses, AStmt, B);
10768}
10769
10770StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10771 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10772 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10773 if (!AStmt)
10774 return StmtError();
10775
10776 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10776, __PRETTY_FUNCTION__))
;
10777 OMPLoopDirective::HelperExprs B;
10778 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10779 // define the nested loops number.
10780 unsigned NestedLoopCount =
10781 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10782 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10783 VarsWithImplicitDSA, B);
10784 if (NestedLoopCount == 0)
10785 return StmtError();
10786
10787 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10788, __PRETTY_FUNCTION__))
10788 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10788, __PRETTY_FUNCTION__))
;
10789
10790 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10791 // The grainsize clause and num_tasks clause are mutually exclusive and may
10792 // not appear on the same taskloop directive.
10793 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10794 return StmtError();
10795 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10796 // If a reduction clause is present on the taskloop directive, the nogroup
10797 // clause must not be specified.
10798 if (checkReductionClauseWithNogroup(*this, Clauses))
10799 return StmtError();
10800
10801 setFunctionHasBranchProtectedScope();
10802 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10803 NestedLoopCount, Clauses, AStmt, B,
10804 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10805}
10806
10807StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10808 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10809 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10810 if (!AStmt)
10811 return StmtError();
10812
10813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10813, __PRETTY_FUNCTION__))
;
10814 OMPLoopDirective::HelperExprs B;
10815 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10816 // define the nested loops number.
10817 unsigned NestedLoopCount =
10818 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10819 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10820 VarsWithImplicitDSA, B);
10821 if (NestedLoopCount == 0)
10822 return StmtError();
10823
10824 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10825, __PRETTY_FUNCTION__))
10825 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10825, __PRETTY_FUNCTION__))
;
10826
10827 if (!CurContext->isDependentContext()) {
10828 // Finalize the clauses that need pre-built expressions for CodeGen.
10829 for (OMPClause *C : Clauses) {
10830 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10831 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10832 B.NumIterations, *this, CurScope,
10833 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10834 return StmtError();
10835 }
10836 }
10837
10838 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10839 // The grainsize clause and num_tasks clause are mutually exclusive and may
10840 // not appear on the same taskloop directive.
10841 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10842 return StmtError();
10843 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10844 // If a reduction clause is present on the taskloop directive, the nogroup
10845 // clause must not be specified.
10846 if (checkReductionClauseWithNogroup(*this, Clauses))
10847 return StmtError();
10848 if (checkSimdlenSafelenSpecified(*this, Clauses))
10849 return StmtError();
10850
10851 setFunctionHasBranchProtectedScope();
10852 return OMPMasterTaskLoopSimdDirective::Create(
10853 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10854}
10855
10856StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10857 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10858 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10859 if (!AStmt)
10860 return StmtError();
10861
10862 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10862, __PRETTY_FUNCTION__))
;
10863 auto *CS = cast<CapturedStmt>(AStmt);
10864 // 1.2.2 OpenMP Language Terminology
10865 // Structured block - An executable statement with a single entry at the
10866 // top and a single exit at the bottom.
10867 // The point of exit cannot be a branch out of the structured block.
10868 // longjmp() and throw() must not violate the entry/exit criteria.
10869 CS->getCapturedDecl()->setNothrow();
10870 for (int ThisCaptureLevel =
10871 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10872 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10873 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10874 // 1.2.2 OpenMP Language Terminology
10875 // Structured block - An executable statement with a single entry at the
10876 // top and a single exit at the bottom.
10877 // The point of exit cannot be a branch out of the structured block.
10878 // longjmp() and throw() must not violate the entry/exit criteria.
10879 CS->getCapturedDecl()->setNothrow();
10880 }
10881
10882 OMPLoopDirective::HelperExprs B;
10883 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10884 // define the nested loops number.
10885 unsigned NestedLoopCount = checkOpenMPLoop(
10886 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10887 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10888 VarsWithImplicitDSA, B);
10889 if (NestedLoopCount == 0)
10890 return StmtError();
10891
10892 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10893, __PRETTY_FUNCTION__))
10893 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10893, __PRETTY_FUNCTION__))
;
10894
10895 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10896 // The grainsize clause and num_tasks clause are mutually exclusive and may
10897 // not appear on the same taskloop directive.
10898 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10899 return StmtError();
10900 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10901 // If a reduction clause is present on the taskloop directive, the nogroup
10902 // clause must not be specified.
10903 if (checkReductionClauseWithNogroup(*this, Clauses))
10904 return StmtError();
10905
10906 setFunctionHasBranchProtectedScope();
10907 return OMPParallelMasterTaskLoopDirective::Create(
10908 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10909 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10910}
10911
10912StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10914 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10915 if (!AStmt)
10916 return StmtError();
10917
10918 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10918, __PRETTY_FUNCTION__))
;
10919 auto *CS = cast<CapturedStmt>(AStmt);
10920 // 1.2.2 OpenMP Language Terminology
10921 // Structured block - An executable statement with a single entry at the
10922 // top and a single exit at the bottom.
10923 // The point of exit cannot be a branch out of the structured block.
10924 // longjmp() and throw() must not violate the entry/exit criteria.
10925 CS->getCapturedDecl()->setNothrow();
10926 for (int ThisCaptureLevel =
10927 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10928 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10929 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10930 // 1.2.2 OpenMP Language Terminology
10931 // Structured block - An executable statement with a single entry at the
10932 // top and a single exit at the bottom.
10933 // The point of exit cannot be a branch out of the structured block.
10934 // longjmp() and throw() must not violate the entry/exit criteria.
10935 CS->getCapturedDecl()->setNothrow();
10936 }
10937
10938 OMPLoopDirective::HelperExprs B;
10939 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10940 // define the nested loops number.
10941 unsigned NestedLoopCount = checkOpenMPLoop(
10942 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10943 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10944 VarsWithImplicitDSA, B);
10945 if (NestedLoopCount == 0)
10946 return StmtError();
10947
10948 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10949, __PRETTY_FUNCTION__))
10949 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10949, __PRETTY_FUNCTION__))
;
10950
10951 if (!CurContext->isDependentContext()) {
10952 // Finalize the clauses that need pre-built expressions for CodeGen.
10953 for (OMPClause *C : Clauses) {
10954 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10955 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10956 B.NumIterations, *this, CurScope,
10957 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10958 return StmtError();
10959 }
10960 }
10961
10962 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10963 // The grainsize clause and num_tasks clause are mutually exclusive and may
10964 // not appear on the same taskloop directive.
10965 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10966 return StmtError();
10967 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10968 // If a reduction clause is present on the taskloop directive, the nogroup
10969 // clause must not be specified.
10970 if (checkReductionClauseWithNogroup(*this, Clauses))
10971 return StmtError();
10972 if (checkSimdlenSafelenSpecified(*this, Clauses))
10973 return StmtError();
10974
10975 setFunctionHasBranchProtectedScope();
10976 return OMPParallelMasterTaskLoopSimdDirective::Create(
10977 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10978}
10979
10980StmtResult Sema::ActOnOpenMPDistributeDirective(
10981 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10982 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10983 if (!AStmt)
10984 return StmtError();
10985
10986 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10986, __PRETTY_FUNCTION__))
;
10987 OMPLoopDirective::HelperExprs B;
10988 // In presence of clause 'collapse' with number of loops, it will
10989 // define the nested loops number.
10990 unsigned NestedLoopCount =
10991 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
10992 nullptr /*ordered not a clause on distribute*/, AStmt,
10993 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10994 if (NestedLoopCount == 0)
10995 return StmtError();
10996
10997 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10998, __PRETTY_FUNCTION__))
10998 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 10998, __PRETTY_FUNCTION__))
;
10999
11000 setFunctionHasBranchProtectedScope();
11001 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11002 NestedLoopCount, Clauses, AStmt, B);
11003}
11004
11005StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11006 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11007 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11008 if (!AStmt)
11009 return StmtError();
11010
11011 auto *CS = cast<CapturedStmt>(AStmt);
11012 // 1.2.2 OpenMP Language Terminology
11013 // Structured block - An executable statement with a single entry at the
11014 // top and a single exit at the bottom.
11015 // The point of exit cannot be a branch out of the structured block.
11016 // longjmp() and throw() must not violate the entry/exit criteria.
11017 CS->getCapturedDecl()->setNothrow();
11018 for (int ThisCaptureLevel =
11019 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11020 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11021 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11022 // 1.2.2 OpenMP Language Terminology
11023 // Structured block - An executable statement with a single entry at the
11024 // top and a single exit at the bottom.
11025 // The point of exit cannot be a branch out of the structured block.
11026 // longjmp() and throw() must not violate the entry/exit criteria.
11027 CS->getCapturedDecl()->setNothrow();
11028 }
11029
11030 OMPLoopDirective::HelperExprs B;
11031 // In presence of clause 'collapse' with number of loops, it will
11032 // define the nested loops number.
11033 unsigned NestedLoopCount = checkOpenMPLoop(
11034 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11035 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11036 VarsWithImplicitDSA, B);
11037 if (NestedLoopCount == 0)
11038 return StmtError();
11039
11040 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11041, __PRETTY_FUNCTION__))
11041 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11041, __PRETTY_FUNCTION__))
;
11042
11043 setFunctionHasBranchProtectedScope();
11044 return OMPDistributeParallelForDirective::Create(
11045 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11046 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11047}
11048
11049StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11050 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11051 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11052 if (!AStmt)
11053 return StmtError();
11054
11055 auto *CS = cast<CapturedStmt>(AStmt);
11056 // 1.2.2 OpenMP Language Terminology
11057 // Structured block - An executable statement with a single entry at the
11058 // top and a single exit at the bottom.
11059 // The point of exit cannot be a branch out of the structured block.
11060 // longjmp() and throw() must not violate the entry/exit criteria.
11061 CS->getCapturedDecl()->setNothrow();
11062 for (int ThisCaptureLevel =
11063 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11064 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11065 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11066 // 1.2.2 OpenMP Language Terminology
11067 // Structured block - An executable statement with a single entry at the
11068 // top and a single exit at the bottom.
11069 // The point of exit cannot be a branch out of the structured block.
11070 // longjmp() and throw() must not violate the entry/exit criteria.
11071 CS->getCapturedDecl()->setNothrow();
11072 }
11073
11074 OMPLoopDirective::HelperExprs B;
11075 // In presence of clause 'collapse' with number of loops, it will
11076 // define the nested loops number.
11077 unsigned NestedLoopCount = checkOpenMPLoop(
11078 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11079 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11080 VarsWithImplicitDSA, B);
11081 if (NestedLoopCount == 0)
11082 return StmtError();
11083
11084 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11085, __PRETTY_FUNCTION__))
11085 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11085, __PRETTY_FUNCTION__))
;
11086
11087 if (!CurContext->isDependentContext()) {
11088 // Finalize the clauses that need pre-built expressions for CodeGen.
11089 for (OMPClause *C : Clauses) {
11090 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11091 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11092 B.NumIterations, *this, CurScope,
11093 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11094 return StmtError();
11095 }
11096 }
11097
11098 if (checkSimdlenSafelenSpecified(*this, Clauses))
11099 return StmtError();
11100
11101 setFunctionHasBranchProtectedScope();
11102 return OMPDistributeParallelForSimdDirective::Create(
11103 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11104}
11105
11106StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11107 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11108 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11109 if (!AStmt)
11110 return StmtError();
11111
11112 auto *CS = cast<CapturedStmt>(AStmt);
11113 // 1.2.2 OpenMP Language Terminology
11114 // Structured block - An executable statement with a single entry at the
11115 // top and a single exit at the bottom.
11116 // The point of exit cannot be a branch out of the structured block.
11117 // longjmp() and throw() must not violate the entry/exit criteria.
11118 CS->getCapturedDecl()->setNothrow();
11119 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11120 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11121 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11122 // 1.2.2 OpenMP Language Terminology
11123 // Structured block - An executable statement with a single entry at the
11124 // top and a single exit at the bottom.
11125 // The point of exit cannot be a branch out of the structured block.
11126 // longjmp() and throw() must not violate the entry/exit criteria.
11127 CS->getCapturedDecl()->setNothrow();
11128 }
11129
11130 OMPLoopDirective::HelperExprs B;
11131 // In presence of clause 'collapse' with number of loops, it will
11132 // define the nested loops number.
11133 unsigned NestedLoopCount =
11134 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11135 nullptr /*ordered not a clause on distribute*/, CS, *this,
11136 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11137 if (NestedLoopCount == 0)
11138 return StmtError();
11139
11140 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11141, __PRETTY_FUNCTION__))
11141 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11141, __PRETTY_FUNCTION__))
;
11142
11143 if (!CurContext->isDependentContext()) {
11144 // Finalize the clauses that need pre-built expressions for CodeGen.
11145 for (OMPClause *C : Clauses) {
11146 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11147 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11148 B.NumIterations, *this, CurScope,
11149 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11150 return StmtError();
11151 }
11152 }
11153
11154 if (checkSimdlenSafelenSpecified(*this, Clauses))
11155 return StmtError();
11156
11157 setFunctionHasBranchProtectedScope();
11158 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11159 NestedLoopCount, Clauses, AStmt, B);
11160}
11161
11162StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11163 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11164 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11165 if (!AStmt)
11166 return StmtError();
11167
11168 auto *CS = cast<CapturedStmt>(AStmt);
11169 // 1.2.2 OpenMP Language Terminology
11170 // Structured block - An executable statement with a single entry at the
11171 // top and a single exit at the bottom.
11172 // The point of exit cannot be a branch out of the structured block.
11173 // longjmp() and throw() must not violate the entry/exit criteria.
11174 CS->getCapturedDecl()->setNothrow();
11175 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11176 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11177 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11178 // 1.2.2 OpenMP Language Terminology
11179 // Structured block - An executable statement with a single entry at the
11180 // top and a single exit at the bottom.
11181 // The point of exit cannot be a branch out of the structured block.
11182 // longjmp() and throw() must not violate the entry/exit criteria.
11183 CS->getCapturedDecl()->setNothrow();
11184 }
11185
11186 OMPLoopDirective::HelperExprs B;
11187 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11188 // define the nested loops number.
11189 unsigned NestedLoopCount = checkOpenMPLoop(
11190 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11191 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11192 VarsWithImplicitDSA, B);
11193 if (NestedLoopCount == 0)
11194 return StmtError();
11195
11196 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11197, __PRETTY_FUNCTION__))
11197 "omp target parallel for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11197, __PRETTY_FUNCTION__))
;
11198
11199 if (!CurContext->isDependentContext()) {
11200 // Finalize the clauses that need pre-built expressions for CodeGen.
11201 for (OMPClause *C : Clauses) {
11202 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11203 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11204 B.NumIterations, *this, CurScope,
11205 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11206 return StmtError();
11207 }
11208 }
11209 if (checkSimdlenSafelenSpecified(*this, Clauses))
11210 return StmtError();
11211
11212 setFunctionHasBranchProtectedScope();
11213 return OMPTargetParallelForSimdDirective::Create(
11214 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11215}
11216
11217StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11218 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11219 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11220 if (!AStmt)
11221 return StmtError();
11222
11223 auto *CS = cast<CapturedStmt>(AStmt);
11224 // 1.2.2 OpenMP Language Terminology
11225 // Structured block - An executable statement with a single entry at the
11226 // top and a single exit at the bottom.
11227 // The point of exit cannot be a branch out of the structured block.
11228 // longjmp() and throw() must not violate the entry/exit criteria.
11229 CS->getCapturedDecl()->setNothrow();
11230 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11231 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11232 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11233 // 1.2.2 OpenMP Language Terminology
11234 // Structured block - An executable statement with a single entry at the
11235 // top and a single exit at the bottom.
11236 // The point of exit cannot be a branch out of the structured block.
11237 // longjmp() and throw() must not violate the entry/exit criteria.
11238 CS->getCapturedDecl()->setNothrow();
11239 }
11240
11241 OMPLoopDirective::HelperExprs B;
11242 // In presence of clause 'collapse' with number of loops, it will define the
11243 // nested loops number.
11244 unsigned NestedLoopCount =
11245 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11246 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11247 VarsWithImplicitDSA, B);
11248 if (NestedLoopCount == 0)
11249 return StmtError();
11250
11251 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11252, __PRETTY_FUNCTION__))
11252 "omp target simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11252, __PRETTY_FUNCTION__))
;
11253
11254 if (!CurContext->isDependentContext()) {
11255 // Finalize the clauses that need pre-built expressions for CodeGen.
11256 for (OMPClause *C : Clauses) {
11257 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11258 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11259 B.NumIterations, *this, CurScope,
11260 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11261 return StmtError();
11262 }
11263 }
11264
11265 if (checkSimdlenSafelenSpecified(*this, Clauses))
11266 return StmtError();
11267
11268 setFunctionHasBranchProtectedScope();
11269 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11270 NestedLoopCount, Clauses, AStmt, B);
11271}
11272
11273StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11276 if (!AStmt)
11277 return StmtError();
11278
11279 auto *CS = cast<CapturedStmt>(AStmt);
11280 // 1.2.2 OpenMP Language Terminology
11281 // Structured block - An executable statement with a single entry at the
11282 // top and a single exit at the bottom.
11283 // The point of exit cannot be a branch out of the structured block.
11284 // longjmp() and throw() must not violate the entry/exit criteria.
11285 CS->getCapturedDecl()->setNothrow();
11286 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11287 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11288 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11289 // 1.2.2 OpenMP Language Terminology
11290 // Structured block - An executable statement with a single entry at the
11291 // top and a single exit at the bottom.
11292 // The point of exit cannot be a branch out of the structured block.
11293 // longjmp() and throw() must not violate the entry/exit criteria.
11294 CS->getCapturedDecl()->setNothrow();
11295 }
11296
11297 OMPLoopDirective::HelperExprs B;
11298 // In presence of clause 'collapse' with number of loops, it will
11299 // define the nested loops number.
11300 unsigned NestedLoopCount =
11301 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11302 nullptr /*ordered not a clause on distribute*/, CS, *this,
11303 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11304 if (NestedLoopCount == 0)
11305 return StmtError();
11306
11307 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11308, __PRETTY_FUNCTION__))
11308 "omp teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11308, __PRETTY_FUNCTION__))
;
11309
11310 setFunctionHasBranchProtectedScope();
11311
11312 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11313
11314 return OMPTeamsDistributeDirective::Create(
11315 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11316}
11317
11318StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11319 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11320 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11321 if (!AStmt)
11322 return StmtError();
11323
11324 auto *CS = cast<CapturedStmt>(AStmt);
11325 // 1.2.2 OpenMP Language Terminology
11326 // Structured block - An executable statement with a single entry at the
11327 // top and a single exit at the bottom.
11328 // The point of exit cannot be a branch out of the structured block.
11329 // longjmp() and throw() must not violate the entry/exit criteria.
11330 CS->getCapturedDecl()->setNothrow();
11331 for (int ThisCaptureLevel =
11332 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11333 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11334 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11335 // 1.2.2 OpenMP Language Terminology
11336 // Structured block - An executable statement with a single entry at the
11337 // top and a single exit at the bottom.
11338 // The point of exit cannot be a branch out of the structured block.
11339 // longjmp() and throw() must not violate the entry/exit criteria.
11340 CS->getCapturedDecl()->setNothrow();
11341 }
11342
11343 OMPLoopDirective::HelperExprs B;
11344 // In presence of clause 'collapse' with number of loops, it will
11345 // define the nested loops number.
11346 unsigned NestedLoopCount = checkOpenMPLoop(
11347 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11348 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11349 VarsWithImplicitDSA, B);
11350
11351 if (NestedLoopCount == 0)
11352 return StmtError();
11353
11354 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
11355 "omp teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11355, __PRETTY_FUNCTION__))
;
11356
11357 if (!CurContext->isDependentContext()) {
11358 // Finalize the clauses that need pre-built expressions for CodeGen.
11359 for (OMPClause *C : Clauses) {
11360 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11361 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11362 B.NumIterations, *this, CurScope,
11363 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11364 return StmtError();
11365 }
11366 }
11367
11368 if (checkSimdlenSafelenSpecified(*this, Clauses))
11369 return StmtError();
11370
11371 setFunctionHasBranchProtectedScope();
11372
11373 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11374
11375 return OMPTeamsDistributeSimdDirective::Create(
11376 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11377}
11378
11379StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11380 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11381 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11382 if (!AStmt)
11383 return StmtError();
11384
11385 auto *CS = cast<CapturedStmt>(AStmt);
11386 // 1.2.2 OpenMP Language Terminology
11387 // Structured block - An executable statement with a single entry at the
11388 // top and a single exit at the bottom.
11389 // The point of exit cannot be a branch out of the structured block.
11390 // longjmp() and throw() must not violate the entry/exit criteria.
11391 CS->getCapturedDecl()->setNothrow();
11392
11393 for (int ThisCaptureLevel =
11394 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11395 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11396 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11397 // 1.2.2 OpenMP Language Terminology
11398 // Structured block - An executable statement with a single entry at the
11399 // top and a single exit at the bottom.
11400 // The point of exit cannot be a branch out of the structured block.
11401 // longjmp() and throw() must not violate the entry/exit criteria.
11402 CS->getCapturedDecl()->setNothrow();
11403 }
11404
11405 OMPLoopDirective::HelperExprs B;
11406 // In presence of clause 'collapse' with number of loops, it will
11407 // define the nested loops number.
11408 unsigned NestedLoopCount = checkOpenMPLoop(
11409 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11410 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11411 VarsWithImplicitDSA, B);
11412
11413 if (NestedLoopCount == 0)
11414 return StmtError();
11415
11416 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11417, __PRETTY_FUNCTION__))
11417 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11417, __PRETTY_FUNCTION__))
;
11418
11419 if (!CurContext->isDependentContext()) {
11420 // Finalize the clauses that need pre-built expressions for CodeGen.
11421 for (OMPClause *C : Clauses) {
11422 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11423 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11424 B.NumIterations, *this, CurScope,
11425 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11426 return StmtError();
11427 }
11428 }
11429
11430 if (checkSimdlenSafelenSpecified(*this, Clauses))
11431 return StmtError();
11432
11433 setFunctionHasBranchProtectedScope();
11434
11435 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11436
11437 return OMPTeamsDistributeParallelForSimdDirective::Create(
11438 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11439}
11440
11441StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11442 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11443 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11444 if (!AStmt)
11445 return StmtError();
11446
11447 auto *CS = cast<CapturedStmt>(AStmt);
11448 // 1.2.2 OpenMP Language Terminology
11449 // Structured block - An executable statement with a single entry at the
11450 // top and a single exit at the bottom.
11451 // The point of exit cannot be a branch out of the structured block.
11452 // longjmp() and throw() must not violate the entry/exit criteria.
11453 CS->getCapturedDecl()->setNothrow();
11454
11455 for (int ThisCaptureLevel =
11456 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11457 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11458 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11459 // 1.2.2 OpenMP Language Terminology
11460 // Structured block - An executable statement with a single entry at the
11461 // top and a single exit at the bottom.
11462 // The point of exit cannot be a branch out of the structured block.
11463 // longjmp() and throw() must not violate the entry/exit criteria.
11464 CS->getCapturedDecl()->setNothrow();
11465 }
11466
11467 OMPLoopDirective::HelperExprs B;
11468 // In presence of clause 'collapse' with number of loops, it will
11469 // define the nested loops number.
11470 unsigned NestedLoopCount = checkOpenMPLoop(
11471 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11472 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11473 VarsWithImplicitDSA, B);
11474
11475 if (NestedLoopCount == 0)
11476 return StmtError();
11477
11478 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11479, __PRETTY_FUNCTION__))
11479 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11479, __PRETTY_FUNCTION__))
;
11480
11481 setFunctionHasBranchProtectedScope();
11482
11483 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11484
11485 return OMPTeamsDistributeParallelForDirective::Create(
11486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11487 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11488}
11489
11490StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11491 Stmt *AStmt,
11492 SourceLocation StartLoc,
11493 SourceLocation EndLoc) {
11494 if (!AStmt)
11495 return StmtError();
11496
11497 auto *CS = cast<CapturedStmt>(AStmt);
11498 // 1.2.2 OpenMP Language Terminology
11499 // Structured block - An executable statement with a single entry at the
11500 // top and a single exit at the bottom.
11501 // The point of exit cannot be a branch out of the structured block.
11502 // longjmp() and throw() must not violate the entry/exit criteria.
11503 CS->getCapturedDecl()->setNothrow();
11504
11505 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11506 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11507 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11508 // 1.2.2 OpenMP Language Terminology
11509 // Structured block - An executable statement with a single entry at the
11510 // top and a single exit at the bottom.
11511 // The point of exit cannot be a branch out of the structured block.
11512 // longjmp() and throw() must not violate the entry/exit criteria.
11513 CS->getCapturedDecl()->setNothrow();
11514 }
11515 setFunctionHasBranchProtectedScope();
11516
11517 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11518 AStmt);
11519}
11520
11521StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11522 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11523 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11524 if (!AStmt)
11525 return StmtError();
11526
11527 auto *CS = cast<CapturedStmt>(AStmt);
11528 // 1.2.2 OpenMP Language Terminology
11529 // Structured block - An executable statement with a single entry at the
11530 // top and a single exit at the bottom.
11531 // The point of exit cannot be a branch out of the structured block.
11532 // longjmp() and throw() must not violate the entry/exit criteria.
11533 CS->getCapturedDecl()->setNothrow();
11534 for (int ThisCaptureLevel =
11535 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11536 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11537 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11538 // 1.2.2 OpenMP Language Terminology
11539 // Structured block - An executable statement with a single entry at the
11540 // top and a single exit at the bottom.
11541 // The point of exit cannot be a branch out of the structured block.
11542 // longjmp() and throw() must not violate the entry/exit criteria.
11543 CS->getCapturedDecl()->setNothrow();
11544 }
11545
11546 OMPLoopDirective::HelperExprs B;
11547 // In presence of clause 'collapse' with number of loops, it will
11548 // define the nested loops number.
11549 unsigned NestedLoopCount = checkOpenMPLoop(
11550 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11551 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11552 VarsWithImplicitDSA, B);
11553 if (NestedLoopCount == 0)
11554 return StmtError();
11555
11556 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11557, __PRETTY_FUNCTION__))
11557 "omp target teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11557, __PRETTY_FUNCTION__))
;
11558
11559 setFunctionHasBranchProtectedScope();
11560 return OMPTargetTeamsDistributeDirective::Create(
11561 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11562}
11563
11564StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11565 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11566 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11567 if (!AStmt)
11568 return StmtError();
11569
11570 auto *CS = cast<CapturedStmt>(AStmt);
11571 // 1.2.2 OpenMP Language Terminology
11572 // Structured block - An executable statement with a single entry at the
11573 // top and a single exit at the bottom.
11574 // The point of exit cannot be a branch out of the structured block.
11575 // longjmp() and throw() must not violate the entry/exit criteria.
11576 CS->getCapturedDecl()->setNothrow();
11577 for (int ThisCaptureLevel =
11578 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11579 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11580 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11581 // 1.2.2 OpenMP Language Terminology
11582 // Structured block - An executable statement with a single entry at the
11583 // top and a single exit at the bottom.
11584 // The point of exit cannot be a branch out of the structured block.
11585 // longjmp() and throw() must not violate the entry/exit criteria.
11586 CS->getCapturedDecl()->setNothrow();
11587 }
11588
11589 OMPLoopDirective::HelperExprs B;
11590 // In presence of clause 'collapse' with number of loops, it will
11591 // define the nested loops number.
11592 unsigned NestedLoopCount = checkOpenMPLoop(
11593 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11594 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11595 VarsWithImplicitDSA, B);
11596 if (NestedLoopCount == 0)
11597 return StmtError();
11598
11599 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11600, __PRETTY_FUNCTION__))
11600 "omp target teams distribute parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11600, __PRETTY_FUNCTION__))
;
11601
11602 if (!CurContext->isDependentContext()) {
11603 // Finalize the clauses that need pre-built expressions for CodeGen.
11604 for (OMPClause *C : Clauses) {
11605 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11607 B.NumIterations, *this, CurScope,
11608 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11609 return StmtError();
11610 }
11611 }
11612
11613 setFunctionHasBranchProtectedScope();
11614 return OMPTargetTeamsDistributeParallelForDirective::Create(
11615 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11617}
11618
11619StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11620 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11621 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11622 if (!AStmt)
11623 return StmtError();
11624
11625 auto *CS = cast<CapturedStmt>(AStmt);
11626 // 1.2.2 OpenMP Language Terminology
11627 // Structured block - An executable statement with a single entry at the
11628 // top and a single exit at the bottom.
11629 // The point of exit cannot be a branch out of the structured block.
11630 // longjmp() and throw() must not violate the entry/exit criteria.
11631 CS->getCapturedDecl()->setNothrow();
11632 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11633 OMPD_target_teams_distribute_parallel_for_simd);
11634 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11635 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11636 // 1.2.2 OpenMP Language Terminology
11637 // Structured block - An executable statement with a single entry at the
11638 // top and a single exit at the bottom.
11639 // The point of exit cannot be a branch out of the structured block.
11640 // longjmp() and throw() must not violate the entry/exit criteria.
11641 CS->getCapturedDecl()->setNothrow();
11642 }
11643
11644 OMPLoopDirective::HelperExprs B;
11645 // In presence of clause 'collapse' with number of loops, it will
11646 // define the nested loops number.
11647 unsigned NestedLoopCount =
11648 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11649 getCollapseNumberExpr(Clauses),
11650 nullptr /*ordered not a clause on distribute*/, CS, *this,
11651 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11652 if (NestedLoopCount == 0)
11653 return StmtError();
11654
11655 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11657, __PRETTY_FUNCTION__))
11656 "omp target teams distribute parallel for simd loop exprs were not "(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11657, __PRETTY_FUNCTION__))
11657 "built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11657, __PRETTY_FUNCTION__))
;
11658
11659 if (!CurContext->isDependentContext()) {
11660 // Finalize the clauses that need pre-built expressions for CodeGen.
11661 for (OMPClause *C : Clauses) {
11662 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11663 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11664 B.NumIterations, *this, CurScope,
11665 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11666 return StmtError();
11667 }
11668 }
11669
11670 if (checkSimdlenSafelenSpecified(*this, Clauses))
11671 return StmtError();
11672
11673 setFunctionHasBranchProtectedScope();
11674 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11675 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11676}
11677
11678StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11679 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11680 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11681 if (!AStmt)
11682 return StmtError();
11683
11684 auto *CS = cast<CapturedStmt>(AStmt);
11685 // 1.2.2 OpenMP Language Terminology
11686 // Structured block - An executable statement with a single entry at the
11687 // top and a single exit at the bottom.
11688 // The point of exit cannot be a branch out of the structured block.
11689 // longjmp() and throw() must not violate the entry/exit criteria.
11690 CS->getCapturedDecl()->setNothrow();
11691 for (int ThisCaptureLevel =
11692 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11693 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11694 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11695 // 1.2.2 OpenMP Language Terminology
11696 // Structured block - An executable statement with a single entry at the
11697 // top and a single exit at the bottom.
11698 // The point of exit cannot be a branch out of the structured block.
11699 // longjmp() and throw() must not violate the entry/exit criteria.
11700 CS->getCapturedDecl()->setNothrow();
11701 }
11702
11703 OMPLoopDirective::HelperExprs B;
11704 // In presence of clause 'collapse' with number of loops, it will
11705 // define the nested loops number.
11706 unsigned NestedLoopCount = checkOpenMPLoop(
11707 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11708 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11709 VarsWithImplicitDSA, B);
11710 if (NestedLoopCount == 0)
11711 return StmtError();
11712
11713 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11714, __PRETTY_FUNCTION__))
11714 "omp target teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11714, __PRETTY_FUNCTION__))
;
11715
11716 if (!CurContext->isDependentContext()) {
11717 // Finalize the clauses that need pre-built expressions for CodeGen.
11718 for (OMPClause *C : Clauses) {
11719 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11720 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11721 B.NumIterations, *this, CurScope,
11722 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11723 return StmtError();
11724 }
11725 }
11726
11727 if (checkSimdlenSafelenSpecified(*this, Clauses))
11728 return StmtError();
11729
11730 setFunctionHasBranchProtectedScope();
11731 return OMPTargetTeamsDistributeSimdDirective::Create(
11732 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11733}
11734
11735OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11736 SourceLocation StartLoc,
11737 SourceLocation LParenLoc,
11738 SourceLocation EndLoc) {
11739 OMPClause *Res = nullptr;
11740 switch (Kind) {
11741 case OMPC_final:
11742 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11743 break;
11744 case OMPC_num_threads:
11745 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11746 break;
11747 case OMPC_safelen:
11748 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11749 break;
11750 case OMPC_simdlen:
11751 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11752 break;
11753 case OMPC_allocator:
11754 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11755 break;
11756 case OMPC_collapse:
11757 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11758 break;
11759 case OMPC_ordered:
11760 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11761 break;
11762 case OMPC_num_teams:
11763 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11764 break;
11765 case OMPC_thread_limit:
11766 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11767 break;
11768 case OMPC_priority:
11769 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11770 break;
11771 case OMPC_grainsize:
11772 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11773 break;
11774 case OMPC_num_tasks:
11775 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11776 break;
11777 case OMPC_hint:
11778 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11779 break;
11780 case OMPC_depobj:
11781 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11782 break;
11783 case OMPC_detach:
11784 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11785 break;
11786 case OMPC_device:
11787 case OMPC_if:
11788 case OMPC_default:
11789 case OMPC_proc_bind:
11790 case OMPC_schedule:
11791 case OMPC_private:
11792 case OMPC_firstprivate:
11793 case OMPC_lastprivate:
11794 case OMPC_shared:
11795 case OMPC_reduction:
11796 case OMPC_task_reduction:
11797 case OMPC_in_reduction:
11798 case OMPC_linear:
11799 case OMPC_aligned:
11800 case OMPC_copyin:
11801 case OMPC_copyprivate:
11802 case OMPC_nowait:
11803 case OMPC_untied:
11804 case OMPC_mergeable:
11805 case OMPC_threadprivate:
11806 case OMPC_allocate:
11807 case OMPC_flush:
11808 case OMPC_read:
11809 case OMPC_write:
11810 case OMPC_update:
11811 case OMPC_capture:
11812 case OMPC_seq_cst:
11813 case OMPC_acq_rel:
11814 case OMPC_acquire:
11815 case OMPC_release:
11816 case OMPC_relaxed:
11817 case OMPC_depend:
11818 case OMPC_threads:
11819 case OMPC_simd:
11820 case OMPC_map:
11821 case OMPC_nogroup:
11822 case OMPC_dist_schedule:
11823 case OMPC_defaultmap:
11824 case OMPC_unknown:
11825 case OMPC_uniform:
11826 case OMPC_to:
11827 case OMPC_from:
11828 case OMPC_use_device_ptr:
11829 case OMPC_use_device_addr:
11830 case OMPC_is_device_ptr:
11831 case OMPC_unified_address:
11832 case OMPC_unified_shared_memory:
11833 case OMPC_reverse_offload:
11834 case OMPC_dynamic_allocators:
11835 case OMPC_atomic_default_mem_order:
11836 case OMPC_device_type:
11837 case OMPC_match:
11838 case OMPC_nontemporal:
11839 case OMPC_order:
11840 case OMPC_destroy:
11841 case OMPC_inclusive:
11842 case OMPC_exclusive:
11843 case OMPC_uses_allocators:
11844 case OMPC_affinity:
11845 default:
11846 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11846)
;
11847 }
11848 return Res;
11849}
11850
11851// An OpenMP directive such as 'target parallel' has two captured regions:
11852// for the 'target' and 'parallel' respectively. This function returns
11853// the region in which to capture expressions associated with a clause.
11854// A return value of OMPD_unknown signifies that the expression should not
11855// be captured.
11856static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11857 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11858 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11859 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11860 switch (CKind) {
11861 case OMPC_if:
11862 switch (DKind) {
11863 case OMPD_target_parallel_for_simd:
11864 if (OpenMPVersion >= 50 &&
11865 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11866 CaptureRegion = OMPD_parallel;
11867 break;
11868 }
11869 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11870 case OMPD_target_parallel:
11871 case OMPD_target_parallel_for:
11872 // If this clause applies to the nested 'parallel' region, capture within
11873 // the 'target' region, otherwise do not capture.
11874 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11875 CaptureRegion = OMPD_target;
11876 break;
11877 case OMPD_target_teams_distribute_parallel_for_simd:
11878 if (OpenMPVersion >= 50 &&
11879 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11880 CaptureRegion = OMPD_parallel;
11881 break;
11882 }
11883 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11884 case OMPD_target_teams_distribute_parallel_for:
11885 // If this clause applies to the nested 'parallel' region, capture within
11886 // the 'teams' region, otherwise do not capture.
11887 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11888 CaptureRegion = OMPD_teams;
11889 break;
11890 case OMPD_teams_distribute_parallel_for_simd:
11891 if (OpenMPVersion >= 50 &&
11892 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11893 CaptureRegion = OMPD_parallel;
11894 break;
11895 }
11896 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11897 case OMPD_teams_distribute_parallel_for:
11898 CaptureRegion = OMPD_teams;
11899 break;
11900 case OMPD_target_update:
11901 case OMPD_target_enter_data:
11902 case OMPD_target_exit_data:
11903 CaptureRegion = OMPD_task;
11904 break;
11905 case OMPD_parallel_master_taskloop:
11906 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11907 CaptureRegion = OMPD_parallel;
11908 break;
11909 case OMPD_parallel_master_taskloop_simd:
11910 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11911 NameModifier == OMPD_taskloop) {
11912 CaptureRegion = OMPD_parallel;
11913 break;
11914 }
11915 if (OpenMPVersion <= 45)
11916 break;
11917 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11918 CaptureRegion = OMPD_taskloop;
11919 break;
11920 case OMPD_parallel_for_simd:
11921 if (OpenMPVersion <= 45)
11922 break;
11923 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11924 CaptureRegion = OMPD_parallel;
11925 break;
11926 case OMPD_taskloop_simd:
11927 case OMPD_master_taskloop_simd:
11928 if (OpenMPVersion <= 45)
11929 break;
11930 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11931 CaptureRegion = OMPD_taskloop;
11932 break;
11933 case OMPD_distribute_parallel_for_simd:
11934 if (OpenMPVersion <= 45)
11935 break;
11936 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11937 CaptureRegion = OMPD_parallel;
11938 break;
11939 case OMPD_target_simd:
11940 if (OpenMPVersion >= 50 &&
11941 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11942 CaptureRegion = OMPD_target;
11943 break;
11944 case OMPD_teams_distribute_simd:
11945 case OMPD_target_teams_distribute_simd:
11946 if (OpenMPVersion >= 50 &&
11947 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11948 CaptureRegion = OMPD_teams;
11949 break;
11950 case OMPD_cancel:
11951 case OMPD_parallel:
11952 case OMPD_parallel_master:
11953 case OMPD_parallel_sections:
11954 case OMPD_parallel_for:
11955 case OMPD_target:
11956 case OMPD_target_teams:
11957 case OMPD_target_teams_distribute:
11958 case OMPD_distribute_parallel_for:
11959 case OMPD_task:
11960 case OMPD_taskloop:
11961 case OMPD_master_taskloop:
11962 case OMPD_target_data:
11963 case OMPD_simd:
11964 case OMPD_for_simd:
11965 case OMPD_distribute_simd:
11966 // Do not capture if-clause expressions.
11967 break;
11968 case OMPD_threadprivate:
11969 case OMPD_allocate:
11970 case OMPD_taskyield:
11971 case OMPD_barrier:
11972 case OMPD_taskwait:
11973 case OMPD_cancellation_point:
11974 case OMPD_flush:
11975 case OMPD_depobj:
11976 case OMPD_scan:
11977 case OMPD_declare_reduction:
11978 case OMPD_declare_mapper:
11979 case OMPD_declare_simd:
11980 case OMPD_declare_variant:
11981 case OMPD_begin_declare_variant:
11982 case OMPD_end_declare_variant:
11983 case OMPD_declare_target:
11984 case OMPD_end_declare_target:
11985 case OMPD_teams:
11986 case OMPD_for:
11987 case OMPD_sections:
11988 case OMPD_section:
11989 case OMPD_single:
11990 case OMPD_master:
11991 case OMPD_critical:
11992 case OMPD_taskgroup:
11993 case OMPD_distribute:
11994 case OMPD_ordered:
11995 case OMPD_atomic:
11996 case OMPD_teams_distribute:
11997 case OMPD_requires:
11998 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 11998)
;
11999 case OMPD_unknown:
12000 default:
12001 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12001)
;
12002 }
12003 break;
12004 case OMPC_num_threads:
12005 switch (DKind) {
12006 case OMPD_target_parallel:
12007 case OMPD_target_parallel_for:
12008 case OMPD_target_parallel_for_simd:
12009 CaptureRegion = OMPD_target;
12010 break;
12011 case OMPD_teams_distribute_parallel_for:
12012 case OMPD_teams_distribute_parallel_for_simd:
12013 case OMPD_target_teams_distribute_parallel_for:
12014 case OMPD_target_teams_distribute_parallel_for_simd:
12015 CaptureRegion = OMPD_teams;
12016 break;
12017 case OMPD_parallel:
12018 case OMPD_parallel_master:
12019 case OMPD_parallel_sections:
12020 case OMPD_parallel_for:
12021 case OMPD_parallel_for_simd:
12022 case OMPD_distribute_parallel_for:
12023 case OMPD_distribute_parallel_for_simd:
12024 case OMPD_parallel_master_taskloop:
12025 case OMPD_parallel_master_taskloop_simd:
12026 // Do not capture num_threads-clause expressions.
12027 break;
12028 case OMPD_target_data:
12029 case OMPD_target_enter_data:
12030 case OMPD_target_exit_data:
12031 case OMPD_target_update:
12032 case OMPD_target:
12033 case OMPD_target_simd:
12034 case OMPD_target_teams:
12035 case OMPD_target_teams_distribute:
12036 case OMPD_target_teams_distribute_simd:
12037 case OMPD_cancel:
12038 case OMPD_task:
12039 case OMPD_taskloop:
12040 case OMPD_taskloop_simd:
12041 case OMPD_master_taskloop:
12042 case OMPD_master_taskloop_simd:
12043 case OMPD_threadprivate:
12044 case OMPD_allocate:
12045 case OMPD_taskyield:
12046 case OMPD_barrier:
12047 case OMPD_taskwait:
12048 case OMPD_cancellation_point:
12049 case OMPD_flush:
12050 case OMPD_depobj:
12051 case OMPD_scan:
12052 case OMPD_declare_reduction:
12053 case OMPD_declare_mapper:
12054 case OMPD_declare_simd:
12055 case OMPD_declare_variant:
12056 case OMPD_begin_declare_variant:
12057 case OMPD_end_declare_variant:
12058 case OMPD_declare_target:
12059 case OMPD_end_declare_target:
12060 case OMPD_teams:
12061 case OMPD_simd:
12062 case OMPD_for:
12063 case OMPD_for_simd:
12064 case OMPD_sections:
12065 case OMPD_section:
12066 case OMPD_single:
12067 case OMPD_master:
12068 case OMPD_critical:
12069 case OMPD_taskgroup:
12070 case OMPD_distribute:
12071 case OMPD_ordered:
12072 case OMPD_atomic:
12073 case OMPD_distribute_simd:
12074 case OMPD_teams_distribute:
12075 case OMPD_teams_distribute_simd:
12076 case OMPD_requires:
12077 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12077)
;
12078 case OMPD_unknown:
12079 default:
12080 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12080)
;
12081 }
12082 break;
12083 case OMPC_num_teams:
12084 switch (DKind) {
12085 case OMPD_target_teams:
12086 case OMPD_target_teams_distribute:
12087 case OMPD_target_teams_distribute_simd:
12088 case OMPD_target_teams_distribute_parallel_for:
12089 case OMPD_target_teams_distribute_parallel_for_simd:
12090 CaptureRegion = OMPD_target;
12091 break;
12092 case OMPD_teams_distribute_parallel_for:
12093 case OMPD_teams_distribute_parallel_for_simd:
12094 case OMPD_teams:
12095 case OMPD_teams_distribute:
12096 case OMPD_teams_distribute_simd:
12097 // Do not capture num_teams-clause expressions.
12098 break;
12099 case OMPD_distribute_parallel_for:
12100 case OMPD_distribute_parallel_for_simd:
12101 case OMPD_task:
12102 case OMPD_taskloop:
12103 case OMPD_taskloop_simd:
12104 case OMPD_master_taskloop:
12105 case OMPD_master_taskloop_simd:
12106 case OMPD_parallel_master_taskloop:
12107 case OMPD_parallel_master_taskloop_simd:
12108 case OMPD_target_data:
12109 case OMPD_target_enter_data:
12110 case OMPD_target_exit_data:
12111 case OMPD_target_update:
12112 case OMPD_cancel:
12113 case OMPD_parallel:
12114 case OMPD_parallel_master:
12115 case OMPD_parallel_sections:
12116 case OMPD_parallel_for:
12117 case OMPD_parallel_for_simd:
12118 case OMPD_target:
12119 case OMPD_target_simd:
12120 case OMPD_target_parallel:
12121 case OMPD_target_parallel_for:
12122 case OMPD_target_parallel_for_simd:
12123 case OMPD_threadprivate:
12124 case OMPD_allocate:
12125 case OMPD_taskyield:
12126 case OMPD_barrier:
12127 case OMPD_taskwait:
12128 case OMPD_cancellation_point:
12129 case OMPD_flush:
12130 case OMPD_depobj:
12131 case OMPD_scan:
12132 case OMPD_declare_reduction:
12133 case OMPD_declare_mapper:
12134 case OMPD_declare_simd:
12135 case OMPD_declare_variant:
12136 case OMPD_begin_declare_variant:
12137 case OMPD_end_declare_variant:
12138 case OMPD_declare_target:
12139 case OMPD_end_declare_target:
12140 case OMPD_simd:
12141 case OMPD_for:
12142 case OMPD_for_simd:
12143 case OMPD_sections:
12144 case OMPD_section:
12145 case OMPD_single:
12146 case OMPD_master:
12147 case OMPD_critical:
12148 case OMPD_taskgroup:
12149 case OMPD_distribute:
12150 case OMPD_ordered:
12151 case OMPD_atomic:
12152 case OMPD_distribute_simd:
12153 case OMPD_requires:
12154 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12154)
;
12155 case OMPD_unknown:
12156 default:
12157 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12157)
;
12158 }
12159 break;
12160 case OMPC_thread_limit:
12161 switch (DKind) {
12162 case OMPD_target_teams:
12163 case OMPD_target_teams_distribute:
12164 case OMPD_target_teams_distribute_simd:
12165 case OMPD_target_teams_distribute_parallel_for:
12166 case OMPD_target_teams_distribute_parallel_for_simd:
12167 CaptureRegion = OMPD_target;
12168 break;
12169 case OMPD_teams_distribute_parallel_for:
12170 case OMPD_teams_distribute_parallel_for_simd:
12171 case OMPD_teams:
12172 case OMPD_teams_distribute:
12173 case OMPD_teams_distribute_simd:
12174 // Do not capture thread_limit-clause expressions.
12175 break;
12176 case OMPD_distribute_parallel_for:
12177 case OMPD_distribute_parallel_for_simd:
12178 case OMPD_task:
12179 case OMPD_taskloop:
12180 case OMPD_taskloop_simd:
12181 case OMPD_master_taskloop:
12182 case OMPD_master_taskloop_simd:
12183 case OMPD_parallel_master_taskloop:
12184 case OMPD_parallel_master_taskloop_simd:
12185 case OMPD_target_data:
12186 case OMPD_target_enter_data:
12187 case OMPD_target_exit_data:
12188 case OMPD_target_update:
12189 case OMPD_cancel:
12190 case OMPD_parallel:
12191 case OMPD_parallel_master:
12192 case OMPD_parallel_sections:
12193 case OMPD_parallel_for:
12194 case OMPD_parallel_for_simd:
12195 case OMPD_target:
12196 case OMPD_target_simd:
12197 case OMPD_target_parallel:
12198 case OMPD_target_parallel_for:
12199 case OMPD_target_parallel_for_simd:
12200 case OMPD_threadprivate:
12201 case OMPD_allocate:
12202 case OMPD_taskyield:
12203 case OMPD_barrier:
12204 case OMPD_taskwait:
12205 case OMPD_cancellation_point:
12206 case OMPD_flush:
12207 case OMPD_depobj:
12208 case OMPD_scan:
12209 case OMPD_declare_reduction:
12210 case OMPD_declare_mapper:
12211 case OMPD_declare_simd:
12212 case OMPD_declare_variant:
12213 case OMPD_begin_declare_variant:
12214 case OMPD_end_declare_variant:
12215 case OMPD_declare_target:
12216 case OMPD_end_declare_target:
12217 case OMPD_simd:
12218 case OMPD_for:
12219 case OMPD_for_simd:
12220 case OMPD_sections:
12221 case OMPD_section:
12222 case OMPD_single:
12223 case OMPD_master:
12224 case OMPD_critical:
12225 case OMPD_taskgroup:
12226 case OMPD_distribute:
12227 case OMPD_ordered:
12228 case OMPD_atomic:
12229 case OMPD_distribute_simd:
12230 case OMPD_requires:
12231 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12231)
;
12232 case OMPD_unknown:
12233 default:
12234 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12234)
;
12235 }
12236 break;
12237 case OMPC_schedule:
12238 switch (DKind) {
12239 case OMPD_parallel_for:
12240 case OMPD_parallel_for_simd:
12241 case OMPD_distribute_parallel_for:
12242 case OMPD_distribute_parallel_for_simd:
12243 case OMPD_teams_distribute_parallel_for:
12244 case OMPD_teams_distribute_parallel_for_simd:
12245 case OMPD_target_parallel_for:
12246 case OMPD_target_parallel_for_simd:
12247 case OMPD_target_teams_distribute_parallel_for:
12248 case OMPD_target_teams_distribute_parallel_for_simd:
12249 CaptureRegion = OMPD_parallel;
12250 break;
12251 case OMPD_for:
12252 case OMPD_for_simd:
12253 // Do not capture schedule-clause expressions.
12254 break;
12255 case OMPD_task:
12256 case OMPD_taskloop:
12257 case OMPD_taskloop_simd:
12258 case OMPD_master_taskloop:
12259 case OMPD_master_taskloop_simd:
12260 case OMPD_parallel_master_taskloop:
12261 case OMPD_parallel_master_taskloop_simd:
12262 case OMPD_target_data:
12263 case OMPD_target_enter_data:
12264 case OMPD_target_exit_data:
12265 case OMPD_target_update:
12266 case OMPD_teams:
12267 case OMPD_teams_distribute:
12268 case OMPD_teams_distribute_simd:
12269 case OMPD_target_teams_distribute:
12270 case OMPD_target_teams_distribute_simd:
12271 case OMPD_target:
12272 case OMPD_target_simd:
12273 case OMPD_target_parallel:
12274 case OMPD_cancel:
12275 case OMPD_parallel:
12276 case OMPD_parallel_master:
12277 case OMPD_parallel_sections:
12278 case OMPD_threadprivate:
12279 case OMPD_allocate:
12280 case OMPD_taskyield:
12281 case OMPD_barrier:
12282 case OMPD_taskwait:
12283 case OMPD_cancellation_point:
12284 case OMPD_flush:
12285 case OMPD_depobj:
12286 case OMPD_scan:
12287 case OMPD_declare_reduction:
12288 case OMPD_declare_mapper:
12289 case OMPD_declare_simd:
12290 case OMPD_declare_variant:
12291 case OMPD_begin_declare_variant:
12292 case OMPD_end_declare_variant:
12293 case OMPD_declare_target:
12294 case OMPD_end_declare_target:
12295 case OMPD_simd:
12296 case OMPD_sections:
12297 case OMPD_section:
12298 case OMPD_single:
12299 case OMPD_master:
12300 case OMPD_critical:
12301 case OMPD_taskgroup:
12302 case OMPD_distribute:
12303 case OMPD_ordered:
12304 case OMPD_atomic:
12305 case OMPD_distribute_simd:
12306 case OMPD_target_teams:
12307 case OMPD_requires:
12308 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12308)
;
12309 case OMPD_unknown:
12310 default:
12311 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12311)
;
12312 }
12313 break;
12314 case OMPC_dist_schedule:
12315 switch (DKind) {
12316 case OMPD_teams_distribute_parallel_for:
12317 case OMPD_teams_distribute_parallel_for_simd:
12318 case OMPD_teams_distribute:
12319 case OMPD_teams_distribute_simd:
12320 case OMPD_target_teams_distribute_parallel_for:
12321 case OMPD_target_teams_distribute_parallel_for_simd:
12322 case OMPD_target_teams_distribute:
12323 case OMPD_target_teams_distribute_simd:
12324 CaptureRegion = OMPD_teams;
12325 break;
12326 case OMPD_distribute_parallel_for:
12327 case OMPD_distribute_parallel_for_simd:
12328 case OMPD_distribute:
12329 case OMPD_distribute_simd:
12330 // Do not capture thread_limit-clause expressions.
12331 break;
12332 case OMPD_parallel_for:
12333 case OMPD_parallel_for_simd:
12334 case OMPD_target_parallel_for_simd:
12335 case OMPD_target_parallel_for:
12336 case OMPD_task:
12337 case OMPD_taskloop:
12338 case OMPD_taskloop_simd:
12339 case OMPD_master_taskloop:
12340 case OMPD_master_taskloop_simd:
12341 case OMPD_parallel_master_taskloop:
12342 case OMPD_parallel_master_taskloop_simd:
12343 case OMPD_target_data:
12344 case OMPD_target_enter_data:
12345 case OMPD_target_exit_data:
12346 case OMPD_target_update:
12347 case OMPD_teams:
12348 case OMPD_target:
12349 case OMPD_target_simd:
12350 case OMPD_target_parallel:
12351 case OMPD_cancel:
12352 case OMPD_parallel:
12353 case OMPD_parallel_master:
12354 case OMPD_parallel_sections:
12355 case OMPD_threadprivate:
12356 case OMPD_allocate:
12357 case OMPD_taskyield:
12358 case OMPD_barrier:
12359 case OMPD_taskwait:
12360 case OMPD_cancellation_point:
12361 case OMPD_flush:
12362 case OMPD_depobj:
12363 case OMPD_scan:
12364 case OMPD_declare_reduction:
12365 case OMPD_declare_mapper:
12366 case OMPD_declare_simd:
12367 case OMPD_declare_variant:
12368 case OMPD_begin_declare_variant:
12369 case OMPD_end_declare_variant:
12370 case OMPD_declare_target:
12371 case OMPD_end_declare_target:
12372 case OMPD_simd:
12373 case OMPD_for:
12374 case OMPD_for_simd:
12375 case OMPD_sections:
12376 case OMPD_section:
12377 case OMPD_single:
12378 case OMPD_master:
12379 case OMPD_critical:
12380 case OMPD_taskgroup:
12381 case OMPD_ordered:
12382 case OMPD_atomic:
12383 case OMPD_target_teams:
12384 case OMPD_requires:
12385 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12385)
;
12386 case OMPD_unknown:
12387 default:
12388 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12388)
;
12389 }
12390 break;
12391 case OMPC_device:
12392 switch (DKind) {
12393 case OMPD_target_update:
12394 case OMPD_target_enter_data:
12395 case OMPD_target_exit_data:
12396 case OMPD_target:
12397 case OMPD_target_simd:
12398 case OMPD_target_teams:
12399 case OMPD_target_parallel:
12400 case OMPD_target_teams_distribute:
12401 case OMPD_target_teams_distribute_simd:
12402 case OMPD_target_parallel_for:
12403 case OMPD_target_parallel_for_simd:
12404 case OMPD_target_teams_distribute_parallel_for:
12405 case OMPD_target_teams_distribute_parallel_for_simd:
12406 CaptureRegion = OMPD_task;
12407 break;
12408 case OMPD_target_data:
12409 // Do not capture device-clause expressions.
12410 break;
12411 case OMPD_teams_distribute_parallel_for:
12412 case OMPD_teams_distribute_parallel_for_simd:
12413 case OMPD_teams:
12414 case OMPD_teams_distribute:
12415 case OMPD_teams_distribute_simd:
12416 case OMPD_distribute_parallel_for:
12417 case OMPD_distribute_parallel_for_simd:
12418 case OMPD_task:
12419 case OMPD_taskloop:
12420 case OMPD_taskloop_simd:
12421 case OMPD_master_taskloop:
12422 case OMPD_master_taskloop_simd:
12423 case OMPD_parallel_master_taskloop:
12424 case OMPD_parallel_master_taskloop_simd:
12425 case OMPD_cancel:
12426 case OMPD_parallel:
12427 case OMPD_parallel_master:
12428 case OMPD_parallel_sections:
12429 case OMPD_parallel_for:
12430 case OMPD_parallel_for_simd:
12431 case OMPD_threadprivate:
12432 case OMPD_allocate:
12433 case OMPD_taskyield:
12434 case OMPD_barrier:
12435 case OMPD_taskwait:
12436 case OMPD_cancellation_point:
12437 case OMPD_flush:
12438 case OMPD_depobj:
12439 case OMPD_scan:
12440 case OMPD_declare_reduction:
12441 case OMPD_declare_mapper:
12442 case OMPD_declare_simd:
12443 case OMPD_declare_variant:
12444 case OMPD_begin_declare_variant:
12445 case OMPD_end_declare_variant:
12446 case OMPD_declare_target:
12447 case OMPD_end_declare_target:
12448 case OMPD_simd:
12449 case OMPD_for:
12450 case OMPD_for_simd:
12451 case OMPD_sections:
12452 case OMPD_section:
12453 case OMPD_single:
12454 case OMPD_master:
12455 case OMPD_critical:
12456 case OMPD_taskgroup:
12457 case OMPD_distribute:
12458 case OMPD_ordered:
12459 case OMPD_atomic:
12460 case OMPD_distribute_simd:
12461 case OMPD_requires:
12462 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12462)
;
12463 case OMPD_unknown:
12464 default:
12465 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12465)
;
12466 }
12467 break;
12468 case OMPC_grainsize:
12469 case OMPC_num_tasks:
12470 case OMPC_final:
12471 case OMPC_priority:
12472 switch (DKind) {
12473 case OMPD_task:
12474 case OMPD_taskloop:
12475 case OMPD_taskloop_simd:
12476 case OMPD_master_taskloop:
12477 case OMPD_master_taskloop_simd:
12478 break;
12479 case OMPD_parallel_master_taskloop:
12480 case OMPD_parallel_master_taskloop_simd:
12481 CaptureRegion = OMPD_parallel;
12482 break;
12483 case OMPD_target_update:
12484 case OMPD_target_enter_data:
12485 case OMPD_target_exit_data:
12486 case OMPD_target:
12487 case OMPD_target_simd:
12488 case OMPD_target_teams:
12489 case OMPD_target_parallel:
12490 case OMPD_target_teams_distribute:
12491 case OMPD_target_teams_distribute_simd:
12492 case OMPD_target_parallel_for:
12493 case OMPD_target_parallel_for_simd:
12494 case OMPD_target_teams_distribute_parallel_for:
12495 case OMPD_target_teams_distribute_parallel_for_simd:
12496 case OMPD_target_data:
12497 case OMPD_teams_distribute_parallel_for:
12498 case OMPD_teams_distribute_parallel_for_simd:
12499 case OMPD_teams:
12500 case OMPD_teams_distribute:
12501 case OMPD_teams_distribute_simd:
12502 case OMPD_distribute_parallel_for:
12503 case OMPD_distribute_parallel_for_simd:
12504 case OMPD_cancel:
12505 case OMPD_parallel:
12506 case OMPD_parallel_master:
12507 case OMPD_parallel_sections:
12508 case OMPD_parallel_for:
12509 case OMPD_parallel_for_simd:
12510 case OMPD_threadprivate:
12511 case OMPD_allocate:
12512 case OMPD_taskyield:
12513 case OMPD_barrier:
12514 case OMPD_taskwait:
12515 case OMPD_cancellation_point:
12516 case OMPD_flush:
12517 case OMPD_depobj:
12518 case OMPD_scan:
12519 case OMPD_declare_reduction:
12520 case OMPD_declare_mapper:
12521 case OMPD_declare_simd:
12522 case OMPD_declare_variant:
12523 case OMPD_begin_declare_variant:
12524 case OMPD_end_declare_variant:
12525 case OMPD_declare_target:
12526 case OMPD_end_declare_target:
12527 case OMPD_simd:
12528 case OMPD_for:
12529 case OMPD_for_simd:
12530 case OMPD_sections:
12531 case OMPD_section:
12532 case OMPD_single:
12533 case OMPD_master:
12534 case OMPD_critical:
12535 case OMPD_taskgroup:
12536 case OMPD_distribute:
12537 case OMPD_ordered:
12538 case OMPD_atomic:
12539 case OMPD_distribute_simd:
12540 case OMPD_requires:
12541 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12541)
;
12542 case OMPD_unknown:
12543 default:
12544 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12544)
;
12545 }
12546 break;
12547 case OMPC_firstprivate:
12548 case OMPC_lastprivate:
12549 case OMPC_reduction:
12550 case OMPC_task_reduction:
12551 case OMPC_in_reduction:
12552 case OMPC_linear:
12553 case OMPC_default:
12554 case OMPC_proc_bind:
12555 case OMPC_safelen:
12556 case OMPC_simdlen:
12557 case OMPC_allocator:
12558 case OMPC_collapse:
12559 case OMPC_private:
12560 case OMPC_shared:
12561 case OMPC_aligned:
12562 case OMPC_copyin:
12563 case OMPC_copyprivate:
12564 case OMPC_ordered:
12565 case OMPC_nowait:
12566 case OMPC_untied:
12567 case OMPC_mergeable:
12568 case OMPC_threadprivate:
12569 case OMPC_allocate:
12570 case OMPC_flush:
12571 case OMPC_depobj:
12572 case OMPC_read:
12573 case OMPC_write:
12574 case OMPC_update:
12575 case OMPC_capture:
12576 case OMPC_seq_cst:
12577 case OMPC_acq_rel:
12578 case OMPC_acquire:
12579 case OMPC_release:
12580 case OMPC_relaxed:
12581 case OMPC_depend:
12582 case OMPC_threads:
12583 case OMPC_simd:
12584 case OMPC_map:
12585 case OMPC_nogroup:
12586 case OMPC_hint:
12587 case OMPC_defaultmap:
12588 case OMPC_unknown:
12589 case OMPC_uniform:
12590 case OMPC_to:
12591 case OMPC_from:
12592 case OMPC_use_device_ptr:
12593 case OMPC_use_device_addr:
12594 case OMPC_is_device_ptr:
12595 case OMPC_unified_address:
12596 case OMPC_unified_shared_memory:
12597 case OMPC_reverse_offload:
12598 case OMPC_dynamic_allocators:
12599 case OMPC_atomic_default_mem_order:
12600 case OMPC_device_type:
12601 case OMPC_match:
12602 case OMPC_nontemporal:
12603 case OMPC_order:
12604 case OMPC_destroy:
12605 case OMPC_detach:
12606 case OMPC_inclusive:
12607 case OMPC_exclusive:
12608 case OMPC_uses_allocators:
12609 case OMPC_affinity:
12610 default:
12611 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12611)
;
12612 }
12613 return CaptureRegion;
12614}
12615
12616OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12617 Expr *Condition, SourceLocation StartLoc,
12618 SourceLocation LParenLoc,
12619 SourceLocation NameModifierLoc,
12620 SourceLocation ColonLoc,
12621 SourceLocation EndLoc) {
12622 Expr *ValExpr = Condition;
12623 Stmt *HelperValStmt = nullptr;
12624 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12625 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12626 !Condition->isInstantiationDependent() &&
12627 !Condition->containsUnexpandedParameterPack()) {
12628 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12629 if (Val.isInvalid())
12630 return nullptr;
12631
12632 ValExpr = Val.get();
12633
12634 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12635 CaptureRegion = getOpenMPCaptureRegionForClause(
12636 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12637 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12638 ValExpr = MakeFullExpr(ValExpr).get();
12639 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12640 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12641 HelperValStmt = buildPreInits(Context, Captures);
12642 }
12643 }
12644
12645 return new (Context)
12646 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12647 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12648}
12649
12650OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12651 SourceLocation StartLoc,
12652 SourceLocation LParenLoc,
12653 SourceLocation EndLoc) {
12654 Expr *ValExpr = Condition;
12655 Stmt *HelperValStmt = nullptr;
12656 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12657 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12658 !Condition->isInstantiationDependent() &&
12659 !Condition->containsUnexpandedParameterPack()) {
12660 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12661 if (Val.isInvalid())
12662 return nullptr;
12663
12664 ValExpr = MakeFullExpr(Val.get()).get();
12665
12666 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12667 CaptureRegion =
12668 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12669 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12670 ValExpr = MakeFullExpr(ValExpr).get();
12671 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12672 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12673 HelperValStmt = buildPreInits(Context, Captures);
12674 }
12675 }
12676
12677 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12678 StartLoc, LParenLoc, EndLoc);
12679}
12680
12681ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12682 Expr *Op) {
12683 if (!Op)
12684 return ExprError();
12685
12686 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12687 public:
12688 IntConvertDiagnoser()
12689 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12690 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12691 QualType T) override {
12692 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12693 }
12694 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12695 QualType T) override {
12696 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12697 }
12698 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12699 QualType T,
12700 QualType ConvTy) override {
12701 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12702 }
12703 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12704 QualType ConvTy) override {
12705 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12706 << ConvTy->isEnumeralType() << ConvTy;
12707 }
12708 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12709 QualType T) override {
12710 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12711 }
12712 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12713 QualType ConvTy) override {
12714 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12715 << ConvTy->isEnumeralType() << ConvTy;
12716 }
12717 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12718 QualType) override {
12719 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 12719)
;
12720 }
12721 } ConvertDiagnoser;
12722 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12723}
12724
12725static bool
12726isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12727 bool StrictlyPositive, bool BuildCapture = false,
12728 OpenMPDirectiveKind DKind = OMPD_unknown,
12729 OpenMPDirectiveKind *CaptureRegion = nullptr,
12730 Stmt **HelperValStmt = nullptr) {
12731 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12732 !ValExpr->isInstantiationDependent()) {
12733 SourceLocation Loc = ValExpr->getExprLoc();
12734 ExprResult Value =
12735 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12736 if (Value.isInvalid())
12737 return false;
12738
12739 ValExpr = Value.get();
12740 // The expression must evaluate to a non-negative integer value.
12741 if (Optional<llvm::APSInt> Result =
12742 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12743 if (Result->isSigned() &&
12744 !((!StrictlyPositive && Result->isNonNegative()) ||
12745 (StrictlyPositive && Result->isStrictlyPositive()))) {
12746 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12747 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12748 << ValExpr->getSourceRange();
12749 return false;
12750 }
12751 }
12752 if (!BuildCapture)
12753 return true;
12754 *CaptureRegion =
12755 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12756 if (*CaptureRegion != OMPD_unknown &&
12757 !SemaRef.CurContext->isDependentContext()) {
12758 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12759 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12760 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12761 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12762 }
12763 }
12764 return true;
12765}
12766
12767OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12768 SourceLocation StartLoc,
12769 SourceLocation LParenLoc,
12770 SourceLocation EndLoc) {
12771 Expr *ValExpr = NumThreads;
12772 Stmt *HelperValStmt = nullptr;
12773
12774 // OpenMP [2.5, Restrictions]
12775 // The num_threads expression must evaluate to a positive integer value.
12776 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12777 /*StrictlyPositive=*/true))
12778 return nullptr;
12779
12780 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12781 OpenMPDirectiveKind CaptureRegion =
12782 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12783 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12784 ValExpr = MakeFullExpr(ValExpr).get();
12785 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12786 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12787 HelperValStmt = buildPreInits(Context, Captures);
12788 }
12789
12790 return new (Context) OMPNumThreadsClause(
12791 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12792}
12793
12794ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12795 OpenMPClauseKind CKind,
12796 bool StrictlyPositive) {
12797 if (!E)
12798 return ExprError();
12799 if (E->isValueDependent() || E->isTypeDependent() ||
12800 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12801 return E;
12802 llvm::APSInt Result;
12803 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
12804 if (ICE.isInvalid())
12805 return ExprError();
12806 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12807 (!StrictlyPositive && !Result.isNonNegative())) {
12808 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12809 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12810 << E->getSourceRange();
12811 return ExprError();
12812 }
12813 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12814 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12815 << E->getSourceRange();
12816 return ExprError();
12817 }
12818 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
12819 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12820 else if (CKind == OMPC_ordered)
12821 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12822 return ICE;
12823}
12824
12825OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12826 SourceLocation LParenLoc,
12827 SourceLocation EndLoc) {
12828 // OpenMP [2.8.1, simd construct, Description]
12829 // The parameter of the safelen clause must be a constant
12830 // positive integer expression.
12831 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12832 if (Safelen.isInvalid())
12833 return nullptr;
12834 return new (Context)
12835 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12836}
12837
12838OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12839 SourceLocation LParenLoc,
12840 SourceLocation EndLoc) {
12841 // OpenMP [2.8.1, simd construct, Description]
12842 // The parameter of the simdlen clause must be a constant
12843 // positive integer expression.
12844 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12845 if (Simdlen.isInvalid())
12846 return nullptr;
12847 return new (Context)
12848 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12849}
12850
12851/// Tries to find omp_allocator_handle_t type.
12852static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12853 DSAStackTy *Stack) {
12854 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12855 if (!OMPAllocatorHandleT.isNull())
12856 return true;
12857 // Build the predefined allocator expressions.
12858 bool ErrorFound = false;
12859 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12860 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12861 StringRef Allocator =
12862 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12863 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12864 auto *VD = dyn_cast_or_null<ValueDecl>(
12865 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12866 if (!VD) {
12867 ErrorFound = true;
12868 break;
12869 }
12870 QualType AllocatorType =
12871 VD->getType().getNonLValueExprType(S.getASTContext());
12872 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12873 if (!Res.isUsable()) {
12874 ErrorFound = true;
12875 break;
12876 }
12877 if (OMPAllocatorHandleT.isNull())
12878 OMPAllocatorHandleT = AllocatorType;
12879 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12880 ErrorFound = true;
12881 break;
12882 }
12883 Stack->setAllocator(AllocatorKind, Res.get());
12884 }
12885 if (ErrorFound) {
12886 S.Diag(Loc, diag::err_omp_implied_type_not_found)
12887 << "omp_allocator_handle_t";
12888 return false;
12889 }
12890 OMPAllocatorHandleT.addConst();
12891 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12892 return true;
12893}
12894
12895OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12896 SourceLocation LParenLoc,
12897 SourceLocation EndLoc) {
12898 // OpenMP [2.11.3, allocate Directive, Description]
12899 // allocator is an expression of omp_allocator_handle_t type.
12900 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12901 return nullptr;
12902
12903 ExprResult Allocator = DefaultLvalueConversion(A);
12904 if (Allocator.isInvalid())
12905 return nullptr;
12906 Allocator = PerformImplicitConversion(Allocator.get(),
12907 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
12908 Sema::AA_Initializing,
12909 /*AllowExplicit=*/true);
12910 if (Allocator.isInvalid())
12911 return nullptr;
12912 return new (Context)
12913 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12914}
12915
12916OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12917 SourceLocation StartLoc,
12918 SourceLocation LParenLoc,
12919 SourceLocation EndLoc) {
12920 // OpenMP [2.7.1, loop construct, Description]
12921 // OpenMP [2.8.1, simd construct, Description]
12922 // OpenMP [2.9.6, distribute construct, Description]
12923 // The parameter of the collapse clause must be a constant
12924 // positive integer expression.
12925 ExprResult NumForLoopsResult =
12926 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12927 if (NumForLoopsResult.isInvalid())
12928 return nullptr;
12929 return new (Context)
12930 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12931}
12932
12933OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12934 SourceLocation EndLoc,
12935 SourceLocation LParenLoc,
12936 Expr *NumForLoops) {
12937 // OpenMP [2.7.1, loop construct, Description]
12938 // OpenMP [2.8.1, simd construct, Description]
12939 // OpenMP [2.9.6, distribute construct, Description]
12940 // The parameter of the ordered clause must be a constant
12941 // positive integer expression if any.
12942 if (NumForLoops && LParenLoc.isValid()) {
12943 ExprResult NumForLoopsResult =
12944 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12945 if (NumForLoopsResult.isInvalid())
12946 return nullptr;
12947 NumForLoops = NumForLoopsResult.get();
12948 } else {
12949 NumForLoops = nullptr;
12950 }
12951 auto *Clause = OMPOrderedClause::Create(
12952 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
12953 StartLoc, LParenLoc, EndLoc);
12954 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12955 return Clause;
12956}
12957
12958OMPClause *Sema::ActOnOpenMPSimpleClause(
12959 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12960 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12961 OMPClause *Res = nullptr;
12962 switch (Kind) {
12963 case OMPC_default:
12964 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12965 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12966 break;
12967 case OMPC_proc_bind:
12968 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12969 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12970 break;
12971 case OMPC_atomic_default_mem_order:
12972 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12973 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12974 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12975 break;
12976 case OMPC_order:
12977 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
12978 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12979 break;
12980 case OMPC_update:
12981 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
12982 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12983 break;
12984 case OMPC_if:
12985 case OMPC_final:
12986 case OMPC_num_threads:
12987 case OMPC_safelen:
12988 case OMPC_simdlen:
12989 case OMPC_allocator:
12990 case OMPC_collapse:
12991 case OMPC_schedule:
12992 case OMPC_private:
12993 case OMPC_firstprivate:
12994 case OMPC_lastprivate:
12995 case OMPC_shared:
12996 case OMPC_reduction:
12997 case OMPC_task_reduction:
12998 case OMPC_in_reduction:
12999 case OMPC_linear:
13000 case OMPC_aligned:
13001 case OMPC_copyin:
13002 case OMPC_copyprivate:
13003 case OMPC_ordered:
13004 case OMPC_nowait:
13005 case OMPC_untied:
13006 case OMPC_mergeable:
13007 case OMPC_threadprivate:
13008 case OMPC_allocate:
13009 case OMPC_flush:
13010 case OMPC_depobj:
13011 case OMPC_read:
13012 case OMPC_write:
13013 case OMPC_capture:
13014 case OMPC_seq_cst:
13015 case OMPC_acq_rel:
13016 case OMPC_acquire:
13017 case OMPC_release:
13018 case OMPC_relaxed:
13019 case OMPC_depend:
13020 case OMPC_device:
13021 case OMPC_threads:
13022 case OMPC_simd:
13023 case OMPC_map:
13024 case OMPC_num_teams:
13025 case OMPC_thread_limit:
13026 case OMPC_priority:
13027 case OMPC_grainsize:
13028 case OMPC_nogroup:
13029 case OMPC_num_tasks:
13030 case OMPC_hint:
13031 case OMPC_dist_schedule:
13032 case OMPC_defaultmap:
13033 case OMPC_unknown:
13034 case OMPC_uniform:
13035 case OMPC_to:
13036 case OMPC_from:
13037 case OMPC_use_device_ptr:
13038 case OMPC_use_device_addr:
13039 case OMPC_is_device_ptr:
13040 case OMPC_unified_address:
13041 case OMPC_unified_shared_memory:
13042 case OMPC_reverse_offload:
13043 case OMPC_dynamic_allocators:
13044 case OMPC_device_type:
13045 case OMPC_match:
13046 case OMPC_nontemporal:
13047 case OMPC_destroy:
13048 case OMPC_detach:
13049 case OMPC_inclusive:
13050 case OMPC_exclusive:
13051 case OMPC_uses_allocators:
13052 case OMPC_affinity:
13053 default:
13054 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13054)
;
13055 }
13056 return Res;
13057}
13058
13059static std::string
13060getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13061 ArrayRef<unsigned> Exclude = llvm::None) {
13062 SmallString<256> Buffer;
13063 llvm::raw_svector_ostream Out(Buffer);
13064 unsigned Skipped = Exclude.size();
13065 auto S = Exclude.begin(), E = Exclude.end();
13066 for (unsigned I = First; I < Last; ++I) {
13067 if (std::find(S, E, I) != E) {
13068 --Skipped;
13069 continue;
13070 }
13071 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13072 if (I + Skipped + 2 == Last)
13073 Out << " or ";
13074 else if (I + Skipped + 1 != Last)
13075 Out << ", ";
13076 }
13077 return std::string(Out.str());
13078}
13079
13080OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13081 SourceLocation KindKwLoc,
13082 SourceLocation StartLoc,
13083 SourceLocation LParenLoc,
13084 SourceLocation EndLoc) {
13085 if (Kind == OMP_DEFAULT_unknown) {
13086 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13087 << getListOfPossibleValues(OMPC_default, /*First=*/0,
13088 /*Last=*/unsigned(OMP_DEFAULT_unknown))
13089 << getOpenMPClauseName(OMPC_default);
13090 return nullptr;
13091 }
13092
13093 switch (Kind) {
13094 case OMP_DEFAULT_none:
13095 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
13096 break;
13097 case OMP_DEFAULT_shared:
13098 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
13099 break;
13100 case OMP_DEFAULT_firstprivate:
13101 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
13102 break;
13103 default:
13104 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13104)
;
13105 }
13106
13107 return new (Context)
13108 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13109}
13110
13111OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13112 SourceLocation KindKwLoc,
13113 SourceLocation StartLoc,
13114 SourceLocation LParenLoc,
13115 SourceLocation EndLoc) {
13116 if (Kind == OMP_PROC_BIND_unknown) {
13117 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13118 << getListOfPossibleValues(OMPC_proc_bind,
13119 /*First=*/unsigned(OMP_PROC_BIND_master),
13120 /*Last=*/5)
13121 << getOpenMPClauseName(OMPC_proc_bind);
13122 return nullptr;
13123 }
13124 return new (Context)
13125 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13126}
13127
13128OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13129 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13130 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13131 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13132 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13133 << getListOfPossibleValues(
13134 OMPC_atomic_default_mem_order, /*First=*/0,
13135 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13136 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13137 return nullptr;
13138 }
13139 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13140 LParenLoc, EndLoc);
13141}
13142
13143OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13144 SourceLocation KindKwLoc,
13145 SourceLocation StartLoc,
13146 SourceLocation LParenLoc,
13147 SourceLocation EndLoc) {
13148 if (Kind == OMPC_ORDER_unknown) {
13149 static_assert(OMPC_ORDER_unknown > 0,
13150 "OMPC_ORDER_unknown not greater than 0");
13151 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13152 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13153 /*Last=*/OMPC_ORDER_unknown)
13154 << getOpenMPClauseName(OMPC_order);
13155 return nullptr;
13156 }
13157 return new (Context)
13158 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13159}
13160
13161OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13162 SourceLocation KindKwLoc,
13163 SourceLocation StartLoc,
13164 SourceLocation LParenLoc,
13165 SourceLocation EndLoc) {
13166 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13167 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13168 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13169 OMPC_DEPEND_depobj};
13170 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13171 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13172 /*Last=*/OMPC_DEPEND_unknown, Except)
13173 << getOpenMPClauseName(OMPC_update);
13174 return nullptr;
13175 }
13176 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13177 EndLoc);
13178}
13179
13180OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13181 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13182 SourceLocation StartLoc, SourceLocation LParenLoc,
13183 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13184 SourceLocation EndLoc) {
13185 OMPClause *Res = nullptr;
13186 switch (Kind) {
13187 case OMPC_schedule:
13188 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13189 assert(Argument.size() == NumberOfElements &&((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13190, __PRETTY_FUNCTION__))
13190 ArgumentLoc.size() == NumberOfElements)((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13190, __PRETTY_FUNCTION__))
;
13191 Res = ActOnOpenMPScheduleClause(
13192 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13193 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13194 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13195 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13196 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13197 break;
13198 case OMPC_if:
13199 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13199, __PRETTY_FUNCTION__))
;
13200 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13201 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13202 DelimLoc, EndLoc);
13203 break;
13204 case OMPC_dist_schedule:
13205 Res = ActOnOpenMPDistScheduleClause(
13206 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13207 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13208 break;
13209 case OMPC_defaultmap:
13210 enum { Modifier, DefaultmapKind };
13211 Res = ActOnOpenMPDefaultmapClause(
13212 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13213 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13214 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13215 EndLoc);
13216 break;
13217 case OMPC_device:
13218 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13218, __PRETTY_FUNCTION__))
;
13219 Res = ActOnOpenMPDeviceClause(
13220 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13221 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13222 break;
13223 case OMPC_final:
13224 case OMPC_num_threads:
13225 case OMPC_safelen:
13226 case OMPC_simdlen:
13227 case OMPC_allocator:
13228 case OMPC_collapse:
13229 case OMPC_default:
13230 case OMPC_proc_bind:
13231 case OMPC_private:
13232 case OMPC_firstprivate:
13233 case OMPC_lastprivate:
13234 case OMPC_shared:
13235 case OMPC_reduction:
13236 case OMPC_task_reduction:
13237 case OMPC_in_reduction:
13238 case OMPC_linear:
13239 case OMPC_aligned:
13240 case OMPC_copyin:
13241 case OMPC_copyprivate:
13242 case OMPC_ordered:
13243 case OMPC_nowait:
13244 case OMPC_untied:
13245 case OMPC_mergeable:
13246 case OMPC_threadprivate:
13247 case OMPC_allocate:
13248 case OMPC_flush:
13249 case OMPC_depobj:
13250 case OMPC_read:
13251 case OMPC_write:
13252 case OMPC_update:
13253 case OMPC_capture:
13254 case OMPC_seq_cst:
13255 case OMPC_acq_rel:
13256 case OMPC_acquire:
13257 case OMPC_release:
13258 case OMPC_relaxed:
13259 case OMPC_depend:
13260 case OMPC_threads:
13261 case OMPC_simd:
13262 case OMPC_map:
13263 case OMPC_num_teams:
13264 case OMPC_thread_limit:
13265 case OMPC_priority:
13266 case OMPC_grainsize:
13267 case OMPC_nogroup:
13268 case OMPC_num_tasks:
13269 case OMPC_hint:
13270 case OMPC_unknown:
13271 case OMPC_uniform:
13272 case OMPC_to:
13273 case OMPC_from:
13274 case OMPC_use_device_ptr:
13275 case OMPC_use_device_addr:
13276 case OMPC_is_device_ptr:
13277 case OMPC_unified_address:
13278 case OMPC_unified_shared_memory:
13279 case OMPC_reverse_offload:
13280 case OMPC_dynamic_allocators:
13281 case OMPC_atomic_default_mem_order:
13282 case OMPC_device_type:
13283 case OMPC_match:
13284 case OMPC_nontemporal:
13285 case OMPC_order:
13286 case OMPC_destroy:
13287 case OMPC_detach:
13288 case OMPC_inclusive:
13289 case OMPC_exclusive:
13290 case OMPC_uses_allocators:
13291 case OMPC_affinity:
13292 default:
13293 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13293)
;
13294 }
13295 return Res;
13296}
13297
13298static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13299 OpenMPScheduleClauseModifier M2,
13300 SourceLocation M1Loc, SourceLocation M2Loc) {
13301 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13302 SmallVector<unsigned, 2> Excluded;
13303 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13304 Excluded.push_back(M2);
13305 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13306 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13307 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13308 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13309 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13310 << getListOfPossibleValues(OMPC_schedule,
13311 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13312 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13313 Excluded)
13314 << getOpenMPClauseName(OMPC_schedule);
13315 return true;
13316 }
13317 return false;
13318}
13319
13320OMPClause *Sema::ActOnOpenMPScheduleClause(
13321 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13322 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13323 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13324 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13325 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13326 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13327 return nullptr;
13328 // OpenMP, 2.7.1, Loop Construct, Restrictions
13329 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13330 // but not both.
13331 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13332 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13333 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13334 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13335 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13336 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13337 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13338 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13339 return nullptr;
13340 }
13341 if (Kind == OMPC_SCHEDULE_unknown) {
13342 std::string Values;
13343 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13344 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13345 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13346 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13347 Exclude);
13348 } else {
13349 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13350 /*Last=*/OMPC_SCHEDULE_unknown);
13351 }
13352 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13353 << Values << getOpenMPClauseName(OMPC_schedule);
13354 return nullptr;
13355 }
13356 // OpenMP, 2.7.1, Loop Construct, Restrictions
13357 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13358 // schedule(guided).
13359 // OpenMP 5.0 does not have this restriction.
13360 if (LangOpts.OpenMP < 50 &&
13361 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13362 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13363 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13364 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13365 diag::err_omp_schedule_nonmonotonic_static);
13366 return nullptr;
13367 }
13368 Expr *ValExpr = ChunkSize;
13369 Stmt *HelperValStmt = nullptr;
13370 if (ChunkSize) {
13371 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13372 !ChunkSize->isInstantiationDependent() &&
13373 !ChunkSize->containsUnexpandedParameterPack()) {
13374 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13375 ExprResult Val =
13376 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13377 if (Val.isInvalid())
13378 return nullptr;
13379
13380 ValExpr = Val.get();
13381
13382 // OpenMP [2.7.1, Restrictions]
13383 // chunk_size must be a loop invariant integer expression with a positive
13384 // value.
13385 if (Optional<llvm::APSInt> Result =
13386 ValExpr->getIntegerConstantExpr(Context)) {
13387 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13388 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13389 << "schedule" << 1 << ChunkSize->getSourceRange();
13390 return nullptr;
13391 }
13392 } else if (getOpenMPCaptureRegionForClause(
13393 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
13394 LangOpts.OpenMP) != OMPD_unknown &&
13395 !CurContext->isDependentContext()) {
13396 ValExpr = MakeFullExpr(ValExpr).get();
13397 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13398 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13399 HelperValStmt = buildPreInits(Context, Captures);
13400 }
13401 }
13402 }
13403
13404 return new (Context)
13405 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13406 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13407}
13408
13409OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13410 SourceLocation StartLoc,
13411 SourceLocation EndLoc) {
13412 OMPClause *Res = nullptr;
13413 switch (Kind) {
13414 case OMPC_ordered:
13415 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13416 break;
13417 case OMPC_nowait:
13418 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13419 break;
13420 case OMPC_untied:
13421 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13422 break;
13423 case OMPC_mergeable:
13424 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13425 break;
13426 case OMPC_read:
13427 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13428 break;
13429 case OMPC_write:
13430 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13431 break;
13432 case OMPC_update:
13433 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13434 break;
13435 case OMPC_capture:
13436 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13437 break;
13438 case OMPC_seq_cst:
13439 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13440 break;
13441 case OMPC_acq_rel:
13442 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13443 break;
13444 case OMPC_acquire:
13445 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13446 break;
13447 case OMPC_release:
13448 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13449 break;
13450 case OMPC_relaxed:
13451 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13452 break;
13453 case OMPC_threads:
13454 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13455 break;
13456 case OMPC_simd:
13457 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13458 break;
13459 case OMPC_nogroup:
13460 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13461 break;
13462 case OMPC_unified_address:
13463 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13464 break;
13465 case OMPC_unified_shared_memory:
13466 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13467 break;
13468 case OMPC_reverse_offload:
13469 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13470 break;
13471 case OMPC_dynamic_allocators:
13472 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13473 break;
13474 case OMPC_destroy:
13475 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13476 break;
13477 case OMPC_if:
13478 case OMPC_final:
13479 case OMPC_num_threads:
13480 case OMPC_safelen:
13481 case OMPC_simdlen:
13482 case OMPC_allocator:
13483 case OMPC_collapse:
13484 case OMPC_schedule:
13485 case OMPC_private:
13486 case OMPC_firstprivate:
13487 case OMPC_lastprivate:
13488 case OMPC_shared:
13489 case OMPC_reduction:
13490 case OMPC_task_reduction:
13491 case OMPC_in_reduction:
13492 case OMPC_linear:
13493 case OMPC_aligned:
13494 case OMPC_copyin:
13495 case OMPC_copyprivate:
13496 case OMPC_default:
13497 case OMPC_proc_bind:
13498 case OMPC_threadprivate:
13499 case OMPC_allocate:
13500 case OMPC_flush:
13501 case OMPC_depobj:
13502 case OMPC_depend:
13503 case OMPC_device:
13504 case OMPC_map:
13505 case OMPC_num_teams:
13506 case OMPC_thread_limit:
13507 case OMPC_priority:
13508 case OMPC_grainsize:
13509 case OMPC_num_tasks:
13510 case OMPC_hint:
13511 case OMPC_dist_schedule:
13512 case OMPC_defaultmap:
13513 case OMPC_unknown:
13514 case OMPC_uniform:
13515 case OMPC_to:
13516 case OMPC_from:
13517 case OMPC_use_device_ptr:
13518 case OMPC_use_device_addr:
13519 case OMPC_is_device_ptr:
13520 case OMPC_atomic_default_mem_order:
13521 case OMPC_device_type:
13522 case OMPC_match:
13523 case OMPC_nontemporal:
13524 case OMPC_order:
13525 case OMPC_detach:
13526 case OMPC_inclusive:
13527 case OMPC_exclusive:
13528 case OMPC_uses_allocators:
13529 case OMPC_affinity:
13530 default:
13531 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13531)
;
13532 }
13533 return Res;
13534}
13535
13536OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13537 SourceLocation EndLoc) {
13538 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
13539 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13540}
13541
13542OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13543 SourceLocation EndLoc) {
13544 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13545}
13546
13547OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13548 SourceLocation EndLoc) {
13549 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13550}
13551
13552OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13553 SourceLocation EndLoc) {
13554 return new (Context) OMPReadClause(StartLoc, EndLoc);
13555}
13556
13557OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13558 SourceLocation EndLoc) {
13559 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13560}
13561
13562OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13563 SourceLocation EndLoc) {
13564 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13565}
13566
13567OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13568 SourceLocation EndLoc) {
13569 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13570}
13571
13572OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13573 SourceLocation EndLoc) {
13574 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13575}
13576
13577OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13578 SourceLocation EndLoc) {
13579 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13580}
13581
13582OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13583 SourceLocation EndLoc) {
13584 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13585}
13586
13587OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13588 SourceLocation EndLoc) {
13589 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13590}
13591
13592OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13593 SourceLocation EndLoc) {
13594 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13595}
13596
13597OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13598 SourceLocation EndLoc) {
13599 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13600}
13601
13602OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13603 SourceLocation EndLoc) {
13604 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13605}
13606
13607OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13608 SourceLocation EndLoc) {
13609 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13610}
13611
13612OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13613 SourceLocation EndLoc) {
13614 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13615}
13616
13617OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13618 SourceLocation EndLoc) {
13619 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13620}
13621
13622OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13623 SourceLocation EndLoc) {
13624 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13625}
13626
13627OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13628 SourceLocation EndLoc) {
13629 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13630}
13631
13632OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13633 SourceLocation EndLoc) {
13634 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13635}
13636
13637OMPClause *Sema::ActOnOpenMPVarListClause(
13638 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13639 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13640 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13641 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13642 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13643 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13644 SourceLocation ExtraModifierLoc,
13645 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13646 ArrayRef<SourceLocation> MotionModifiersLoc) {
13647 SourceLocation StartLoc = Locs.StartLoc;
13648 SourceLocation LParenLoc = Locs.LParenLoc;
13649 SourceLocation EndLoc = Locs.EndLoc;
13650 OMPClause *Res = nullptr;
13651 switch (Kind) {
13652 case OMPC_private:
13653 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13654 break;
13655 case OMPC_firstprivate:
13656 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13657 break;
13658 case OMPC_lastprivate:
13659 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13660, __PRETTY_FUNCTION__))
13660 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13660, __PRETTY_FUNCTION__))
;
13661 Res = ActOnOpenMPLastprivateClause(
13662 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13663 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13664 break;
13665 case OMPC_shared:
13666 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13667 break;
13668 case OMPC_reduction:
13669 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13670, __PRETTY_FUNCTION__))
13670 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13670, __PRETTY_FUNCTION__))
;
13671 Res = ActOnOpenMPReductionClause(
13672 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13673 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13674 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13675 break;
13676 case OMPC_task_reduction:
13677 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13678 EndLoc, ReductionOrMapperIdScopeSpec,
13679 ReductionOrMapperId);
13680 break;
13681 case OMPC_in_reduction:
13682 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13683 EndLoc, ReductionOrMapperIdScopeSpec,
13684 ReductionOrMapperId);
13685 break;
13686 case OMPC_linear:
13687 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13688, __PRETTY_FUNCTION__))
13688 "Unexpected linear modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13688, __PRETTY_FUNCTION__))
;
13689 Res = ActOnOpenMPLinearClause(
13690 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13691 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13692 ColonLoc, EndLoc);
13693 break;
13694 case OMPC_aligned:
13695 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13696 LParenLoc, ColonLoc, EndLoc);
13697 break;
13698 case OMPC_copyin:
13699 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13700 break;
13701 case OMPC_copyprivate:
13702 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13703 break;
13704 case OMPC_flush:
13705 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13706 break;
13707 case OMPC_depend:
13708 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13709, __PRETTY_FUNCTION__))
13709 "Unexpected depend modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13709, __PRETTY_FUNCTION__))
;
13710 Res = ActOnOpenMPDependClause(
13711 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13712 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13713 break;
13714 case OMPC_map:
13715 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13716, __PRETTY_FUNCTION__))
13716 "Unexpected map modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13716, __PRETTY_FUNCTION__))
;
13717 Res = ActOnOpenMPMapClause(
13718 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13719 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13720 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13721 break;
13722 case OMPC_to:
13723 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13724 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13725 ColonLoc, VarList, Locs);
13726 break;
13727 case OMPC_from:
13728 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13729 ReductionOrMapperIdScopeSpec,
13730 ReductionOrMapperId, ColonLoc, VarList, Locs);
13731 break;
13732 case OMPC_use_device_ptr:
13733 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13734 break;
13735 case OMPC_use_device_addr:
13736 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13737 break;
13738 case OMPC_is_device_ptr:
13739 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13740 break;
13741 case OMPC_allocate:
13742 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13743 LParenLoc, ColonLoc, EndLoc);
13744 break;
13745 case OMPC_nontemporal:
13746 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13747 break;
13748 case OMPC_inclusive:
13749 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13750 break;
13751 case OMPC_exclusive:
13752 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13753 break;
13754 case OMPC_affinity:
13755 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13756 DepModOrTailExpr, VarList);
13757 break;
13758 case OMPC_if:
13759 case OMPC_depobj:
13760 case OMPC_final:
13761 case OMPC_num_threads:
13762 case OMPC_safelen:
13763 case OMPC_simdlen:
13764 case OMPC_allocator:
13765 case OMPC_collapse:
13766 case OMPC_default:
13767 case OMPC_proc_bind:
13768 case OMPC_schedule:
13769 case OMPC_ordered:
13770 case OMPC_nowait:
13771 case OMPC_untied:
13772 case OMPC_mergeable:
13773 case OMPC_threadprivate:
13774 case OMPC_read:
13775 case OMPC_write:
13776 case OMPC_update:
13777 case OMPC_capture:
13778 case OMPC_seq_cst:
13779 case OMPC_acq_rel:
13780 case OMPC_acquire:
13781 case OMPC_release:
13782 case OMPC_relaxed:
13783 case OMPC_device:
13784 case OMPC_threads:
13785 case OMPC_simd:
13786 case OMPC_num_teams:
13787 case OMPC_thread_limit:
13788 case OMPC_priority:
13789 case OMPC_grainsize:
13790 case OMPC_nogroup:
13791 case OMPC_num_tasks:
13792 case OMPC_hint:
13793 case OMPC_dist_schedule:
13794 case OMPC_defaultmap:
13795 case OMPC_unknown:
13796 case OMPC_uniform:
13797 case OMPC_unified_address:
13798 case OMPC_unified_shared_memory:
13799 case OMPC_reverse_offload:
13800 case OMPC_dynamic_allocators:
13801 case OMPC_atomic_default_mem_order:
13802 case OMPC_device_type:
13803 case OMPC_match:
13804 case OMPC_order:
13805 case OMPC_destroy:
13806 case OMPC_detach:
13807 case OMPC_uses_allocators:
13808 default:
13809 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13809)
;
13810 }
13811 return Res;
13812}
13813
13814ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13815 ExprObjectKind OK, SourceLocation Loc) {
13816 ExprResult Res = BuildDeclRefExpr(
13817 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13818 if (!Res.isUsable())
13819 return ExprError();
13820 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13821 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13822 if (!Res.isUsable())
13823 return ExprError();
13824 }
13825 if (VK != VK_LValue && Res.get()->isGLValue()) {
13826 Res = DefaultLvalueConversion(Res.get());
13827 if (!Res.isUsable())
13828 return ExprError();
13829 }
13830 return Res;
13831}
13832
13833OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13834 SourceLocation StartLoc,
13835 SourceLocation LParenLoc,
13836 SourceLocation EndLoc) {
13837 SmallVector<Expr *, 8> Vars;
13838 SmallVector<Expr *, 8> PrivateCopies;
13839 for (Expr *RefExpr : VarList) {
13840 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 13840, __PRETTY_FUNCTION__))
;
13841 SourceLocation ELoc;
13842 SourceRange ERange;
13843 Expr *SimpleRefExpr = RefExpr;
13844 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13845 if (Res.second) {
13846 // It will be analyzed later.
13847 Vars.push_back(RefExpr);
13848 PrivateCopies.push_back(nullptr);
13849 }
13850 ValueDecl *D = Res.first;
13851 if (!D)
13852 continue;
13853
13854 QualType Type = D->getType();
13855 auto *VD = dyn_cast<VarDecl>(D);
13856
13857 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13858 // A variable that appears in a private clause must not have an incomplete
13859 // type or a reference type.
13860 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13861 continue;
13862 Type = Type.getNonReferenceType();
13863
13864 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13865 // A variable that is privatized must not have a const-qualified type
13866 // unless it is of class type with a mutable member. This restriction does
13867 // not apply to the firstprivate clause.
13868 //
13869 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13870 // A variable that appears in a private clause must not have a
13871 // const-qualified type unless it is of class type with a mutable member.
13872 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13873 continue;
13874
13875 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13876 // in a Construct]
13877 // Variables with the predetermined data-sharing attributes may not be
13878 // listed in data-sharing attributes clauses, except for the cases
13879 // listed below. For these exceptions only, listing a predetermined
13880 // variable in a data-sharing attribute clause is allowed and overrides
13881 // the variable's predetermined data-sharing attributes.
13882 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13883 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13884 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13885 << getOpenMPClauseName(OMPC_private);
13886 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13887 continue;
13888 }
13889
13890 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13891 // Variably modified types are not supported for tasks.
13892 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13893 isOpenMPTaskingDirective(CurrDir)) {
13894 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13895 << getOpenMPClauseName(OMPC_private) << Type
13896 << getOpenMPDirectiveName(CurrDir);
13897 bool IsDecl =
13898 !VD ||
13899 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13900 Diag(D->getLocation(),
13901 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13902 << D;
13903 continue;
13904 }
13905
13906 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13907 // A list item cannot appear in both a map clause and a data-sharing
13908 // attribute clause on the same construct
13909 //
13910 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13911 // A list item cannot appear in both a map clause and a data-sharing
13912 // attribute clause on the same construct unless the construct is a
13913 // combined construct.
13914 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13915 CurrDir == OMPD_target) {
13916 OpenMPClauseKind ConflictKind;
13917 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
13918 VD, /*CurrentRegionOnly=*/true,
13919 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13920 OpenMPClauseKind WhereFoundClauseKind) -> bool {
13921 ConflictKind = WhereFoundClauseKind;
13922 return true;
13923 })) {
13924 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13925 << getOpenMPClauseName(OMPC_private)
13926 << getOpenMPClauseName(ConflictKind)
13927 << getOpenMPDirectiveName(CurrDir);
13928 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13929 continue;
13930 }
13931 }
13932
13933 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13934 // A variable of class type (or array thereof) that appears in a private
13935 // clause requires an accessible, unambiguous default constructor for the
13936 // class type.
13937 // Generate helper private variable and initialize it with the default
13938 // value. The address of the original variable is replaced by the address of
13939 // the new private variable in CodeGen. This new variable is not added to
13940 // IdResolver, so the code in the OpenMP region uses original variable for
13941 // proper diagnostics.
13942 Type = Type.getUnqualifiedType();
13943 VarDecl *VDPrivate =
13944 buildVarDecl(*this, ELoc, Type, D->getName(),
13945 D->hasAttrs() ? &D->getAttrs() : nullptr,
13946 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13947 ActOnUninitializedDecl(VDPrivate);
13948 if (VDPrivate->isInvalidDecl())
13949 continue;
13950 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13951 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13952
13953 DeclRefExpr *Ref = nullptr;
13954 if (!VD && !CurContext->isDependentContext())
13955 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13956 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13957 Vars.push_back((VD || CurContext->isDependentContext())
13958 ? RefExpr->IgnoreParens()
13959 : Ref);
13960 PrivateCopies.push_back(VDPrivateRefExpr);
13961 }
13962
13963 if (Vars.empty())
13964 return nullptr;
13965
13966 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13967 PrivateCopies);
13968}
13969
13970namespace {
13971class DiagsUninitializedSeveretyRAII {
13972private:
13973 DiagnosticsEngine &Diags;
13974 SourceLocation SavedLoc;
13975 bool IsIgnored = false;
13976
13977public:
13978 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
13979 bool IsIgnored)
13980 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
13981 if (!IsIgnored) {
13982 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
13983 /*Map*/ diag::Severity::Ignored, Loc);
13984 }
13985 }
13986 ~DiagsUninitializedSeveretyRAII() {
13987 if (!IsIgnored)
13988 Diags.popMappings(SavedLoc);
13989 }
13990};
13991}
13992
13993OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
13994 SourceLocation StartLoc,
13995 SourceLocation LParenLoc,
13996 SourceLocation EndLoc) {
13997 SmallVector<Expr *, 8> Vars;
13998 SmallVector<Expr *, 8> PrivateCopies;
13999 SmallVector<Expr *, 8> Inits;
14000 SmallVector<Decl *, 4> ExprCaptures;
14001 bool IsImplicitClause =
14002 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14003 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
14004
14005 for (Expr *RefExpr : VarList) {
14006 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((RefExpr && "NULL expr in OpenMP firstprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14006, __PRETTY_FUNCTION__))
;
14007 SourceLocation ELoc;
14008 SourceRange ERange;
14009 Expr *SimpleRefExpr = RefExpr;
14010 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14011 if (Res.second) {
14012 // It will be analyzed later.
14013 Vars.push_back(RefExpr);
14014 PrivateCopies.push_back(nullptr);
14015 Inits.push_back(nullptr);
14016 }
14017 ValueDecl *D = Res.first;
14018 if (!D)
14019 continue;
14020
14021 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14022 QualType Type = D->getType();
14023 auto *VD = dyn_cast<VarDecl>(D);
14024
14025 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14026 // A variable that appears in a private clause must not have an incomplete
14027 // type or a reference type.
14028 if (RequireCompleteType(ELoc, Type,
14029 diag::err_omp_firstprivate_incomplete_type))
14030 continue;
14031 Type = Type.getNonReferenceType();
14032
14033 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14034 // A variable of class type (or array thereof) that appears in a private
14035 // clause requires an accessible, unambiguous copy constructor for the
14036 // class type.
14037 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14038
14039 // If an implicit firstprivate variable found it was checked already.
14040 DSAStackTy::DSAVarData TopDVar;
14041 if (!IsImplicitClause) {
14042 DSAStackTy::DSAVarData DVar =
14043 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14044 TopDVar = DVar;
14045 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14046 bool IsConstant = ElemType.isConstant(Context);
14047 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14048 // A list item that specifies a given variable may not appear in more
14049 // than one clause on the same directive, except that a variable may be
14050 // specified in both firstprivate and lastprivate clauses.
14051 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14052 // A list item may appear in a firstprivate or lastprivate clause but not
14053 // both.
14054 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14055 (isOpenMPDistributeDirective(CurrDir) ||
14056 DVar.CKind != OMPC_lastprivate) &&
14057 DVar.RefExpr) {
14058 Diag(ELoc, diag::err_omp_wrong_dsa)
14059 << getOpenMPClauseName(DVar.CKind)
14060 << getOpenMPClauseName(OMPC_firstprivate);
14061 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14062 continue;
14063 }
14064
14065 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14066 // in a Construct]
14067 // Variables with the predetermined data-sharing attributes may not be
14068 // listed in data-sharing attributes clauses, except for the cases
14069 // listed below. For these exceptions only, listing a predetermined
14070 // variable in a data-sharing attribute clause is allowed and overrides
14071 // the variable's predetermined data-sharing attributes.
14072 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14073 // in a Construct, C/C++, p.2]
14074 // Variables with const-qualified type having no mutable member may be
14075 // listed in a firstprivate clause, even if they are static data members.
14076 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14077 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14078 Diag(ELoc, diag::err_omp_wrong_dsa)
14079 << getOpenMPClauseName(DVar.CKind)
14080 << getOpenMPClauseName(OMPC_firstprivate);
14081 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14082 continue;
14083 }
14084
14085 // OpenMP [2.9.3.4, Restrictions, p.2]
14086 // A list item that is private within a parallel region must not appear
14087 // in a firstprivate clause on a worksharing construct if any of the
14088 // worksharing regions arising from the worksharing construct ever bind
14089 // to any of the parallel regions arising from the parallel construct.
14090 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14091 // A list item that is private within a teams region must not appear in a
14092 // firstprivate clause on a distribute construct if any of the distribute
14093 // regions arising from the distribute construct ever bind to any of the
14094 // teams regions arising from the teams construct.
14095 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14096 // A list item that appears in a reduction clause of a teams construct
14097 // must not appear in a firstprivate clause on a distribute construct if
14098 // any of the distribute regions arising from the distribute construct
14099 // ever bind to any of the teams regions arising from the teams construct.
14100 if ((isOpenMPWorksharingDirective(CurrDir) ||
14101 isOpenMPDistributeDirective(CurrDir)) &&
14102 !isOpenMPParallelDirective(CurrDir) &&
14103 !isOpenMPTeamsDirective(CurrDir)) {
14104 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14105 if (DVar.CKind != OMPC_shared &&
14106 (isOpenMPParallelDirective(DVar.DKind) ||
14107 isOpenMPTeamsDirective(DVar.DKind) ||
14108 DVar.DKind == OMPD_unknown)) {
14109 Diag(ELoc, diag::err_omp_required_access)
14110 << getOpenMPClauseName(OMPC_firstprivate)
14111 << getOpenMPClauseName(OMPC_shared);
14112 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14113 continue;
14114 }
14115 }
14116 // OpenMP [2.9.3.4, Restrictions, p.3]
14117 // A list item that appears in a reduction clause of a parallel construct
14118 // must not appear in a firstprivate clause on a worksharing or task
14119 // construct if any of the worksharing or task regions arising from the
14120 // worksharing or task construct ever bind to any of the parallel regions
14121 // arising from the parallel construct.
14122 // OpenMP [2.9.3.4, Restrictions, p.4]
14123 // A list item that appears in a reduction clause in worksharing
14124 // construct must not appear in a firstprivate clause in a task construct
14125 // encountered during execution of any of the worksharing regions arising
14126 // from the worksharing construct.
14127 if (isOpenMPTaskingDirective(CurrDir)) {
14128 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
14129 D,
14130 [](OpenMPClauseKind C, bool AppliedToPointee) {
14131 return C == OMPC_reduction && !AppliedToPointee;
14132 },
14133 [](OpenMPDirectiveKind K) {
14134 return isOpenMPParallelDirective(K) ||
14135 isOpenMPWorksharingDirective(K) ||
14136 isOpenMPTeamsDirective(K);
14137 },
14138 /*FromParent=*/true);
14139 if (DVar.CKind == OMPC_reduction &&
14140 (isOpenMPParallelDirective(DVar.DKind) ||
14141 isOpenMPWorksharingDirective(DVar.DKind) ||
14142 isOpenMPTeamsDirective(DVar.DKind))) {
14143 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14144 << getOpenMPDirectiveName(DVar.DKind);
14145 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14146 continue;
14147 }
14148 }
14149
14150 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14151 // A list item cannot appear in both a map clause and a data-sharing
14152 // attribute clause on the same construct
14153 //
14154 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14155 // A list item cannot appear in both a map clause and a data-sharing
14156 // attribute clause on the same construct unless the construct is a
14157 // combined construct.
14158 if ((LangOpts.OpenMP <= 45 &&
14159 isOpenMPTargetExecutionDirective(CurrDir)) ||
14160 CurrDir == OMPD_target) {
14161 OpenMPClauseKind ConflictKind;
14162 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14163 VD, /*CurrentRegionOnly=*/true,
14164 [&ConflictKind](
14165 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14166 OpenMPClauseKind WhereFoundClauseKind) {
14167 ConflictKind = WhereFoundClauseKind;
14168 return true;
14169 })) {
14170 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14171 << getOpenMPClauseName(OMPC_firstprivate)
14172 << getOpenMPClauseName(ConflictKind)
14173 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14174 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14175 continue;
14176 }
14177 }
14178 }
14179
14180 // Variably modified types are not supported for tasks.
14181 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14182 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
14183 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14184 << getOpenMPClauseName(OMPC_firstprivate) << Type
14185 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14186 bool IsDecl =
14187 !VD ||
14188 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14189 Diag(D->getLocation(),
14190 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14191 << D;
14192 continue;
14193 }
14194
14195 Type = Type.getUnqualifiedType();
14196 VarDecl *VDPrivate =
14197 buildVarDecl(*this, ELoc, Type, D->getName(),
14198 D->hasAttrs() ? &D->getAttrs() : nullptr,
14199 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14200 // Generate helper private variable and initialize it with the value of the
14201 // original variable. The address of the original variable is replaced by
14202 // the address of the new private variable in the CodeGen. This new variable
14203 // is not added to IdResolver, so the code in the OpenMP region uses
14204 // original variable for proper diagnostics and variable capturing.
14205 Expr *VDInitRefExpr = nullptr;
14206 // For arrays generate initializer for single element and replace it by the
14207 // original array element in CodeGen.
14208 if (Type->isArrayType()) {
14209 VarDecl *VDInit =
14210 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14211 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14212 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14213 ElemType = ElemType.getUnqualifiedType();
14214 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14215 ".firstprivate.temp");
14216 InitializedEntity Entity =
14217 InitializedEntity::InitializeVariable(VDInitTemp);
14218 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14219
14220 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14221 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14222 if (Result.isInvalid())
14223 VDPrivate->setInvalidDecl();
14224 else
14225 VDPrivate->setInit(Result.getAs<Expr>());
14226 // Remove temp variable declaration.
14227 Context.Deallocate(VDInitTemp);
14228 } else {
14229 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14230 ".firstprivate.temp");
14231 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14232 RefExpr->getExprLoc());
14233 AddInitializerToDecl(VDPrivate,
14234 DefaultLvalueConversion(VDInitRefExpr).get(),
14235 /*DirectInit=*/false);
14236 }
14237 if (VDPrivate->isInvalidDecl()) {
14238 if (IsImplicitClause) {
14239 Diag(RefExpr->getExprLoc(),
14240 diag::note_omp_task_predetermined_firstprivate_here);
14241 }
14242 continue;
14243 }
14244 CurContext->addDecl(VDPrivate);
14245 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14246 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14247 RefExpr->getExprLoc());
14248 DeclRefExpr *Ref = nullptr;
14249 if (!VD && !CurContext->isDependentContext()) {
14250 if (TopDVar.CKind == OMPC_lastprivate) {
14251 Ref = TopDVar.PrivateCopy;
14252 } else {
14253 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14254 if (!isOpenMPCapturedDecl(D))
14255 ExprCaptures.push_back(Ref->getDecl());
14256 }
14257 }
14258 if (!IsImplicitClause)
14259 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14260 Vars.push_back((VD || CurContext->isDependentContext())
14261 ? RefExpr->IgnoreParens()
14262 : Ref);
14263 PrivateCopies.push_back(VDPrivateRefExpr);
14264 Inits.push_back(VDInitRefExpr);
14265 }
14266
14267 if (Vars.empty())
14268 return nullptr;
14269
14270 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14271 Vars, PrivateCopies, Inits,
14272 buildPreInits(Context, ExprCaptures));
14273}
14274
14275OMPClause *Sema::ActOnOpenMPLastprivateClause(
14276 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14277 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14278 SourceLocation LParenLoc, SourceLocation EndLoc) {
14279 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14280 assert(ColonLoc.isValid() && "Colon location must be valid.")((ColonLoc.isValid() && "Colon location must be valid."
) ? static_cast<void> (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14280, __PRETTY_FUNCTION__))
;
14281 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14282 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14283 /*Last=*/OMPC_LASTPRIVATE_unknown)
14284 << getOpenMPClauseName(OMPC_lastprivate);
14285 return nullptr;
14286 }
14287
14288 SmallVector<Expr *, 8> Vars;
14289 SmallVector<Expr *, 8> SrcExprs;
14290 SmallVector<Expr *, 8> DstExprs;
14291 SmallVector<Expr *, 8> AssignmentOps;
14292 SmallVector<Decl *, 4> ExprCaptures;
14293 SmallVector<Expr *, 4> ExprPostUpdates;
14294 for (Expr *RefExpr : VarList) {
14295 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14295, __PRETTY_FUNCTION__))
;
14296 SourceLocation ELoc;
14297 SourceRange ERange;
14298 Expr *SimpleRefExpr = RefExpr;
14299 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14300 if (Res.second) {
14301 // It will be analyzed later.
14302 Vars.push_back(RefExpr);
14303 SrcExprs.push_back(nullptr);
14304 DstExprs.push_back(nullptr);
14305 AssignmentOps.push_back(nullptr);
14306 }
14307 ValueDecl *D = Res.first;
14308 if (!D)
14309 continue;
14310
14311 QualType Type = D->getType();
14312 auto *VD = dyn_cast<VarDecl>(D);
14313
14314 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14315 // A variable that appears in a lastprivate clause must not have an
14316 // incomplete type or a reference type.
14317 if (RequireCompleteType(ELoc, Type,
14318 diag::err_omp_lastprivate_incomplete_type))
14319 continue;
14320 Type = Type.getNonReferenceType();
14321
14322 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14323 // A variable that is privatized must not have a const-qualified type
14324 // unless it is of class type with a mutable member. This restriction does
14325 // not apply to the firstprivate clause.
14326 //
14327 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14328 // A variable that appears in a lastprivate clause must not have a
14329 // const-qualified type unless it is of class type with a mutable member.
14330 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14331 continue;
14332
14333 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14334 // A list item that appears in a lastprivate clause with the conditional
14335 // modifier must be a scalar variable.
14336 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14337 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14338 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14339 VarDecl::DeclarationOnly;
14340 Diag(D->getLocation(),
14341 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14342 << D;
14343 continue;
14344 }
14345
14346 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14347 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14348 // in a Construct]
14349 // Variables with the predetermined data-sharing attributes may not be
14350 // listed in data-sharing attributes clauses, except for the cases
14351 // listed below.
14352 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14353 // A list item may appear in a firstprivate or lastprivate clause but not
14354 // both.
14355 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14356 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14357 (isOpenMPDistributeDirective(CurrDir) ||
14358 DVar.CKind != OMPC_firstprivate) &&
14359 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14360 Diag(ELoc, diag::err_omp_wrong_dsa)
14361 << getOpenMPClauseName(DVar.CKind)
14362 << getOpenMPClauseName(OMPC_lastprivate);
14363 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14364 continue;
14365 }
14366
14367 // OpenMP [2.14.3.5, Restrictions, p.2]
14368 // A list item that is private within a parallel region, or that appears in
14369 // the reduction clause of a parallel construct, must not appear in a
14370 // lastprivate clause on a worksharing construct if any of the corresponding
14371 // worksharing regions ever binds to any of the corresponding parallel
14372 // regions.
14373 DSAStackTy::DSAVarData TopDVar = DVar;
14374 if (isOpenMPWorksharingDirective(CurrDir) &&
14375 !isOpenMPParallelDirective(CurrDir) &&
14376 !isOpenMPTeamsDirective(CurrDir)) {
14377 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14378 if (DVar.CKind != OMPC_shared) {
14379 Diag(ELoc, diag::err_omp_required_access)
14380 << getOpenMPClauseName(OMPC_lastprivate)
14381 << getOpenMPClauseName(OMPC_shared);
14382 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14383 continue;
14384 }
14385 }
14386
14387 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14388 // A variable of class type (or array thereof) that appears in a
14389 // lastprivate clause requires an accessible, unambiguous default
14390 // constructor for the class type, unless the list item is also specified
14391 // in a firstprivate clause.
14392 // A variable of class type (or array thereof) that appears in a
14393 // lastprivate clause requires an accessible, unambiguous copy assignment
14394 // operator for the class type.
14395 Type = Context.getBaseElementType(Type).getNonReferenceType();
14396 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14397 Type.getUnqualifiedType(), ".lastprivate.src",
14398 D->hasAttrs() ? &D->getAttrs() : nullptr);
14399 DeclRefExpr *PseudoSrcExpr =
14400 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14401 VarDecl *DstVD =
14402 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14403 D->hasAttrs() ? &D->getAttrs() : nullptr);
14404 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14405 // For arrays generate assignment operation for single element and replace
14406 // it by the original array element in CodeGen.
14407 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14408 PseudoDstExpr, PseudoSrcExpr);
14409 if (AssignmentOp.isInvalid())
14410 continue;
14411 AssignmentOp =
14412 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14413 if (AssignmentOp.isInvalid())
14414 continue;
14415
14416 DeclRefExpr *Ref = nullptr;
14417 if (!VD && !CurContext->isDependentContext()) {
14418 if (TopDVar.CKind == OMPC_firstprivate) {
14419 Ref = TopDVar.PrivateCopy;
14420 } else {
14421 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14422 if (!isOpenMPCapturedDecl(D))
14423 ExprCaptures.push_back(Ref->getDecl());
14424 }
14425 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14426 (!isOpenMPCapturedDecl(D) &&
14427 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14428 ExprResult RefRes = DefaultLvalueConversion(Ref);
14429 if (!RefRes.isUsable())
14430 continue;
14431 ExprResult PostUpdateRes =
14432 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14433 RefRes.get());
14434 if (!PostUpdateRes.isUsable())
14435 continue;
14436 ExprPostUpdates.push_back(
14437 IgnoredValueConversions(PostUpdateRes.get()).get());
14438 }
14439 }
14440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14441 Vars.push_back((VD || CurContext->isDependentContext())
14442 ? RefExpr->IgnoreParens()
14443 : Ref);
14444 SrcExprs.push_back(PseudoSrcExpr);
14445 DstExprs.push_back(PseudoDstExpr);
14446 AssignmentOps.push_back(AssignmentOp.get());
14447 }
14448
14449 if (Vars.empty())
14450 return nullptr;
14451
14452 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14453 Vars, SrcExprs, DstExprs, AssignmentOps,
14454 LPKind, LPKindLoc, ColonLoc,
14455 buildPreInits(Context, ExprCaptures),
14456 buildPostUpdate(*this, ExprPostUpdates));
14457}
14458
14459OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14460 SourceLocation StartLoc,
14461 SourceLocation LParenLoc,
14462 SourceLocation EndLoc) {
14463 SmallVector<Expr *, 8> Vars;
14464 for (Expr *RefExpr : VarList) {
14465 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14465, __PRETTY_FUNCTION__))
;
14466 SourceLocation ELoc;
14467 SourceRange ERange;
14468 Expr *SimpleRefExpr = RefExpr;
14469 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14470 if (Res.second) {
14471 // It will be analyzed later.
14472 Vars.push_back(RefExpr);
14473 }
14474 ValueDecl *D = Res.first;
14475 if (!D)
14476 continue;
14477
14478 auto *VD = dyn_cast<VarDecl>(D);
14479 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14480 // in a Construct]
14481 // Variables with the predetermined data-sharing attributes may not be
14482 // listed in data-sharing attributes clauses, except for the cases
14483 // listed below. For these exceptions only, listing a predetermined
14484 // variable in a data-sharing attribute clause is allowed and overrides
14485 // the variable's predetermined data-sharing attributes.
14486 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14487 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14488 DVar.RefExpr) {
14489 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14490 << getOpenMPClauseName(OMPC_shared);
14491 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14492 continue;
14493 }
14494
14495 DeclRefExpr *Ref = nullptr;
14496 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14497 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14498 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14499 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14500 ? RefExpr->IgnoreParens()
14501 : Ref);
14502 }
14503
14504 if (Vars.empty())
14505 return nullptr;
14506
14507 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14508}
14509
14510namespace {
14511class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14512 DSAStackTy *Stack;
14513
14514public:
14515 bool VisitDeclRefExpr(DeclRefExpr *E) {
14516 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14517 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14518 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14519 return false;
14520 if (DVar.CKind != OMPC_unknown)
14521 return true;
14522 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14523 VD,
14524 [](OpenMPClauseKind C, bool AppliedToPointee) {
14525 return isOpenMPPrivate(C) && !AppliedToPointee;
14526 },
14527 [](OpenMPDirectiveKind) { return true; },
14528 /*FromParent=*/true);
14529 return DVarPrivate.CKind != OMPC_unknown;
14530 }
14531 return false;
14532 }
14533 bool VisitStmt(Stmt *S) {
14534 for (Stmt *Child : S->children()) {
14535 if (Child && Visit(Child))
14536 return true;
14537 }
14538 return false;
14539 }
14540 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14541};
14542} // namespace
14543
14544namespace {
14545// Transform MemberExpression for specified FieldDecl of current class to
14546// DeclRefExpr to specified OMPCapturedExprDecl.
14547class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14548 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14549 ValueDecl *Field = nullptr;
14550 DeclRefExpr *CapturedExpr = nullptr;
14551
14552public:
14553 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14554 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14555
14556 ExprResult TransformMemberExpr(MemberExpr *E) {
14557 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14558 E->getMemberDecl() == Field) {
14559 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14560 return CapturedExpr;
14561 }
14562 return BaseTransform::TransformMemberExpr(E);
14563 }
14564 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14565};
14566} // namespace
14567
14568template <typename T, typename U>
14569static T filterLookupForUDReductionAndMapper(
14570 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14571 for (U &Set : Lookups) {
14572 for (auto *D : Set) {
14573 if (T Res = Gen(cast<ValueDecl>(D)))
14574 return Res;
14575 }
14576 }
14577 return T();
14578}
14579
14580static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14581 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((!LookupResult::isVisible(SemaRef, D) && "not in slow case"
) ? static_cast<void> (0) : __assert_fail ("!LookupResult::isVisible(SemaRef, D) && \"not in slow case\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14581, __PRETTY_FUNCTION__))
;
14582
14583 for (auto RD : D->redecls()) {
14584 // Don't bother with extra checks if we already know this one isn't visible.
14585 if (RD == D)
14586 continue;
14587
14588 auto ND = cast<NamedDecl>(RD);
14589 if (LookupResult::isVisible(SemaRef, ND))
14590 return ND;
14591 }
14592
14593 return nullptr;
14594}
14595
14596static void
14597argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14598 SourceLocation Loc, QualType Ty,
14599 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14600 // Find all of the associated namespaces and classes based on the
14601 // arguments we have.
14602 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14603 Sema::AssociatedClassSet AssociatedClasses;
14604 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14605 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14606 AssociatedClasses);
14607
14608 // C++ [basic.lookup.argdep]p3:
14609 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14610 // and let Y be the lookup set produced by argument dependent
14611 // lookup (defined as follows). If X contains [...] then Y is
14612 // empty. Otherwise Y is the set of declarations found in the
14613 // namespaces associated with the argument types as described
14614 // below. The set of declarations found by the lookup of the name
14615 // is the union of X and Y.
14616 //
14617 // Here, we compute Y and add its members to the overloaded
14618 // candidate set.
14619 for (auto *NS : AssociatedNamespaces) {
14620 // When considering an associated namespace, the lookup is the
14621 // same as the lookup performed when the associated namespace is
14622 // used as a qualifier (3.4.3.2) except that:
14623 //
14624 // -- Any using-directives in the associated namespace are
14625 // ignored.
14626 //
14627 // -- Any namespace-scope friend functions declared in
14628 // associated classes are visible within their respective
14629 // namespaces even if they are not visible during an ordinary
14630 // lookup (11.4).
14631 DeclContext::lookup_result R = NS->lookup(Id.getName());
14632 for (auto *D : R) {
14633 auto *Underlying = D;
14634 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14635 Underlying = USD->getTargetDecl();
14636
14637 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14638 !isa<OMPDeclareMapperDecl>(Underlying))
14639 continue;
14640
14641 if (!SemaRef.isVisible(D)) {
14642 D = findAcceptableDecl(SemaRef, D);
14643 if (!D)
14644 continue;
14645 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14646 Underlying = USD->getTargetDecl();
14647 }
14648 Lookups.emplace_back();
14649 Lookups.back().addDecl(Underlying);
14650 }
14651 }
14652}
14653
14654static ExprResult
14655buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14656 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14657 const DeclarationNameInfo &ReductionId, QualType Ty,
14658 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14659 if (ReductionIdScopeSpec.isInvalid())
14660 return ExprError();
14661 SmallVector<UnresolvedSet<8>, 4> Lookups;
14662 if (S) {
14663 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14664 Lookup.suppressDiagnostics();
14665 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14666 NamedDecl *D = Lookup.getRepresentativeDecl();
14667 do {
14668 S = S->getParent();
14669 } while (S && !S->isDeclScope(D));
14670 if (S)
14671 S = S->getParent();
14672 Lookups.emplace_back();
14673 Lookups.back().append(Lookup.begin(), Lookup.end());
14674 Lookup.clear();
14675 }
14676 } else if (auto *ULE =
14677 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14678 Lookups.push_back(UnresolvedSet<8>());
14679 Decl *PrevD = nullptr;
14680 for (NamedDecl *D : ULE->decls()) {
14681 if (D == PrevD)
14682 Lookups.push_back(UnresolvedSet<8>());
14683 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14684 Lookups.back().addDecl(DRD);
14685 PrevD = D;
14686 }
14687 }
14688 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14689 Ty->isInstantiationDependentType() ||
14690 Ty->containsUnexpandedParameterPack() ||
14691 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14692 return !D->isInvalidDecl() &&
14693 (D->getType()->isDependentType() ||
14694 D->getType()->isInstantiationDependentType() ||
14695 D->getType()->containsUnexpandedParameterPack());
14696 })) {
14697 UnresolvedSet<8> ResSet;
14698 for (const UnresolvedSet<8> &Set : Lookups) {
14699 if (Set.empty())
14700 continue;
14701 ResSet.append(Set.begin(), Set.end());
14702 // The last item marks the end of all declarations at the specified scope.
14703 ResSet.addDecl(Set[Set.size() - 1]);
14704 }
14705 return UnresolvedLookupExpr::Create(
14706 SemaRef.Context, /*NamingClass=*/nullptr,
14707 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14708 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14709 }
14710 // Lookup inside the classes.
14711 // C++ [over.match.oper]p3:
14712 // For a unary operator @ with an operand of a type whose
14713 // cv-unqualified version is T1, and for a binary operator @ with
14714 // a left operand of a type whose cv-unqualified version is T1 and
14715 // a right operand of a type whose cv-unqualified version is T2,
14716 // three sets of candidate functions, designated member
14717 // candidates, non-member candidates and built-in candidates, are
14718 // constructed as follows:
14719 // -- If T1 is a complete class type or a class currently being
14720 // defined, the set of member candidates is the result of the
14721 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14722 // the set of member candidates is empty.
14723 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14724 Lookup.suppressDiagnostics();
14725 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14726 // Complete the type if it can be completed.
14727 // If the type is neither complete nor being defined, bail out now.
14728 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14729 TyRec->getDecl()->getDefinition()) {
14730 Lookup.clear();
14731 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14732 if (Lookup.empty()) {
14733 Lookups.emplace_back();
14734 Lookups.back().append(Lookup.begin(), Lookup.end());
14735 }
14736 }
14737 }
14738 // Perform ADL.
14739 if (SemaRef.getLangOpts().CPlusPlus)
14740 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14741 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14742 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14743 if (!D->isInvalidDecl() &&
14744 SemaRef.Context.hasSameType(D->getType(), Ty))
14745 return D;
14746 return nullptr;
14747 }))
14748 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14749 VK_LValue, Loc);
14750 if (SemaRef.getLangOpts().CPlusPlus) {
14751 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14752 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14753 if (!D->isInvalidDecl() &&
14754 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14755 !Ty.isMoreQualifiedThan(D->getType()))
14756 return D;
14757 return nullptr;
14758 })) {
14759 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14760 /*DetectVirtual=*/false);
14761 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14762 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14763 VD->getType().getUnqualifiedType()))) {
14764 if (SemaRef.CheckBaseClassAccess(
14765 Loc, VD->getType(), Ty, Paths.front(),
14766 /*DiagID=*/0) != Sema::AR_inaccessible) {
14767 SemaRef.BuildBasePathArray(Paths, BasePath);
14768 return SemaRef.BuildDeclRefExpr(
14769 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14770 }
14771 }
14772 }
14773 }
14774 }
14775 if (ReductionIdScopeSpec.isSet()) {
14776 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14777 << Ty << Range;
14778 return ExprError();
14779 }
14780 return ExprEmpty();
14781}
14782
14783namespace {
14784/// Data for the reduction-based clauses.
14785struct ReductionData {
14786 /// List of original reduction items.
14787 SmallVector<Expr *, 8> Vars;
14788 /// List of private copies of the reduction items.
14789 SmallVector<Expr *, 8> Privates;
14790 /// LHS expressions for the reduction_op expressions.
14791 SmallVector<Expr *, 8> LHSs;
14792 /// RHS expressions for the reduction_op expressions.
14793 SmallVector<Expr *, 8> RHSs;
14794 /// Reduction operation expression.
14795 SmallVector<Expr *, 8> ReductionOps;
14796 /// inscan copy operation expressions.
14797 SmallVector<Expr *, 8> InscanCopyOps;
14798 /// inscan copy temp array expressions for prefix sums.
14799 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14800 /// inscan copy temp array element expressions for prefix sums.
14801 SmallVector<Expr *, 8> InscanCopyArrayElems;
14802 /// Taskgroup descriptors for the corresponding reduction items in
14803 /// in_reduction clauses.
14804 SmallVector<Expr *, 8> TaskgroupDescriptors;
14805 /// List of captures for clause.
14806 SmallVector<Decl *, 4> ExprCaptures;
14807 /// List of postupdate expressions.
14808 SmallVector<Expr *, 4> ExprPostUpdates;
14809 /// Reduction modifier.
14810 unsigned RedModifier = 0;
14811 ReductionData() = delete;
14812 /// Reserves required memory for the reduction data.
14813 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14814 Vars.reserve(Size);
14815 Privates.reserve(Size);
14816 LHSs.reserve(Size);
14817 RHSs.reserve(Size);
14818 ReductionOps.reserve(Size);
14819 if (RedModifier == OMPC_REDUCTION_inscan) {
14820 InscanCopyOps.reserve(Size);
14821 InscanCopyArrayTemps.reserve(Size);
14822 InscanCopyArrayElems.reserve(Size);
14823 }
14824 TaskgroupDescriptors.reserve(Size);
14825 ExprCaptures.reserve(Size);
14826 ExprPostUpdates.reserve(Size);
14827 }
14828 /// Stores reduction item and reduction operation only (required for dependent
14829 /// reduction item).
14830 void push(Expr *Item, Expr *ReductionOp) {
14831 Vars.emplace_back(Item);
14832 Privates.emplace_back(nullptr);
14833 LHSs.emplace_back(nullptr);
14834 RHSs.emplace_back(nullptr);
14835 ReductionOps.emplace_back(ReductionOp);
14836 TaskgroupDescriptors.emplace_back(nullptr);
14837 if (RedModifier == OMPC_REDUCTION_inscan) {
14838 InscanCopyOps.push_back(nullptr);
14839 InscanCopyArrayTemps.push_back(nullptr);
14840 InscanCopyArrayElems.push_back(nullptr);
14841 }
14842 }
14843 /// Stores reduction data.
14844 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14845 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14846 Expr *CopyArrayElem) {
14847 Vars.emplace_back(Item);
14848 Privates.emplace_back(Private);
14849 LHSs.emplace_back(LHS);
14850 RHSs.emplace_back(RHS);
14851 ReductionOps.emplace_back(ReductionOp);
14852 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14853 if (RedModifier == OMPC_REDUCTION_inscan) {
14854 InscanCopyOps.push_back(CopyOp);
14855 InscanCopyArrayTemps.push_back(CopyArrayTemp);
14856 InscanCopyArrayElems.push_back(CopyArrayElem);
14857 } else {
14858 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14860, __PRETTY_FUNCTION__))
14859 CopyArrayElem == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14860, __PRETTY_FUNCTION__))
14860 "Copy operation must be used for inscan reductions only.")((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 14860, __PRETTY_FUNCTION__))
;
14861 }
14862 }
14863};
14864} // namespace
14865
14866static bool checkOMPArraySectionConstantForReduction(
14867 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14868 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14869 const Expr *Length = OASE->getLength();
14870 if (Length == nullptr) {
14871 // For array sections of the form [1:] or [:], we would need to analyze
14872 // the lower bound...
14873 if (OASE->getColonLocFirst().isValid())
14874 return false;
14875
14876 // This is an array subscript which has implicit length 1!
14877 SingleElement = true;
14878 ArraySizes.push_back(llvm::APSInt::get(1));
14879 } else {
14880 Expr::EvalResult Result;
14881 if (!Length->EvaluateAsInt(Result, Context))
14882 return false;
14883
14884 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14885 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14886 ArraySizes.push_back(ConstantLengthValue);
14887 }
14888
14889 // Get the base of this array section and walk up from there.
14890 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14891
14892 // We require length = 1 for all array sections except the right-most to
14893 // guarantee that the memory region is contiguous and has no holes in it.
14894 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14895 Length = TempOASE->getLength();
14896 if (Length == nullptr) {
14897 // For array sections of the form [1:] or [:], we would need to analyze
14898 // the lower bound...
14899 if (OASE->getColonLocFirst().isValid())
14900 return false;
14901
14902 // This is an array subscript which has implicit length 1!
14903 ArraySizes.push_back(llvm::APSInt::get(1));
14904 } else {
14905 Expr::EvalResult Result;
14906 if (!Length->EvaluateAsInt(Result, Context))
14907 return false;
14908
14909 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14910 if (ConstantLengthValue.getSExtValue() != 1)
14911 return false;
14912
14913 ArraySizes.push_back(ConstantLengthValue);
14914 }
14915 Base = TempOASE->getBase()->IgnoreParenImpCasts();
14916 }
14917
14918 // If we have a single element, we don't need to add the implicit lengths.
14919 if (!SingleElement) {
14920 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14921 // Has implicit length 1!
14922 ArraySizes.push_back(llvm::APSInt::get(1));
14923 Base = TempASE->getBase()->IgnoreParenImpCasts();
14924 }
14925 }
14926
14927 // This array section can be privatized as a single value or as a constant
14928 // sized array.
14929 return true;
14930}
14931
14932static bool actOnOMPReductionKindClause(
14933 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14934 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14935 SourceLocation ColonLoc, SourceLocation EndLoc,
14936 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14937 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14938 DeclarationName DN = ReductionId.getName();
14939 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14940 BinaryOperatorKind BOK = BO_Comma;
14941
14942 ASTContext &Context = S.Context;
14943 // OpenMP [2.14.3.6, reduction clause]
14944 // C
14945 // reduction-identifier is either an identifier or one of the following
14946 // operators: +, -, *, &, |, ^, && and ||
14947 // C++
14948 // reduction-identifier is either an id-expression or one of the following
14949 // operators: +, -, *, &, |, ^, && and ||
14950 switch (OOK) {
14951 case OO_Plus:
14952 case OO_Minus:
14953 BOK = BO_Add;
14954 break;
14955 case OO_Star:
14956 BOK = BO_Mul;
14957 break;
14958 case OO_Amp:
14959 BOK = BO_And;
14960 break;
14961 case OO_Pipe:
14962 BOK = BO_Or;
14963 break;
14964 case OO_Caret:
14965 BOK = BO_Xor;
14966 break;
14967 case OO_AmpAmp:
14968 BOK = BO_LAnd;
14969 break;
14970 case OO_PipePipe:
14971 BOK = BO_LOr;
14972 break;
14973 case OO_New:
14974 case OO_Delete:
14975 case OO_Array_New:
14976 case OO_Array_Delete:
14977 case OO_Slash:
14978 case OO_Percent:
14979 case OO_Tilde:
14980 case OO_Exclaim:
14981 case OO_Equal:
14982 case OO_Less:
14983 case OO_Greater:
14984 case OO_LessEqual:
14985 case OO_GreaterEqual:
14986 case OO_PlusEqual:
14987 case OO_MinusEqual:
14988 case OO_StarEqual:
14989 case OO_SlashEqual:
14990 case OO_PercentEqual:
14991 case OO_CaretEqual:
14992 case OO_AmpEqual:
14993 case OO_PipeEqual:
14994 case OO_LessLess:
14995 case OO_GreaterGreater:
14996 case OO_LessLessEqual:
14997 case OO_GreaterGreaterEqual:
14998 case OO_EqualEqual:
14999 case OO_ExclaimEqual:
15000 case OO_Spaceship:
15001 case OO_PlusPlus:
15002 case OO_MinusMinus:
15003 case OO_Comma:
15004 case OO_ArrowStar:
15005 case OO_Arrow:
15006 case OO_Call:
15007 case OO_Subscript:
15008 case OO_Conditional:
15009 case OO_Coawait:
15010 case NUM_OVERLOADED_OPERATORS:
15011 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 15011)
;
15012 case OO_None:
15013 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15014 if (II->isStr("max"))
15015 BOK = BO_GT;
15016 else if (II->isStr("min"))
15017 BOK = BO_LT;
15018 }
15019 break;
15020 }
15021 SourceRange ReductionIdRange;
15022 if (ReductionIdScopeSpec.isValid())
15023 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15024 else
15025 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15026 ReductionIdRange.setEnd(ReductionId.getEndLoc());
15027
15028 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15029 bool FirstIter = true;
15030 for (Expr *RefExpr : VarList) {
15031 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((RefExpr && "nullptr expr in OpenMP reduction clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 15031, __PRETTY_FUNCTION__))
;
15032 // OpenMP [2.1, C/C++]
15033 // A list item is a variable or array section, subject to the restrictions
15034 // specified in Section 2.4 on page 42 and in each of the sections
15035 // describing clauses and directives for which a list appears.
15036 // OpenMP [2.14.3.3, Restrictions, p.1]
15037 // A variable that is part of another variable (as an array or
15038 // structure element) cannot appear in a private clause.
15039 if (!FirstIter && IR != ER)
15040 ++IR;
15041 FirstIter = false;
15042 SourceLocation ELoc;
15043 SourceRange ERange;
15044 Expr *SimpleRefExpr = RefExpr;
15045 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15046 /*AllowArraySection=*/true);
15047 if (Res.second) {
15048 // Try to find 'declare reduction' corresponding construct before using
15049 // builtin/overloaded operators.
15050 QualType Type = Context.DependentTy;
15051 CXXCastPath BasePath;
15052 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15053 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15054 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15055 Expr *ReductionOp = nullptr;
15056 if (S.CurContext->isDependentContext() &&
15057 (DeclareReductionRef.isUnset() ||
15058 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15059 ReductionOp = DeclareReductionRef.get();
15060 // It will be analyzed later.
15061 RD.push(RefExpr, ReductionOp);
15062 }
15063 ValueDecl *D = Res.first;
15064 if (!D)
15065 continue;
15066
15067 Expr *TaskgroupDescriptor = nullptr;
15068 QualType Type;
15069 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15070 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15071 if (ASE) {
15072 Type = ASE->getType().getNonReferenceType();
15073 } else if (OASE) {
15074 QualType BaseType =
15075 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15076 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15077 Type = ATy->getElementType();
15078 else
15079 Type = BaseType->getPointeeType();
15080 Type = Type.getNonReferenceType();
15081 } else {
15082 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15083 }
15084 auto *VD = dyn_cast<VarDecl>(D);
15085
15086 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15087 // A variable that appears in a private clause must not have an incomplete
15088 // type or a reference type.
15089 if (S.RequireCompleteType(ELoc, D->getType(),
15090 diag::err_omp_reduction_incomplete_type))
15091 continue;
15092 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15093 // A list item that appears in a reduction clause must not be
15094 // const-qualified.
15095 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15096 /*AcceptIfMutable*/ false, ASE || OASE))
15097 continue;
15098
15099 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15100 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15101 // If a list-item is a reference type then it must bind to the same object
15102 // for all threads of the team.
15103 if (!ASE && !OASE) {
15104 if (VD) {
15105 VarDecl *VDDef = VD->getDefinition();
15106 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15107 DSARefChecker Check(Stack);
15108 if (Check.Visit(VDDef->getInit())) {
15109 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15110 << getOpenMPClauseName(ClauseKind) << ERange;
15111 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15112 continue;
15113 }
15114 }
15115 }
15116
15117 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15118 // in a Construct]
15119 // Variables with the predetermined data-sharing attributes may not be
15120 // listed in data-sharing attributes clauses, except for the cases
15121 // listed below. For these exceptions only, listing a predetermined
15122 // variable in a data-sharing attribute clause is allowed and overrides
15123 // the variable's predetermined data-sharing attributes.
15124 // OpenMP [2.14.3.6, Restrictions, p.3]
15125 // Any number of reduction clauses can be specified on the directive,
15126 // but a list item can appear only once in the reduction clauses for that
15127 // directive.
15128 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15129 if (DVar.CKind == OMPC_reduction) {
15130 S.Diag(ELoc, diag::err_omp_once_referenced)
15131 << getOpenMPClauseName(ClauseKind);
15132 if (DVar.RefExpr)
15133 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15134 continue;
15135 }
15136 if (DVar.CKind != OMPC_unknown) {
15137 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15138 << getOpenMPClauseName(DVar.CKind)
15139 << getOpenMPClauseName(OMPC_reduction);
15140 reportOriginalDsa(S, Stack, D, DVar);
15141 continue;
15142 }
15143
15144 // OpenMP [2.14.3.6, Restrictions, p.1]
15145 // A list item that appears in a reduction clause of a worksharing
15146 // construct must be shared in the parallel regions to which any of the
15147 // worksharing regions arising from the worksharing construct bind.
15148 if (isOpenMPWorksharingDirective(CurrDir) &&
15149 !isOpenMPParallelDirective(CurrDir) &&
15150 !isOpenMPTeamsDirective(CurrDir)) {
15151 DVar = Stack->getImplicitDSA(D, true);
15152 if (DVar.CKind != OMPC_shared) {
15153 S.Diag(ELoc, diag::err_omp_required_access)
15154 << getOpenMPClauseName(OMPC_reduction)
15155 << getOpenMPClauseName(OMPC_shared);
15156 reportOriginalDsa(S, Stack, D, DVar);
15157 continue;
15158 }
15159 }
15160 } else {
15161 // Threadprivates cannot be shared between threads, so dignose if the base
15162 // is a threadprivate variable.
15163 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15164 if (DVar.CKind == OMPC_threadprivate) {
15165 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15166 << getOpenMPClauseName(DVar.CKind)
15167 << getOpenMPClauseName(OMPC_reduction);
15168 reportOriginalDsa(S, Stack, D, DVar);
15169 continue;
15170 }
15171 }
15172
15173 // Try to find 'declare reduction' corresponding construct before using
15174 // builtin/overloaded operators.
15175 CXXCastPath BasePath;
15176 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15177 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15178 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15179 if (DeclareReductionRef.isInvalid())
15180 continue;
15181 if (S.CurContext->isDependentContext() &&
15182 (DeclareReductionRef.isUnset() ||
15183 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15184 RD.push(RefExpr, DeclareReductionRef.get());
15185 continue;
15186 }
15187 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15188 // Not allowed reduction identifier is found.
15189 S.Diag(ReductionId.getBeginLoc(),
15190 diag::err_omp_unknown_reduction_identifier)
15191 << Type << ReductionIdRange;
15192 continue;
15193 }
15194
15195 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15196 // The type of a list item that appears in a reduction clause must be valid
15197 // for the reduction-identifier. For a max or min reduction in C, the type
15198 // of the list item must be an allowed arithmetic data type: char, int,
15199 // float, double, or _Bool, possibly modified with long, short, signed, or
15200 // unsigned. For a max or min reduction in C++, the type of the list item
15201 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15202 // double, or bool, possibly modified with long, short, signed, or unsigned.
15203 if (DeclareReductionRef.isUnset()) {
15204 if ((BOK == BO_GT || BOK == BO_LT) &&
15205 !(Type->isScalarType() ||
15206 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15207 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15208 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15209 if (!ASE && !OASE) {
15210 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15211 VarDecl::DeclarationOnly;
15212 S.Diag(D->getLocation(),
15213 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15214 << D;
15215 }
15216 continue;
15217 }
15218 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15219 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15220 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15221 << getOpenMPClauseName(ClauseKind);
15222 if (!ASE && !OASE) {
15223 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15224 VarDecl::DeclarationOnly;
15225 S.Diag(D->getLocation(),
15226 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15227 << D;
15228 }
15229 continue;
15230 }
15231 }
15232
15233 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15234 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15235 D->hasAttrs() ? &D->getAttrs() : nullptr);
15236 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15237 D->hasAttrs() ? &D->getAttrs() : nullptr);
15238 QualType PrivateTy = Type;
15239
15240 // Try if we can determine constant lengths for all array sections and avoid
15241 // the VLA.
15242 bool ConstantLengthOASE = false;
15243 if (OASE) {
15244 bool SingleElement;
15245 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15246 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15247 Context, OASE, SingleElement, ArraySizes);
15248
15249 // If we don't have a single element, we must emit a constant array type.
15250 if (ConstantLengthOASE && !SingleElement) {
15251 for (llvm::APSInt &Size : ArraySizes)
15252 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15253 ArrayType::Normal,
15254 /*IndexTypeQuals=*/0);
15255 }
15256 }
15257
15258 if ((OASE && !ConstantLengthOASE) ||
15259 (!OASE && !ASE &&
15260 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15261 if (!Context.getTargetInfo().isVLASupported()) {
15262 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15263 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15264 S.Diag(ELoc, diag::note_vla_unsupported);
15265 continue;
15266 } else {
15267 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15268 S.targetDiag(ELoc, diag::note_vla_unsupported);
15269 }
15270 }
15271 // For arrays/array sections only:
15272 // Create pseudo array type for private copy. The size for this array will
15273 // be generated during codegen.
15274 // For array subscripts or single variables Private Ty is the same as Type
15275 // (type of the variable or single array element).
15276 PrivateTy = Context.getVariableArrayType(
15277 Type,
15278 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15279 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15280 } else if (!ASE && !OASE &&
15281 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15282 PrivateTy = D->getType().getNonReferenceType();
15283 }
15284 // Private copy.
15285 VarDecl *PrivateVD =
15286 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15287 D->hasAttrs() ? &D->getAttrs() : nullptr,
15288 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15289 // Add initializer for private variable.
15290 Expr *Init = nullptr;
15291 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15292 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15293 if (DeclareReductionRef.isUsable()) {
15294 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15295 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15296 if (DRD->getInitializer()) {
15297 S.ActOnUninitializedDecl(PrivateVD);
15298 Init = DRDRef;
15299 RHSVD->setInit(DRDRef);
15300 RHSVD->setInitStyle(VarDecl::CallInit);
15301 }
15302 } else {
15303 switch (BOK) {
15304 case BO_Add:
15305 case BO_Xor:
15306 case BO_Or:
15307 case BO_LOr:
15308 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15309 if (Type->isScalarType() || Type->isAnyComplexType())
15310 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15311 break;
15312 case BO_Mul:
15313 case BO_LAnd:
15314 if (Type->isScalarType() || Type->isAnyComplexType()) {
15315 // '*' and '&&' reduction ops - initializer is '1'.
15316 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15317 }
15318 break;
15319 case BO_And: {
15320 // '&' reduction op - initializer is '~0'.
15321 QualType OrigType = Type;
15322 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15323 Type = ComplexTy->getElementType();
15324 if (Type->isRealFloatingType()) {
15325 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15326 Context.getFloatTypeSemantics(Type),
15327 Context.getTypeSize(Type));
15328 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15329 Type, ELoc);
15330 } else if (Type->isScalarType()) {
15331 uint64_t Size = Context.getTypeSize(Type);
15332 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15333 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15334 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15335 }
15336 if (Init && OrigType->isAnyComplexType()) {
15337 // Init = 0xFFFF + 0xFFFFi;
15338 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15339 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15340 }
15341 Type = OrigType;
15342 break;
15343 }
15344 case BO_LT:
15345 case BO_GT: {
15346 // 'min' reduction op - initializer is 'Largest representable number in
15347 // the reduction list item type'.
15348 // 'max' reduction op - initializer is 'Least representable number in
15349 // the reduction list item type'.
15350 if (Type->isIntegerType() || Type->isPointerType()) {
15351 bool IsSigned = Type->hasSignedIntegerRepresentation();
15352 uint64_t Size = Context.getTypeSize(Type);
15353 QualType IntTy =
15354 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15355 llvm::APInt InitValue =
15356 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15357 : llvm::APInt::getMinValue(Size)
15358 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15359 : llvm::APInt::getMaxValue(Size);
15360 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15361 if (Type->isPointerType()) {
15362 // Cast to pointer type.
15363 ExprResult CastExpr = S.BuildCStyleCastExpr(
15364 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15365 if (CastExpr.isInvalid())
15366 continue;
15367 Init = CastExpr.get();
15368 }
15369 } else if (Type->isRealFloatingType()) {
15370 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15371 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15372 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15373 Type, ELoc);
15374 }
15375 break;
15376 }
15377 case BO_PtrMemD:
15378 case BO_PtrMemI:
15379 case BO_MulAssign:
15380 case BO_Div:
15381 case BO_Rem:
15382 case BO_Sub:
15383 case BO_Shl:
15384 case BO_Shr:
15385 case BO_LE:
15386 case BO_GE:
15387 case BO_EQ:
15388 case BO_NE:
15389 case BO_Cmp:
15390 case BO_AndAssign:
15391 case BO_XorAssign:
15392 case BO_OrAssign:
15393 case BO_Assign:
15394 case BO_AddAssign:
15395 case BO_SubAssign:
15396 case BO_DivAssign:
15397 case BO_RemAssign:
15398 case BO_ShlAssign:
15399 case BO_ShrAssign:
15400 case BO_Comma:
15401 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 15401)
;
15402 }
15403 }
15404 if (Init && DeclareReductionRef.isUnset()) {
15405 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15406 // Store initializer for single element in private copy. Will be used
15407 // during codegen.
15408 PrivateVD->setInit(RHSVD->getInit());
15409 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15410 } else if (!Init) {
15411 S.ActOnUninitializedDecl(RHSVD);
15412 // Store initializer for single element in private copy. Will be used
15413 // during codegen.
15414 PrivateVD->setInit(RHSVD->getInit());
15415 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15416 }
15417 if (RHSVD->isInvalidDecl())
15418 continue;
15419 if (!RHSVD->hasInit() &&
15420 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15421 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15422 << Type << ReductionIdRange;
15423 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15424 VarDecl::DeclarationOnly;
15425 S.Diag(D->getLocation(),
15426 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15427 << D;
15428 continue;
15429 }
15430 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15431 ExprResult ReductionOp;
15432 if (DeclareReductionRef.isUsable()) {
15433 QualType RedTy = DeclareReductionRef.get()->getType();
15434 QualType PtrRedTy = Context.getPointerType(RedTy);
15435 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15436 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15437 if (!BasePath.empty()) {
15438 LHS = S.DefaultLvalueConversion(LHS.get());
15439 RHS = S.DefaultLvalueConversion(RHS.get());
15440 LHS = ImplicitCastExpr::Create(
15441 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15442 LHS.get()->getValueKind(), FPOptionsOverride());
15443 RHS = ImplicitCastExpr::Create(
15444 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15445 RHS.get()->getValueKind(), FPOptionsOverride());
15446 }
15447 FunctionProtoType::ExtProtoInfo EPI;
15448 QualType Params[] = {PtrRedTy, PtrRedTy};
15449 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15450 auto *OVE = new (Context) OpaqueValueExpr(
15451 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15452 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15453 Expr *Args[] = {LHS.get(), RHS.get()};
15454 ReductionOp =
15455 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15456 S.CurFPFeatureOverrides());
15457 } else {
15458 ReductionOp = S.BuildBinOp(
15459 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15460 if (ReductionOp.isUsable()) {
15461 if (BOK != BO_LT && BOK != BO_GT) {
15462 ReductionOp =
15463 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15464 BO_Assign, LHSDRE, ReductionOp.get());
15465 } else {
15466 auto *ConditionalOp = new (Context)
15467 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15468 Type, VK_LValue, OK_Ordinary);
15469 ReductionOp =
15470 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15471 BO_Assign, LHSDRE, ConditionalOp);
15472 }
15473 if (ReductionOp.isUsable())
15474 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15475 /*DiscardedValue*/ false);
15476 }
15477 if (!ReductionOp.isUsable())
15478 continue;
15479 }
15480
15481 // Add copy operations for inscan reductions.
15482 // LHS = RHS;
15483 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15484 if (ClauseKind == OMPC_reduction &&
15485 RD.RedModifier == OMPC_REDUCTION_inscan) {
15486 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15487 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15488 RHS.get());
15489 if (!CopyOpRes.isUsable())
15490 continue;
15491 CopyOpRes =
15492 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15493 if (!CopyOpRes.isUsable())
15494 continue;
15495 // For simd directive and simd-based directives in simd mode no need to
15496 // construct temp array, need just a single temp element.
15497 if (Stack->getCurrentDirective() == OMPD_simd ||
15498 (S.getLangOpts().OpenMPSimd &&
15499 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15500 VarDecl *TempArrayVD =
15501 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15502 D->hasAttrs() ? &D->getAttrs() : nullptr);
15503 // Add a constructor to the temp decl.
15504 S.ActOnUninitializedDecl(TempArrayVD);
15505 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15506 } else {
15507 // Build temp array for prefix sum.
15508 auto *Dim = new (S.Context)
15509 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15510 QualType ArrayTy =
15511 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15512 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15513 VarDecl *TempArrayVD =
15514 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15515 D->hasAttrs() ? &D->getAttrs() : nullptr);
15516 // Add a constructor to the temp decl.
15517 S.ActOnUninitializedDecl(TempArrayVD);
15518 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15519 TempArrayElem =
15520 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15521 auto *Idx = new (S.Context)
15522 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15523 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15524 ELoc, Idx, ELoc);
15525 }
15526 }
15527
15528 // OpenMP [2.15.4.6, Restrictions, p.2]
15529 // A list item that appears in an in_reduction clause of a task construct
15530 // must appear in a task_reduction clause of a construct associated with a
15531 // taskgroup region that includes the participating task in its taskgroup
15532 // set. The construct associated with the innermost region that meets this
15533 // condition must specify the same reduction-identifier as the in_reduction
15534 // clause.
15535 if (ClauseKind == OMPC_in_reduction) {
15536 SourceRange ParentSR;
15537 BinaryOperatorKind ParentBOK;
15538 const Expr *ParentReductionOp = nullptr;
15539 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15540 DSAStackTy::DSAVarData ParentBOKDSA =
15541 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15542 ParentBOKTD);
15543 DSAStackTy::DSAVarData ParentReductionOpDSA =
15544 Stack->getTopMostTaskgroupReductionData(
15545 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15546 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15547 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15548 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15549 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15550 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15551 bool EmitError = true;
15552 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15553 llvm::FoldingSetNodeID RedId, ParentRedId;
15554 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15555 DeclareReductionRef.get()->Profile(RedId, Context,
15556 /*Canonical=*/true);
15557 EmitError = RedId != ParentRedId;
15558 }
15559 if (EmitError) {
15560 S.Diag(ReductionId.getBeginLoc(),
15561 diag::err_omp_reduction_identifier_mismatch)
15562 << ReductionIdRange << RefExpr->getSourceRange();
15563 S.Diag(ParentSR.getBegin(),
15564 diag::note_omp_previous_reduction_identifier)
15565 << ParentSR
15566 << (IsParentBOK ? ParentBOKDSA.RefExpr
15567 : ParentReductionOpDSA.RefExpr)
15568 ->getSourceRange();
15569 continue;
15570 }
15571 }
15572 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15573 }
15574
15575 DeclRefExpr *Ref = nullptr;
15576 Expr *VarsExpr = RefExpr->IgnoreParens();
15577 if (!VD && !S.CurContext->isDependentContext()) {
15578 if (ASE || OASE) {
15579 TransformExprToCaptures RebuildToCapture(S, D);
15580 VarsExpr =
15581 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15582 Ref = RebuildToCapture.getCapturedExpr();
15583 } else {
15584 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15585 }
15586 if (!S.isOpenMPCapturedDecl(D)) {
15587 RD.ExprCaptures.emplace_back(Ref->getDecl());
15588 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15589 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15590 if (!RefRes.isUsable())
15591 continue;
15592 ExprResult PostUpdateRes =
15593 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15594 RefRes.get());
15595 if (!PostUpdateRes.isUsable())
15596 continue;
15597 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15598 Stack->getCurrentDirective() == OMPD_taskgroup) {
15599 S.Diag(RefExpr->getExprLoc(),
15600 diag::err_omp_reduction_non_addressable_expression)
15601 << RefExpr->getSourceRange();
15602 continue;
15603 }
15604 RD.ExprPostUpdates.emplace_back(
15605 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15606 }
15607 }
15608 }
15609 // All reduction items are still marked as reduction (to do not increase
15610 // code base size).
15611 unsigned Modifier = RD.RedModifier;
15612 // Consider task_reductions as reductions with task modifier. Required for
15613 // correct analysis of in_reduction clauses.
15614 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15615 Modifier = OMPC_REDUCTION_task;
15616 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15617 ASE || OASE);
15618 if (Modifier == OMPC_REDUCTION_task &&
15619 (CurrDir == OMPD_taskgroup ||
15620 ((isOpenMPParallelDirective(CurrDir) ||
15621 isOpenMPWorksharingDirective(CurrDir)) &&
15622 !isOpenMPSimdDirective(CurrDir)))) {
15623 if (DeclareReductionRef.isUsable())
15624 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15625 DeclareReductionRef.get());
15626 else
15627 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15628 }
15629 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15630 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15631 TempArrayElem.get());
15632 }
15633 return RD.Vars.empty();
15634}
15635
15636OMPClause *Sema::ActOnOpenMPReductionClause(
15637 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15638 SourceLocation StartLoc, SourceLocation LParenLoc,
15639 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15640 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15641 ArrayRef<Expr *> UnresolvedReductions) {
15642 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15643 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15644 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15645 /*Last=*/OMPC_REDUCTION_unknown)
15646 << getOpenMPClauseName(OMPC_reduction);
15647 return nullptr;
15648 }
15649 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15650 // A reduction clause with the inscan reduction-modifier may only appear on a
15651 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15652 // construct, a parallel worksharing-loop construct or a parallel
15653 // worksharing-loop SIMD construct.
15654 if (Modifier == OMPC_REDUCTION_inscan &&
15655 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
15656 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
15657 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
15658 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
15659 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
15660 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15661 return nullptr;
15662 }
15663
15664 ReductionData RD(VarList.size(), Modifier);
15665 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
15666 StartLoc, LParenLoc, ColonLoc, EndLoc,
15667 ReductionIdScopeSpec, ReductionId,
15668 UnresolvedReductions, RD))
15669 return nullptr;
15670
15671 return OMPReductionClause::Create(
15672 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15673 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15674 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15675 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15676 buildPreInits(Context, RD.ExprCaptures),
15677 buildPostUpdate(*this, RD.ExprPostUpdates));
15678}
15679
15680OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15681 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15682 SourceLocation ColonLoc, SourceLocation EndLoc,
15683 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15684 ArrayRef<Expr *> UnresolvedReductions) {
15685 ReductionData RD(VarList.size());
15686 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
15687 StartLoc, LParenLoc, ColonLoc, EndLoc,
15688 ReductionIdScopeSpec, ReductionId,
15689 UnresolvedReductions, RD))
15690 return nullptr;
15691
15692 return OMPTaskReductionClause::Create(
15693 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15694 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15695 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15696 buildPreInits(Context, RD.ExprCaptures),
15697 buildPostUpdate(*this, RD.ExprPostUpdates));
15698}
15699
15700OMPClause *Sema::ActOnOpenMPInReductionClause(
15701 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15702 SourceLocation ColonLoc, SourceLocation EndLoc,
15703 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15704 ArrayRef<Expr *> UnresolvedReductions) {
15705 ReductionData RD(VarList.size());
15706 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
15707 StartLoc, LParenLoc, ColonLoc, EndLoc,
15708 ReductionIdScopeSpec, ReductionId,
15709 UnresolvedReductions, RD))
15710 return nullptr;
15711
15712 return OMPInReductionClause::Create(
15713 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15714 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15715 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15716 buildPreInits(Context, RD.ExprCaptures),
15717 buildPostUpdate(*this, RD.ExprPostUpdates));
15718}
15719
15720bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15721 SourceLocation LinLoc) {
15722 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15723 LinKind == OMPC_LINEAR_unknown) {
15724 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15725 return true;
15726 }
15727 return false;
15728}
15729
15730bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15731 OpenMPLinearClauseKind LinKind, QualType Type,
15732 bool IsDeclareSimd) {
15733 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15734 // A variable must not have an incomplete type or a reference type.
15735 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15736 return true;
15737 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15738 !Type->isReferenceType()) {
15739 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15740 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15741 return true;
15742 }
15743 Type = Type.getNonReferenceType();
15744
15745 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15746 // A variable that is privatized must not have a const-qualified type
15747 // unless it is of class type with a mutable member. This restriction does
15748 // not apply to the firstprivate clause, nor to the linear clause on
15749 // declarative directives (like declare simd).
15750 if (!IsDeclareSimd &&
15751 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15752 return true;
15753
15754 // A list item must be of integral or pointer type.
15755 Type = Type.getUnqualifiedType().getCanonicalType();
15756 const auto *Ty = Type.getTypePtrOrNull();
15757 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15758 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15759 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15760 if (D) {
15761 bool IsDecl =
15762 !VD ||
15763 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15764 Diag(D->getLocation(),
15765 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15766 << D;
15767 }
15768 return true;
15769 }
15770 return false;
15771}
15772
15773OMPClause *Sema::ActOnOpenMPLinearClause(
15774 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15775 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15776 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15777 SmallVector<Expr *, 8> Vars;
15778 SmallVector<Expr *, 8> Privates;
15779 SmallVector<Expr *, 8> Inits;
15780 SmallVector<Decl *, 4> ExprCaptures;
15781 SmallVector<Expr *, 4> ExprPostUpdates;
15782 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15783 LinKind = OMPC_LINEAR_val;
15784 for (Expr *RefExpr : VarList) {
15785 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 15785, __PRETTY_FUNCTION__))
;
15786 SourceLocation ELoc;
15787 SourceRange ERange;
15788 Expr *SimpleRefExpr = RefExpr;
15789 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15790 if (Res.second) {
15791 // It will be analyzed later.
15792 Vars.push_back(RefExpr);
15793 Privates.push_back(nullptr);
15794 Inits.push_back(nullptr);
15795 }
15796 ValueDecl *D = Res.first;
15797 if (!D)
15798 continue;
15799
15800 QualType Type = D->getType();
15801 auto *VD = dyn_cast<VarDecl>(D);
15802
15803 // OpenMP [2.14.3.7, linear clause]
15804 // A list-item cannot appear in more than one linear clause.
15805 // A list-item that appears in a linear clause cannot appear in any
15806 // other data-sharing attribute clause.
15807 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15808 if (DVar.RefExpr) {
15809 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15810 << getOpenMPClauseName(OMPC_linear);
15811 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15812 continue;
15813 }
15814
15815 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15816 continue;
15817 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15818
15819 // Build private copy of original var.
15820 VarDecl *Private =
15821 buildVarDecl(*this, ELoc, Type, D->getName(),
15822 D->hasAttrs() ? &D->getAttrs() : nullptr,
15823 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15824 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15825 // Build var to save initial value.
15826 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15827 Expr *InitExpr;
15828 DeclRefExpr *Ref = nullptr;
15829 if (!VD && !CurContext->isDependentContext()) {
15830 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15831 if (!isOpenMPCapturedDecl(D)) {
15832 ExprCaptures.push_back(Ref->getDecl());
15833 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15834 ExprResult RefRes = DefaultLvalueConversion(Ref);
15835 if (!RefRes.isUsable())
15836 continue;
15837 ExprResult PostUpdateRes =
15838 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
15839 SimpleRefExpr, RefRes.get());
15840 if (!PostUpdateRes.isUsable())
15841 continue;
15842 ExprPostUpdates.push_back(
15843 IgnoredValueConversions(PostUpdateRes.get()).get());
15844 }
15845 }
15846 }
15847 if (LinKind == OMPC_LINEAR_uval)
15848 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15849 else
15850 InitExpr = VD ? SimpleRefExpr : Ref;
15851 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15852 /*DirectInit=*/false);
15853 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15854
15855 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15856 Vars.push_back((VD || CurContext->isDependentContext())
15857 ? RefExpr->IgnoreParens()
15858 : Ref);
15859 Privates.push_back(PrivateRef);
15860 Inits.push_back(InitRef);
15861 }
15862
15863 if (Vars.empty())
15864 return nullptr;
15865
15866 Expr *StepExpr = Step;
15867 Expr *CalcStepExpr = nullptr;
15868 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15869 !Step->isInstantiationDependent() &&
15870 !Step->containsUnexpandedParameterPack()) {
15871 SourceLocation StepLoc = Step->getBeginLoc();
15872 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15873 if (Val.isInvalid())
15874 return nullptr;
15875 StepExpr = Val.get();
15876
15877 // Build var to save the step value.
15878 VarDecl *SaveVar =
15879 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15880 ExprResult SaveRef =
15881 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15882 ExprResult CalcStep =
15883 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15884 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15885
15886 // Warn about zero linear step (it would be probably better specified as
15887 // making corresponding variables 'const').
15888 if (Optional<llvm::APSInt> Result =
15889 StepExpr->getIntegerConstantExpr(Context)) {
15890 if (!Result->isNegative() && !Result->isStrictlyPositive())
15891 Diag(StepLoc, diag::warn_omp_linear_step_zero)
15892 << Vars[0] << (Vars.size() > 1);
15893 } else if (CalcStep.isUsable()) {
15894 // Calculate the step beforehand instead of doing this on each iteration.
15895 // (This is not used if the number of iterations may be kfold-ed).
15896 CalcStepExpr = CalcStep.get();
15897 }
15898 }
15899
15900 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15901 ColonLoc, EndLoc, Vars, Privates, Inits,
15902 StepExpr, CalcStepExpr,
15903 buildPreInits(Context, ExprCaptures),
15904 buildPostUpdate(*this, ExprPostUpdates));
15905}
15906
15907static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15908 Expr *NumIterations, Sema &SemaRef,
15909 Scope *S, DSAStackTy *Stack) {
15910 // Walk the vars and build update/final expressions for the CodeGen.
15911 SmallVector<Expr *, 8> Updates;
15912 SmallVector<Expr *, 8> Finals;
15913 SmallVector<Expr *, 8> UsedExprs;
15914 Expr *Step = Clause.getStep();
15915 Expr *CalcStep = Clause.getCalcStep();
15916 // OpenMP [2.14.3.7, linear clause]
15917 // If linear-step is not specified it is assumed to be 1.
15918 if (!Step)
15919 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15920 else if (CalcStep)
15921 Step = cast<BinaryOperator>(CalcStep)->getLHS();
15922 bool HasErrors = false;
15923 auto CurInit = Clause.inits().begin();
15924 auto CurPrivate = Clause.privates().begin();
15925 OpenMPLinearClauseKind LinKind = Clause.getModifier();
15926 for (Expr *RefExpr : Clause.varlists()) {
15927 SourceLocation ELoc;
15928 SourceRange ERange;
15929 Expr *SimpleRefExpr = RefExpr;
15930 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15931 ValueDecl *D = Res.first;
15932 if (Res.second || !D) {
15933 Updates.push_back(nullptr);
15934 Finals.push_back(nullptr);
15935 HasErrors = true;
15936 continue;
15937 }
15938 auto &&Info = Stack->isLoopControlVariable(D);
15939 // OpenMP [2.15.11, distribute simd Construct]
15940 // A list item may not appear in a linear clause, unless it is the loop
15941 // iteration variable.
15942 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15943 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15944 SemaRef.Diag(ELoc,
15945 diag::err_omp_linear_distribute_var_non_loop_iteration);
15946 Updates.push_back(nullptr);
15947 Finals.push_back(nullptr);
15948 HasErrors = true;
15949 continue;
15950 }
15951 Expr *InitExpr = *CurInit;
15952
15953 // Build privatized reference to the current linear var.
15954 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15955 Expr *CapturedRef;
15956 if (LinKind == OMPC_LINEAR_uval)
15957 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15958 else
15959 CapturedRef =
15960 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15961 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15962 /*RefersToCapture=*/true);
15963
15964 // Build update: Var = InitExpr + IV * Step
15965 ExprResult Update;
15966 if (!Info.first)
15967 Update = buildCounterUpdate(
15968 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15969 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15970 else
15971 Update = *CurPrivate;
15972 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15973 /*DiscardedValue*/ false);
15974
15975 // Build final: Var = InitExpr + NumIterations * Step
15976 ExprResult Final;
15977 if (!Info.first)
15978 Final =
15979 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
15980 InitExpr, NumIterations, Step, /*Subtract=*/false,
15981 /*IsNonRectangularLB=*/false);
15982 else
15983 Final = *CurPrivate;
15984 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
15985 /*DiscardedValue*/ false);
15986
15987 if (!Update.isUsable() || !Final.isUsable()) {
15988 Updates.push_back(nullptr);
15989 Finals.push_back(nullptr);
15990 UsedExprs.push_back(nullptr);
15991 HasErrors = true;
15992 } else {
15993 Updates.push_back(Update.get());
15994 Finals.push_back(Final.get());
15995 if (!Info.first)
15996 UsedExprs.push_back(SimpleRefExpr);
15997 }
15998 ++CurInit;
15999 ++CurPrivate;
16000 }
16001 if (Expr *S = Clause.getStep())
16002 UsedExprs.push_back(S);
16003 // Fill the remaining part with the nullptr.
16004 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16005 Clause.setUpdates(Updates);
16006 Clause.setFinals(Finals);
16007 Clause.setUsedExprs(UsedExprs);
16008 return HasErrors;
16009}
16010
16011OMPClause *Sema::ActOnOpenMPAlignedClause(
16012 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16013 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16014 SmallVector<Expr *, 8> Vars;
16015 for (Expr *RefExpr : VarList) {
16016 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16016, __PRETTY_FUNCTION__))
;
16017 SourceLocation ELoc;
16018 SourceRange ERange;
16019 Expr *SimpleRefExpr = RefExpr;
16020 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16021 if (Res.second) {
16022 // It will be analyzed later.
16023 Vars.push_back(RefExpr);
16024 }
16025 ValueDecl *D = Res.first;
16026 if (!D)
16027 continue;
16028
16029 QualType QType = D->getType();
16030 auto *VD = dyn_cast<VarDecl>(D);
16031
16032 // OpenMP [2.8.1, simd construct, Restrictions]
16033 // The type of list items appearing in the aligned clause must be
16034 // array, pointer, reference to array, or reference to pointer.
16035 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16036 const Type *Ty = QType.getTypePtrOrNull();
16037 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16038 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16039 << QType << getLangOpts().CPlusPlus << ERange;
16040 bool IsDecl =
16041 !VD ||
16042 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16043 Diag(D->getLocation(),
16044 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16045 << D;
16046 continue;
16047 }
16048
16049 // OpenMP [2.8.1, simd construct, Restrictions]
16050 // A list-item cannot appear in more than one aligned clause.
16051 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
16052 Diag(ELoc, diag::err_omp_used_in_clause_twice)
16053 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16054 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16055 << getOpenMPClauseName(OMPC_aligned);
16056 continue;
16057 }
16058
16059 DeclRefExpr *Ref = nullptr;
16060 if (!VD && isOpenMPCapturedDecl(D))
16061 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16062 Vars.push_back(DefaultFunctionArrayConversion(
16063 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16064 .get());
16065 }
16066
16067 // OpenMP [2.8.1, simd construct, Description]
16068 // The parameter of the aligned clause, alignment, must be a constant
16069 // positive integer expression.
16070 // If no optional parameter is specified, implementation-defined default
16071 // alignments for SIMD instructions on the target platforms are assumed.
16072 if (Alignment != nullptr) {
16073 ExprResult AlignResult =
16074 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16075 if (AlignResult.isInvalid())
16076 return nullptr;
16077 Alignment = AlignResult.get();
16078 }
16079 if (Vars.empty())
16080 return nullptr;
16081
16082 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16083 EndLoc, Vars, Alignment);
16084}
16085
16086OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16087 SourceLocation StartLoc,
16088 SourceLocation LParenLoc,
16089 SourceLocation EndLoc) {
16090 SmallVector<Expr *, 8> Vars;
16091 SmallVector<Expr *, 8> SrcExprs;
16092 SmallVector<Expr *, 8> DstExprs;
16093 SmallVector<Expr *, 8> AssignmentOps;
16094 for (Expr *RefExpr : VarList) {
16095 assert(RefExpr && "NULL expr in OpenMP copyin clause.")((RefExpr && "NULL expr in OpenMP copyin clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16095, __PRETTY_FUNCTION__))
;
16096 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16097 // It will be analyzed later.
16098 Vars.push_back(RefExpr);
16099 SrcExprs.push_back(nullptr);
16100 DstExprs.push_back(nullptr);
16101 AssignmentOps.push_back(nullptr);
16102 continue;
16103 }
16104
16105 SourceLocation ELoc = RefExpr->getExprLoc();
16106 // OpenMP [2.1, C/C++]
16107 // A list item is a variable name.
16108 // OpenMP [2.14.4.1, Restrictions, p.1]
16109 // A list item that appears in a copyin clause must be threadprivate.
16110 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16111 if (!DE || !isa<VarDecl>(DE->getDecl())) {
16112 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16113 << 0 << RefExpr->getSourceRange();
16114 continue;
16115 }
16116
16117 Decl *D = DE->getDecl();
16118 auto *VD = cast<VarDecl>(D);
16119
16120 QualType Type = VD->getType();
16121 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16122 // It will be analyzed later.
16123 Vars.push_back(DE);
16124 SrcExprs.push_back(nullptr);
16125 DstExprs.push_back(nullptr);
16126 AssignmentOps.push_back(nullptr);
16127 continue;
16128 }
16129
16130 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16131 // A list item that appears in a copyin clause must be threadprivate.
16132 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16133 Diag(ELoc, diag::err_omp_required_access)
16134 << getOpenMPClauseName(OMPC_copyin)
16135 << getOpenMPDirectiveName(OMPD_threadprivate);
16136 continue;
16137 }
16138
16139 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16140 // A variable of class type (or array thereof) that appears in a
16141 // copyin clause requires an accessible, unambiguous copy assignment
16142 // operator for the class type.
16143 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16144 VarDecl *SrcVD =
16145 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16146 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16147 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16148 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16149 VarDecl *DstVD =
16150 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16151 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16152 DeclRefExpr *PseudoDstExpr =
16153 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16154 // For arrays generate assignment operation for single element and replace
16155 // it by the original array element in CodeGen.
16156 ExprResult AssignmentOp =
16157 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16158 PseudoSrcExpr);
16159 if (AssignmentOp.isInvalid())
16160 continue;
16161 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16162 /*DiscardedValue*/ false);
16163 if (AssignmentOp.isInvalid())
16164 continue;
16165
16166 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
16167 Vars.push_back(DE);
16168 SrcExprs.push_back(PseudoSrcExpr);
16169 DstExprs.push_back(PseudoDstExpr);
16170 AssignmentOps.push_back(AssignmentOp.get());
16171 }
16172
16173 if (Vars.empty())
16174 return nullptr;
16175
16176 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16177 SrcExprs, DstExprs, AssignmentOps);
16178}
16179
16180OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16181 SourceLocation StartLoc,
16182 SourceLocation LParenLoc,
16183 SourceLocation EndLoc) {
16184 SmallVector<Expr *, 8> Vars;
16185 SmallVector<Expr *, 8> SrcExprs;
16186 SmallVector<Expr *, 8> DstExprs;
16187 SmallVector<Expr *, 8> AssignmentOps;
16188 for (Expr *RefExpr : VarList) {
16189 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16189, __PRETTY_FUNCTION__))
;
16190 SourceLocation ELoc;
16191 SourceRange ERange;
16192 Expr *SimpleRefExpr = RefExpr;
16193 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16194 if (Res.second) {
16195 // It will be analyzed later.
16196 Vars.push_back(RefExpr);
16197 SrcExprs.push_back(nullptr);
16198 DstExprs.push_back(nullptr);
16199 AssignmentOps.push_back(nullptr);
16200 }
16201 ValueDecl *D = Res.first;
16202 if (!D)
16203 continue;
16204
16205 QualType Type = D->getType();
16206 auto *VD = dyn_cast<VarDecl>(D);
16207
16208 // OpenMP [2.14.4.2, Restrictions, p.2]
16209 // A list item that appears in a copyprivate clause may not appear in a
16210 // private or firstprivate clause on the single construct.
16211 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16212 DSAStackTy::DSAVarData DVar =
16213 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16214 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16215 DVar.RefExpr) {
16216 Diag(ELoc, diag::err_omp_wrong_dsa)
16217 << getOpenMPClauseName(DVar.CKind)
16218 << getOpenMPClauseName(OMPC_copyprivate);
16219 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16220 continue;
16221 }
16222
16223 // OpenMP [2.11.4.2, Restrictions, p.1]
16224 // All list items that appear in a copyprivate clause must be either
16225 // threadprivate or private in the enclosing context.
16226 if (DVar.CKind == OMPC_unknown) {
16227 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
16228 if (DVar.CKind == OMPC_shared) {
16229 Diag(ELoc, diag::err_omp_required_access)
16230 << getOpenMPClauseName(OMPC_copyprivate)
16231 << "threadprivate or private in the enclosing context";
16232 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16233 continue;
16234 }
16235 }
16236 }
16237
16238 // Variably modified types are not supported.
16239 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16240 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16241 << getOpenMPClauseName(OMPC_copyprivate) << Type
16242 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
16243 bool IsDecl =
16244 !VD ||
16245 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16246 Diag(D->getLocation(),
16247 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16248 << D;
16249 continue;
16250 }
16251
16252 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16253 // A variable of class type (or array thereof) that appears in a
16254 // copyin clause requires an accessible, unambiguous copy assignment
16255 // operator for the class type.
16256 Type = Context.getBaseElementType(Type.getNonReferenceType())
16257 .getUnqualifiedType();
16258 VarDecl *SrcVD =
16259 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16260 D->hasAttrs() ? &D->getAttrs() : nullptr);
16261 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16262 VarDecl *DstVD =
16263 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16264 D->hasAttrs() ? &D->getAttrs() : nullptr);
16265 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16266 ExprResult AssignmentOp = BuildBinOp(
16267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16268 if (AssignmentOp.isInvalid())
16269 continue;
16270 AssignmentOp =
16271 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16272 if (AssignmentOp.isInvalid())
16273 continue;
16274
16275 // No need to mark vars as copyprivate, they are already threadprivate or
16276 // implicitly private.
16277 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16277, __PRETTY_FUNCTION__))
;
16278 Vars.push_back(
16279 VD ? RefExpr->IgnoreParens()
16280 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16281 SrcExprs.push_back(PseudoSrcExpr);
16282 DstExprs.push_back(PseudoDstExpr);
16283 AssignmentOps.push_back(AssignmentOp.get());
16284 }
16285
16286 if (Vars.empty())
16287 return nullptr;
16288
16289 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16290 Vars, SrcExprs, DstExprs, AssignmentOps);
16291}
16292
16293OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16294 SourceLocation StartLoc,
16295 SourceLocation LParenLoc,
16296 SourceLocation EndLoc) {
16297 if (VarList.empty())
16298 return nullptr;
16299
16300 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16301}
16302
16303/// Tries to find omp_depend_t. type.
16304static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16305 bool Diagnose = true) {
16306 QualType OMPDependT = Stack->getOMPDependT();
16307 if (!OMPDependT.isNull())
16308 return true;
16309 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16310 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16311 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16312 if (Diagnose)
16313 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16314 return false;
16315 }
16316 Stack->setOMPDependT(PT.get());
16317 return true;
16318}
16319
16320OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16321 SourceLocation LParenLoc,
16322 SourceLocation EndLoc) {
16323 if (!Depobj)
16324 return nullptr;
16325
16326 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
16327
16328 // OpenMP 5.0, 2.17.10.1 depobj Construct
16329 // depobj is an lvalue expression of type omp_depend_t.
16330 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16331 !Depobj->isInstantiationDependent() &&
16332 !Depobj->containsUnexpandedParameterPack() &&
16333 (OMPDependTFound &&
16334 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
16335 /*CompareUnqualified=*/true))) {
16336 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16337 << 0 << Depobj->getType() << Depobj->getSourceRange();
16338 }
16339
16340 if (!Depobj->isLValue()) {
16341 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16342 << 1 << Depobj->getSourceRange();
16343 }
16344
16345 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16346}
16347
16348OMPClause *
16349Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16350 SourceLocation DepLoc, SourceLocation ColonLoc,
16351 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16352 SourceLocation LParenLoc, SourceLocation EndLoc) {
16353 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
16354 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16355 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16356 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16357 return nullptr;
16358 }
16359 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
16360 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16361 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16362 DepKind == OMPC_DEPEND_sink ||
16363 ((LangOpts.OpenMP < 50 ||
16364 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16365 DepKind == OMPC_DEPEND_depobj))) {
16366 SmallVector<unsigned, 3> Except;
16367 Except.push_back(OMPC_DEPEND_source);
16368 Except.push_back(OMPC_DEPEND_sink);
16369 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
16370 Except.push_back(OMPC_DEPEND_depobj);
16371 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16372 ? "depend modifier(iterator) or "
16373 : "";
16374 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16375 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16376 /*Last=*/OMPC_DEPEND_unknown,
16377 Except)
16378 << getOpenMPClauseName(OMPC_depend);
16379 return nullptr;
16380 }
16381 if (DepModifier &&
16382 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16383 Diag(DepModifier->getExprLoc(),
16384 diag::err_omp_depend_sink_source_with_modifier);
16385 return nullptr;
16386 }
16387 if (DepModifier &&
16388 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16389 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16390
16391 SmallVector<Expr *, 8> Vars;
16392 DSAStackTy::OperatorOffsetTy OpsOffs;
16393 llvm::APSInt DepCounter(/*BitWidth=*/32);
16394 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16395 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16396 if (const Expr *OrderedCountExpr =
16397 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
16398 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16399 TotalDepCount.setIsUnsigned(/*Val=*/true);
16400 }
16401 }
16402 for (Expr *RefExpr : VarList) {
16403 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16403, __PRETTY_FUNCTION__))
;
16404 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16405 // It will be analyzed later.
16406 Vars.push_back(RefExpr);
16407 continue;
16408 }
16409
16410 SourceLocation ELoc = RefExpr->getExprLoc();
16411 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16412 if (DepKind == OMPC_DEPEND_sink) {
16413 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16414 DepCounter >= TotalDepCount) {
16415 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16416 continue;
16417 }
16418 ++DepCounter;
16419 // OpenMP [2.13.9, Summary]
16420 // depend(dependence-type : vec), where dependence-type is:
16421 // 'sink' and where vec is the iteration vector, which has the form:
16422 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16423 // where n is the value specified by the ordered clause in the loop
16424 // directive, xi denotes the loop iteration variable of the i-th nested
16425 // loop associated with the loop directive, and di is a constant
16426 // non-negative integer.
16427 if (CurContext->isDependentContext()) {
16428 // It will be analyzed later.
16429 Vars.push_back(RefExpr);
16430 continue;
16431 }
16432 SimpleExpr = SimpleExpr->IgnoreImplicit();
16433 OverloadedOperatorKind OOK = OO_None;
16434 SourceLocation OOLoc;
16435 Expr *LHS = SimpleExpr;
16436 Expr *RHS = nullptr;
16437 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16438 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16439 OOLoc = BO->getOperatorLoc();
16440 LHS = BO->getLHS()->IgnoreParenImpCasts();
16441 RHS = BO->getRHS()->IgnoreParenImpCasts();
16442 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16443 OOK = OCE->getOperator();
16444 OOLoc = OCE->getOperatorLoc();
16445 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16446 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16447 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16448 OOK = MCE->getMethodDecl()
16449 ->getNameInfo()
16450 .getName()
16451 .getCXXOverloadedOperator();
16452 OOLoc = MCE->getCallee()->getExprLoc();
16453 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16454 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16455 }
16456 SourceLocation ELoc;
16457 SourceRange ERange;
16458 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16459 if (Res.second) {
16460 // It will be analyzed later.
16461 Vars.push_back(RefExpr);
16462 }
16463 ValueDecl *D = Res.first;
16464 if (!D)
16465 continue;
16466
16467 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16468 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16469 continue;
16470 }
16471 if (RHS) {
16472 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16473 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16474 if (RHSRes.isInvalid())
16475 continue;
16476 }
16477 if (!CurContext->isDependentContext() &&
16478 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16479 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
16480 const ValueDecl *VD =
16481 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
16482 if (VD)
16483 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16484 << 1 << VD;
16485 else
16486 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16487 continue;
16488 }
16489 OpsOffs.emplace_back(RHS, OOK);
16490 } else {
16491 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16492 if (OMPDependTFound)
16493 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
16494 DepKind == OMPC_DEPEND_depobj);
16495 if (DepKind == OMPC_DEPEND_depobj) {
16496 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16497 // List items used in depend clauses with the depobj dependence type
16498 // must be expressions of the omp_depend_t type.
16499 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16500 !RefExpr->isInstantiationDependent() &&
16501 !RefExpr->containsUnexpandedParameterPack() &&
16502 (OMPDependTFound &&
16503 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
16504 RefExpr->getType()))) {
16505 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16506 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16507 continue;
16508 }
16509 if (!RefExpr->isLValue()) {
16510 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16511 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16512 continue;
16513 }
16514 } else {
16515 // OpenMP 5.0 [2.17.11, Restrictions]
16516 // List items used in depend clauses cannot be zero-length array
16517 // sections.
16518 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16519 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16520 if (OASE) {
16521 QualType BaseType =
16522 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16523 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16524 ExprTy = ATy->getElementType();
16525 else
16526 ExprTy = BaseType->getPointeeType();
16527 ExprTy = ExprTy.getNonReferenceType();
16528 const Expr *Length = OASE->getLength();
16529 Expr::EvalResult Result;
16530 if (Length && !Length->isValueDependent() &&
16531 Length->EvaluateAsInt(Result, Context) &&
16532 Result.Val.getInt().isNullValue()) {
16533 Diag(ELoc,
16534 diag::err_omp_depend_zero_length_array_section_not_allowed)
16535 << SimpleExpr->getSourceRange();
16536 continue;
16537 }
16538 }
16539
16540 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16541 // List items used in depend clauses with the in, out, inout or
16542 // mutexinoutset dependence types cannot be expressions of the
16543 // omp_depend_t type.
16544 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16545 !RefExpr->isInstantiationDependent() &&
16546 !RefExpr->containsUnexpandedParameterPack() &&
16547 (OMPDependTFound &&
16548 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16549 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16550 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16551 << RefExpr->getSourceRange();
16552 continue;
16553 }
16554
16555 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16556 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16557 (ASE && !ASE->getBase()->isTypeDependent() &&
16558 !ASE->getBase()
16559 ->getType()
16560 .getNonReferenceType()
16561 ->isPointerType() &&
16562 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16563 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16564 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16565 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16566 continue;
16567 }
16568
16569 ExprResult Res;
16570 {
16571 Sema::TentativeAnalysisScope Trap(*this);
16572 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16573 RefExpr->IgnoreParenImpCasts());
16574 }
16575 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16576 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16577 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16578 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16579 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16580 continue;
16581 }
16582 }
16583 }
16584 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16585 }
16586
16587 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16588 TotalDepCount > VarList.size() &&
16589 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16590 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
16591 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16592 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
16593 }
16594 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16595 Vars.empty())
16596 return nullptr;
16597
16598 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16599 DepModifier, DepKind, DepLoc, ColonLoc,
16600 Vars, TotalDepCount.getZExtValue());
16601 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16602 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
16603 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
16604 return C;
16605}
16606
16607OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16608 Expr *Device, SourceLocation StartLoc,
16609 SourceLocation LParenLoc,
16610 SourceLocation ModifierLoc,
16611 SourceLocation EndLoc) {
16612 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16613, __PRETTY_FUNCTION__))
16613 "Unexpected device modifier in OpenMP < 50.")(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16613, __PRETTY_FUNCTION__))
;
16614
16615 bool ErrorFound = false;
16616 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16617 std::string Values =
16618 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16619 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16620 << Values << getOpenMPClauseName(OMPC_device);
16621 ErrorFound = true;
16622 }
16623
16624 Expr *ValExpr = Device;
16625 Stmt *HelperValStmt = nullptr;
16626
16627 // OpenMP [2.9.1, Restrictions]
16628 // The device expression must evaluate to a non-negative integer value.
16629 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16630 /*StrictlyPositive=*/false) ||
16631 ErrorFound;
16632 if (ErrorFound)
16633 return nullptr;
16634
16635 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16636 OpenMPDirectiveKind CaptureRegion =
16637 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16638 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16639 ValExpr = MakeFullExpr(ValExpr).get();
16640 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16641 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16642 HelperValStmt = buildPreInits(Context, Captures);
16643 }
16644
16645 return new (Context)
16646 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16647 LParenLoc, ModifierLoc, EndLoc);
16648}
16649
16650static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16651 DSAStackTy *Stack, QualType QTy,
16652 bool FullCheck = true) {
16653 NamedDecl *ND;
16654 if (QTy->isIncompleteType(&ND)) {
16655 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16656 return false;
16657 }
16658 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16659 !QTy.isTriviallyCopyableType(SemaRef.Context))
16660 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16661 return true;
16662}
16663
16664/// Return true if it can be proven that the provided array expression
16665/// (array section or array subscript) does NOT specify the whole size of the
16666/// array whose base type is \a BaseQTy.
16667static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16668 const Expr *E,
16669 QualType BaseQTy) {
16670 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16671
16672 // If this is an array subscript, it refers to the whole size if the size of
16673 // the dimension is constant and equals 1. Also, an array section assumes the
16674 // format of an array subscript if no colon is used.
16675 if (isa<ArraySubscriptExpr>(E) ||
16676 (OASE && OASE->getColonLocFirst().isInvalid())) {
16677 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16678 return ATy->getSize().getSExtValue() != 1;
16679 // Size can't be evaluated statically.
16680 return false;
16681 }
16682
16683 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16683, __PRETTY_FUNCTION__))
;
16684 const Expr *LowerBound = OASE->getLowerBound();
16685 const Expr *Length = OASE->getLength();
16686
16687 // If there is a lower bound that does not evaluates to zero, we are not
16688 // covering the whole dimension.
16689 if (LowerBound) {
16690 Expr::EvalResult Result;
16691 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16692 return false; // Can't get the integer value as a constant.
16693
16694 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16695 if (ConstLowerBound.getSExtValue())
16696 return true;
16697 }
16698
16699 // If we don't have a length we covering the whole dimension.
16700 if (!Length)
16701 return false;
16702
16703 // If the base is a pointer, we don't have a way to get the size of the
16704 // pointee.
16705 if (BaseQTy->isPointerType())
16706 return false;
16707
16708 // We can only check if the length is the same as the size of the dimension
16709 // if we have a constant array.
16710 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16711 if (!CATy)
16712 return false;
16713
16714 Expr::EvalResult Result;
16715 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16716 return false; // Can't get the integer value as a constant.
16717
16718 llvm::APSInt ConstLength = Result.Val.getInt();
16719 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16720}
16721
16722// Return true if it can be proven that the provided array expression (array
16723// section or array subscript) does NOT specify a single element of the array
16724// whose base type is \a BaseQTy.
16725static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16726 const Expr *E,
16727 QualType BaseQTy) {
16728 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16729
16730 // An array subscript always refer to a single element. Also, an array section
16731 // assumes the format of an array subscript if no colon is used.
16732 if (isa<ArraySubscriptExpr>(E) ||
16733 (OASE && OASE->getColonLocFirst().isInvalid()))
16734 return false;
16735
16736 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16736, __PRETTY_FUNCTION__))
;
16737 const Expr *Length = OASE->getLength();
16738
16739 // If we don't have a length we have to check if the array has unitary size
16740 // for this dimension. Also, we should always expect a length if the base type
16741 // is pointer.
16742 if (!Length) {
16743 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16744 return ATy->getSize().getSExtValue() != 1;
16745 // We cannot assume anything.
16746 return false;
16747 }
16748
16749 // Check if the length evaluates to 1.
16750 Expr::EvalResult Result;
16751 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16752 return false; // Can't get the integer value as a constant.
16753
16754 llvm::APSInt ConstLength = Result.Val.getInt();
16755 return ConstLength.getSExtValue() != 1;
16756}
16757
16758// The base of elements of list in a map clause have to be either:
16759// - a reference to variable or field.
16760// - a member expression.
16761// - an array expression.
16762//
16763// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16764// reference to 'r'.
16765//
16766// If we have:
16767//
16768// struct SS {
16769// Bla S;
16770// foo() {
16771// #pragma omp target map (S.Arr[:12]);
16772// }
16773// }
16774//
16775// We want to retrieve the member expression 'this->S';
16776
16777// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16778// If a list item is an array section, it must specify contiguous storage.
16779//
16780// For this restriction it is sufficient that we make sure only references
16781// to variables or fields and array expressions, and that no array sections
16782// exist except in the rightmost expression (unless they cover the whole
16783// dimension of the array). E.g. these would be invalid:
16784//
16785// r.ArrS[3:5].Arr[6:7]
16786//
16787// r.ArrS[3:5].x
16788//
16789// but these would be valid:
16790// r.ArrS[3].Arr[6:7]
16791//
16792// r.ArrS[3].x
16793namespace {
16794class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16795 Sema &SemaRef;
16796 OpenMPClauseKind CKind = OMPC_unknown;
16797 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16798 bool NoDiagnose = false;
16799 const Expr *RelevantExpr = nullptr;
16800 bool AllowUnitySizeArraySection = true;
16801 bool AllowWholeSizeArraySection = true;
16802 SourceLocation ELoc;
16803 SourceRange ERange;
16804
16805 void emitErrorMsg() {
16806 // If nothing else worked, this is not a valid map clause expression.
16807 if (SemaRef.getLangOpts().OpenMP < 50) {
16808 SemaRef.Diag(ELoc,
16809 diag::err_omp_expected_named_var_member_or_array_expression)
16810 << ERange;
16811 } else {
16812 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16813 << getOpenMPClauseName(CKind) << ERange;
16814 }
16815 }
16816
16817public:
16818 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16819 if (!isa<VarDecl>(DRE->getDecl())) {
16820 emitErrorMsg();
16821 return false;
16822 }
16823 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16823, __PRETTY_FUNCTION__))
;
16824 RelevantExpr = DRE;
16825 // Record the component.
16826 Components.emplace_back(DRE, DRE->getDecl());
16827 return true;
16828 }
16829
16830 bool VisitMemberExpr(MemberExpr *ME) {
16831 Expr *E = ME;
16832 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16833
16834 if (isa<CXXThisExpr>(BaseE)) {
16835 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16835, __PRETTY_FUNCTION__))
;
16836 // We found a base expression: this->Val.
16837 RelevantExpr = ME;
16838 } else {
16839 E = BaseE;
16840 }
16841
16842 if (!isa<FieldDecl>(ME->getMemberDecl())) {
16843 if (!NoDiagnose) {
16844 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16845 << ME->getSourceRange();
16846 return false;
16847 }
16848 if (RelevantExpr)
16849 return false;
16850 return Visit(E);
16851 }
16852
16853 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16854
16855 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16856 // A bit-field cannot appear in a map clause.
16857 //
16858 if (FD->isBitField()) {
16859 if (!NoDiagnose) {
16860 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16861 << ME->getSourceRange() << getOpenMPClauseName(CKind);
16862 return false;
16863 }
16864 if (RelevantExpr)
16865 return false;
16866 return Visit(E);
16867 }
16868
16869 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16870 // If the type of a list item is a reference to a type T then the type
16871 // will be considered to be T for all purposes of this clause.
16872 QualType CurType = BaseE->getType().getNonReferenceType();
16873
16874 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16875 // A list item cannot be a variable that is a member of a structure with
16876 // a union type.
16877 //
16878 if (CurType->isUnionType()) {
16879 if (!NoDiagnose) {
16880 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16881 << ME->getSourceRange();
16882 return false;
16883 }
16884 return RelevantExpr || Visit(E);
16885 }
16886
16887 // If we got a member expression, we should not expect any array section
16888 // before that:
16889 //
16890 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16891 // If a list item is an element of a structure, only the rightmost symbol
16892 // of the variable reference can be an array section.
16893 //
16894 AllowUnitySizeArraySection = false;
16895 AllowWholeSizeArraySection = false;
16896
16897 // Record the component.
16898 Components.emplace_back(ME, FD);
16899 return RelevantExpr || Visit(E);
16900 }
16901
16902 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16903 Expr *E = AE->getBase()->IgnoreParenImpCasts();
16904
16905 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16906 if (!NoDiagnose) {
16907 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16908 << 0 << AE->getSourceRange();
16909 return false;
16910 }
16911 return RelevantExpr || Visit(E);
16912 }
16913
16914 // If we got an array subscript that express the whole dimension we
16915 // can have any array expressions before. If it only expressing part of
16916 // the dimension, we can only have unitary-size array expressions.
16917 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16918 E->getType()))
16919 AllowWholeSizeArraySection = false;
16920
16921 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16922 Expr::EvalResult Result;
16923 if (!AE->getIdx()->isValueDependent() &&
16924 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16925 !Result.Val.getInt().isNullValue()) {
16926 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16927 diag::err_omp_invalid_map_this_expr);
16928 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16929 diag::note_omp_invalid_subscript_on_this_ptr_map);
16930 }
16931 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16931, __PRETTY_FUNCTION__))
;
16932 RelevantExpr = TE;
16933 }
16934
16935 // Record the component - we don't have any declaration associated.
16936 Components.emplace_back(AE, nullptr);
16937
16938 return RelevantExpr || Visit(E);
16939 }
16940
16941 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16942 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((!NoDiagnose && "Array sections cannot be implicitly mapped."
) ? static_cast<void> (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 16942, __PRETTY_FUNCTION__))
;
16943 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16944 QualType CurType =
16945 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16946
16947 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16948 // If the type of a list item is a reference to a type T then the type
16949 // will be considered to be T for all purposes of this clause.
16950 if (CurType->isReferenceType())
16951 CurType = CurType->getPointeeType();
16952
16953 bool IsPointer = CurType->isAnyPointerType();
16954
16955 if (!IsPointer && !CurType->isArrayType()) {
16956 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16957 << 0 << OASE->getSourceRange();
16958 return false;
16959 }
16960
16961 bool NotWhole =
16962 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16963 bool NotUnity =
16964 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16965
16966 if (AllowWholeSizeArraySection) {
16967 // Any array section is currently allowed. Allowing a whole size array
16968 // section implies allowing a unity array section as well.
16969 //
16970 // If this array section refers to the whole dimension we can still
16971 // accept other array sections before this one, except if the base is a
16972 // pointer. Otherwise, only unitary sections are accepted.
16973 if (NotWhole || IsPointer)
16974 AllowWholeSizeArraySection = false;
16975 } else if (AllowUnitySizeArraySection && NotUnity) {
16976 // A unity or whole array section is not allowed and that is not
16977 // compatible with the properties of the current array section.
16978 SemaRef.Diag(
16979 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
16980 << OASE->getSourceRange();
16981 return false;
16982 }
16983
16984 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
16985 Expr::EvalResult ResultR;
16986 Expr::EvalResult ResultL;
16987 if (!OASE->getLength()->isValueDependent() &&
16988 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
16989 !ResultR.Val.getInt().isOneValue()) {
16990 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16991 diag::err_omp_invalid_map_this_expr);
16992 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16993 diag::note_omp_invalid_length_on_this_ptr_mapping);
16994 }
16995 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
16996 OASE->getLowerBound()->EvaluateAsInt(ResultL,
16997 SemaRef.getASTContext()) &&
16998 !ResultL.Val.getInt().isNullValue()) {
16999 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17000 diag::err_omp_invalid_map_this_expr);
17001 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17002 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17003 }
17004 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17004, __PRETTY_FUNCTION__))
;
17005 RelevantExpr = TE;
17006 }
17007
17008 // Record the component - we don't have any declaration associated.
17009 Components.emplace_back(OASE, nullptr);
17010 return RelevantExpr || Visit(E);
17011 }
17012 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17013 Expr *Base = E->getBase();
17014
17015 // Record the component - we don't have any declaration associated.
17016 Components.emplace_back(E, nullptr);
17017
17018 return Visit(Base->IgnoreParenImpCasts());
17019 }
17020
17021 bool VisitUnaryOperator(UnaryOperator *UO) {
17022 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17023 UO->getOpcode() != UO_Deref) {
17024 emitErrorMsg();
17025 return false;
17026 }
17027 if (!RelevantExpr) {
17028 // Record the component if haven't found base decl.
17029 Components.emplace_back(UO, nullptr);
17030 }
17031 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17032 }
17033 bool VisitBinaryOperator(BinaryOperator *BO) {
17034 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17035 emitErrorMsg();
17036 return false;
17037 }
17038
17039 // Pointer arithmetic is the only thing we expect to happen here so after we
17040 // make sure the binary operator is a pointer type, the we only thing need
17041 // to to is to visit the subtree that has the same type as root (so that we
17042 // know the other subtree is just an offset)
17043 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17044 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17045 Components.emplace_back(BO, nullptr);
17046 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17048, __PRETTY_FUNCTION__))
17047 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17048, __PRETTY_FUNCTION__))
17048 "Either LHS or RHS have base decl inside")(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17048, __PRETTY_FUNCTION__))
;
17049 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17050 return RelevantExpr || Visit(LE);
17051 return RelevantExpr || Visit(RE);
17052 }
17053 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17054 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17054, __PRETTY_FUNCTION__))
;
17055 RelevantExpr = CTE;
17056 Components.emplace_back(CTE, nullptr);
17057 return true;
17058 }
17059 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17060 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17060, __PRETTY_FUNCTION__))
;
17061 Components.emplace_back(COCE, nullptr);
17062 return true;
17063 }
17064 bool VisitStmt(Stmt *) {
17065 emitErrorMsg();
17066 return false;
17067 }
17068 const Expr *getFoundBase() const {
17069 return RelevantExpr;
17070 }
17071 explicit MapBaseChecker(
17072 Sema &SemaRef, OpenMPClauseKind CKind,
17073 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17074 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17075 : SemaRef(SemaRef), CKind(CKind), Components(Components),
17076 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17077};
17078} // namespace
17079
17080/// Return the expression of the base of the mappable expression or null if it
17081/// cannot be determined and do all the necessary checks to see if the expression
17082/// is valid as a standalone mappable expression. In the process, record all the
17083/// components of the expression.
17084static const Expr *checkMapClauseExpressionBase(
17085 Sema &SemaRef, Expr *E,
17086 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17087 OpenMPClauseKind CKind, bool NoDiagnose) {
17088 SourceLocation ELoc = E->getExprLoc();
17089 SourceRange ERange = E->getSourceRange();
17090 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
17091 ERange);
17092 if (Checker.Visit(E->IgnoreParens()))
17093 return Checker.getFoundBase();
17094 return nullptr;
17095}
17096
17097// Return true if expression E associated with value VD has conflicts with other
17098// map information.
17099static bool checkMapConflicts(
17100 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17101 bool CurrentRegionOnly,
17102 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17103 OpenMPClauseKind CKind) {
17104 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17104, __PRETTY_FUNCTION__))
;
17105 SourceLocation ELoc = E->getExprLoc();
17106 SourceRange ERange = E->getSourceRange();
17107
17108 // In order to easily check the conflicts we need to match each component of
17109 // the expression under test with the components of the expressions that are
17110 // already in the stack.
17111
17112 assert(!CurComponents.empty() && "Map clause expression with no components!")((!CurComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17112, __PRETTY_FUNCTION__))
;
17113 assert(CurComponents.back().getAssociatedDeclaration() == VD &&((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17114, __PRETTY_FUNCTION__))
17114 "Map clause expression with unexpected base!")((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17114, __PRETTY_FUNCTION__))
;
17115
17116 // Variables to help detecting enclosing problems in data environment nests.
17117 bool IsEnclosedByDataEnvironmentExpr = false;
17118 const Expr *EnclosingExpr = nullptr;
17119
17120 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17121 VD, CurrentRegionOnly,
17122 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17123 ERange, CKind, &EnclosingExpr,
17124 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17125 StackComponents,
17126 OpenMPClauseKind) {
17127 assert(!StackComponents.empty() &&((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17128, __PRETTY_FUNCTION__))
17128 "Map clause expression with no components!")((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17128, __PRETTY_FUNCTION__))
;
17129 assert(StackComponents.back().getAssociatedDeclaration() == VD &&((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17130, __PRETTY_FUNCTION__))
17130 "Map clause expression with unexpected base!")((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17130, __PRETTY_FUNCTION__))
;
17131 (void)VD;
17132
17133 // The whole expression in the stack.
17134 const Expr *RE = StackComponents.front().getAssociatedExpression();
17135
17136 // Expressions must start from the same base. Here we detect at which
17137 // point both expressions diverge from each other and see if we can
17138 // detect if the memory referred to both expressions is contiguous and
17139 // do not overlap.
17140 auto CI = CurComponents.rbegin();
17141 auto CE = CurComponents.rend();
17142 auto SI = StackComponents.rbegin();
17143 auto SE = StackComponents.rend();
17144 for (; CI != CE && SI != SE; ++CI, ++SI) {
17145
17146 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17147 // At most one list item can be an array item derived from a given
17148 // variable in map clauses of the same construct.
17149 if (CurrentRegionOnly &&
17150 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17151 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17152 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17153 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17154 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17155 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17156 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17157 diag::err_omp_multiple_array_items_in_map_clause)
17158 << CI->getAssociatedExpression()->getSourceRange();
17159 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17160 diag::note_used_here)
17161 << SI->getAssociatedExpression()->getSourceRange();
17162 return true;
17163 }
17164
17165 // Do both expressions have the same kind?
17166 if (CI->getAssociatedExpression()->getStmtClass() !=
17167 SI->getAssociatedExpression()->getStmtClass())
17168 break;
17169
17170 // Are we dealing with different variables/fields?
17171 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17172 break;
17173 }
17174 // Check if the extra components of the expressions in the enclosing
17175 // data environment are redundant for the current base declaration.
17176 // If they are, the maps completely overlap, which is legal.
17177 for (; SI != SE; ++SI) {
17178 QualType Type;
17179 if (const auto *ASE =
17180 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17181 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17182 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17183 SI->getAssociatedExpression())) {
17184 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17185 Type =
17186 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17187 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17188 SI->getAssociatedExpression())) {
17189 Type = OASE->getBase()->getType()->getPointeeType();
17190 }
17191 if (Type.isNull() || Type->isAnyPointerType() ||
17192 checkArrayExpressionDoesNotReferToWholeSize(
17193 SemaRef, SI->getAssociatedExpression(), Type))
17194 break;
17195 }
17196
17197 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17198 // List items of map clauses in the same construct must not share
17199 // original storage.
17200 //
17201 // If the expressions are exactly the same or one is a subset of the
17202 // other, it means they are sharing storage.
17203 if (CI == CE && SI == SE) {
17204 if (CurrentRegionOnly) {
17205 if (CKind == OMPC_map) {
17206 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17207 } else {
17208 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17208, __PRETTY_FUNCTION__))
;
17209 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17210 << ERange;
17211 }
17212 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17213 << RE->getSourceRange();
17214 return true;
17215 }
17216 // If we find the same expression in the enclosing data environment,
17217 // that is legal.
17218 IsEnclosedByDataEnvironmentExpr = true;
17219 return false;
17220 }
17221
17222 QualType DerivedType =
17223 std::prev(CI)->getAssociatedDeclaration()->getType();
17224 SourceLocation DerivedLoc =
17225 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17226
17227 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17228 // If the type of a list item is a reference to a type T then the type
17229 // will be considered to be T for all purposes of this clause.
17230 DerivedType = DerivedType.getNonReferenceType();
17231
17232 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17233 // A variable for which the type is pointer and an array section
17234 // derived from that variable must not appear as list items of map
17235 // clauses of the same construct.
17236 //
17237 // Also, cover one of the cases in:
17238 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17239 // If any part of the original storage of a list item has corresponding
17240 // storage in the device data environment, all of the original storage
17241 // must have corresponding storage in the device data environment.
17242 //
17243 if (DerivedType->isAnyPointerType()) {
17244 if (CI == CE || SI == SE) {
17245 SemaRef.Diag(
17246 DerivedLoc,
17247 diag::err_omp_pointer_mapped_along_with_derived_section)
17248 << DerivedLoc;
17249 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17250 << RE->getSourceRange();
17251 return true;
17252 }
17253 if (CI->getAssociatedExpression()->getStmtClass() !=
17254 SI->getAssociatedExpression()->getStmtClass() ||
17255 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17256 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17257 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17257, __PRETTY_FUNCTION__))
;
17258 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17259 << DerivedLoc;
17260 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17261 << RE->getSourceRange();
17262 return true;
17263 }
17264 }
17265
17266 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17267 // List items of map clauses in the same construct must not share
17268 // original storage.
17269 //
17270 // An expression is a subset of the other.
17271 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17272 if (CKind == OMPC_map) {
17273 if (CI != CE || SI != SE) {
17274 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17275 // a pointer.
17276 auto Begin =
17277 CI != CE ? CurComponents.begin() : StackComponents.begin();
17278 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17279 auto It = Begin;
17280 while (It != End && !It->getAssociatedDeclaration())
17281 std::advance(It, 1);
17282 assert(It != End &&((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17283, __PRETTY_FUNCTION__))
17283 "Expected at least one component with the declaration.")((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17283, __PRETTY_FUNCTION__))
;
17284 if (It != Begin && It->getAssociatedDeclaration()
17285 ->getType()
17286 .getCanonicalType()
17287 ->isAnyPointerType()) {
17288 IsEnclosedByDataEnvironmentExpr = false;
17289 EnclosingExpr = nullptr;
17290 return false;
17291 }
17292 }
17293 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17294 } else {
17295 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17295, __PRETTY_FUNCTION__))
;
17296 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17297 << ERange;
17298 }
17299 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17300 << RE->getSourceRange();
17301 return true;
17302 }
17303
17304 // The current expression uses the same base as other expression in the
17305 // data environment but does not contain it completely.
17306 if (!CurrentRegionOnly && SI != SE)
17307 EnclosingExpr = RE;
17308
17309 // The current expression is a subset of the expression in the data
17310 // environment.
17311 IsEnclosedByDataEnvironmentExpr |=
17312 (!CurrentRegionOnly && CI != CE && SI == SE);
17313
17314 return false;
17315 });
17316
17317 if (CurrentRegionOnly)
17318 return FoundError;
17319
17320 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17321 // If any part of the original storage of a list item has corresponding
17322 // storage in the device data environment, all of the original storage must
17323 // have corresponding storage in the device data environment.
17324 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17325 // If a list item is an element of a structure, and a different element of
17326 // the structure has a corresponding list item in the device data environment
17327 // prior to a task encountering the construct associated with the map clause,
17328 // then the list item must also have a corresponding list item in the device
17329 // data environment prior to the task encountering the construct.
17330 //
17331 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17332 SemaRef.Diag(ELoc,
17333 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17334 << ERange;
17335 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17336 << EnclosingExpr->getSourceRange();
17337 return true;
17338 }
17339
17340 return FoundError;
17341}
17342
17343// Look up the user-defined mapper given the mapper name and mapped type, and
17344// build a reference to it.
17345static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17346 CXXScopeSpec &MapperIdScopeSpec,
17347 const DeclarationNameInfo &MapperId,
17348 QualType Type,
17349 Expr *UnresolvedMapper) {
17350 if (MapperIdScopeSpec.isInvalid())
17351 return ExprError();
17352 // Get the actual type for the array type.
17353 if (Type->isArrayType()) {
17354 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"
) ? static_cast<void> (0) : __assert_fail ("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17354, __PRETTY_FUNCTION__))
;
17355 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17356 }
17357 // Find all user-defined mappers with the given MapperId.
17358 SmallVector<UnresolvedSet<8>, 4> Lookups;
17359 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17360 Lookup.suppressDiagnostics();
17361 if (S) {
17362 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17363 NamedDecl *D = Lookup.getRepresentativeDecl();
17364 while (S && !S->isDeclScope(D))
17365 S = S->getParent();
17366 if (S)
17367 S = S->getParent();
17368 Lookups.emplace_back();
17369 Lookups.back().append(Lookup.begin(), Lookup.end());
17370 Lookup.clear();
17371 }
17372 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17373 // Extract the user-defined mappers with the given MapperId.
17374 Lookups.push_back(UnresolvedSet<8>());
17375 for (NamedDecl *D : ULE->decls()) {
17376 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17377 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((DMD && "Expect valid OMPDeclareMapperDecl during instantiation."
) ? static_cast<void> (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17377, __PRETTY_FUNCTION__))
;
17378 Lookups.back().addDecl(DMD);
17379 }
17380 }
17381 // Defer the lookup for dependent types. The results will be passed through
17382 // UnresolvedMapper on instantiation.
17383 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17384 Type->isInstantiationDependentType() ||
17385 Type->containsUnexpandedParameterPack() ||
17386 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17387 return !D->isInvalidDecl() &&
17388 (D->getType()->isDependentType() ||
17389 D->getType()->isInstantiationDependentType() ||
17390 D->getType()->containsUnexpandedParameterPack());
17391 })) {
17392 UnresolvedSet<8> URS;
17393 for (const UnresolvedSet<8> &Set : Lookups) {
17394 if (Set.empty())
17395 continue;
17396 URS.append(Set.begin(), Set.end());
17397 }
17398 return UnresolvedLookupExpr::Create(
17399 SemaRef.Context, /*NamingClass=*/nullptr,
17400 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17401 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17402 }
17403 SourceLocation Loc = MapperId.getLoc();
17404 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17405 // The type must be of struct, union or class type in C and C++
17406 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17407 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17408 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17409 return ExprError();
17410 }
17411 // Perform argument dependent lookup.
17412 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17413 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17414 // Return the first user-defined mapper with the desired type.
17415 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17416 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17417 if (!D->isInvalidDecl() &&
17418 SemaRef.Context.hasSameType(D->getType(), Type))
17419 return D;
17420 return nullptr;
17421 }))
17422 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17423 // Find the first user-defined mapper with a type derived from the desired
17424 // type.
17425 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17426 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17427 if (!D->isInvalidDecl() &&
17428 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17429 !Type.isMoreQualifiedThan(D->getType()))
17430 return D;
17431 return nullptr;
17432 })) {
17433 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17434 /*DetectVirtual=*/false);
17435 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17436 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17437 VD->getType().getUnqualifiedType()))) {
17438 if (SemaRef.CheckBaseClassAccess(
17439 Loc, VD->getType(), Type, Paths.front(),
17440 /*DiagID=*/0) != Sema::AR_inaccessible) {
17441 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17442 }
17443 }
17444 }
17445 }
17446 // Report error if a mapper is specified, but cannot be found.
17447 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17448 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17449 << Type << MapperId.getName();
17450 return ExprError();
17451 }
17452 return ExprEmpty();
17453}
17454
17455namespace {
17456// Utility struct that gathers all the related lists associated with a mappable
17457// expression.
17458struct MappableVarListInfo {
17459 // The list of expressions.
17460 ArrayRef<Expr *> VarList;
17461 // The list of processed expressions.
17462 SmallVector<Expr *, 16> ProcessedVarList;
17463 // The mappble components for each expression.
17464 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17465 // The base declaration of the variable.
17466 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17467 // The reference to the user-defined mapper associated with every expression.
17468 SmallVector<Expr *, 16> UDMapperList;
17469
17470 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17471 // We have a list of components and base declarations for each entry in the
17472 // variable list.
17473 VarComponents.reserve(VarList.size());
17474 VarBaseDeclarations.reserve(VarList.size());
17475 }
17476};
17477}
17478
17479// Check the validity of the provided variable list for the provided clause kind
17480// \a CKind. In the check process the valid expressions, mappable expression
17481// components, variables, and user-defined mappers are extracted and used to
17482// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17483// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17484// and \a MapperId are expected to be valid if the clause kind is 'map'.
17485static void checkMappableExpressionList(
17486 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17487 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17488 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17489 ArrayRef<Expr *> UnresolvedMappers,
17490 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17491 bool IsMapTypeImplicit = false) {
17492 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17493 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17494, __PRETTY_FUNCTION__))
17494 "Unexpected clause kind with mappable expressions!")(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17494, __PRETTY_FUNCTION__))
;
17495
17496 // If the identifier of user-defined mapper is not specified, it is "default".
17497 // We do not change the actual name in this clause to distinguish whether a
17498 // mapper is specified explicitly, i.e., it is not explicitly specified when
17499 // MapperId.getName() is empty.
17500 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17501 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17502 MapperId.setName(DeclNames.getIdentifier(
17503 &SemaRef.getASTContext().Idents.get("default")));
17504 }
17505
17506 // Iterators to find the current unresolved mapper expression.
17507 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17508 bool UpdateUMIt = false;
17509 Expr *UnresolvedMapper = nullptr;
17510
17511 // Keep track of the mappable components and base declarations in this clause.
17512 // Each entry in the list is going to have a list of components associated. We
17513 // record each set of the components so that we can build the clause later on.
17514 // In the end we should have the same amount of declarations and component
17515 // lists.
17516
17517 for (Expr *RE : MVLI.VarList) {
17518 assert(RE && "Null expr in omp to/from/map clause")((RE && "Null expr in omp to/from/map clause") ? static_cast
<void> (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17518, __PRETTY_FUNCTION__))
;
17519 SourceLocation ELoc = RE->getExprLoc();
17520
17521 // Find the current unresolved mapper expression.
17522 if (UpdateUMIt && UMIt != UMEnd) {
17523 UMIt++;
17524 assert(((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17526, __PRETTY_FUNCTION__))
17525 UMIt != UMEnd &&((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17526, __PRETTY_FUNCTION__))
17526 "Expect the size of UnresolvedMappers to match with that of VarList")((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17526, __PRETTY_FUNCTION__))
;
17527 }
17528 UpdateUMIt = true;
17529 if (UMIt != UMEnd)
17530 UnresolvedMapper = *UMIt;
17531
17532 const Expr *VE = RE->IgnoreParenLValueCasts();
17533
17534 if (VE->isValueDependent() || VE->isTypeDependent() ||
17535 VE->isInstantiationDependent() ||
17536 VE->containsUnexpandedParameterPack()) {
17537 // Try to find the associated user-defined mapper.
17538 ExprResult ER = buildUserDefinedMapperRef(
17539 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17540 VE->getType().getCanonicalType(), UnresolvedMapper);
17541 if (ER.isInvalid())
17542 continue;
17543 MVLI.UDMapperList.push_back(ER.get());
17544 // We can only analyze this information once the missing information is
17545 // resolved.
17546 MVLI.ProcessedVarList.push_back(RE);
17547 continue;
17548 }
17549
17550 Expr *SimpleExpr = RE->IgnoreParenCasts();
17551
17552 if (!RE->isLValue()) {
17553 if (SemaRef.getLangOpts().OpenMP < 50) {
17554 SemaRef.Diag(
17555 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17556 << RE->getSourceRange();
17557 } else {
17558 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17559 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17560 }
17561 continue;
17562 }
17563
17564 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17565 ValueDecl *CurDeclaration = nullptr;
17566
17567 // Obtain the array or member expression bases if required. Also, fill the
17568 // components array with all the components identified in the process.
17569 const Expr *BE = checkMapClauseExpressionBase(
17570 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
17571 if (!BE)
17572 continue;
17573
17574 assert(!CurComponents.empty() &&((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17575, __PRETTY_FUNCTION__))
17575 "Invalid mappable expression information.")((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17575, __PRETTY_FUNCTION__))
;
17576
17577 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17578 // Add store "this" pointer to class in DSAStackTy for future checking
17579 DSAS->addMappedClassesQualTypes(TE->getType());
17580 // Try to find the associated user-defined mapper.
17581 ExprResult ER = buildUserDefinedMapperRef(
17582 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17583 VE->getType().getCanonicalType(), UnresolvedMapper);
17584 if (ER.isInvalid())
17585 continue;
17586 MVLI.UDMapperList.push_back(ER.get());
17587 // Skip restriction checking for variable or field declarations
17588 MVLI.ProcessedVarList.push_back(RE);
17589 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17590 MVLI.VarComponents.back().append(CurComponents.begin(),
17591 CurComponents.end());
17592 MVLI.VarBaseDeclarations.push_back(nullptr);
17593 continue;
17594 }
17595
17596 // For the following checks, we rely on the base declaration which is
17597 // expected to be associated with the last component. The declaration is
17598 // expected to be a variable or a field (if 'this' is being mapped).
17599 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17600 assert(CurDeclaration && "Null decl on map clause.")((CurDeclaration && "Null decl on map clause.") ? static_cast
<void> (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17600, __PRETTY_FUNCTION__))
;
17601 assert(((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17603, __PRETTY_FUNCTION__))
17602 CurDeclaration->isCanonicalDecl() &&((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17603, __PRETTY_FUNCTION__))
17603 "Expecting components to have associated only canonical declarations.")((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17603, __PRETTY_FUNCTION__))
;
17604
17605 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17606 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17607
17608 assert((VD || FD) && "Only variables or fields are expected here!")(((VD || FD) && "Only variables or fields are expected here!"
) ? static_cast<void> (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17608, __PRETTY_FUNCTION__))
;
17609 (void)FD;
17610
17611 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17612 // threadprivate variables cannot appear in a map clause.
17613 // OpenMP 4.5 [2.10.5, target update Construct]
17614 // threadprivate variables cannot appear in a from clause.
17615 if (VD && DSAS->isThreadPrivate(VD)) {
17616 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17617 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17618 << getOpenMPClauseName(CKind);
17619 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17620 continue;
17621 }
17622
17623 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17624 // A list item cannot appear in both a map clause and a data-sharing
17625 // attribute clause on the same construct.
17626
17627 // Check conflicts with other map clause expressions. We check the conflicts
17628 // with the current construct separately from the enclosing data
17629 // environment, because the restrictions are different. We only have to
17630 // check conflicts across regions for the map clauses.
17631 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17632 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17633 break;
17634 if (CKind == OMPC_map &&
17635 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17636 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17637 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17638 break;
17639
17640 // OpenMP 4.5 [2.10.5, target update Construct]
17641 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17642 // If the type of a list item is a reference to a type T then the type will
17643 // be considered to be T for all purposes of this clause.
17644 auto I = llvm::find_if(
17645 CurComponents,
17646 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17647 return MC.getAssociatedDeclaration();
17648 });
17649 assert(I != CurComponents.end() && "Null decl on map clause.")((I != CurComponents.end() && "Null decl on map clause."
) ? static_cast<void> (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17649, __PRETTY_FUNCTION__))
;
17650 QualType Type;
17651 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17652 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17653 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17654 if (ASE) {
17655 Type = ASE->getType().getNonReferenceType();
17656 } else if (OASE) {
17657 QualType BaseType =
17658 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17659 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17660 Type = ATy->getElementType();
17661 else
17662 Type = BaseType->getPointeeType();
17663 Type = Type.getNonReferenceType();
17664 } else if (OAShE) {
17665 Type = OAShE->getBase()->getType()->getPointeeType();
17666 } else {
17667 Type = VE->getType();
17668 }
17669
17670 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17671 // A list item in a to or from clause must have a mappable type.
17672 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17673 // A list item must have a mappable type.
17674 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17675 DSAS, Type))
17676 continue;
17677
17678 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17679
17680 if (CKind == OMPC_map) {
17681 // target enter data
17682 // OpenMP [2.10.2, Restrictions, p. 99]
17683 // A map-type must be specified in all map clauses and must be either
17684 // to or alloc.
17685 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17686 if (DKind == OMPD_target_enter_data &&
17687 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17688 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17689 << (IsMapTypeImplicit ? 1 : 0)
17690 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17691 << getOpenMPDirectiveName(DKind);
17692 continue;
17693 }
17694
17695 // target exit_data
17696 // OpenMP [2.10.3, Restrictions, p. 102]
17697 // A map-type must be specified in all map clauses and must be either
17698 // from, release, or delete.
17699 if (DKind == OMPD_target_exit_data &&
17700 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17701 MapType == OMPC_MAP_delete)) {
17702 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17703 << (IsMapTypeImplicit ? 1 : 0)
17704 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17705 << getOpenMPDirectiveName(DKind);
17706 continue;
17707 }
17708
17709 // target, target data
17710 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17711 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17712 // A map-type in a map clause must be to, from, tofrom or alloc
17713 if ((DKind == OMPD_target_data ||
17714 isOpenMPTargetExecutionDirective(DKind)) &&
17715 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17716 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17717 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17718 << (IsMapTypeImplicit ? 1 : 0)
17719 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17720 << getOpenMPDirectiveName(DKind);
17721 continue;
17722 }
17723
17724 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17725 // A list item cannot appear in both a map clause and a data-sharing
17726 // attribute clause on the same construct
17727 //
17728 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17729 // A list item cannot appear in both a map clause and a data-sharing
17730 // attribute clause on the same construct unless the construct is a
17731 // combined construct.
17732 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17733 isOpenMPTargetExecutionDirective(DKind)) ||
17734 DKind == OMPD_target)) {
17735 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17736 if (isOpenMPPrivate(DVar.CKind)) {
17737 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17738 << getOpenMPClauseName(DVar.CKind)
17739 << getOpenMPClauseName(OMPC_map)
17740 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17741 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17742 continue;
17743 }
17744 }
17745 }
17746
17747 // Try to find the associated user-defined mapper.
17748 ExprResult ER = buildUserDefinedMapperRef(
17749 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17750 Type.getCanonicalType(), UnresolvedMapper);
17751 if (ER.isInvalid())
17752 continue;
17753 MVLI.UDMapperList.push_back(ER.get());
17754
17755 // Save the current expression.
17756 MVLI.ProcessedVarList.push_back(RE);
17757
17758 // Store the components in the stack so that they can be used to check
17759 // against other clauses later on.
17760 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17761 /*WhereFoundClauseKind=*/OMPC_map);
17762
17763 // Save the components and declaration to create the clause. For purposes of
17764 // the clause creation, any component list that has has base 'this' uses
17765 // null as base declaration.
17766 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17767 MVLI.VarComponents.back().append(CurComponents.begin(),
17768 CurComponents.end());
17769 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17770 : CurDeclaration);
17771 }
17772}
17773
17774OMPClause *Sema::ActOnOpenMPMapClause(
17775 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17776 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17777 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17778 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17779 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17780 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17781 OpenMPMapModifierKind Modifiers[] = {
17782 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17783 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17784 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17785
17786 // Process map-type-modifiers, flag errors for duplicate modifiers.
17787 unsigned Count = 0;
17788 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17789 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17790 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17791 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17792 continue;
17793 }
17794 assert(Count < NumberOfOMPMapClauseModifiers &&((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17795, __PRETTY_FUNCTION__))
17795 "Modifiers exceed the allowed number of map type modifiers")((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17795, __PRETTY_FUNCTION__))
;
17796 Modifiers[Count] = MapTypeModifiers[I];
17797 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17798 ++Count;
17799 }
17800
17801 MappableVarListInfo MVLI(VarList);
17802 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
17803 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17804 MapType, IsMapTypeImplicit);
17805
17806 // We need to produce a map clause even if we don't have variables so that
17807 // other diagnostics related with non-existing map clauses are accurate.
17808 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17809 MVLI.VarBaseDeclarations, MVLI.VarComponents,
17810 MVLI.UDMapperList, Modifiers, ModifiersLoc,
17811 MapperIdScopeSpec.getWithLocInContext(Context),
17812 MapperId, MapType, IsMapTypeImplicit, MapLoc);
17813}
17814
17815QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17816 TypeResult ParsedType) {
17817 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 17817, __PRETTY_FUNCTION__))
;
17818
17819 QualType ReductionType = GetTypeFromParser(ParsedType.get());
17820 if (ReductionType.isNull())
17821 return QualType();
17822
17823 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17824 // A type name in a declare reduction directive cannot be a function type, an
17825 // array type, a reference type, or a type qualified with const, volatile or
17826 // restrict.
17827 if (ReductionType.hasQualifiers()) {
17828 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17829 return QualType();
17830 }
17831
17832 if (ReductionType->isFunctionType()) {
17833 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17834 return QualType();
17835 }
17836 if (ReductionType->isReferenceType()) {
17837 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17838 return QualType();
17839 }
17840 if (ReductionType->isArrayType()) {
17841 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17842 return QualType();
17843 }
17844 return ReductionType;
17845}
17846
17847Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17848 Scope *S, DeclContext *DC, DeclarationName Name,
17849 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17850 AccessSpecifier AS, Decl *PrevDeclInScope) {
17851 SmallVector<Decl *, 8> Decls;
17852 Decls.reserve(ReductionTypes.size());
17853
17854 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17855 forRedeclarationInCurContext());
17856 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17857 // A reduction-identifier may not be re-declared in the current scope for the
17858 // same type or for a type that is compatible according to the base language
17859 // rules.
17860 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17861 OMPDeclareReductionDecl *PrevDRD = nullptr;
17862 bool InCompoundScope = true;
17863 if (S != nullptr) {
17864 // Find previous declaration with the same name not referenced in other
17865 // declarations.
17866 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17867 InCompoundScope =
17868 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17869 LookupName(Lookup, S);
17870 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17871 /*AllowInlineNamespace=*/false);
17872 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17873 LookupResult::Filter Filter = Lookup.makeFilter();
17874 while (Filter.hasNext()) {
17875 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17876 if (InCompoundScope) {
17877 auto I = UsedAsPrevious.find(PrevDecl);
17878 if (I == UsedAsPrevious.end())
17879 UsedAsPrevious[PrevDecl] = false;
17880 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17881 UsedAsPrevious[D] = true;
17882 }
17883 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17884 PrevDecl->getLocation();
17885 }
17886 Filter.done();
17887 if (InCompoundScope) {
17888 for (const auto &PrevData : UsedAsPrevious) {
17889 if (!PrevData.second) {
17890 PrevDRD = PrevData.first;
17891 break;
17892 }
17893 }
17894 }
17895 } else if (PrevDeclInScope != nullptr) {
17896 auto *PrevDRDInScope = PrevDRD =
17897 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17898 do {
17899 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17900 PrevDRDInScope->getLocation();
17901 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17902 } while (PrevDRDInScope != nullptr);
17903 }
17904 for (const auto &TyData : ReductionTypes) {
17905 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17906 bool Invalid = false;
17907 if (I != PreviousRedeclTypes.end()) {
17908 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17909 << TyData.first;
17910 Diag(I->second, diag::note_previous_definition);
17911 Invalid = true;
17912 }
17913 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17914 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17915 Name, TyData.first, PrevDRD);
17916 DC->addDecl(DRD);
17917 DRD->setAccess(AS);
17918 Decls.push_back(DRD);
17919 if (Invalid)
17920 DRD->setInvalidDecl();
17921 else
17922 PrevDRD = DRD;
17923 }
17924
17925 return DeclGroupPtrTy::make(
17926 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17927}
17928
17929void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17930 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17931
17932 // Enter new function scope.
17933 PushFunctionScope();
17934 setFunctionHasBranchProtectedScope();
17935 getCurFunction()->setHasOMPDeclareReductionCombiner();
17936
17937 if (S != nullptr)
17938 PushDeclContext(S, DRD);
17939 else
17940 CurContext = DRD;
17941
17942 PushExpressionEvaluationContext(
17943 ExpressionEvaluationContext::PotentiallyEvaluated);
17944
17945 QualType ReductionType = DRD->getType();
17946 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
17947 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
17948 // uses semantics of argument handles by value, but it should be passed by
17949 // reference. C lang does not support references, so pass all parameters as
17950 // pointers.
17951 // Create 'T omp_in;' variable.
17952 VarDecl *OmpInParm =
17953 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
17954 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
17955 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
17956 // uses semantics of argument handles by value, but it should be passed by
17957 // reference. C lang does not support references, so pass all parameters as
17958 // pointers.
17959 // Create 'T omp_out;' variable.
17960 VarDecl *OmpOutParm =
17961 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
17962 if (S != nullptr) {
17963 PushOnScopeChains(OmpInParm, S);
17964 PushOnScopeChains(OmpOutParm, S);
17965 } else {
17966 DRD->addDecl(OmpInParm);
17967 DRD->addDecl(OmpOutParm);
17968 }
17969 Expr *InE =
17970 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
17971 Expr *OutE =
17972 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
17973 DRD->setCombinerData(InE, OutE);
17974}
17975
17976void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
17977 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17978 DiscardCleanupsInEvaluationContext();
17979 PopExpressionEvaluationContext();
17980
17981 PopDeclContext();
17982 PopFunctionScopeInfo();
17983
17984 if (Combiner != nullptr)
17985 DRD->setCombiner(Combiner);
17986 else
17987 DRD->setInvalidDecl();
17988}
17989
17990VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
17991 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17992
17993 // Enter new function scope.
17994 PushFunctionScope();
17995 setFunctionHasBranchProtectedScope();
17996
17997 if (S != nullptr)
17998 PushDeclContext(S, DRD);
17999 else
18000 CurContext = DRD;
18001
18002 PushExpressionEvaluationContext(
18003 ExpressionEvaluationContext::PotentiallyEvaluated);
18004
18005 QualType ReductionType = DRD->getType();
18006 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18007 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18008 // uses semantics of argument handles by value, but it should be passed by
18009 // reference. C lang does not support references, so pass all parameters as
18010 // pointers.
18011 // Create 'T omp_priv;' variable.
18012 VarDecl *OmpPrivParm =
18013 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18014 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18015 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18016 // uses semantics of argument handles by value, but it should be passed by
18017 // reference. C lang does not support references, so pass all parameters as
18018 // pointers.
18019 // Create 'T omp_orig;' variable.
18020 VarDecl *OmpOrigParm =
18021 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18022 if (S != nullptr) {
18023 PushOnScopeChains(OmpPrivParm, S);
18024 PushOnScopeChains(OmpOrigParm, S);
18025 } else {
18026 DRD->addDecl(OmpPrivParm);
18027 DRD->addDecl(OmpOrigParm);
18028 }
18029 Expr *OrigE =
18030 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18031 Expr *PrivE =
18032 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18033 DRD->setInitializerData(OrigE, PrivE);
18034 return OmpPrivParm;
18035}
18036
18037void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18038 VarDecl *OmpPrivParm) {
18039 auto *DRD = cast<OMPDeclareReductionDecl>(D);
18040 DiscardCleanupsInEvaluationContext();
18041 PopExpressionEvaluationContext();
18042
18043 PopDeclContext();
18044 PopFunctionScopeInfo();
18045
18046 if (Initializer != nullptr) {
18047 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18048 } else if (OmpPrivParm->hasInit()) {
18049 DRD->setInitializer(OmpPrivParm->getInit(),
18050 OmpPrivParm->isDirectInit()
18051 ? OMPDeclareReductionDecl::DirectInit
18052 : OMPDeclareReductionDecl::CopyInit);
18053 } else {
18054 DRD->setInvalidDecl();
18055 }
18056}
18057
18058Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18059 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18060 for (Decl *D : DeclReductions.get()) {
18061 if (IsValid) {
18062 if (S)
18063 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18064 /*AddToContext=*/false);
18065 } else {
18066 D->setInvalidDecl();
18067 }
18068 }
18069 return DeclReductions;
18070}
18071
18072TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18073 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18074 QualType T = TInfo->getType();
18075 if (D.isInvalidType())
18076 return true;
18077
18078 if (getLangOpts().CPlusPlus) {
18079 // Check that there are no default arguments (C++ only).
18080 CheckExtraCXXDefaultArguments(D);
18081 }
18082
18083 return CreateParsedType(T, TInfo);
18084}
18085
18086QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18087 TypeResult ParsedType) {
18088 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((ParsedType.isUsable() && "Expect usable parsed mapper type"
) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18088, __PRETTY_FUNCTION__))
;
18089
18090 QualType MapperType = GetTypeFromParser(ParsedType.get());
18091 assert(!MapperType.isNull() && "Expect valid mapper type")((!MapperType.isNull() && "Expect valid mapper type")
? static_cast<void> (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18091, __PRETTY_FUNCTION__))
;
18092
18093 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18094 // The type must be of struct, union or class type in C and C++
18095 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18096 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18097 return QualType();
18098 }
18099 return MapperType;
18100}
18101
18102Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18103 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18104 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18105 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18106 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18107 forRedeclarationInCurContext());
18108 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18109 // A mapper-identifier may not be redeclared in the current scope for the
18110 // same type or for a type that is compatible according to the base language
18111 // rules.
18112 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18113 OMPDeclareMapperDecl *PrevDMD = nullptr;
18114 bool InCompoundScope = true;
18115 if (S != nullptr) {
18116 // Find previous declaration with the same name not referenced in other
18117 // declarations.
18118 FunctionScopeInfo *ParentFn = getEnclosingFunction();
18119 InCompoundScope =
18120 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18121 LookupName(Lookup, S);
18122 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18123 /*AllowInlineNamespace=*/false);
18124 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18125 LookupResult::Filter Filter = Lookup.makeFilter();
18126 while (Filter.hasNext()) {
18127 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18128 if (InCompoundScope) {
18129 auto I = UsedAsPrevious.find(PrevDecl);
18130 if (I == UsedAsPrevious.end())
18131 UsedAsPrevious[PrevDecl] = false;
18132 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18133 UsedAsPrevious[D] = true;
18134 }
18135 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18136 PrevDecl->getLocation();
18137 }
18138 Filter.done();
18139 if (InCompoundScope) {
18140 for (const auto &PrevData : UsedAsPrevious) {
18141 if (!PrevData.second) {
18142 PrevDMD = PrevData.first;
18143 break;
18144 }
18145 }
18146 }
18147 } else if (PrevDeclInScope) {
18148 auto *PrevDMDInScope = PrevDMD =
18149 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18150 do {
18151 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18152 PrevDMDInScope->getLocation();
18153 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18154 } while (PrevDMDInScope != nullptr);
18155 }
18156 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18157 bool Invalid = false;
18158 if (I != PreviousRedeclTypes.end()) {
18159 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18160 << MapperType << Name;
18161 Diag(I->second, diag::note_previous_definition);
18162 Invalid = true;
18163 }
18164 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18165 MapperType, VN, Clauses, PrevDMD);
18166 if (S)
18167 PushOnScopeChains(DMD, S);
18168 else
18169 DC->addDecl(DMD);
18170 DMD->setAccess(AS);
18171 if (Invalid)
18172 DMD->setInvalidDecl();
18173
18174 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18175 VD->setDeclContext(DMD);
18176 VD->setLexicalDeclContext(DMD);
18177 DMD->addDecl(VD);
18178 DMD->setMapperVarRef(MapperVarRef);
18179
18180 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18181}
18182
18183ExprResult
18184Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18185 SourceLocation StartLoc,
18186 DeclarationName VN) {
18187 TypeSourceInfo *TInfo =
18188 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18189 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18190 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18191 MapperType, TInfo, SC_None);
18192 if (S)
18193 PushOnScopeChains(VD, S, /*AddToContext=*/false);
18194 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18195 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
18196 return E;
18197}
18198
18199bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18200 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18200, __PRETTY_FUNCTION__))
;
18201 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
18202 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18203 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18204 return true;
18205}
18206
18207const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18208 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18208, __PRETTY_FUNCTION__))
;
18209 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
18210}
18211
18212OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18213 SourceLocation StartLoc,
18214 SourceLocation LParenLoc,
18215 SourceLocation EndLoc) {
18216 Expr *ValExpr = NumTeams;
18217 Stmt *HelperValStmt = nullptr;
18218
18219 // OpenMP [teams Constrcut, Restrictions]
18220 // The num_teams expression must evaluate to a positive integer value.
18221 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18222 /*StrictlyPositive=*/true))
18223 return nullptr;
18224
18225 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18226 OpenMPDirectiveKind CaptureRegion =
18227 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18228 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18229 ValExpr = MakeFullExpr(ValExpr).get();
18230 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18231 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18232 HelperValStmt = buildPreInits(Context, Captures);
18233 }
18234
18235 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18236 StartLoc, LParenLoc, EndLoc);
18237}
18238
18239OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18240 SourceLocation StartLoc,
18241 SourceLocation LParenLoc,
18242 SourceLocation EndLoc) {
18243 Expr *ValExpr = ThreadLimit;
18244 Stmt *HelperValStmt = nullptr;
18245
18246 // OpenMP [teams Constrcut, Restrictions]
18247 // The thread_limit expression must evaluate to a positive integer value.
18248 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18249 /*StrictlyPositive=*/true))
18250 return nullptr;
18251
18252 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18253 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18254 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18255 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18256 ValExpr = MakeFullExpr(ValExpr).get();
18257 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18258 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18259 HelperValStmt = buildPreInits(Context, Captures);
18260 }
18261
18262 return new (Context) OMPThreadLimitClause(
18263 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18264}
18265
18266OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18267 SourceLocation StartLoc,
18268 SourceLocation LParenLoc,
18269 SourceLocation EndLoc) {
18270 Expr *ValExpr = Priority;
18271 Stmt *HelperValStmt = nullptr;
18272 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18273
18274 // OpenMP [2.9.1, task Constrcut]
18275 // The priority-value is a non-negative numerical scalar expression.
18276 if (!isNonNegativeIntegerValue(
18277 ValExpr, *this, OMPC_priority,
18278 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18279 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18280 return nullptr;
18281
18282 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18283 StartLoc, LParenLoc, EndLoc);
18284}
18285
18286OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18287 SourceLocation StartLoc,
18288 SourceLocation LParenLoc,
18289 SourceLocation EndLoc) {
18290 Expr *ValExpr = Grainsize;
18291 Stmt *HelperValStmt = nullptr;
18292 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18293
18294 // OpenMP [2.9.2, taskloop Constrcut]
18295 // The parameter of the grainsize clause must be a positive integer
18296 // expression.
18297 if (!isNonNegativeIntegerValue(
18298 ValExpr, *this, OMPC_grainsize,
18299 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18300 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18301 return nullptr;
18302
18303 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18304 StartLoc, LParenLoc, EndLoc);
18305}
18306
18307OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18308 SourceLocation StartLoc,
18309 SourceLocation LParenLoc,
18310 SourceLocation EndLoc) {
18311 Expr *ValExpr = NumTasks;
18312 Stmt *HelperValStmt = nullptr;
18313 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18314
18315 // OpenMP [2.9.2, taskloop Constrcut]
18316 // The parameter of the num_tasks clause must be a positive integer
18317 // expression.
18318 if (!isNonNegativeIntegerValue(
18319 ValExpr, *this, OMPC_num_tasks,
18320 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18321 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18322 return nullptr;
18323
18324 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18325 StartLoc, LParenLoc, EndLoc);
18326}
18327
18328OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18329 SourceLocation LParenLoc,
18330 SourceLocation EndLoc) {
18331 // OpenMP [2.13.2, critical construct, Description]
18332 // ... where hint-expression is an integer constant expression that evaluates
18333 // to a valid lock hint.
18334 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18335 if (HintExpr.isInvalid())
18336 return nullptr;
18337 return new (Context)
18338 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18339}
18340
18341/// Tries to find omp_event_handle_t type.
18342static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18343 DSAStackTy *Stack) {
18344 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18345 if (!OMPEventHandleT.isNull())
18346 return true;
18347 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18348 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18349 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18350 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18351 return false;
18352 }
18353 Stack->setOMPEventHandleT(PT.get());
18354 return true;
18355}
18356
18357OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18358 SourceLocation LParenLoc,
18359 SourceLocation EndLoc) {
18360 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18361 !Evt->isInstantiationDependent() &&
18362 !Evt->containsUnexpandedParameterPack()) {
18363 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
18364 return nullptr;
18365 // OpenMP 5.0, 2.10.1 task Construct.
18366 // event-handle is a variable of the omp_event_handle_t type.
18367 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18368 if (!Ref) {
18369 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18370 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18371 return nullptr;
18372 }
18373 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18374 if (!VD) {
18375 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18376 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18377 return nullptr;
18378 }
18379 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
18380 VD->getType()) ||
18381 VD->getType().isConstant(Context)) {
18382 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18383 << "omp_event_handle_t" << 1 << VD->getType()
18384 << Evt->getSourceRange();
18385 return nullptr;
18386 }
18387 // OpenMP 5.0, 2.10.1 task Construct
18388 // [detach clause]... The event-handle will be considered as if it was
18389 // specified on a firstprivate clause.
18390 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
18391 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18392 DVar.RefExpr) {
18393 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18394 << getOpenMPClauseName(DVar.CKind)
18395 << getOpenMPClauseName(OMPC_firstprivate);
18396 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
18397 return nullptr;
18398 }
18399 }
18400
18401 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18402}
18403
18404OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18405 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18406 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18407 SourceLocation EndLoc) {
18408 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18409 std::string Values;
18410 Values += "'";
18411 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18412 Values += "'";
18413 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18414 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18415 return nullptr;
18416 }
18417 Expr *ValExpr = ChunkSize;
18418 Stmt *HelperValStmt = nullptr;
18419 if (ChunkSize) {
18420 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18421 !ChunkSize->isInstantiationDependent() &&
18422 !ChunkSize->containsUnexpandedParameterPack()) {
18423 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18424 ExprResult Val =
18425 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18426 if (Val.isInvalid())
18427 return nullptr;
18428
18429 ValExpr = Val.get();
18430
18431 // OpenMP [2.7.1, Restrictions]
18432 // chunk_size must be a loop invariant integer expression with a positive
18433 // value.
18434 if (Optional<llvm::APSInt> Result =
18435 ValExpr->getIntegerConstantExpr(Context)) {
18436 if (Result->isSigned() && !Result->isStrictlyPositive()) {
18437 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18438 << "dist_schedule" << ChunkSize->getSourceRange();
18439 return nullptr;
18440 }
18441 } else if (getOpenMPCaptureRegionForClause(
18442 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
18443 LangOpts.OpenMP) != OMPD_unknown &&
18444 !CurContext->isDependentContext()) {
18445 ValExpr = MakeFullExpr(ValExpr).get();
18446 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18447 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18448 HelperValStmt = buildPreInits(Context, Captures);
18449 }
18450 }
18451 }
18452
18453 return new (Context)
18454 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18455 Kind, ValExpr, HelperValStmt);
18456}
18457
18458OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18459 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18460 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18461 SourceLocation KindLoc, SourceLocation EndLoc) {
18462 if (getLangOpts().OpenMP < 50) {
18463 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18464 Kind != OMPC_DEFAULTMAP_scalar) {
18465 std::string Value;
18466 SourceLocation Loc;
18467 Value += "'";
18468 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18469 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18470 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18471 Loc = MLoc;
18472 } else {
18473 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18474 OMPC_DEFAULTMAP_scalar);
18475 Loc = KindLoc;
18476 }
18477 Value += "'";
18478 Diag(Loc, diag::err_omp_unexpected_clause_value)
18479 << Value << getOpenMPClauseName(OMPC_defaultmap);
18480 return nullptr;
18481 }
18482 } else {
18483 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18484 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18485 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18486 if (!isDefaultmapKind || !isDefaultmapModifier) {
18487 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18488 "'firstprivate', 'none', 'default'";
18489 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18490 if (!isDefaultmapKind && isDefaultmapModifier) {
18491 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18492 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18493 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18494 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18495 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18496 } else {
18497 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18498 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18499 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18500 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18501 }
18502 return nullptr;
18503 }
18504
18505 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18506 // At most one defaultmap clause for each category can appear on the
18507 // directive.
18508 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
18509 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18510 return nullptr;
18511 }
18512 }
18513 if (Kind == OMPC_DEFAULTMAP_unknown) {
18514 // Variable category is not specified - mark all categories.
18515 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18516 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18517 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18518 } else {
18519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
18520 }
18521
18522 return new (Context)
18523 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18524}
18525
18526bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18527 DeclContext *CurLexicalContext = getCurLexicalContext();
18528 if (!CurLexicalContext->isFileContext() &&
18529 !CurLexicalContext->isExternCContext() &&
18530 !CurLexicalContext->isExternCXXContext() &&
18531 !isa<CXXRecordDecl>(CurLexicalContext) &&
18532 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18533 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18534 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18535 Diag(Loc, diag::err_omp_region_not_file_context);
18536 return false;
18537 }
18538 DeclareTargetNesting.push_back(Loc);
18539 return true;
18540}
18541
18542void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18543 assert(!DeclareTargetNesting.empty() &&((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18544, __PRETTY_FUNCTION__))
18544 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((!DeclareTargetNesting.empty() && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("!DeclareTargetNesting.empty() && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18544, __PRETTY_FUNCTION__))
;
18545 DeclareTargetNesting.pop_back();
18546}
18547
18548NamedDecl *
18549Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18550 const DeclarationNameInfo &Id,
18551 NamedDeclSetType &SameDirectiveDecls) {
18552 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18553 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18554
18555 if (Lookup.isAmbiguous())
18556 return nullptr;
18557 Lookup.suppressDiagnostics();
18558
18559 if (!Lookup.isSingleResult()) {
18560 VarOrFuncDeclFilterCCC CCC(*this);
18561 if (TypoCorrection Corrected =
18562 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18563 CTK_ErrorRecovery)) {
18564 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18565 << Id.getName());
18566 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18567 return nullptr;
18568 }
18569
18570 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18571 return nullptr;
18572 }
18573
18574 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18575 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18576 !isa<FunctionTemplateDecl>(ND)) {
18577 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18578 return nullptr;
18579 }
18580 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18581 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18582 return ND;
18583}
18584
18585void Sema::ActOnOpenMPDeclareTargetName(
18586 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18587 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18588 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18590, __PRETTY_FUNCTION__))
18589 isa<FunctionTemplateDecl>(ND)) &&(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18590, __PRETTY_FUNCTION__))
18590 "Expected variable, function or function template.")(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18590, __PRETTY_FUNCTION__))
;
18591
18592 // Diagnose marking after use as it may lead to incorrect diagnosis and
18593 // codegen.
18594 if (LangOpts.OpenMP >= 50 &&
18595 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18596 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18597
18598 auto *VD = cast<ValueDecl>(ND);
18599 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18600 OMPDeclareTargetDeclAttr::getDeviceType(VD);
18601 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18602 if (DevTy.hasValue() && *DevTy != DT &&
18603 (DeclareTargetNesting.empty() ||
18604 *AttrLoc != DeclareTargetNesting.back())) {
18605 Diag(Loc, diag::err_omp_device_type_mismatch)
18606 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18607 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18608 return;
18609 }
18610 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18611 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18612 if (!Res || (!DeclareTargetNesting.empty() &&
18613 *AttrLoc == DeclareTargetNesting.back())) {
18614 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18615 Context, MT, DT, DeclareTargetNesting.size() + 1,
18616 SourceRange(Loc, Loc));
18617 ND->addAttr(A);
18618 if (ASTMutationListener *ML = Context.getASTMutationListener())
18619 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18620 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18621 } else if (*Res != MT) {
18622 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18623 }
18624}
18625
18626static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18627 Sema &SemaRef, Decl *D) {
18628 if (!D || !isa<VarDecl>(D))
18629 return;
18630 auto *VD = cast<VarDecl>(D);
18631 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18632 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18633 if (SemaRef.LangOpts.OpenMP >= 50 &&
18634 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18635 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18636 VD->hasGlobalStorage()) {
18637 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18639 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18640 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18641 // If a lambda declaration and definition appears between a
18642 // declare target directive and the matching end declare target
18643 // directive, all variables that are captured by the lambda
18644 // expression must also appear in a to clause.
18645 SemaRef.Diag(VD->getLocation(),
18646 diag::err_omp_lambda_capture_in_declare_target_not_to);
18647 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18648 << VD << 0 << SR;
18649 return;
18650 }
18651 }
18652 if (MapTy.hasValue())
18653 return;
18654 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18655 SemaRef.Diag(SL, diag::note_used_here) << SR;
18656}
18657
18658static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18659 Sema &SemaRef, DSAStackTy *Stack,
18660 ValueDecl *VD) {
18661 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18662 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18663 /*FullCheck=*/false);
18664}
18665
18666void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18667 SourceLocation IdLoc) {
18668 if (!D || D->isInvalidDecl())
18669 return;
18670 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18671 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18672 if (auto *VD = dyn_cast<VarDecl>(D)) {
18673 // Only global variables can be marked as declare target.
18674 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18675 !VD->isStaticDataMember())
18676 return;
18677 // 2.10.6: threadprivate variable cannot appear in a declare target
18678 // directive.
18679 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
18680 Diag(SL, diag::err_omp_threadprivate_in_target);
18681 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
18682 return;
18683 }
18684 }
18685 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18686 D = FTD->getTemplatedDecl();
18687 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18688 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18689 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18690 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18691 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18692 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18693 return;
18694 }
18695 }
18696 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18697 // Problem if any with var declared with incomplete type will be reported
18698 // as normal, so no need to check it here.
18699 if ((E || !VD->getType()->isIncompleteType()) &&
18700 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
18701 return;
18702 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18703 // Checking declaration inside declare target region.
18704 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18705 isa<FunctionTemplateDecl>(D)) {
18706 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18707 Context, OMPDeclareTargetDeclAttr::MT_To,
18708 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18709 SourceRange(DeclareTargetNesting.back(),
18710 DeclareTargetNesting.back()));
18711 D->addAttr(A);
18712 if (ASTMutationListener *ML = Context.getASTMutationListener())
18713 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18714 }
18715 return;
18716 }
18717 }
18718 if (!E)
18719 return;
18720 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18721}
18722
18723OMPClause *Sema::ActOnOpenMPToClause(
18724 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18725 ArrayRef<SourceLocation> MotionModifiersLoc,
18726 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18727 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18728 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18729 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18730 OMPC_MOTION_MODIFIER_unknown};
18731 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18732
18733 // Process motion-modifiers, flag errors for duplicate modifiers.
18734 unsigned Count = 0;
18735 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18736 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18737 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18738 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18739 continue;
18740 }
18741 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18742, __PRETTY_FUNCTION__))
18742 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18742, __PRETTY_FUNCTION__))
;
18743 Modifiers[Count] = MotionModifiers[I];
18744 ModifiersLoc[Count] = MotionModifiersLoc[I];
18745 ++Count;
18746 }
18747
18748 MappableVarListInfo MVLI(VarList);
18749 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
18750 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18751 if (MVLI.ProcessedVarList.empty())
18752 return nullptr;
18753
18754 return OMPToClause::Create(
18755 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18756 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18757 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18758}
18759
18760OMPClause *Sema::ActOnOpenMPFromClause(
18761 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18762 ArrayRef<SourceLocation> MotionModifiersLoc,
18763 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18764 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18765 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18766 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18767 OMPC_MOTION_MODIFIER_unknown};
18768 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18769
18770 // Process motion-modifiers, flag errors for duplicate modifiers.
18771 unsigned Count = 0;
18772 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18773 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18774 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18775 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18776 continue;
18777 }
18778 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18779, __PRETTY_FUNCTION__))
18779 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18779, __PRETTY_FUNCTION__))
;
18780 Modifiers[Count] = MotionModifiers[I];
18781 ModifiersLoc[Count] = MotionModifiersLoc[I];
18782 ++Count;
18783 }
18784
18785 MappableVarListInfo MVLI(VarList);
18786 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
18787 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18788 if (MVLI.ProcessedVarList.empty())
18789 return nullptr;
18790
18791 return OMPFromClause::Create(
18792 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18793 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18794 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18795}
18796
18797OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18798 const OMPVarListLocTy &Locs) {
18799 MappableVarListInfo MVLI(VarList);
18800 SmallVector<Expr *, 8> PrivateCopies;
18801 SmallVector<Expr *, 8> Inits;
18802
18803 for (Expr *RefExpr : VarList) {
18804 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((RefExpr && "NULL expr in OpenMP use_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18804, __PRETTY_FUNCTION__))
;
18805 SourceLocation ELoc;
18806 SourceRange ERange;
18807 Expr *SimpleRefExpr = RefExpr;
18808 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18809 if (Res.second) {
18810 // It will be analyzed later.
18811 MVLI.ProcessedVarList.push_back(RefExpr);
18812 PrivateCopies.push_back(nullptr);
18813 Inits.push_back(nullptr);
18814 }
18815 ValueDecl *D = Res.first;
18816 if (!D)
18817 continue;
18818
18819 QualType Type = D->getType();
18820 Type = Type.getNonReferenceType().getUnqualifiedType();
18821
18822 auto *VD = dyn_cast<VarDecl>(D);
18823
18824 // Item should be a pointer or reference to pointer.
18825 if (!Type->isPointerType()) {
18826 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18827 << 0 << RefExpr->getSourceRange();
18828 continue;
18829 }
18830
18831 // Build the private variable and the expression that refers to it.
18832 auto VDPrivate =
18833 buildVarDecl(*this, ELoc, Type, D->getName(),
18834 D->hasAttrs() ? &D->getAttrs() : nullptr,
18835 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18836 if (VDPrivate->isInvalidDecl())
18837 continue;
18838
18839 CurContext->addDecl(VDPrivate);
18840 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18841 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18842
18843 // Add temporary variable to initialize the private copy of the pointer.
18844 VarDecl *VDInit =
18845 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18846 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18847 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18848 AddInitializerToDecl(VDPrivate,
18849 DefaultLvalueConversion(VDInitRefExpr).get(),
18850 /*DirectInit=*/false);
18851
18852 // If required, build a capture to implement the privatization initialized
18853 // with the current list item value.
18854 DeclRefExpr *Ref = nullptr;
18855 if (!VD)
18856 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18857 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18858 PrivateCopies.push_back(VDPrivateRefExpr);
18859 Inits.push_back(VDInitRefExpr);
18860
18861 // We need to add a data sharing attribute for this variable to make sure it
18862 // is correctly captured. A variable that shows up in a use_device_ptr has
18863 // similar properties of a first private variable.
18864 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18865
18866 // Create a mappable component for the list item. List items in this clause
18867 // only need a component.
18868 MVLI.VarBaseDeclarations.push_back(D);
18869 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18870 MVLI.VarComponents.back().push_back(
18871 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
18872 }
18873
18874 if (MVLI.ProcessedVarList.empty())
18875 return nullptr;
18876
18877 return OMPUseDevicePtrClause::Create(
18878 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18879 MVLI.VarBaseDeclarations, MVLI.VarComponents);
18880}
18881
18882OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18883 const OMPVarListLocTy &Locs) {
18884 MappableVarListInfo MVLI(VarList);
18885
18886 for (Expr *RefExpr : VarList) {
18887 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((RefExpr && "NULL expr in OpenMP use_device_addr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18887, __PRETTY_FUNCTION__))
;
18888 SourceLocation ELoc;
18889 SourceRange ERange;
18890 Expr *SimpleRefExpr = RefExpr;
18891 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18892 /*AllowArraySection=*/true);
18893 if (Res.second) {
18894 // It will be analyzed later.
18895 MVLI.ProcessedVarList.push_back(RefExpr);
18896 }
18897 ValueDecl *D = Res.first;
18898 if (!D)
18899 continue;
18900 auto *VD = dyn_cast<VarDecl>(D);
18901
18902 // If required, build a capture to implement the privatization initialized
18903 // with the current list item value.
18904 DeclRefExpr *Ref = nullptr;
18905 if (!VD)
18906 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18907 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18908
18909 // We need to add a data sharing attribute for this variable to make sure it
18910 // is correctly captured. A variable that shows up in a use_device_addr has
18911 // similar properties of a first private variable.
18912 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18913
18914 // Create a mappable component for the list item. List items in this clause
18915 // only need a component.
18916 MVLI.VarBaseDeclarations.push_back(D);
18917 MVLI.VarComponents.emplace_back();
18918 Expr *Component = SimpleRefExpr;
18919 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18920 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18921 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18922 MVLI.VarComponents.back().push_back(
18923 OMPClauseMappableExprCommon::MappableComponent(Component, D));
18924 }
18925
18926 if (MVLI.ProcessedVarList.empty())
18927 return nullptr;
18928
18929 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18930 MVLI.VarBaseDeclarations,
18931 MVLI.VarComponents);
18932}
18933
18934OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18935 const OMPVarListLocTy &Locs) {
18936 MappableVarListInfo MVLI(VarList);
18937 for (Expr *RefExpr : VarList) {
18938 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((RefExpr && "NULL expr in OpenMP is_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 18938, __PRETTY_FUNCTION__))
;
18939 SourceLocation ELoc;
18940 SourceRange ERange;
18941 Expr *SimpleRefExpr = RefExpr;
18942 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18943 if (Res.second) {
18944 // It will be analyzed later.
18945 MVLI.ProcessedVarList.push_back(RefExpr);
18946 }
18947 ValueDecl *D = Res.first;
18948 if (!D)
18949 continue;
18950
18951 QualType Type = D->getType();
18952 // item should be a pointer or array or reference to pointer or array
18953 if (!Type.getNonReferenceType()->isPointerType() &&
18954 !Type.getNonReferenceType()->isArrayType()) {
18955 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
18956 << 0 << RefExpr->getSourceRange();
18957 continue;
18958 }
18959
18960 // Check if the declaration in the clause does not show up in any data
18961 // sharing attribute.
18962 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18963 if (isOpenMPPrivate(DVar.CKind)) {
18964 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18965 << getOpenMPClauseName(DVar.CKind)
18966 << getOpenMPClauseName(OMPC_is_device_ptr)
18967 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18968 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18969 continue;
18970 }
18971
18972 const Expr *ConflictExpr;
18973 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
18974 D, /*CurrentRegionOnly=*/true,
18975 [&ConflictExpr](
18976 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
18977 OpenMPClauseKind) -> bool {
18978 ConflictExpr = R.front().getAssociatedExpression();
18979 return true;
18980 })) {
18981 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
18982 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
18983 << ConflictExpr->getSourceRange();
18984 continue;
18985 }
18986
18987 // Store the components in the stack so that they can be used to check
18988 // against other clauses later on.
18989 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
18990 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
18991 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
18992
18993 // Record the expression we've just processed.
18994 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
18995
18996 // Create a mappable component for the list item. List items in this clause
18997 // only need a component. We use a null declaration to signal fields in
18998 // 'this'.
18999 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19001, __PRETTY_FUNCTION__))
19000 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19001, __PRETTY_FUNCTION__))
19001 "Unexpected device pointer expression!")(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19001, __PRETTY_FUNCTION__))
;
19002 MVLI.VarBaseDeclarations.push_back(
19003 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19004 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19005 MVLI.VarComponents.back().push_back(MC);
19006 }
19007
19008 if (MVLI.ProcessedVarList.empty())
19009 return nullptr;
19010
19011 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19012 MVLI.VarBaseDeclarations,
19013 MVLI.VarComponents);
19014}
19015
19016OMPClause *Sema::ActOnOpenMPAllocateClause(
19017 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19018 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19019 if (Allocator) {
19020 // OpenMP [2.11.4 allocate Clause, Description]
19021 // allocator is an expression of omp_allocator_handle_t type.
19022 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19023 return nullptr;
19024
19025 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19026 if (AllocatorRes.isInvalid())
19027 return nullptr;
19028 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19029 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19030 Sema::AA_Initializing,
19031 /*AllowExplicit=*/true);
19032 if (AllocatorRes.isInvalid())
19033 return nullptr;
19034 Allocator = AllocatorRes.get();
19035 } else {
19036 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19037 // allocate clauses that appear on a target construct or on constructs in a
19038 // target region must specify an allocator expression unless a requires
19039 // directive with the dynamic_allocators clause is present in the same
19040 // compilation unit.
19041 if (LangOpts.OpenMPIsDevice &&
19042 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19043 targetDiag(StartLoc, diag::err_expected_allocator_expression);
19044 }
19045 // Analyze and build list of variables.
19046 SmallVector<Expr *, 8> Vars;
19047 for (Expr *RefExpr : VarList) {
19048 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19048, __PRETTY_FUNCTION__))
;
19049 SourceLocation ELoc;
19050 SourceRange ERange;
19051 Expr *SimpleRefExpr = RefExpr;
19052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19053 if (Res.second) {
19054 // It will be analyzed later.
19055 Vars.push_back(RefExpr);
19056 }
19057 ValueDecl *D = Res.first;
19058 if (!D)
19059 continue;
19060
19061 auto *VD = dyn_cast<VarDecl>(D);
19062 DeclRefExpr *Ref = nullptr;
19063 if (!VD && !CurContext->isDependentContext())
19064 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19065 Vars.push_back((VD || CurContext->isDependentContext())
19066 ? RefExpr->IgnoreParens()
19067 : Ref);
19068 }
19069
19070 if (Vars.empty())
19071 return nullptr;
19072
19073 if (Allocator)
19074 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
19075 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19076 ColonLoc, EndLoc, Vars);
19077}
19078
19079OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19080 SourceLocation StartLoc,
19081 SourceLocation LParenLoc,
19082 SourceLocation EndLoc) {
19083 SmallVector<Expr *, 8> Vars;
19084 for (Expr *RefExpr : VarList) {
19085 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19085, __PRETTY_FUNCTION__))
;
19086 SourceLocation ELoc;
19087 SourceRange ERange;
19088 Expr *SimpleRefExpr = RefExpr;
19089 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19090 if (Res.second)
19091 // It will be analyzed later.
19092 Vars.push_back(RefExpr);
19093 ValueDecl *D = Res.first;
19094 if (!D)
19095 continue;
19096
19097 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19098 // A list-item cannot appear in more than one nontemporal clause.
19099 if (const Expr *PrevRef =
19100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
19101 Diag(ELoc, diag::err_omp_used_in_clause_twice)
19102 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19103 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19104 << getOpenMPClauseName(OMPC_nontemporal);
19105 continue;
19106 }
19107
19108 Vars.push_back(RefExpr);
19109 }
19110
19111 if (Vars.empty())
19112 return nullptr;
19113
19114 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19115 Vars);
19116}
19117
19118OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19119 SourceLocation StartLoc,
19120 SourceLocation LParenLoc,
19121 SourceLocation EndLoc) {
19122 SmallVector<Expr *, 8> Vars;
19123 for (Expr *RefExpr : VarList) {
19124 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19124, __PRETTY_FUNCTION__))
;
19125 SourceLocation ELoc;
19126 SourceRange ERange;
19127 Expr *SimpleRefExpr = RefExpr;
19128 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19129 /*AllowArraySection=*/true);
19130 if (Res.second)
19131 // It will be analyzed later.
19132 Vars.push_back(RefExpr);
19133 ValueDecl *D = Res.first;
19134 if (!D)
19135 continue;
19136
19137 const DSAStackTy::DSAVarData DVar =
19138 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19139 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19140 // A list item that appears in the inclusive or exclusive clause must appear
19141 // in a reduction clause with the inscan modifier on the enclosing
19142 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19143 if (DVar.CKind != OMPC_reduction ||
19144 DVar.Modifier != OMPC_REDUCTION_inscan)
19145 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19146 << RefExpr->getSourceRange();
19147
19148 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
19149 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19150 Vars.push_back(RefExpr);
19151 }
19152
19153 if (Vars.empty())
19154 return nullptr;
19155
19156 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19157}
19158
19159OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19160 SourceLocation StartLoc,
19161 SourceLocation LParenLoc,
19162 SourceLocation EndLoc) {
19163 SmallVector<Expr *, 8> Vars;
19164 for (Expr *RefExpr : VarList) {
19165 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19165, __PRETTY_FUNCTION__))
;
19166 SourceLocation ELoc;
19167 SourceRange ERange;
19168 Expr *SimpleRefExpr = RefExpr;
19169 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19170 /*AllowArraySection=*/true);
19171 if (Res.second)
19172 // It will be analyzed later.
19173 Vars.push_back(RefExpr);
19174 ValueDecl *D = Res.first;
19175 if (!D)
19176 continue;
19177
19178 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
19179 DSAStackTy::DSAVarData DVar;
19180 if (ParentDirective != OMPD_unknown)
19181 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19182 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19183 // A list item that appears in the inclusive or exclusive clause must appear
19184 // in a reduction clause with the inscan modifier on the enclosing
19185 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19186 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19187 DVar.Modifier != OMPC_REDUCTION_inscan) {
19188 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19189 << RefExpr->getSourceRange();
19190 } else {
19191 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19192 }
19193 Vars.push_back(RefExpr);
19194 }
19195
19196 if (Vars.empty())
19197 return nullptr;
19198
19199 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19200}
19201
19202/// Tries to find omp_alloctrait_t type.
19203static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19204 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19205 if (!OMPAlloctraitT.isNull())
19206 return true;
19207 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19208 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19209 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19210 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19211 return false;
19212 }
19213 Stack->setOMPAlloctraitT(PT.get());
19214 return true;
19215}
19216
19217OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19218 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19219 ArrayRef<UsesAllocatorsData> Data) {
19220 // OpenMP [2.12.5, target Construct]
19221 // allocator is an identifier of omp_allocator_handle_t type.
19222 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19223 return nullptr;
19224 // OpenMP [2.12.5, target Construct]
19225 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19226 if (llvm::any_of(
19227 Data,
19228 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19229 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19230 return nullptr;
19231 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19232 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19233 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19234 StringRef Allocator =
19235 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19236 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19237 PredefinedAllocators.insert(LookupSingleName(
19238 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19239 }
19240
19241 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19242 for (const UsesAllocatorsData &D : Data) {
19243 Expr *AllocatorExpr = nullptr;
19244 // Check allocator expression.
19245 if (D.Allocator->isTypeDependent()) {
19246 AllocatorExpr = D.Allocator;
19247 } else {
19248 // Traits were specified - need to assign new allocator to the specified
19249 // allocator, so it must be an lvalue.
19250 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19251 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19252 bool IsPredefinedAllocator = false;
19253 if (DRE)
19254 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19255 if (!DRE ||
19256 !(Context.hasSameUnqualifiedType(
19257 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
19258 Context.typesAreCompatible(AllocatorExpr->getType(),
19259 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19260 /*CompareUnqualified=*/true)) ||
19261 (!IsPredefinedAllocator &&
19262 (AllocatorExpr->getType().isConstant(Context) ||
19263 !AllocatorExpr->isLValue()))) {
19264 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19265 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19266 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19267 continue;
19268 }
19269 // OpenMP [2.12.5, target Construct]
19270 // Predefined allocators appearing in a uses_allocators clause cannot have
19271 // traits specified.
19272 if (IsPredefinedAllocator && D.AllocatorTraits) {
19273 Diag(D.AllocatorTraits->getExprLoc(),
19274 diag::err_omp_predefined_allocator_with_traits)
19275 << D.AllocatorTraits->getSourceRange();
19276 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19277 << cast<NamedDecl>(DRE->getDecl())->getName()
19278 << D.Allocator->getSourceRange();
19279 continue;
19280 }
19281 // OpenMP [2.12.5, target Construct]
19282 // Non-predefined allocators appearing in a uses_allocators clause must
19283 // have traits specified.
19284 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19285 Diag(D.Allocator->getExprLoc(),
19286 diag::err_omp_nonpredefined_allocator_without_traits);
19287 continue;
19288 }
19289 // No allocator traits - just convert it to rvalue.
19290 if (!D.AllocatorTraits)
19291 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19292 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19293 DRE->getDecl(),
19294 IsPredefinedAllocator
19295 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19296 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19297 }
19298 Expr *AllocatorTraitsExpr = nullptr;
19299 if (D.AllocatorTraits) {
19300 if (D.AllocatorTraits->isTypeDependent()) {
19301 AllocatorTraitsExpr = D.AllocatorTraits;
19302 } else {
19303 // OpenMP [2.12.5, target Construct]
19304 // Arrays that contain allocator traits that appear in a uses_allocators
19305 // clause must be constant arrays, have constant values and be defined
19306 // in the same scope as the construct in which the clause appears.
19307 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19308 // Check that traits expr is a constant array.
19309 QualType TraitTy;
19310 if (const ArrayType *Ty =
19311 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19312 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19313 TraitTy = ConstArrayTy->getElementType();
19314 if (TraitTy.isNull() ||
19315 !(Context.hasSameUnqualifiedType(TraitTy,
19316 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
19317 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
19318 /*CompareUnqualified=*/true))) {
19319 Diag(D.AllocatorTraits->getExprLoc(),
19320 diag::err_omp_expected_array_alloctraits)
19321 << AllocatorTraitsExpr->getType();
19322 continue;
19323 }
19324 // Do not map by default allocator traits if it is a standalone
19325 // variable.
19326 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19327 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19328 DRE->getDecl(),
19329 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19330 }
19331 }
19332 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19333 NewD.Allocator = AllocatorExpr;
19334 NewD.AllocatorTraits = AllocatorTraitsExpr;
19335 NewD.LParenLoc = D.LParenLoc;
19336 NewD.RParenLoc = D.RParenLoc;
19337 }
19338 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19339 NewData);
19340}
19341
19342OMPClause *Sema::ActOnOpenMPAffinityClause(
19343 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19344 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19345 SmallVector<Expr *, 8> Vars;
19346 for (Expr *RefExpr : Locators) {
19347 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/lib/Sema/SemaOpenMP.cpp"
, 19347, __PRETTY_FUNCTION__))
;
19348 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19349 // It will be analyzed later.
19350 Vars.push_back(RefExpr);
19351 continue;
19352 }
19353
19354 SourceLocation ELoc = RefExpr->getExprLoc();
19355 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19356
19357 if (!SimpleExpr->isLValue()) {
19358 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19359 << 1 << 0 << RefExpr->getSourceRange();
19360 continue;
19361 }
19362
19363 ExprResult Res;
19364 {
19365 Sema::TentativeAnalysisScope Trap(*this);
19366 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19367 }
19368 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19369 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19370 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19371 << 1 << 0 << RefExpr->getSourceRange();
19372 continue;
19373 }
19374 Vars.push_back(SimpleExpr);
19375 }
19376
19377 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19378 EndLoc, Modifier, Vars);
19379}

/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h

1//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the Decl and DeclContext interfaces.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_DECLBASE_H
14#define LLVM_CLANG_AST_DECLBASE_H
15
16#include "clang/AST/ASTDumperUtils.h"
17#include "clang/AST/AttrIterator.h"
18#include "clang/AST/DeclarationName.h"
19#include "clang/Basic/IdentifierTable.h"
20#include "clang/Basic/LLVM.h"
21#include "clang/Basic/SourceLocation.h"
22#include "clang/Basic/Specifiers.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/PointerIntPair.h"
25#include "llvm/ADT/PointerUnion.h"
26#include "llvm/ADT/iterator.h"
27#include "llvm/ADT/iterator_range.h"
28#include "llvm/Support/Casting.h"
29#include "llvm/Support/Compiler.h"
30#include "llvm/Support/PrettyStackTrace.h"
31#include "llvm/Support/VersionTuple.h"
32#include <algorithm>
33#include <cassert>
34#include <cstddef>
35#include <iterator>
36#include <string>
37#include <type_traits>
38#include <utility>
39
40namespace clang {
41
42class ASTContext;
43class ASTMutationListener;
44class Attr;
45class BlockDecl;
46class DeclContext;
47class ExternalSourceSymbolAttr;
48class FunctionDecl;
49class FunctionType;
50class IdentifierInfo;
51enum Linkage : unsigned char;
52class LinkageSpecDecl;
53class Module;
54class NamedDecl;
55class ObjCCategoryDecl;
56class ObjCCategoryImplDecl;
57class ObjCContainerDecl;
58class ObjCImplDecl;
59class ObjCImplementationDecl;
60class ObjCInterfaceDecl;
61class ObjCMethodDecl;
62class ObjCProtocolDecl;
63struct PrintingPolicy;
64class RecordDecl;
65class SourceManager;
66class Stmt;
67class StoredDeclsMap;
68class TemplateDecl;
69class TemplateParameterList;
70class TranslationUnitDecl;
71class UsingDirectiveDecl;
72
73/// Captures the result of checking the availability of a
74/// declaration.
75enum AvailabilityResult {
76 AR_Available = 0,
77 AR_NotYetIntroduced,
78 AR_Deprecated,
79 AR_Unavailable
80};
81
82/// Decl - This represents one declaration (or definition), e.g. a variable,
83/// typedef, function, struct, etc.
84///
85/// Note: There are objects tacked on before the *beginning* of Decl
86/// (and its subclasses) in its Decl::operator new(). Proper alignment
87/// of all subclasses (not requiring more than the alignment of Decl) is
88/// asserted in DeclBase.cpp.
89class alignas(8) Decl {
90public:
91 /// Lists the kind of concrete classes of Decl.
92 enum Kind {
93#define DECL(DERIVED, BASE) DERIVED,
94#define ABSTRACT_DECL(DECL)
95#define DECL_RANGE(BASE, START, END) \
96 first##BASE = START, last##BASE = END,
97#define LAST_DECL_RANGE(BASE, START, END) \
98 first##BASE = START, last##BASE = END
99#include "clang/AST/DeclNodes.inc"
100 };
101
102 /// A placeholder type used to construct an empty shell of a
103 /// decl-derived type that will be filled in later (e.g., by some
104 /// deserialization method).
105 struct EmptyShell {};
106
107 /// IdentifierNamespace - The different namespaces in which
108 /// declarations may appear. According to C99 6.2.3, there are
109 /// four namespaces, labels, tags, members and ordinary
110 /// identifiers. C++ describes lookup completely differently:
111 /// certain lookups merely "ignore" certain kinds of declarations,
112 /// usually based on whether the declaration is of a type, etc.
113 ///
114 /// These are meant as bitmasks, so that searches in
115 /// C++ can look into the "tag" namespace during ordinary lookup.
116 ///
117 /// Decl currently provides 15 bits of IDNS bits.
118 enum IdentifierNamespace {
119 /// Labels, declared with 'x:' and referenced with 'goto x'.
120 IDNS_Label = 0x0001,
121
122 /// Tags, declared with 'struct foo;' and referenced with
123 /// 'struct foo'. All tags are also types. This is what
124 /// elaborated-type-specifiers look for in C.
125 /// This also contains names that conflict with tags in the
126 /// same scope but that are otherwise ordinary names (non-type
127 /// template parameters and indirect field declarations).
128 IDNS_Tag = 0x0002,
129
130 /// Types, declared with 'struct foo', typedefs, etc.
131 /// This is what elaborated-type-specifiers look for in C++,
132 /// but note that it's ill-formed to find a non-tag.
133 IDNS_Type = 0x0004,
134
135 /// Members, declared with object declarations within tag
136 /// definitions. In C, these can only be found by "qualified"
137 /// lookup in member expressions. In C++, they're found by
138 /// normal lookup.
139 IDNS_Member = 0x0008,
140
141 /// Namespaces, declared with 'namespace foo {}'.
142 /// Lookup for nested-name-specifiers find these.
143 IDNS_Namespace = 0x0010,
144
145 /// Ordinary names. In C, everything that's not a label, tag,
146 /// member, or function-local extern ends up here.
147 IDNS_Ordinary = 0x0020,
148
149 /// Objective C \@protocol.
150 IDNS_ObjCProtocol = 0x0040,
151
152 /// This declaration is a friend function. A friend function
153 /// declaration is always in this namespace but may also be in
154 /// IDNS_Ordinary if it was previously declared.
155 IDNS_OrdinaryFriend = 0x0080,
156
157 /// This declaration is a friend class. A friend class
158 /// declaration is always in this namespace but may also be in
159 /// IDNS_Tag|IDNS_Type if it was previously declared.
160 IDNS_TagFriend = 0x0100,
161
162 /// This declaration is a using declaration. A using declaration
163 /// *introduces* a number of other declarations into the current
164 /// scope, and those declarations use the IDNS of their targets,
165 /// but the actual using declarations go in this namespace.
166 IDNS_Using = 0x0200,
167
168 /// This declaration is a C++ operator declared in a non-class
169 /// context. All such operators are also in IDNS_Ordinary.
170 /// C++ lexical operator lookup looks for these.
171 IDNS_NonMemberOperator = 0x0400,
172
173 /// This declaration is a function-local extern declaration of a
174 /// variable or function. This may also be IDNS_Ordinary if it
175 /// has been declared outside any function. These act mostly like
176 /// invisible friend declarations, but are also visible to unqualified
177 /// lookup within the scope of the declaring function.
178 IDNS_LocalExtern = 0x0800,
179
180 /// This declaration is an OpenMP user defined reduction construction.
181 IDNS_OMPReduction = 0x1000,
182
183 /// This declaration is an OpenMP user defined mapper.
184 IDNS_OMPMapper = 0x2000,
185 };
186
187 /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
188 /// parameter types in method declarations. Other than remembering
189 /// them and mangling them into the method's signature string, these
190 /// are ignored by the compiler; they are consumed by certain
191 /// remote-messaging frameworks.
192 ///
193 /// in, inout, and out are mutually exclusive and apply only to
194 /// method parameters. bycopy and byref are mutually exclusive and
195 /// apply only to method parameters (?). oneway applies only to
196 /// results. All of these expect their corresponding parameter to
197 /// have a particular type. None of this is currently enforced by
198 /// clang.
199 ///
200 /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier.
201 enum ObjCDeclQualifier {
202 OBJC_TQ_None = 0x0,
203 OBJC_TQ_In = 0x1,
204 OBJC_TQ_Inout = 0x2,
205 OBJC_TQ_Out = 0x4,
206 OBJC_TQ_Bycopy = 0x8,
207 OBJC_TQ_Byref = 0x10,
208 OBJC_TQ_Oneway = 0x20,
209
210 /// The nullability qualifier is set when the nullability of the
211 /// result or parameter was expressed via a context-sensitive
212 /// keyword.
213 OBJC_TQ_CSNullability = 0x40
214 };
215
216 /// The kind of ownership a declaration has, for visibility purposes.
217 /// This enumeration is designed such that higher values represent higher
218 /// levels of name hiding.
219 enum class ModuleOwnershipKind : unsigned {
220 /// This declaration is not owned by a module.
221 Unowned,
222
223 /// This declaration has an owning module, but is globally visible
224 /// (typically because its owning module is visible and we know that
225 /// modules cannot later become hidden in this compilation).
226 /// After serialization and deserialization, this will be converted
227 /// to VisibleWhenImported.
228 Visible,
229
230 /// This declaration has an owning module, and is visible when that
231 /// module is imported.
232 VisibleWhenImported,
233
234 /// This declaration has an owning module, but is only visible to
235 /// lookups that occur within that module.
236 ModulePrivate
237 };
238
239protected:
240 /// The next declaration within the same lexical
241 /// DeclContext. These pointers form the linked list that is
242 /// traversed via DeclContext's decls_begin()/decls_end().
243 ///
244 /// The extra two bits are used for the ModuleOwnershipKind.
245 llvm::PointerIntPair<Decl *, 2, ModuleOwnershipKind> NextInContextAndBits;
246
247private:
248 friend class DeclContext;
249
250 struct MultipleDC {
251 DeclContext *SemanticDC;
252 DeclContext *LexicalDC;
253 };
254
255 /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
256 /// For declarations that don't contain C++ scope specifiers, it contains
257 /// the DeclContext where the Decl was declared.
258 /// For declarations with C++ scope specifiers, it contains a MultipleDC*
259 /// with the context where it semantically belongs (SemanticDC) and the
260 /// context where it was lexically declared (LexicalDC).
261 /// e.g.:
262 ///
263 /// namespace A {
264 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
265 /// }
266 /// void A::f(); // SemanticDC == namespace 'A'
267 /// // LexicalDC == global namespace
268 llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx;
269
270 bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); }
271 bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); }
272
273 MultipleDC *getMultipleDC() const {
274 return DeclCtx.get<MultipleDC*>();
275 }
276
277 DeclContext *getSemanticDC() const {
278 return DeclCtx.get<DeclContext*>();
279 }
280
281 /// Loc - The location of this decl.
282 SourceLocation Loc;
283
284 /// DeclKind - This indicates which class this is.
285 unsigned DeclKind : 7;
286
287 /// InvalidDecl - This indicates a semantic error occurred.
288 unsigned InvalidDecl : 1;
289
290 /// HasAttrs - This indicates whether the decl has attributes or not.
291 unsigned HasAttrs : 1;
292
293 /// Implicit - Whether this declaration was implicitly generated by
294 /// the implementation rather than explicitly written by the user.
295 unsigned Implicit : 1;
296
297 /// Whether this declaration was "used", meaning that a definition is
298 /// required.
299 unsigned Used : 1;
300
301 /// Whether this declaration was "referenced".
302 /// The difference with 'Used' is whether the reference appears in a
303 /// evaluated context or not, e.g. functions used in uninstantiated templates
304 /// are regarded as "referenced" but not "used".
305 unsigned Referenced : 1;
306
307 /// Whether this declaration is a top-level declaration (function,
308 /// global variable, etc.) that is lexically inside an objc container
309 /// definition.
310 unsigned TopLevelDeclInObjCContainer : 1;
311
312 /// Whether statistic collection is enabled.
313 static bool StatisticsEnabled;
314
315protected:
316 friend class ASTDeclReader;
317 friend class ASTDeclWriter;
318 friend class ASTNodeImporter;
319 friend class ASTReader;
320 friend class CXXClassMemberWrapper;
321 friend class LinkageComputer;
322 template<typename decl_type> friend class Redeclarable;
323
324 /// Access - Used by C++ decls for the access specifier.
325 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
326 unsigned Access : 2;
327
328 /// Whether this declaration was loaded from an AST file.
329 unsigned FromASTFile : 1;
330
331 /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
332 unsigned IdentifierNamespace : 14;
333
334 /// If 0, we have not computed the linkage of this declaration.
335 /// Otherwise, it is the linkage + 1.
336 mutable unsigned CacheValidAndLinkage : 3;
337
338 /// Allocate memory for a deserialized declaration.
339 ///
340 /// This routine must be used to allocate memory for any declaration that is
341 /// deserialized from a module file.
342 ///
343 /// \param Size The size of the allocated object.
344 /// \param Ctx The context in which we will allocate memory.
345 /// \param ID The global ID of the deserialized declaration.
346 /// \param Extra The amount of extra space to allocate after the object.
347 void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
348 std::size_t Extra = 0);
349
350 /// Allocate memory for a non-deserialized declaration.
351 void *operator new(std::size_t Size, const ASTContext &Ctx,
352 DeclContext *Parent, std::size_t Extra = 0);
353
354private:
355 bool AccessDeclContextSanity() const;
356
357 /// Get the module ownership kind to use for a local lexical child of \p DC,
358 /// which may be either a local or (rarely) an imported declaration.
359 static ModuleOwnershipKind getModuleOwnershipKindForChildOf(DeclContext *DC) {
360 if (DC) {
361 auto *D = cast<Decl>(DC);
362 auto MOK = D->getModuleOwnershipKind();
363 if (MOK != ModuleOwnershipKind::Unowned &&
364 (!D->isFromASTFile() || D->hasLocalOwningModuleStorage()))
365 return MOK;
366 // If D is not local and we have no local module storage, then we don't
367 // need to track module ownership at all.
368 }
369 return ModuleOwnershipKind::Unowned;
370 }
371
372public:
373 Decl() = delete;
374 Decl(const Decl&) = delete;
375 Decl(Decl &&) = delete;
376 Decl &operator=(const Decl&) = delete;
377 Decl &operator=(Decl&&) = delete;
378
379protected:
380 Decl(Kind DK, DeclContext *DC, SourceLocation L)
381 : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)),
382 DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false),
383 Implicit(false), Used(false), Referenced(false),
384 TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
385 IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
386 CacheValidAndLinkage(0) {
387 if (StatisticsEnabled) add(DK);
388 }
389
390 Decl(Kind DK, EmptyShell Empty)
391 : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false),
392 Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
393 Access(AS_none), FromASTFile(0),
394 IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
395 CacheValidAndLinkage(0) {
396 if (StatisticsEnabled) add(DK);
397 }
398
399 virtual ~Decl();
400
401 /// Update a potentially out-of-date declaration.
402 void updateOutOfDate(IdentifierInfo &II) const;
403
404 Linkage getCachedLinkage() const {
405 return Linkage(CacheValidAndLinkage - 1);
406 }
407
408 void setCachedLinkage(Linkage L) const {
409 CacheValidAndLinkage = L + 1;
410 }
411
412 bool hasCachedLinkage() const {
413 return CacheValidAndLinkage;
414 }
415
416public:
417 /// Source range that this declaration covers.
418 virtual SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) {
419 return SourceRange(getLocation(), getLocation());
420 }
421
422 SourceLocation getBeginLoc() const LLVM_READONLY__attribute__((__pure__)) {
423 return getSourceRange().getBegin();
424 }
425
426 SourceLocation getEndLoc() const LLVM_READONLY__attribute__((__pure__)) {
427 return getSourceRange().getEnd();
428 }
429
430 SourceLocation getLocation() const { return Loc; }
431 void setLocation(SourceLocation L) { Loc = L; }
432
433 Kind getKind() const { return static_cast<Kind>(DeclKind); }
434 const char *getDeclKindName() const;
435
436 Decl *getNextDeclInContext() { return NextInContextAndBits.getPointer(); }
437 const Decl *getNextDeclInContext() const {return NextInContextAndBits.getPointer();}
438
439 DeclContext *getDeclContext() {
440 if (isInSemaDC())
441 return getSemanticDC();
442 return getMultipleDC()->SemanticDC;
443 }
444 const DeclContext *getDeclContext() const {
445 return const_cast<Decl*>(this)->getDeclContext();
446 }
447
448 /// Find the innermost non-closure ancestor of this declaration,
449 /// walking up through blocks, lambdas, etc. If that ancestor is
450 /// not a code context (!isFunctionOrMethod()), returns null.
451 ///
452 /// A declaration may be its own non-closure context.
453 Decl *getNonClosureContext();
454 const Decl *getNonClosureContext() const {
455 return const_cast<Decl*>(this)->getNonClosureContext();
456 }
457
458 TranslationUnitDecl *getTranslationUnitDecl();
459 const TranslationUnitDecl *getTranslationUnitDecl() const {
460 return const_cast<Decl*>(this)->getTranslationUnitDecl();
461 }
462
463 bool isInAnonymousNamespace() const;
464
465 bool isInStdNamespace() const;
466
467 ASTContext &getASTContext() const LLVM_READONLY__attribute__((__pure__));
468
469 /// Helper to get the language options from the ASTContext.
470 /// Defined out of line to avoid depending on ASTContext.h.
471 const LangOptions &getLangOpts() const LLVM_READONLY__attribute__((__pure__));
472
473 void setAccess(AccessSpecifier AS) {
474 Access = AS;
475 assert(AccessDeclContextSanity())((AccessDeclContextSanity()) ? static_cast<void> (0) : __assert_fail
("AccessDeclContextSanity()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 475, __PRETTY_FUNCTION__))
;
476 }
477
478 AccessSpecifier getAccess() const {
479 assert(AccessDeclContextSanity())((AccessDeclContextSanity()) ? static_cast<void> (0) : __assert_fail
("AccessDeclContextSanity()", "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 479, __PRETTY_FUNCTION__))
;
480 return AccessSpecifier(Access);
481 }
482
483 /// Retrieve the access specifier for this declaration, even though
484 /// it may not yet have been properly set.
485 AccessSpecifier getAccessUnsafe() const {
486 return AccessSpecifier(Access);
487 }
488
489 bool hasAttrs() const { return HasAttrs; }
490
491 void setAttrs(const AttrVec& Attrs) {
492 return setAttrsImpl(Attrs, getASTContext());
493 }
494
495 AttrVec &getAttrs() {
496 return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
497 }
498
499 const AttrVec &getAttrs() const;
500 void dropAttrs();
501 void addAttr(Attr *A);
502
503 using attr_iterator = AttrVec::const_iterator;
504 using attr_range = llvm::iterator_range<attr_iterator>;
505
506 attr_range attrs() const {
507 return attr_range(attr_begin(), attr_end());
508 }
509
510 attr_iterator attr_begin() const {
511 return hasAttrs() ? getAttrs().begin() : nullptr;
512 }
513 attr_iterator attr_end() const {
514 return hasAttrs() ? getAttrs().end() : nullptr;
515 }
516
517 template <typename T>
518 void dropAttr() {
519 if (!HasAttrs) return;
520
521 AttrVec &Vec = getAttrs();
522 llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); });
523
524 if (Vec.empty())
525 HasAttrs = false;
526 }
527
528 template <typename T>
529 llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
530 return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
531 }
532
533 template <typename T>
534 specific_attr_iterator<T> specific_attr_begin() const {
535 return specific_attr_iterator<T>(attr_begin());
536 }
537
538 template <typename T>
539 specific_attr_iterator<T> specific_attr_end() const {
540 return specific_attr_iterator<T>(attr_end());
541 }
542
543 template<typename T> T *getAttr() const {
544 return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
545 }
546
547 template<typename T> bool hasAttr() const {
548 return hasAttrs() && hasSpecificAttr<T>(getAttrs());
5
Assuming the condition is true
6
Returning the value 1, which participates in a condition later
549 }
550
551 /// getMaxAlignment - return the maximum alignment specified by attributes
552 /// on this decl, 0 if there are none.
553 unsigned getMaxAlignment() const;
554
555 /// setInvalidDecl - Indicates the Decl had a semantic error. This
556 /// allows for graceful error recovery.
557 void setInvalidDecl(bool Invalid = true);
558 bool isInvalidDecl() const { return (bool) InvalidDecl; }
559
560 /// isImplicit - Indicates whether the declaration was implicitly
561 /// generated by the implementation. If false, this declaration
562 /// was written explicitly in the source code.
563 bool isImplicit() const { return Implicit; }
564 void setImplicit(bool I = true) { Implicit = I; }
565
566 /// Whether *any* (re-)declaration of the entity was used, meaning that
567 /// a definition is required.
568 ///
569 /// \param CheckUsedAttr When true, also consider the "used" attribute
570 /// (in addition to the "used" bit set by \c setUsed()) when determining
571 /// whether the function is used.
572 bool isUsed(bool CheckUsedAttr = true) const;
573
574 /// Set whether the declaration is used, in the sense of odr-use.
575 ///
576 /// This should only be used immediately after creating a declaration.
577 /// It intentionally doesn't notify any listeners.
578 void setIsUsed() { getCanonicalDecl()->Used = true; }
579
580 /// Mark the declaration used, in the sense of odr-use.
581 ///
582 /// This notifies any mutation listeners in addition to setting a bit
583 /// indicating the declaration is used.
584 void markUsed(ASTContext &C);
585
586 /// Whether any declaration of this entity was referenced.
587 bool isReferenced() const;
588
589 /// Whether this declaration was referenced. This should not be relied
590 /// upon for anything other than debugging.
591 bool isThisDeclarationReferenced() const { return Referenced; }
592
593 void setReferenced(bool R = true) { Referenced = R; }
594
595 /// Whether this declaration is a top-level declaration (function,
596 /// global variable, etc.) that is lexically inside an objc container
597 /// definition.
598 bool isTopLevelDeclInObjCContainer() const {
599 return TopLevelDeclInObjCContainer;
600 }
601
602 void setTopLevelDeclInObjCContainer(bool V = true) {
603 TopLevelDeclInObjCContainer = V;
604 }
605
606 /// Looks on this and related declarations for an applicable
607 /// external source symbol attribute.
608 ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const;
609
610 /// Whether this declaration was marked as being private to the
611 /// module in which it was defined.
612 bool isModulePrivate() const {
613 return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
614 }
615
616 /// Return true if this declaration has an attribute which acts as
617 /// definition of the entity, such as 'alias' or 'ifunc'.
618 bool hasDefiningAttr() const;
619
620 /// Return this declaration's defining attribute if it has one.
621 const Attr *getDefiningAttr() const;
622
623protected:
624 /// Specify that this declaration was marked as being private
625 /// to the module in which it was defined.
626 void setModulePrivate() {
627 // The module-private specifier has no effect on unowned declarations.
628 // FIXME: We should track this in some way for source fidelity.
629 if (getModuleOwnershipKind() == ModuleOwnershipKind::Unowned)
630 return;
631 setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate);
632 }
633
634public:
635 /// Set the FromASTFile flag. This indicates that this declaration
636 /// was deserialized and not parsed from source code and enables
637 /// features such as module ownership information.
638 void setFromASTFile() {
639 FromASTFile = true;
640 }
641
642 /// Set the owning module ID. This may only be called for
643 /// deserialized Decls.
644 void setOwningModuleID(unsigned ID) {
645 assert(isFromASTFile() && "Only works on a deserialized declaration")((isFromASTFile() && "Only works on a deserialized declaration"
) ? static_cast<void> (0) : __assert_fail ("isFromASTFile() && \"Only works on a deserialized declaration\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 645, __PRETTY_FUNCTION__))
;
646 *((unsigned*)this - 2) = ID;
647 }
648
649public:
650 /// Determine the availability of the given declaration.
651 ///
652 /// This routine will determine the most restrictive availability of
653 /// the given declaration (e.g., preferring 'unavailable' to
654 /// 'deprecated').
655 ///
656 /// \param Message If non-NULL and the result is not \c
657 /// AR_Available, will be set to a (possibly empty) message
658 /// describing why the declaration has not been introduced, is
659 /// deprecated, or is unavailable.
660 ///
661 /// \param EnclosingVersion The version to compare with. If empty, assume the
662 /// deployment target version.
663 ///
664 /// \param RealizedPlatform If non-NULL and the availability result is found
665 /// in an available attribute it will set to the platform which is written in
666 /// the available attribute.
667 AvailabilityResult
668 getAvailability(std::string *Message = nullptr,
669 VersionTuple EnclosingVersion = VersionTuple(),
670 StringRef *RealizedPlatform = nullptr) const;
671
672 /// Retrieve the version of the target platform in which this
673 /// declaration was introduced.
674 ///
675 /// \returns An empty version tuple if this declaration has no 'introduced'
676 /// availability attributes, or the version tuple that's specified in the
677 /// attribute otherwise.
678 VersionTuple getVersionIntroduced() const;
679
680 /// Determine whether this declaration is marked 'deprecated'.
681 ///
682 /// \param Message If non-NULL and the declaration is deprecated,
683 /// this will be set to the message describing why the declaration
684 /// was deprecated (which may be empty).
685 bool isDeprecated(std::string *Message = nullptr) const {
686 return getAvailability(Message) == AR_Deprecated;
687 }
688
689 /// Determine whether this declaration is marked 'unavailable'.
690 ///
691 /// \param Message If non-NULL and the declaration is unavailable,
692 /// this will be set to the message describing why the declaration
693 /// was made unavailable (which may be empty).
694 bool isUnavailable(std::string *Message = nullptr) const {
695 return getAvailability(Message) == AR_Unavailable;
696 }
697
698 /// Determine whether this is a weak-imported symbol.
699 ///
700 /// Weak-imported symbols are typically marked with the
701 /// 'weak_import' attribute, but may also be marked with an
702 /// 'availability' attribute where we're targing a platform prior to
703 /// the introduction of this feature.
704 bool isWeakImported() const;
705
706 /// Determines whether this symbol can be weak-imported,
707 /// e.g., whether it would be well-formed to add the weak_import
708 /// attribute.
709 ///
710 /// \param IsDefinition Set to \c true to indicate that this
711 /// declaration cannot be weak-imported because it has a definition.
712 bool canBeWeakImported(bool &IsDefinition) const;
713
714 /// Determine whether this declaration came from an AST file (such as
715 /// a precompiled header or module) rather than having been parsed.
716 bool isFromASTFile() const { return FromASTFile; }
717
718 /// Retrieve the global declaration ID associated with this
719 /// declaration, which specifies where this Decl was loaded from.
720 unsigned getGlobalID() const {
721 if (isFromASTFile())
722 return *((const unsigned*)this - 1);
723 return 0;
724 }
725
726 /// Retrieve the global ID of the module that owns this particular
727 /// declaration.
728 unsigned getOwningModuleID() const {
729 if (isFromASTFile())
730 return *((const unsigned*)this - 2);
731 return 0;
732 }
733
734private:
735 Module *getOwningModuleSlow() const;
736
737protected:
738 bool hasLocalOwningModuleStorage() const;
739
740public:
741 /// Get the imported owning module, if this decl is from an imported
742 /// (non-local) module.
743 Module *getImportedOwningModule() const {
744 if (!isFromASTFile() || !hasOwningModule())
745 return nullptr;
746
747 return getOwningModuleSlow();
748 }
749
750 /// Get the local owning module, if known. Returns nullptr if owner is
751 /// not yet known or declaration is not from a module.
752 Module *getLocalOwningModule() const {
753 if (isFromASTFile() || !hasOwningModule())
754 return nullptr;
755
756 assert(hasLocalOwningModuleStorage() &&((hasLocalOwningModuleStorage() && "owned local decl but no local module storage"
) ? static_cast<void> (0) : __assert_fail ("hasLocalOwningModuleStorage() && \"owned local decl but no local module storage\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 757, __PRETTY_FUNCTION__))
757 "owned local decl but no local module storage")((hasLocalOwningModuleStorage() && "owned local decl but no local module storage"
) ? static_cast<void> (0) : __assert_fail ("hasLocalOwningModuleStorage() && \"owned local decl but no local module storage\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 757, __PRETTY_FUNCTION__))
;
758 return reinterpret_cast<Module *const *>(this)[-1];
759 }
760 void setLocalOwningModule(Module *M) {
761 assert(!isFromASTFile() && hasOwningModule() &&((!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage
() && "should not have a cached owning module") ? static_cast
<void> (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 763, __PRETTY_FUNCTION__))
762 hasLocalOwningModuleStorage() &&((!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage
() && "should not have a cached owning module") ? static_cast
<void> (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 763, __PRETTY_FUNCTION__))
763 "should not have a cached owning module")((!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage
() && "should not have a cached owning module") ? static_cast
<void> (0) : __assert_fail ("!isFromASTFile() && hasOwningModule() && hasLocalOwningModuleStorage() && \"should not have a cached owning module\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 763, __PRETTY_FUNCTION__))
;
764 reinterpret_cast<Module **>(this)[-1] = M;
765 }
766
767 /// Is this declaration owned by some module?
768 bool hasOwningModule() const {
769 return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned;
770 }
771
772 /// Get the module that owns this declaration (for visibility purposes).
773 Module *getOwningModule() const {
774 return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();
775 }
776
777 /// Get the module that owns this declaration for linkage purposes.
778 /// There only ever is such a module under the C++ Modules TS.
779 ///
780 /// \param IgnoreLinkage Ignore the linkage of the entity; assume that
781 /// all declarations in a global module fragment are unowned.
782 Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
783
784 /// Determine whether this declaration is definitely visible to name lookup,
785 /// independent of whether the owning module is visible.
786 /// Note: The declaration may be visible even if this returns \c false if the
787 /// owning module is visible within the query context. This is a low-level
788 /// helper function; most code should be calling Sema::isVisible() instead.
789 bool isUnconditionallyVisible() const {
790 return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible;
791 }
792
793 /// Set that this declaration is globally visible, even if it came from a
794 /// module that is not visible.
795 void setVisibleDespiteOwningModule() {
796 if (!isUnconditionallyVisible())
797 setModuleOwnershipKind(ModuleOwnershipKind::Visible);
798 }
799
800 /// Get the kind of module ownership for this declaration.
801 ModuleOwnershipKind getModuleOwnershipKind() const {
802 return NextInContextAndBits.getInt();
803 }
804
805 /// Set whether this declaration is hidden from name lookup.
806 void setModuleOwnershipKind(ModuleOwnershipKind MOK) {
807 assert(!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&((!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile
() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration"
) ? static_cast<void> (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 810, __PRETTY_FUNCTION__))
808 MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() &&((!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile
() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration"
) ? static_cast<void> (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 810, __PRETTY_FUNCTION__))
809 !hasLocalOwningModuleStorage()) &&((!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile
() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration"
) ? static_cast<void> (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 810, __PRETTY_FUNCTION__))
810 "no storage available for owning module for this declaration")((!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile
() && !hasLocalOwningModuleStorage()) && "no storage available for owning module for this declaration"
) ? static_cast<void> (0) : __assert_fail ("!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned && MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() && !hasLocalOwningModuleStorage()) && \"no storage available for owning module for this declaration\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 810, __PRETTY_FUNCTION__))
;
811 NextInContextAndBits.setInt(MOK);
812 }
813
814 unsigned getIdentifierNamespace() const {
815 return IdentifierNamespace;
816 }
817
818 bool isInIdentifierNamespace(unsigned NS) const {
819 return getIdentifierNamespace() & NS;
820 }
821
822 static unsigned getIdentifierNamespaceForKind(Kind DK);
823
824 bool hasTagIdentifierNamespace() const {
825 return isTagIdentifierNamespace(getIdentifierNamespace());
826 }
827
828 static bool isTagIdentifierNamespace(unsigned NS) {
829 // TagDecls have Tag and Type set and may also have TagFriend.
830 return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
831 }
832
833 /// getLexicalDeclContext - The declaration context where this Decl was
834 /// lexically declared (LexicalDC). May be different from
835 /// getDeclContext() (SemanticDC).
836 /// e.g.:
837 ///
838 /// namespace A {
839 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
840 /// }
841 /// void A::f(); // SemanticDC == namespace 'A'
842 /// // LexicalDC == global namespace
843 DeclContext *getLexicalDeclContext() {
844 if (isInSemaDC())
845 return getSemanticDC();
846 return getMultipleDC()->LexicalDC;
847 }
848 const DeclContext *getLexicalDeclContext() const {
849 return const_cast<Decl*>(this)->getLexicalDeclContext();
850 }
851
852 /// Determine whether this declaration is declared out of line (outside its
853 /// semantic context).
854 virtual bool isOutOfLine() const;
855
856 /// setDeclContext - Set both the semantic and lexical DeclContext
857 /// to DC.
858 void setDeclContext(DeclContext *DC);
859
860 void setLexicalDeclContext(DeclContext *DC);
861
862 /// Determine whether this declaration is a templated entity (whether it is
863 // within the scope of a template parameter).
864 bool isTemplated() const;
865
866 /// Determine the number of levels of template parameter surrounding this
867 /// declaration.
868 unsigned getTemplateDepth() const;
869
870 /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
871 /// scoped decl is defined outside the current function or method. This is
872 /// roughly global variables and functions, but also handles enums (which
873 /// could be defined inside or outside a function etc).
874 bool isDefinedOutsideFunctionOrMethod() const {
875 return getParentFunctionOrMethod() == nullptr;
876 }
877
878 /// Determine whether a substitution into this declaration would occur as
879 /// part of a substitution into a dependent local scope. Such a substitution
880 /// transitively substitutes into all constructs nested within this
881 /// declaration.
882 ///
883 /// This recognizes non-defining declarations as well as members of local
884 /// classes and lambdas:
885 /// \code
886 /// template<typename T> void foo() { void bar(); }
887 /// template<typename T> void foo2() { class ABC { void bar(); }; }
888 /// template<typename T> inline int x = [](){ return 0; }();
889 /// \endcode
890 bool isInLocalScopeForInstantiation() const;
891
892 /// If this decl is defined inside a function/method/block it returns
893 /// the corresponding DeclContext, otherwise it returns null.
894 const DeclContext *getParentFunctionOrMethod() const;
895 DeclContext *getParentFunctionOrMethod() {
896 return const_cast<DeclContext*>(
897 const_cast<const Decl*>(this)->getParentFunctionOrMethod());
898 }
899
900 /// Retrieves the "canonical" declaration of the given declaration.
901 virtual Decl *getCanonicalDecl() { return this; }
902 const Decl *getCanonicalDecl() const {
903 return const_cast<Decl*>(this)->getCanonicalDecl();
904 }
905
906 /// Whether this particular Decl is a canonical one.
907 bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
908
909protected:
910 /// Returns the next redeclaration or itself if this is the only decl.
911 ///
912 /// Decl subclasses that can be redeclared should override this method so that
913 /// Decl::redecl_iterator can iterate over them.
914 virtual Decl *getNextRedeclarationImpl() { return this; }
915
916 /// Implementation of getPreviousDecl(), to be overridden by any
917 /// subclass that has a redeclaration chain.
918 virtual Decl *getPreviousDeclImpl() { return nullptr; }
919
920 /// Implementation of getMostRecentDecl(), to be overridden by any
921 /// subclass that has a redeclaration chain.
922 virtual Decl *getMostRecentDeclImpl() { return this; }
923
924public:
925 /// Iterates through all the redeclarations of the same decl.
926 class redecl_iterator {
927 /// Current - The current declaration.
928 Decl *Current = nullptr;
929 Decl *Starter;
930
931 public:
932 using value_type = Decl *;
933 using reference = const value_type &;
934 using pointer = const value_type *;
935 using iterator_category = std::forward_iterator_tag;
936 using difference_type = std::ptrdiff_t;
937
938 redecl_iterator() = default;
939 explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {}
940
941 reference operator*() const { return Current; }
942 value_type operator->() const { return Current; }
943
944 redecl_iterator& operator++() {
945 assert(Current && "Advancing while iterator has reached end")((Current && "Advancing while iterator has reached end"
) ? static_cast<void> (0) : __assert_fail ("Current && \"Advancing while iterator has reached end\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 945, __PRETTY_FUNCTION__))
;
946 // Get either previous decl or latest decl.
947 Decl *Next = Current->getNextRedeclarationImpl();
948 assert(Next && "Should return next redeclaration or itself, never null!")((Next && "Should return next redeclaration or itself, never null!"
) ? static_cast<void> (0) : __assert_fail ("Next && \"Should return next redeclaration or itself, never null!\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 948, __PRETTY_FUNCTION__))
;
949 Current = (Next != Starter) ? Next : nullptr;
950 return *this;
951 }
952
953 redecl_iterator operator++(int) {
954 redecl_iterator tmp(*this);
955 ++(*this);
956 return tmp;
957 }
958
959 friend bool operator==(redecl_iterator x, redecl_iterator y) {
960 return x.Current == y.Current;
961 }
962
963 friend bool operator!=(redecl_iterator x, redecl_iterator y) {
964 return x.Current != y.Current;
965 }
966 };
967
968 using redecl_range = llvm::iterator_range<redecl_iterator>;
969
970 /// Returns an iterator range for all the redeclarations of the same
971 /// decl. It will iterate at least once (when this decl is the only one).
972 redecl_range redecls() const {
973 return redecl_range(redecls_begin(), redecls_end());
974 }
975
976 redecl_iterator redecls_begin() const {
977 return redecl_iterator(const_cast<Decl *>(this));
978 }
979
980 redecl_iterator redecls_end() const { return redecl_iterator(); }
981
982 /// Retrieve the previous declaration that declares the same entity
983 /// as this declaration, or NULL if there is no previous declaration.
984 Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
985
986 /// Retrieve the previous declaration that declares the same entity
987 /// as this declaration, or NULL if there is no previous declaration.
988 const Decl *getPreviousDecl() const {
989 return const_cast<Decl *>(this)->getPreviousDeclImpl();
990 }
991
992 /// True if this is the first declaration in its redeclaration chain.
993 bool isFirstDecl() const {
994 return getPreviousDecl() == nullptr;
995 }
996
997 /// Retrieve the most recent declaration that declares the same entity
998 /// as this declaration (which may be this declaration).
999 Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
1000
1001 /// Retrieve the most recent declaration that declares the same entity
1002 /// as this declaration (which may be this declaration).
1003 const Decl *getMostRecentDecl() const {
1004 return const_cast<Decl *>(this)->getMostRecentDeclImpl();
1005 }
1006
1007 /// getBody - If this Decl represents a declaration for a body of code,
1008 /// such as a function or method definition, this method returns the
1009 /// top-level Stmt* of that body. Otherwise this method returns null.
1010 virtual Stmt* getBody() const { return nullptr; }
1011
1012 /// Returns true if this \c Decl represents a declaration for a body of
1013 /// code, such as a function or method definition.
1014 /// Note that \c hasBody can also return true if any redeclaration of this
1015 /// \c Decl represents a declaration for a body of code.
1016 virtual bool hasBody() const { return getBody() != nullptr; }
1017
1018 /// getBodyRBrace - Gets the right brace of the body, if a body exists.
1019 /// This works whether the body is a CompoundStmt or a CXXTryStmt.
1020 SourceLocation getBodyRBrace() const;
1021
1022 // global temp stats (until we have a per-module visitor)
1023 static void add(Kind k);
1024 static void EnableStatistics();
1025 static void PrintStats();
1026
1027 /// isTemplateParameter - Determines whether this declaration is a
1028 /// template parameter.
1029 bool isTemplateParameter() const;
1030
1031 /// isTemplateParameter - Determines whether this declaration is a
1032 /// template parameter pack.
1033 bool isTemplateParameterPack() const;
1034
1035 /// Whether this declaration is a parameter pack.
1036 bool isParameterPack() const;
1037
1038 /// returns true if this declaration is a template
1039 bool isTemplateDecl() const;
1040
1041 /// Whether this declaration is a function or function template.
1042 bool isFunctionOrFunctionTemplate() const {
1043 return (DeclKind >= Decl::firstFunction &&
1044 DeclKind <= Decl::lastFunction) ||
1045 DeclKind == FunctionTemplate;
1046 }
1047
1048 /// If this is a declaration that describes some template, this
1049 /// method returns that template declaration.
1050 ///
1051 /// Note that this returns nullptr for partial specializations, because they
1052 /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle
1053 /// those cases.
1054 TemplateDecl *getDescribedTemplate() const;
1055
1056 /// If this is a declaration that describes some template or partial
1057 /// specialization, this returns the corresponding template parameter list.
1058 const TemplateParameterList *getDescribedTemplateParams() const;
1059
1060 /// Returns the function itself, or the templated function if this is a
1061 /// function template.
1062 FunctionDecl *getAsFunction() LLVM_READONLY__attribute__((__pure__));
1063
1064 const FunctionDecl *getAsFunction() const {
1065 return const_cast<Decl *>(this)->getAsFunction();
1066 }
1067
1068 /// Changes the namespace of this declaration to reflect that it's
1069 /// a function-local extern declaration.
1070 ///
1071 /// These declarations appear in the lexical context of the extern
1072 /// declaration, but in the semantic context of the enclosing namespace
1073 /// scope.
1074 void setLocalExternDecl() {
1075 Decl *Prev = getPreviousDecl();
1076 IdentifierNamespace &= ~IDNS_Ordinary;
1077
1078 // It's OK for the declaration to still have the "invisible friend" flag or
1079 // the "conflicts with tag declarations in this scope" flag for the outer
1080 // scope.
1081 assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 &&(((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag
)) == 0 && "namespace is not ordinary") ? static_cast
<void> (0) : __assert_fail ("(IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && \"namespace is not ordinary\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1082, __PRETTY_FUNCTION__))
1082 "namespace is not ordinary")(((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag
)) == 0 && "namespace is not ordinary") ? static_cast
<void> (0) : __assert_fail ("(IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && \"namespace is not ordinary\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1082, __PRETTY_FUNCTION__))
;
1083
1084 IdentifierNamespace |= IDNS_LocalExtern;
1085 if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
1086 IdentifierNamespace |= IDNS_Ordinary;
1087 }
1088
1089 /// Determine whether this is a block-scope declaration with linkage.
1090 /// This will either be a local variable declaration declared 'extern', or a
1091 /// local function declaration.
1092 bool isLocalExternDecl() {
1093 return IdentifierNamespace & IDNS_LocalExtern;
1094 }
1095
1096 /// Changes the namespace of this declaration to reflect that it's
1097 /// the object of a friend declaration.
1098 ///
1099 /// These declarations appear in the lexical context of the friending
1100 /// class, but in the semantic context of the actual entity. This property
1101 /// applies only to a specific decl object; other redeclarations of the
1102 /// same entity may not (and probably don't) share this property.
1103 void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
1104 unsigned OldNS = IdentifierNamespace;
1105 assert((OldNS & (IDNS_Tag | IDNS_Ordinary |(((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend
| IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes neither ordinary nor tag"
) ? static_cast<void> (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1108, __PRETTY_FUNCTION__))
1106 IDNS_TagFriend | IDNS_OrdinaryFriend |(((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend
| IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes neither ordinary nor tag"
) ? static_cast<void> (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1108, __PRETTY_FUNCTION__))
1107 IDNS_LocalExtern | IDNS_NonMemberOperator)) &&(((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend
| IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes neither ordinary nor tag"
) ? static_cast<void> (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1108, __PRETTY_FUNCTION__))
1108 "namespace includes neither ordinary nor tag")(((OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend
| IDNS_LocalExtern | IDNS_NonMemberOperator)) && "namespace includes neither ordinary nor tag"
) ? static_cast<void> (0) : __assert_fail ("(OldNS & (IDNS_Tag | IDNS_Ordinary | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes neither ordinary nor tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1108, __PRETTY_FUNCTION__))
;
1109 assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |((!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend
| IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator
)) && "namespace includes other than ordinary or tag"
) ? static_cast<void> (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1112, __PRETTY_FUNCTION__))
1110 IDNS_TagFriend | IDNS_OrdinaryFriend |((!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend
| IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator
)) && "namespace includes other than ordinary or tag"
) ? static_cast<void> (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1112, __PRETTY_FUNCTION__))
1111 IDNS_LocalExtern | IDNS_NonMemberOperator)) &&((!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend
| IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator
)) && "namespace includes other than ordinary or tag"
) ? static_cast<void> (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1112, __PRETTY_FUNCTION__))
1112 "namespace includes other than ordinary or tag")((!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend
| IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator
)) && "namespace includes other than ordinary or tag"
) ? static_cast<void> (0) : __assert_fail ("!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type | IDNS_TagFriend | IDNS_OrdinaryFriend | IDNS_LocalExtern | IDNS_NonMemberOperator)) && \"namespace includes other than ordinary or tag\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1112, __PRETTY_FUNCTION__))
;
1113
1114 Decl *Prev = getPreviousDecl();
1115 IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
1116
1117 if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
1118 IdentifierNamespace |= IDNS_TagFriend;
1119 if (PerformFriendInjection ||
1120 (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
1121 IdentifierNamespace |= IDNS_Tag | IDNS_Type;
1122 }
1123
1124 if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend |
1125 IDNS_LocalExtern | IDNS_NonMemberOperator)) {
1126 IdentifierNamespace |= IDNS_OrdinaryFriend;
1127 if (PerformFriendInjection ||
1128 (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
1129 IdentifierNamespace |= IDNS_Ordinary;
1130 }
1131 }
1132
1133 enum FriendObjectKind {
1134 FOK_None, ///< Not a friend object.
1135 FOK_Declared, ///< A friend of a previously-declared entity.
1136 FOK_Undeclared ///< A friend of a previously-undeclared entity.
1137 };
1138
1139 /// Determines whether this declaration is the object of a
1140 /// friend declaration and, if so, what kind.
1141 ///
1142 /// There is currently no direct way to find the associated FriendDecl.
1143 FriendObjectKind getFriendObjectKind() const {
1144 unsigned mask =
1145 (IdentifierNamespace & (IDNS_TagFriend | IDNS_OrdinaryFriend));
1146 if (!mask) return FOK_None;
1147 return (IdentifierNamespace & (IDNS_Tag | IDNS_Ordinary) ? FOK_Declared
1148 : FOK_Undeclared);
1149 }
1150
1151 /// Specifies that this declaration is a C++ overloaded non-member.
1152 void setNonMemberOperator() {
1153 assert(getKind() == Function || getKind() == FunctionTemplate)((getKind() == Function || getKind() == FunctionTemplate) ? static_cast
<void> (0) : __assert_fail ("getKind() == Function || getKind() == FunctionTemplate"
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1153, __PRETTY_FUNCTION__))
;
1154 assert((IdentifierNamespace & IDNS_Ordinary) &&(((IdentifierNamespace & IDNS_Ordinary) && "visible non-member operators should be in ordinary namespace"
) ? static_cast<void> (0) : __assert_fail ("(IdentifierNamespace & IDNS_Ordinary) && \"visible non-member operators should be in ordinary namespace\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1155, __PRETTY_FUNCTION__))
1155 "visible non-member operators should be in ordinary namespace")(((IdentifierNamespace & IDNS_Ordinary) && "visible non-member operators should be in ordinary namespace"
) ? static_cast<void> (0) : __assert_fail ("(IdentifierNamespace & IDNS_Ordinary) && \"visible non-member operators should be in ordinary namespace\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 1155, __PRETTY_FUNCTION__))
;
1156 IdentifierNamespace |= IDNS_NonMemberOperator;
1157 }
1158
1159 static bool classofKind(Kind K) { return true; }
1160 static DeclContext *castToDeclContext(const Decl *);
1161 static Decl *castFromDeclContext(const DeclContext *);
1162
1163 void print(raw_ostream &Out, unsigned Indentation = 0,
1164 bool PrintInstantiation = false) const;
1165 void print(raw_ostream &Out, const PrintingPolicy &Policy,
1166 unsigned Indentation = 0, bool PrintInstantiation = false) const;
1167 static void printGroup(Decl** Begin, unsigned NumDecls,
1168 raw_ostream &Out, const PrintingPolicy &Policy,
1169 unsigned Indentation = 0);
1170
1171 // Debuggers don't usually respect default arguments.
1172 void dump() const;
1173
1174 // Same as dump(), but forces color printing.
1175 void dumpColor() const;
1176
1177 void dump(raw_ostream &Out, bool Deserialize = false,
1178 ASTDumpOutputFormat OutputFormat = ADOF_Default) const;
1179
1180 /// \return Unique reproducible object identifier
1181 int64_t getID() const;
1182
1183 /// Looks through the Decl's underlying type to extract a FunctionType
1184 /// when possible. Will return null if the type underlying the Decl does not
1185 /// have a FunctionType.
1186 const FunctionType *getFunctionType(bool BlocksToo = true) const;
1187
1188private:
1189 void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
1190 void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
1191 ASTContext &Ctx);
1192
1193protected:
1194 ASTMutationListener *getASTMutationListener() const;
1195};
1196
1197/// Determine whether two declarations declare the same entity.
1198inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
1199 if (!D1 || !D2)
1200 return false;
1201
1202 if (D1 == D2)
1203 return true;
1204
1205 return D1->getCanonicalDecl() == D2->getCanonicalDecl();
1206}
1207
1208/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
1209/// doing something to a specific decl.
1210class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
1211 const Decl *TheDecl;
1212 SourceLocation Loc;
1213 SourceManager &SM;
1214 const char *Message;
1215
1216public:
1217 PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L,
1218 SourceManager &sm, const char *Msg)
1219 : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
1220
1221 void print(raw_ostream &OS) const override;
1222};
1223
1224/// The results of name lookup within a DeclContext. This is either a
1225/// single result (with no stable storage) or a collection of results (with
1226/// stable storage provided by the lookup table).
1227class DeclContextLookupResult {
1228 using ResultTy = ArrayRef<NamedDecl *>;
1229
1230 ResultTy Result;
1231
1232 // If there is only one lookup result, it would be invalidated by
1233 // reallocations of the name table, so store it separately.
1234 NamedDecl *Single = nullptr;
1235
1236 static NamedDecl *const SingleElementDummyList;
1237
1238public:
1239 DeclContextLookupResult() = default;
1240 DeclContextLookupResult(ArrayRef<NamedDecl *> Result)
1241 : Result(Result) {}
1242 DeclContextLookupResult(NamedDecl *Single)
1243 : Result(SingleElementDummyList), Single(Single) {}
1244
1245 class iterator;
1246
1247 using IteratorBase =
1248 llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
1249 std::random_access_iterator_tag,
1250 NamedDecl *const>;
1251
1252 class iterator : public IteratorBase {
1253 value_type SingleElement;
1254
1255 public:
1256 explicit iterator(pointer Pos, value_type Single = nullptr)
1257 : IteratorBase(Pos), SingleElement(Single) {}
1258
1259 reference operator*() const {
1260 return SingleElement ? SingleElement : IteratorBase::operator*();
1261 }
1262 };
1263
1264 using const_iterator = iterator;
1265 using pointer = iterator::pointer;
1266 using reference = iterator::reference;
1267
1268 iterator begin() const { return iterator(Result.begin(), Single); }
1269 iterator end() const { return iterator(Result.end(), Single); }
1270
1271 bool empty() const { return Result.empty(); }
1272 pointer data() const { return Single ? &Single : Result.data(); }
1273 size_t size() const { return Single ? 1 : Result.size(); }
1274 reference front() const { return Single ? Single : Result.front(); }
1275 reference back() const { return Single ? Single : Result.back(); }
1276 reference operator[](size_t N) const { return Single ? Single : Result[N]; }
1277
1278 // FIXME: Remove this from the interface
1279 DeclContextLookupResult slice(size_t N) const {
1280 DeclContextLookupResult Sliced = Result.slice(N);
1281 Sliced.Single = Single;
1282 return Sliced;
1283 }
1284};
1285
1286/// DeclContext - This is used only as base class of specific decl types that
1287/// can act as declaration contexts. These decls are (only the top classes
1288/// that directly derive from DeclContext are mentioned, not their subclasses):
1289///
1290/// TranslationUnitDecl
1291/// ExternCContext
1292/// NamespaceDecl
1293/// TagDecl
1294/// OMPDeclareReductionDecl
1295/// OMPDeclareMapperDecl
1296/// FunctionDecl
1297/// ObjCMethodDecl
1298/// ObjCContainerDecl
1299/// LinkageSpecDecl
1300/// ExportDecl
1301/// BlockDecl
1302/// CapturedDecl
1303class DeclContext {
1304 /// For makeDeclVisibleInContextImpl
1305 friend class ASTDeclReader;
1306 /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
1307 /// hasNeedToReconcileExternalVisibleStorage
1308 friend class ExternalASTSource;
1309 /// For CreateStoredDeclsMap
1310 friend class DependentDiagnostic;
1311 /// For hasNeedToReconcileExternalVisibleStorage,
1312 /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups
1313 friend class ASTWriter;
1314
1315 // We use uint64_t in the bit-fields below since some bit-fields
1316 // cross the unsigned boundary and this breaks the packing.
1317
1318 /// Stores the bits used by DeclContext.
1319 /// If modified NumDeclContextBit, the ctor of DeclContext and the accessor
1320 /// methods in DeclContext should be updated appropriately.
1321 class DeclContextBitfields {
1322 friend class DeclContext;
1323 /// DeclKind - This indicates which class this is.
1324 uint64_t DeclKind : 7;
1325
1326 /// Whether this declaration context also has some external
1327 /// storage that contains additional declarations that are lexically
1328 /// part of this context.
1329 mutable uint64_t ExternalLexicalStorage : 1;
1330
1331 /// Whether this declaration context also has some external
1332 /// storage that contains additional declarations that are visible
1333 /// in this context.
1334 mutable uint64_t ExternalVisibleStorage : 1;
1335
1336 /// Whether this declaration context has had externally visible
1337 /// storage added since the last lookup. In this case, \c LookupPtr's
1338 /// invariant may not hold and needs to be fixed before we perform
1339 /// another lookup.
1340 mutable uint64_t NeedToReconcileExternalVisibleStorage : 1;
1341
1342 /// If \c true, this context may have local lexical declarations
1343 /// that are missing from the lookup table.
1344 mutable uint64_t HasLazyLocalLexicalLookups : 1;
1345
1346 /// If \c true, the external source may have lexical declarations
1347 /// that are missing from the lookup table.
1348 mutable uint64_t HasLazyExternalLexicalLookups : 1;
1349
1350 /// If \c true, lookups should only return identifier from
1351 /// DeclContext scope (for example TranslationUnit). Used in
1352 /// LookupQualifiedName()
1353 mutable uint64_t UseQualifiedLookup : 1;
1354 };
1355
1356 /// Number of bits in DeclContextBitfields.
1357 enum { NumDeclContextBits = 13 };
1358
1359 /// Stores the bits used by TagDecl.
1360 /// If modified NumTagDeclBits and the accessor
1361 /// methods in TagDecl should be updated appropriately.
1362 class TagDeclBitfields {
1363 friend class TagDecl;
1364 /// For the bits in DeclContextBitfields
1365 uint64_t : NumDeclContextBits;
1366
1367 /// The TagKind enum.
1368 uint64_t TagDeclKind : 3;
1369
1370 /// True if this is a definition ("struct foo {};"), false if it is a
1371 /// declaration ("struct foo;"). It is not considered a definition
1372 /// until the definition has been fully processed.
1373 uint64_t IsCompleteDefinition : 1;
1374
1375 /// True if this is currently being defined.
1376 uint64_t IsBeingDefined : 1;
1377
1378 /// True if this tag declaration is "embedded" (i.e., defined or declared
1379 /// for the very first time) in the syntax of a declarator.
1380 uint64_t IsEmbeddedInDeclarator : 1;
1381
1382 /// True if this tag is free standing, e.g. "struct foo;".
1383 uint64_t IsFreeStanding : 1;
1384
1385 /// Indicates whether it is possible for declarations of this kind
1386 /// to have an out-of-date definition.
1387 ///
1388 /// This option is only enabled when modules are enabled.
1389 uint64_t MayHaveOutOfDateDef : 1;
1390
1391 /// Has the full definition of this type been required by a use somewhere in
1392 /// the TU.
1393 uint64_t IsCompleteDefinitionRequired : 1;
1394 };
1395
1396 /// Number of non-inherited bits in TagDeclBitfields.
1397 enum { NumTagDeclBits = 9 };
1398
1399 /// Stores the bits used by EnumDecl.
1400 /// If modified NumEnumDeclBit and the accessor
1401 /// methods in EnumDecl should be updated appropriately.
1402 class EnumDeclBitfields {
1403 friend class EnumDecl;
1404 /// For the bits in DeclContextBitfields.
1405 uint64_t : NumDeclContextBits;
1406 /// For the bits in TagDeclBitfields.
1407 uint64_t : NumTagDeclBits;
1408
1409 /// Width in bits required to store all the non-negative
1410 /// enumerators of this enum.
1411 uint64_t NumPositiveBits : 8;
1412
1413 /// Width in bits required to store all the negative
1414 /// enumerators of this enum.
1415 uint64_t NumNegativeBits : 8;
1416
1417 /// True if this tag declaration is a scoped enumeration. Only
1418 /// possible in C++11 mode.
1419 uint64_t IsScoped : 1;
1420
1421 /// If this tag declaration is a scoped enum,
1422 /// then this is true if the scoped enum was declared using the class
1423 /// tag, false if it was declared with the struct tag. No meaning is
1424 /// associated if this tag declaration is not a scoped enum.
1425 uint64_t IsScopedUsingClassTag : 1;
1426
1427 /// True if this is an enumeration with fixed underlying type. Only
1428 /// possible in C++11, Microsoft extensions, or Objective C mode.
1429 uint64_t IsFixed : 1;
1430
1431 /// True if a valid hash is stored in ODRHash.
1432 uint64_t HasODRHash : 1;
1433 };
1434
1435 /// Number of non-inherited bits in EnumDeclBitfields.
1436 enum { NumEnumDeclBits = 20 };
1437
1438 /// Stores the bits used by RecordDecl.
1439 /// If modified NumRecordDeclBits and the accessor
1440 /// methods in RecordDecl should be updated appropriately.
1441 class RecordDeclBitfields {
1442 friend class RecordDecl;
1443 /// For the bits in DeclContextBitfields.
1444 uint64_t : NumDeclContextBits;
1445 /// For the bits in TagDeclBitfields.
1446 uint64_t : NumTagDeclBits;
1447
1448 /// This is true if this struct ends with a flexible
1449 /// array member (e.g. int X[]) or if this union contains a struct that does.
1450 /// If so, this cannot be contained in arrays or other structs as a member.
1451 uint64_t HasFlexibleArrayMember : 1;
1452
1453 /// Whether this is the type of an anonymous struct or union.
1454 uint64_t AnonymousStructOrUnion : 1;
1455
1456 /// This is true if this struct has at least one member
1457 /// containing an Objective-C object pointer type.
1458 uint64_t HasObjectMember : 1;
1459
1460 /// This is true if struct has at least one member of
1461 /// 'volatile' type.
1462 uint64_t HasVolatileMember : 1;
1463
1464 /// Whether the field declarations of this record have been loaded
1465 /// from external storage. To avoid unnecessary deserialization of
1466 /// methods/nested types we allow deserialization of just the fields
1467 /// when needed.
1468 mutable uint64_t LoadedFieldsFromExternalStorage : 1;
1469
1470 /// Basic properties of non-trivial C structs.
1471 uint64_t NonTrivialToPrimitiveDefaultInitialize : 1;
1472 uint64_t NonTrivialToPrimitiveCopy : 1;
1473 uint64_t NonTrivialToPrimitiveDestroy : 1;
1474
1475 /// The following bits indicate whether this is or contains a C union that
1476 /// is non-trivial to default-initialize, destruct, or copy. These bits
1477 /// imply the associated basic non-triviality predicates declared above.
1478 uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1;
1479 uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1;
1480 uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1;
1481
1482 /// Indicates whether this struct is destroyed in the callee.
1483 uint64_t ParamDestroyedInCallee : 1;
1484
1485 /// Represents the way this type is passed to a function.
1486 uint64_t ArgPassingRestrictions : 2;
1487 };
1488
1489 /// Number of non-inherited bits in RecordDeclBitfields.
1490 enum { NumRecordDeclBits = 14 };
1491
1492 /// Stores the bits used by OMPDeclareReductionDecl.
1493 /// If modified NumOMPDeclareReductionDeclBits and the accessor
1494 /// methods in OMPDeclareReductionDecl should be updated appropriately.
1495 class OMPDeclareReductionDeclBitfields {
1496 friend class OMPDeclareReductionDecl;
1497 /// For the bits in DeclContextBitfields
1498 uint64_t : NumDeclContextBits;
1499
1500 /// Kind of initializer,
1501 /// function call or omp_priv<init_expr> initializtion.
1502 uint64_t InitializerKind : 2;
1503 };
1504
1505 /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
1506 enum { NumOMPDeclareReductionDeclBits = 2 };
1507
1508 /// Stores the bits used by FunctionDecl.
1509 /// If modified NumFunctionDeclBits and the accessor
1510 /// methods in FunctionDecl and CXXDeductionGuideDecl
1511 /// (for IsCopyDeductionCandidate) should be updated appropriately.
1512 class FunctionDeclBitfields {
1513 friend class FunctionDecl;
1514 /// For IsCopyDeductionCandidate
1515 friend class CXXDeductionGuideDecl;
1516 /// For the bits in DeclContextBitfields.
1517 uint64_t : NumDeclContextBits;
1518
1519 uint64_t SClass : 3;
1520 uint64_t IsInline : 1;
1521 uint64_t IsInlineSpecified : 1;
1522
1523 uint64_t IsVirtualAsWritten : 1;
1524 uint64_t IsPure : 1;
1525 uint64_t HasInheritedPrototype : 1;
1526 uint64_t HasWrittenPrototype : 1;
1527 uint64_t IsDeleted : 1;
1528 /// Used by CXXMethodDecl
1529 uint64_t IsTrivial : 1;
1530
1531 /// This flag indicates whether this function is trivial for the purpose of
1532 /// calls. This is meaningful only when this function is a copy/move
1533 /// constructor or a destructor.
1534 uint64_t IsTrivialForCall : 1;
1535
1536 uint64_t IsDefaulted : 1;
1537 uint64_t IsExplicitlyDefaulted : 1;
1538 uint64_t HasDefaultedFunctionInfo : 1;
1539 uint64_t HasImplicitReturnZero : 1;
1540 uint64_t IsLateTemplateParsed : 1;
1541
1542 /// Kind of contexpr specifier as defined by ConstexprSpecKind.
1543 uint64_t ConstexprKind : 2;
1544 uint64_t InstantiationIsPending : 1;
1545
1546 /// Indicates if the function uses __try.
1547 uint64_t UsesSEHTry : 1;
1548
1549 /// Indicates if the function was a definition
1550 /// but its body was skipped.
1551 uint64_t HasSkippedBody : 1;
1552
1553 /// Indicates if the function declaration will
1554 /// have a body, once we're done parsing it.
1555 uint64_t WillHaveBody : 1;
1556
1557 /// Indicates that this function is a multiversioned
1558 /// function using attribute 'target'.
1559 uint64_t IsMultiVersion : 1;
1560
1561 /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that
1562 /// the Deduction Guide is the implicitly generated 'copy
1563 /// deduction candidate' (is used during overload resolution).
1564 uint64_t IsCopyDeductionCandidate : 1;
1565
1566 /// Store the ODRHash after first calculation.
1567 uint64_t HasODRHash : 1;
1568
1569 /// Indicates if the function uses Floating Point Constrained Intrinsics
1570 uint64_t UsesFPIntrin : 1;
1571 };
1572
1573 /// Number of non-inherited bits in FunctionDeclBitfields.
1574 enum { NumFunctionDeclBits = 27 };
1575
1576 /// Stores the bits used by CXXConstructorDecl. If modified
1577 /// NumCXXConstructorDeclBits and the accessor
1578 /// methods in CXXConstructorDecl should be updated appropriately.
1579 class CXXConstructorDeclBitfields {
1580 friend class CXXConstructorDecl;
1581 /// For the bits in DeclContextBitfields.
1582 uint64_t : NumDeclContextBits;
1583 /// For the bits in FunctionDeclBitfields.
1584 uint64_t : NumFunctionDeclBits;
1585
1586 /// 24 bits to fit in the remaining available space.
1587 /// Note that this makes CXXConstructorDeclBitfields take
1588 /// exactly 64 bits and thus the width of NumCtorInitializers
1589 /// will need to be shrunk if some bit is added to NumDeclContextBitfields,
1590 /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
1591 uint64_t NumCtorInitializers : 21;
1592 uint64_t IsInheritingConstructor : 1;
1593
1594 /// Whether this constructor has a trail-allocated explicit specifier.
1595 uint64_t HasTrailingExplicitSpecifier : 1;
1596 /// If this constructor does't have a trail-allocated explicit specifier.
1597 /// Whether this constructor is explicit specified.
1598 uint64_t IsSimpleExplicit : 1;
1599 };
1600
1601 /// Number of non-inherited bits in CXXConstructorDeclBitfields.
1602 enum {
1603 NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits
1604 };
1605
1606 /// Stores the bits used by ObjCMethodDecl.
1607 /// If modified NumObjCMethodDeclBits and the accessor
1608 /// methods in ObjCMethodDecl should be updated appropriately.
1609 class ObjCMethodDeclBitfields {
1610 friend class ObjCMethodDecl;
1611
1612 /// For the bits in DeclContextBitfields.
1613 uint64_t : NumDeclContextBits;
1614
1615 /// The conventional meaning of this method; an ObjCMethodFamily.
1616 /// This is not serialized; instead, it is computed on demand and
1617 /// cached.
1618 mutable uint64_t Family : ObjCMethodFamilyBitWidth;
1619
1620 /// instance (true) or class (false) method.
1621 uint64_t IsInstance : 1;
1622 uint64_t IsVariadic : 1;
1623
1624 /// True if this method is the getter or setter for an explicit property.
1625 uint64_t IsPropertyAccessor : 1;
1626
1627 /// True if this method is a synthesized property accessor stub.
1628 uint64_t IsSynthesizedAccessorStub : 1;
1629
1630 /// Method has a definition.
1631 uint64_t IsDefined : 1;
1632
1633 /// Method redeclaration in the same interface.
1634 uint64_t IsRedeclaration : 1;
1635
1636 /// Is redeclared in the same interface.
1637 mutable uint64_t HasRedeclaration : 1;
1638
1639 /// \@required/\@optional
1640 uint64_t DeclImplementation : 2;
1641
1642 /// in, inout, etc.
1643 uint64_t objcDeclQualifier : 7;
1644
1645 /// Indicates whether this method has a related result type.
1646 uint64_t RelatedResultType : 1;
1647
1648 /// Whether the locations of the selector identifiers are in a
1649 /// "standard" position, a enum SelectorLocationsKind.
1650 uint64_t SelLocsKind : 2;
1651
1652 /// Whether this method overrides any other in the class hierarchy.
1653 ///
1654 /// A method is said to override any method in the class's
1655 /// base classes, its protocols, or its categories' protocols, that has
1656 /// the same selector and is of the same kind (class or instance).
1657 /// A method in an implementation is not considered as overriding the same
1658 /// method in the interface or its categories.
1659 uint64_t IsOverriding : 1;
1660
1661 /// Indicates if the method was a definition but its body was skipped.
1662 uint64_t HasSkippedBody : 1;
1663 };
1664
1665 /// Number of non-inherited bits in ObjCMethodDeclBitfields.
1666 enum { NumObjCMethodDeclBits = 24 };
1667
1668 /// Stores the bits used by ObjCContainerDecl.
1669 /// If modified NumObjCContainerDeclBits and the accessor
1670 /// methods in ObjCContainerDecl should be updated appropriately.
1671 class ObjCContainerDeclBitfields {
1672 friend class ObjCContainerDecl;
1673 /// For the bits in DeclContextBitfields
1674 uint32_t : NumDeclContextBits;
1675
1676 // Not a bitfield but this saves space.
1677 // Note that ObjCContainerDeclBitfields is full.
1678 SourceLocation AtStart;
1679 };
1680
1681 /// Number of non-inherited bits in ObjCContainerDeclBitfields.
1682 /// Note that here we rely on the fact that SourceLocation is 32 bits
1683 /// wide. We check this with the static_assert in the ctor of DeclContext.
1684 enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits };
1685
1686 /// Stores the bits used by LinkageSpecDecl.
1687 /// If modified NumLinkageSpecDeclBits and the accessor
1688 /// methods in LinkageSpecDecl should be updated appropriately.
1689 class LinkageSpecDeclBitfields {
1690 friend class LinkageSpecDecl;
1691 /// For the bits in DeclContextBitfields.
1692 uint64_t : NumDeclContextBits;
1693
1694 /// The language for this linkage specification with values
1695 /// in the enum LinkageSpecDecl::LanguageIDs.
1696 uint64_t Language : 3;
1697
1698 /// True if this linkage spec has braces.
1699 /// This is needed so that hasBraces() returns the correct result while the
1700 /// linkage spec body is being parsed. Once RBraceLoc has been set this is
1701 /// not used, so it doesn't need to be serialized.
1702 uint64_t HasBraces : 1;
1703 };
1704
1705 /// Number of non-inherited bits in LinkageSpecDeclBitfields.
1706 enum { NumLinkageSpecDeclBits = 4 };
1707
1708 /// Stores the bits used by BlockDecl.
1709 /// If modified NumBlockDeclBits and the accessor
1710 /// methods in BlockDecl should be updated appropriately.
1711 class BlockDeclBitfields {
1712 friend class BlockDecl;
1713 /// For the bits in DeclContextBitfields.
1714 uint64_t : NumDeclContextBits;
1715
1716 uint64_t IsVariadic : 1;
1717 uint64_t CapturesCXXThis : 1;
1718 uint64_t BlockMissingReturnType : 1;
1719 uint64_t IsConversionFromLambda : 1;
1720
1721 /// A bit that indicates this block is passed directly to a function as a
1722 /// non-escaping parameter.
1723 uint64_t DoesNotEscape : 1;
1724
1725 /// A bit that indicates whether it's possible to avoid coying this block to
1726 /// the heap when it initializes or is assigned to a local variable with
1727 /// automatic storage.
1728 uint64_t CanAvoidCopyToHeap : 1;
1729 };
1730
1731 /// Number of non-inherited bits in BlockDeclBitfields.
1732 enum { NumBlockDeclBits = 5 };
1733
1734 /// Pointer to the data structure used to lookup declarations
1735 /// within this context (or a DependentStoredDeclsMap if this is a
1736 /// dependent context). We maintain the invariant that, if the map
1737 /// contains an entry for a DeclarationName (and we haven't lazily
1738 /// omitted anything), then it contains all relevant entries for that
1739 /// name (modulo the hasExternalDecls() flag).
1740 mutable StoredDeclsMap *LookupPtr = nullptr;
1741
1742protected:
1743 /// This anonymous union stores the bits belonging to DeclContext and classes
1744 /// deriving from it. The goal is to use otherwise wasted
1745 /// space in DeclContext to store data belonging to derived classes.
1746 /// The space saved is especially significient when pointers are aligned
1747 /// to 8 bytes. In this case due to alignment requirements we have a
1748 /// little less than 8 bytes free in DeclContext which we can use.
1749 /// We check that none of the classes in this union is larger than
1750 /// 8 bytes with static_asserts in the ctor of DeclContext.
1751 union {
1752 DeclContextBitfields DeclContextBits;
1753 TagDeclBitfields TagDeclBits;
1754 EnumDeclBitfields EnumDeclBits;
1755 RecordDeclBitfields RecordDeclBits;
1756 OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits;
1757 FunctionDeclBitfields FunctionDeclBits;
1758 CXXConstructorDeclBitfields CXXConstructorDeclBits;
1759 ObjCMethodDeclBitfields ObjCMethodDeclBits;
1760 ObjCContainerDeclBitfields ObjCContainerDeclBits;
1761 LinkageSpecDeclBitfields LinkageSpecDeclBits;
1762 BlockDeclBitfields BlockDeclBits;
1763
1764 static_assert(sizeof(DeclContextBitfields) <= 8,
1765 "DeclContextBitfields is larger than 8 bytes!");
1766 static_assert(sizeof(TagDeclBitfields) <= 8,
1767 "TagDeclBitfields is larger than 8 bytes!");
1768 static_assert(sizeof(EnumDeclBitfields) <= 8,
1769 "EnumDeclBitfields is larger than 8 bytes!");
1770 static_assert(sizeof(RecordDeclBitfields) <= 8,
1771 "RecordDeclBitfields is larger than 8 bytes!");
1772 static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8,
1773 "OMPDeclareReductionDeclBitfields is larger than 8 bytes!");
1774 static_assert(sizeof(FunctionDeclBitfields) <= 8,
1775 "FunctionDeclBitfields is larger than 8 bytes!");
1776 static_assert(sizeof(CXXConstructorDeclBitfields) <= 8,
1777 "CXXConstructorDeclBitfields is larger than 8 bytes!");
1778 static_assert(sizeof(ObjCMethodDeclBitfields) <= 8,
1779 "ObjCMethodDeclBitfields is larger than 8 bytes!");
1780 static_assert(sizeof(ObjCContainerDeclBitfields) <= 8,
1781 "ObjCContainerDeclBitfields is larger than 8 bytes!");
1782 static_assert(sizeof(LinkageSpecDeclBitfields) <= 8,
1783 "LinkageSpecDeclBitfields is larger than 8 bytes!");
1784 static_assert(sizeof(BlockDeclBitfields) <= 8,
1785 "BlockDeclBitfields is larger than 8 bytes!");
1786 };
1787
1788 /// FirstDecl - The first declaration stored within this declaration
1789 /// context.
1790 mutable Decl *FirstDecl = nullptr;
1791
1792 /// LastDecl - The last declaration stored within this declaration
1793 /// context. FIXME: We could probably cache this value somewhere
1794 /// outside of the DeclContext, to reduce the size of DeclContext by
1795 /// another pointer.
1796 mutable Decl *LastDecl = nullptr;
1797
1798 /// Build up a chain of declarations.
1799 ///
1800 /// \returns the first/last pair of declarations.
1801 static std::pair<Decl *, Decl *>
1802 BuildDeclChain(ArrayRef<Decl*> Decls, bool FieldsAlreadyLoaded);
1803
1804 DeclContext(Decl::Kind K);
1805
1806public:
1807 ~DeclContext();
1808
1809 Decl::Kind getDeclKind() const {
1810 return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
1811 }
1812
1813 const char *getDeclKindName() const;
1814
1815 /// getParent - Returns the containing DeclContext.
1816 DeclContext *getParent() {
1817 return cast<Decl>(this)->getDeclContext();
1818 }
1819 const DeclContext *getParent() const {
1820 return const_cast<DeclContext*>(this)->getParent();
1821 }
1822
1823 /// getLexicalParent - Returns the containing lexical DeclContext. May be
1824 /// different from getParent, e.g.:
1825 ///
1826 /// namespace A {
1827 /// struct S;
1828 /// }
1829 /// struct A::S {}; // getParent() == namespace 'A'
1830 /// // getLexicalParent() == translation unit
1831 ///
1832 DeclContext *getLexicalParent() {
1833 return cast<Decl>(this)->getLexicalDeclContext();
1834 }
1835 const DeclContext *getLexicalParent() const {
1836 return const_cast<DeclContext*>(this)->getLexicalParent();
1837 }
1838
1839 DeclContext *getLookupParent();
1840
1841 const DeclContext *getLookupParent() const {
1842 return const_cast<DeclContext*>(this)->getLookupParent();
1843 }
1844
1845 ASTContext &getParentASTContext() const {
1846 return cast<Decl>(this)->getASTContext();
1847 }
1848
1849 bool isClosure() const { return getDeclKind() == Decl::Block; }
1850
1851 /// Return this DeclContext if it is a BlockDecl. Otherwise, return the
1852 /// innermost enclosing BlockDecl or null if there are no enclosing blocks.
1853 const BlockDecl *getInnermostBlockDecl() const;
1854
1855 bool isObjCContainer() const {
1856 switch (getDeclKind()) {
1857 case Decl::ObjCCategory:
1858 case Decl::ObjCCategoryImpl:
1859 case Decl::ObjCImplementation:
1860 case Decl::ObjCInterface:
1861 case Decl::ObjCProtocol:
1862 return true;
1863 default:
1864 return false;
1865 }
1866 }
1867
1868 bool isFunctionOrMethod() const {
1869 switch (getDeclKind()) {
1870 case Decl::Block:
1871 case Decl::Captured:
1872 case Decl::ObjCMethod:
1873 return true;
1874 default:
1875 return getDeclKind() >= Decl::firstFunction &&
1876 getDeclKind() <= Decl::lastFunction;
1877 }
1878 }
1879
1880 /// Test whether the context supports looking up names.
1881 bool isLookupContext() const {
1882 return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec &&
1883 getDeclKind() != Decl::Export;
1884 }
1885
1886 bool isFileContext() const {
1887 return getDeclKind() == Decl::TranslationUnit ||
1888 getDeclKind() == Decl::Namespace;
1889 }
1890
1891 bool isTranslationUnit() const {
1892 return getDeclKind() == Decl::TranslationUnit;
1893 }
1894
1895 bool isRecord() const {
1896 return getDeclKind() >= Decl::firstRecord &&
1897 getDeclKind() <= Decl::lastRecord;
1898 }
1899
1900 bool isNamespace() const { return getDeclKind() == Decl::Namespace; }
1901
1902 bool isStdNamespace() const;
1903
1904 bool isInlineNamespace() const;
1905
1906 /// Determines whether this context is dependent on a
1907 /// template parameter.
1908 bool isDependentContext() const;
1909
1910 /// isTransparentContext - Determines whether this context is a
1911 /// "transparent" context, meaning that the members declared in this
1912 /// context are semantically declared in the nearest enclosing
1913 /// non-transparent (opaque) context but are lexically declared in
1914 /// this context. For example, consider the enumerators of an
1915 /// enumeration type:
1916 /// @code
1917 /// enum E {
1918 /// Val1
1919 /// };
1920 /// @endcode
1921 /// Here, E is a transparent context, so its enumerator (Val1) will
1922 /// appear (semantically) that it is in the same context of E.
1923 /// Examples of transparent contexts include: enumerations (except for
1924 /// C++0x scoped enums), and C++ linkage specifications.
1925 bool isTransparentContext() const;
1926
1927 /// Determines whether this context or some of its ancestors is a
1928 /// linkage specification context that specifies C linkage.
1929 bool isExternCContext() const;
1930
1931 /// Retrieve the nearest enclosing C linkage specification context.
1932 const LinkageSpecDecl *getExternCContext() const;
1933
1934 /// Determines whether this context or some of its ancestors is a
1935 /// linkage specification context that specifies C++ linkage.
1936 bool isExternCXXContext() const;
1937
1938 /// Determine whether this declaration context is equivalent
1939 /// to the declaration context DC.
1940 bool Equals(const DeclContext *DC) const {
1941 return DC && this->getPrimaryContext() == DC->getPrimaryContext();
1942 }
1943
1944 /// Determine whether this declaration context encloses the
1945 /// declaration context DC.
1946 bool Encloses(const DeclContext *DC) const;
1947
1948 /// Find the nearest non-closure ancestor of this context,
1949 /// i.e. the innermost semantic parent of this context which is not
1950 /// a closure. A context may be its own non-closure ancestor.
1951 Decl *getNonClosureAncestor();
1952 const Decl *getNonClosureAncestor() const {
1953 return const_cast<DeclContext*>(this)->getNonClosureAncestor();
1954 }
1955
1956 /// getPrimaryContext - There may be many different
1957 /// declarations of the same entity (including forward declarations
1958 /// of classes, multiple definitions of namespaces, etc.), each with
1959 /// a different set of declarations. This routine returns the
1960 /// "primary" DeclContext structure, which will contain the
1961 /// information needed to perform name lookup into this context.
1962 DeclContext *getPrimaryContext();
1963 const DeclContext *getPrimaryContext() const {
1964 return const_cast<DeclContext*>(this)->getPrimaryContext();
1965 }
1966
1967 /// getRedeclContext - Retrieve the context in which an entity conflicts with
1968 /// other entities of the same name, or where it is a redeclaration if the
1969 /// two entities are compatible. This skips through transparent contexts.
1970 DeclContext *getRedeclContext();
1971 const DeclContext *getRedeclContext() const {
1972 return const_cast<DeclContext *>(this)->getRedeclContext();
1973 }
1974
1975 /// Retrieve the nearest enclosing namespace context.
1976 DeclContext *getEnclosingNamespaceContext();
1977 const DeclContext *getEnclosingNamespaceContext() const {
1978 return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
1979 }
1980
1981 /// Retrieve the outermost lexically enclosing record context.
1982 RecordDecl *getOuterLexicalRecordContext();
1983 const RecordDecl *getOuterLexicalRecordContext() const {
1984 return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
1985 }
1986
1987 /// Test if this context is part of the enclosing namespace set of
1988 /// the context NS, as defined in C++0x [namespace.def]p9. If either context
1989 /// isn't a namespace, this is equivalent to Equals().
1990 ///
1991 /// The enclosing namespace set of a namespace is the namespace and, if it is
1992 /// inline, its enclosing namespace, recursively.
1993 bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
1994
1995 /// Collects all of the declaration contexts that are semantically
1996 /// connected to this declaration context.
1997 ///
1998 /// For declaration contexts that have multiple semantically connected but
1999 /// syntactically distinct contexts, such as C++ namespaces, this routine
2000 /// retrieves the complete set of such declaration contexts in source order.
2001 /// For example, given:
2002 ///
2003 /// \code
2004 /// namespace N {
2005 /// int x;
2006 /// }
2007 /// namespace N {
2008 /// int y;
2009 /// }
2010 /// \endcode
2011 ///
2012 /// The \c Contexts parameter will contain both definitions of N.
2013 ///
2014 /// \param Contexts Will be cleared and set to the set of declaration
2015 /// contexts that are semanticaly connected to this declaration context,
2016 /// in source order, including this context (which may be the only result,
2017 /// for non-namespace contexts).
2018 void collectAllContexts(SmallVectorImpl<DeclContext *> &Contexts);
2019
2020 /// decl_iterator - Iterates through the declarations stored
2021 /// within this context.
2022 class decl_iterator {
2023 /// Current - The current declaration.
2024 Decl *Current = nullptr;
2025
2026 public:
2027 using value_type = Decl *;
2028 using reference = const value_type &;
2029 using pointer = const value_type *;
2030 using iterator_category = std::forward_iterator_tag;
2031 using difference_type = std::ptrdiff_t;
2032
2033 decl_iterator() = default;
2034 explicit decl_iterator(Decl *C) : Current(C) {}
2035
2036 reference operator*() const { return Current; }
2037
2038 // This doesn't meet the iterator requirements, but it's convenient
2039 value_type operator->() const { return Current; }
2040
2041 decl_iterator& operator++() {
2042 Current = Current->getNextDeclInContext();
2043 return *this;
2044 }
2045
2046 decl_iterator operator++(int) {
2047 decl_iterator tmp(*this);
2048 ++(*this);
2049 return tmp;
2050 }
2051
2052 friend bool operator==(decl_iterator x, decl_iterator y) {
2053 return x.Current == y.Current;
2054 }
2055
2056 friend bool operator!=(decl_iterator x, decl_iterator y) {
2057 return x.Current != y.Current;
2058 }
2059 };
2060
2061 using decl_range = llvm::iterator_range<decl_iterator>;
2062
2063 /// decls_begin/decls_end - Iterate over the declarations stored in
2064 /// this context.
2065 decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
2066 decl_iterator decls_begin() const;
2067 decl_iterator decls_end() const { return decl_iterator(); }
2068 bool decls_empty() const;
2069
2070 /// noload_decls_begin/end - Iterate over the declarations stored in this
2071 /// context that are currently loaded; don't attempt to retrieve anything
2072 /// from an external source.
2073 decl_range noload_decls() const {
2074 return decl_range(noload_decls_begin(), noload_decls_end());
2075 }
2076 decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
2077 decl_iterator noload_decls_end() const { return decl_iterator(); }
2078
2079 /// specific_decl_iterator - Iterates over a subrange of
2080 /// declarations stored in a DeclContext, providing only those that
2081 /// are of type SpecificDecl (or a class derived from it). This
2082 /// iterator is used, for example, to provide iteration over just
2083 /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
2084 template<typename SpecificDecl>
2085 class specific_decl_iterator {
2086 /// Current - The current, underlying declaration iterator, which
2087 /// will either be NULL or will point to a declaration of
2088 /// type SpecificDecl.
2089 DeclContext::decl_iterator Current;
2090
2091 /// SkipToNextDecl - Advances the current position up to the next
2092 /// declaration of type SpecificDecl that also meets the criteria
2093 /// required by Acceptable.
2094 void SkipToNextDecl() {
2095 while (*Current && !isa<SpecificDecl>(*Current))
2096 ++Current;
2097 }
2098
2099 public:
2100 using value_type = SpecificDecl *;
2101 // TODO: Add reference and pointer types (with some appropriate proxy type)
2102 // if we ever have a need for them.
2103 using reference = void;
2104 using pointer = void;
2105 using difference_type =
2106 std::iterator_traits<DeclContext::decl_iterator>::difference_type;
2107 using iterator_category = std::forward_iterator_tag;
2108
2109 specific_decl_iterator() = default;
2110
2111 /// specific_decl_iterator - Construct a new iterator over a
2112 /// subset of the declarations the range [C,
2113 /// end-of-declarations). If A is non-NULL, it is a pointer to a
2114 /// member function of SpecificDecl that should return true for
2115 /// all of the SpecificDecl instances that will be in the subset
2116 /// of iterators. For example, if you want Objective-C instance
2117 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
2118 /// &ObjCMethodDecl::isInstanceMethod.
2119 explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
2120 SkipToNextDecl();
2121 }
2122
2123 value_type operator*() const { return cast<SpecificDecl>(*Current); }
2124
2125 // This doesn't meet the iterator requirements, but it's convenient
2126 value_type operator->() const { return **this; }
2127
2128 specific_decl_iterator& operator++() {
2129 ++Current;
2130 SkipToNextDecl();
2131 return *this;
2132 }
2133
2134 specific_decl_iterator operator++(int) {
2135 specific_decl_iterator tmp(*this);
2136 ++(*this);
2137 return tmp;
2138 }
2139
2140 friend bool operator==(const specific_decl_iterator& x,
2141 const specific_decl_iterator& y) {
2142 return x.Current == y.Current;
2143 }
2144
2145 friend bool operator!=(const specific_decl_iterator& x,
2146 const specific_decl_iterator& y) {
2147 return x.Current != y.Current;
2148 }
2149 };
2150
2151 /// Iterates over a filtered subrange of declarations stored
2152 /// in a DeclContext.
2153 ///
2154 /// This iterator visits only those declarations that are of type
2155 /// SpecificDecl (or a class derived from it) and that meet some
2156 /// additional run-time criteria. This iterator is used, for
2157 /// example, to provide access to the instance methods within an
2158 /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
2159 /// Acceptable = ObjCMethodDecl::isInstanceMethod).
2160 template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
2161 class filtered_decl_iterator {
2162 /// Current - The current, underlying declaration iterator, which
2163 /// will either be NULL or will point to a declaration of
2164 /// type SpecificDecl.
2165 DeclContext::decl_iterator Current;
2166
2167 /// SkipToNextDecl - Advances the current position up to the next
2168 /// declaration of type SpecificDecl that also meets the criteria
2169 /// required by Acceptable.
2170 void SkipToNextDecl() {
2171 while (*Current &&
2172 (!isa<SpecificDecl>(*Current) ||
2173 (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
2174 ++Current;
2175 }
2176
2177 public:
2178 using value_type = SpecificDecl *;
2179 // TODO: Add reference and pointer types (with some appropriate proxy type)
2180 // if we ever have a need for them.
2181 using reference = void;
2182 using pointer = void;
2183 using difference_type =
2184 std::iterator_traits<DeclContext::decl_iterator>::difference_type;
2185 using iterator_category = std::forward_iterator_tag;
2186
2187 filtered_decl_iterator() = default;
2188
2189 /// filtered_decl_iterator - Construct a new iterator over a
2190 /// subset of the declarations the range [C,
2191 /// end-of-declarations). If A is non-NULL, it is a pointer to a
2192 /// member function of SpecificDecl that should return true for
2193 /// all of the SpecificDecl instances that will be in the subset
2194 /// of iterators. For example, if you want Objective-C instance
2195 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
2196 /// &ObjCMethodDecl::isInstanceMethod.
2197 explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
2198 SkipToNextDecl();
2199 }
2200
2201 value_type operator*() const { return cast<SpecificDecl>(*Current); }
2202 value_type operator->() const { return cast<SpecificDecl>(*Current); }
2203
2204 filtered_decl_iterator& operator++() {
2205 ++Current;
2206 SkipToNextDecl();
2207 return *this;
2208 }
2209
2210 filtered_decl_iterator operator++(int) {
2211 filtered_decl_iterator tmp(*this);
2212 ++(*this);
2213 return tmp;
2214 }
2215
2216 friend bool operator==(const filtered_decl_iterator& x,
2217 const filtered_decl_iterator& y) {
2218 return x.Current == y.Current;
2219 }
2220
2221 friend bool operator!=(const filtered_decl_iterator& x,
2222 const filtered_decl_iterator& y) {
2223 return x.Current != y.Current;
2224 }
2225 };
2226
2227 /// Add the declaration D into this context.
2228 ///
2229 /// This routine should be invoked when the declaration D has first
2230 /// been declared, to place D into the context where it was
2231 /// (lexically) defined. Every declaration must be added to one
2232 /// (and only one!) context, where it can be visited via
2233 /// [decls_begin(), decls_end()). Once a declaration has been added
2234 /// to its lexical context, the corresponding DeclContext owns the
2235 /// declaration.
2236 ///
2237 /// If D is also a NamedDecl, it will be made visible within its
2238 /// semantic context via makeDeclVisibleInContext.
2239 void addDecl(Decl *D);
2240
2241 /// Add the declaration D into this context, but suppress
2242 /// searches for external declarations with the same name.
2243 ///
2244 /// Although analogous in function to addDecl, this removes an
2245 /// important check. This is only useful if the Decl is being
2246 /// added in response to an external search; in all other cases,
2247 /// addDecl() is the right function to use.
2248 /// See the ASTImporter for use cases.
2249 void addDeclInternal(Decl *D);
2250
2251 /// Add the declaration D to this context without modifying
2252 /// any lookup tables.
2253 ///
2254 /// This is useful for some operations in dependent contexts where
2255 /// the semantic context might not be dependent; this basically
2256 /// only happens with friends.
2257 void addHiddenDecl(Decl *D);
2258
2259 /// Removes a declaration from this context.
2260 void removeDecl(Decl *D);
2261
2262 /// Checks whether a declaration is in this context.
2263 bool containsDecl(Decl *D) const;
2264
2265 /// Checks whether a declaration is in this context.
2266 /// This also loads the Decls from the external source before the check.
2267 bool containsDeclAndLoad(Decl *D) const;
2268
2269 using lookup_result = DeclContextLookupResult;
2270 using lookup_iterator = lookup_result::iterator;
2271
2272 /// lookup - Find the declarations (if any) with the given Name in
2273 /// this context. Returns a range of iterators that contains all of
2274 /// the declarations with this name, with object, function, member,
2275 /// and enumerator names preceding any tag name. Note that this
2276 /// routine will not look into parent contexts.
2277 lookup_result lookup(DeclarationName Name) const;
2278
2279 /// Find the declarations with the given name that are visible
2280 /// within this context; don't attempt to retrieve anything from an
2281 /// external source.
2282 lookup_result noload_lookup(DeclarationName Name);
2283
2284 /// A simplistic name lookup mechanism that performs name lookup
2285 /// into this declaration context without consulting the external source.
2286 ///
2287 /// This function should almost never be used, because it subverts the
2288 /// usual relationship between a DeclContext and the external source.
2289 /// See the ASTImporter for the (few, but important) use cases.
2290 ///
2291 /// FIXME: This is very inefficient; replace uses of it with uses of
2292 /// noload_lookup.
2293 void localUncachedLookup(DeclarationName Name,
2294 SmallVectorImpl<NamedDecl *> &Results);
2295
2296 /// Makes a declaration visible within this context.
2297 ///
2298 /// This routine makes the declaration D visible to name lookup
2299 /// within this context and, if this is a transparent context,
2300 /// within its parent contexts up to the first enclosing
2301 /// non-transparent context. Making a declaration visible within a
2302 /// context does not transfer ownership of a declaration, and a
2303 /// declaration can be visible in many contexts that aren't its
2304 /// lexical context.
2305 ///
2306 /// If D is a redeclaration of an existing declaration that is
2307 /// visible from this context, as determined by
2308 /// NamedDecl::declarationReplaces, the previous declaration will be
2309 /// replaced with D.
2310 void makeDeclVisibleInContext(NamedDecl *D);
2311
2312 /// all_lookups_iterator - An iterator that provides a view over the results
2313 /// of looking up every possible name.
2314 class all_lookups_iterator;
2315
2316 using lookups_range = llvm::iterator_range<all_lookups_iterator>;
2317
2318 lookups_range lookups() const;
2319 // Like lookups(), but avoids loading external declarations.
2320 // If PreserveInternalState, avoids building lookup data structures too.
2321 lookups_range noload_lookups(bool PreserveInternalState) const;
2322
2323 /// Iterators over all possible lookups within this context.
2324 all_lookups_iterator lookups_begin() const;
2325 all_lookups_iterator lookups_end() const;
2326
2327 /// Iterators over all possible lookups within this context that are
2328 /// currently loaded; don't attempt to retrieve anything from an external
2329 /// source.
2330 all_lookups_iterator noload_lookups_begin() const;
2331 all_lookups_iterator noload_lookups_end() const;
2332
2333 struct udir_iterator;
2334
2335 using udir_iterator_base =
2336 llvm::iterator_adaptor_base<udir_iterator, lookup_iterator,
2337 std::random_access_iterator_tag,
2338 UsingDirectiveDecl *>;
2339
2340 struct udir_iterator : udir_iterator_base {
2341 udir_iterator(lookup_iterator I) : udir_iterator_base(I) {}
2342
2343 UsingDirectiveDecl *operator*() const;
2344 };
2345
2346 using udir_range = llvm::iterator_range<udir_iterator>;
2347
2348 udir_range using_directives() const;
2349
2350 // These are all defined in DependentDiagnostic.h.
2351 class ddiag_iterator;
2352
2353 using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>;
2354
2355 inline ddiag_range ddiags() const;
2356
2357 // Low-level accessors
2358
2359 /// Mark that there are external lexical declarations that we need
2360 /// to include in our lookup table (and that are not available as external
2361 /// visible lookups). These extra lookup results will be found by walking
2362 /// the lexical declarations of this context. This should be used only if
2363 /// setHasExternalLexicalStorage() has been called on any decl context for
2364 /// which this is the primary context.
2365 void setMustBuildLookupTable() {
2366 assert(this == getPrimaryContext() &&((this == getPrimaryContext() && "should only be called on primary context"
) ? static_cast<void> (0) : __assert_fail ("this == getPrimaryContext() && \"should only be called on primary context\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 2367, __PRETTY_FUNCTION__))
2367 "should only be called on primary context")((this == getPrimaryContext() && "should only be called on primary context"
) ? static_cast<void> (0) : __assert_fail ("this == getPrimaryContext() && \"should only be called on primary context\""
, "/build/llvm-toolchain-snapshot-12~++20200927111121+5811d723998/clang/include/clang/AST/DeclBase.h"
, 2367, __PRETTY_FUNCTION__))
;
2368 DeclContextBits.HasLazyExternalLexicalLookups = true;
2369 }
2370
2371 /// Retrieve the internal representation of the lookup structure.
2372 /// This may omit some names if we are lazily building the structure.
2373 StoredDeclsMap *getLookupPtr() const { return LookupPtr; }
2374
2375 /// Ensure the lookup structure is fully-built and return it.
2376 StoredDeclsMap *buildLookup();
2377
2378 /// Whether this DeclContext has external storage containing
2379 /// additional declarations that are lexically in this context.
2380 bool hasExternalLexicalStorage() const {
2381 return DeclContextBits.ExternalLexicalStorage;
2382 }
2383
2384 /// State whether this DeclContext has external storage for
2385 /// declarations lexically in this context.
2386 void setHasExternalLexicalStorage(bool ES = true) const {
2387 DeclContextBits.ExternalLexicalStorage = ES;
2388 }
2389
2390 /// Whether this DeclContext has external storage containing
2391 /// additional declarations that are visible in this context.
2392 bool hasExternalVisibleStorage() const {
2393 return DeclContextBits.ExternalVisibleStorage;
2394 }
2395
2396 /// State whether this DeclContext has external storage for
2397 /// declarations visible in this context.
2398 void setHasExternalVisibleStorage(bool ES = true) const {
2399 DeclContextBits.ExternalVisibleStorage = ES;
2400 if (ES && LookupPtr)
2401 DeclContextBits.NeedToReconcileExternalVisibleStorage = true;
2402 }
2403
2404 /// Determine whether the given declaration is stored in the list of
2405 /// declarations lexically within this context.
2406 bool isDeclInLexicalTraversal(const Decl *D) const {
2407 return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl ||
2408 D == LastDecl);
2409 }
2410
2411 bool setUseQualifiedLookup(bool use = true) const {
2412 bool old_value = DeclContextBits.UseQualifiedLookup;
2413 DeclContextBits.UseQualifiedLookup = use;
2414 return old_value;
2415 }
2416
2417 bool shouldUseQualifiedLookup() const {
2418 return DeclContextBits.UseQualifiedLookup;
2419 }
2420
2421 static bool classof(const Decl *D);
2422 static bool classof(const DeclContext *D) { return true; }
2423
2424 void dumpDeclContext() const;
2425 void dumpLookups() const;
2426 void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
2427 bool Deserialize = false) const;
2428
2429private:
2430 /// Whether this declaration context has had externally visible
2431 /// storage added since the last lookup. In this case, \c LookupPtr's
2432 /// invariant may not hold and needs to be fixed before we perform
2433 /// another lookup.
2434 bool hasNeedToReconcileExternalVisibleStorage() const {
2435 return DeclContextBits.NeedToReconcileExternalVisibleStorage;
2436 }
2437
2438 /// State that this declaration context has had externally visible
2439 /// storage added since the last lookup. In this case, \c LookupPtr's
2440 /// invariant may not hold and needs to be fixed before we perform
2441 /// another lookup.
2442 void setNeedToReconcileExternalVisibleStorage(bool Need = true) const {
2443 DeclContextBits.NeedToReconcileExternalVisibleStorage = Need;
2444 }
2445
2446 /// If \c true, this context may have local lexical declarations
2447 /// that are missing from the lookup table.
2448 bool hasLazyLocalLexicalLookups() const {
2449 return DeclContextBits.HasLazyLocalLexicalLookups;
2450 }
2451
2452 /// If \c true, this context may have local lexical declarations
2453 /// that are missing from the lookup table.
2454 void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const {
2455 DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL;
2456 }
2457
2458 /// If \c true, the external source may have lexical declarations
2459 /// that are missing from the lookup table.
2460 bool hasLazyExternalLexicalLookups() const {
2461 return DeclContextBits.HasLazyExternalLexicalLookups;
2462 }
2463
2464 /// If \c true, the external source may have lexical declarations
2465 /// that are missing from the lookup table.
2466 void setHasLazyExternalLexicalLookups(bool HasLELL = true) const {
2467 DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
2468 }
2469
2470 void reconcileExternalVisibleStorage() const;
2471 bool LoadLexicalDeclsFromExternalStorage() const;
2472
2473 /// Makes a declaration visible within this context, but
2474 /// suppresses searches for external declarations with the same
2475 /// name.
2476 ///
2477 /// Analogous to makeDeclVisibleInContext, but for the exclusive
2478 /// use of addDeclInternal().
2479 void makeDeclVisibleInContextInternal(NamedDecl *D);
2480
2481 StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
2482
2483 void loadLazyLocalLexicalLookups();
2484 void buildLookupImpl(DeclContext *DCtx, bool Internal);
2485 void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
2486 bool Rediscoverable);
2487 void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal);
2488};
2489
2490inline bool Decl::isTemplateParameter() const {
2491 return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm ||
2492 getKind() == TemplateTemplateParm;
2493}
2494
2495// Specialization selected when ToTy is not a known subclass of DeclContext.
2496template <class ToTy,
2497 bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
2498struct cast_convert_decl_context {
2499 static const ToTy *doit(const DeclContext *Val) {
2500 return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
2501 }
2502
2503 static ToTy *doit(DeclContext *Val) {
2504 return static_cast<ToTy*>(Decl::castFromDeclContext(Val));
2505 }
2506};
2507
2508// Specialization selected when ToTy is a known subclass of DeclContext.
2509template <class ToTy>
2510struct cast_convert_decl_context<ToTy, true> {
2511 static const ToTy *doit(const DeclContext *Val) {
2512 return static_cast<const ToTy*>(Val);
2513 }
2514
2515 static ToTy *doit(DeclContext *Val) {
2516 return static_cast<ToTy*>(Val);
2517 }
2518};
2519
2520} // namespace clang
2521
2522namespace llvm {
2523
2524/// isa<T>(DeclContext*)
2525template <typename To>
2526struct isa_impl<To, ::clang::DeclContext> {
2527 static bool doit(const ::clang::DeclContext &Val) {
2528 return To::classofKind(Val.getDeclKind());
2529 }
2530};
2531
2532/// cast<T>(DeclContext*)
2533template<class ToTy>
2534struct cast_convert_val<ToTy,
2535 const ::clang::DeclContext,const ::clang::DeclContext> {
2536 static const ToTy &doit(const ::clang::DeclContext &Val) {
2537 return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
2538 }
2539};
2540
2541template<class ToTy>
2542struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> {
2543 static ToTy &doit(::clang::DeclContext &Val) {
2544 return *::clang::cast_convert_decl_context<ToTy>::doit(&Val);
2545 }
2546};
2547
2548template<class ToTy>
2549struct cast_convert_val<ToTy,
2550 const ::clang::DeclContext*, const ::clang::DeclContext*> {
2551 static const ToTy *doit(const ::clang::DeclContext *Val) {
2552 return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
2553 }
2554};
2555
2556template<class ToTy>
2557struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> {
2558 static ToTy *doit(::clang::DeclContext *Val) {
2559 return ::clang::cast_convert_decl_context<ToTy>::doit(Val);
2560 }
2561};
2562
2563/// Implement cast_convert_val for Decl -> DeclContext conversions.
2564template<class FromTy>
2565struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
2566 static ::clang::DeclContext &doit(const FromTy &Val) {
2567 return *FromTy::castToDeclContext(&Val);
2568 }
2569};
2570
2571template<class FromTy>
2572struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
2573 static ::clang::DeclContext *doit(const FromTy *Val) {
2574 return FromTy::castToDeclContext(Val);
2575 }
2576};
2577
2578template<class FromTy>
2579struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
2580 static const ::clang::DeclContext &doit(const FromTy &Val) {
2581 return *FromTy::castToDeclContext(&Val);
2582 }
2583};
2584
2585template<class FromTy>
2586struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
2587 static const ::clang::DeclContext *doit(const FromTy *Val) {
2588 return FromTy::castToDeclContext(Val);
2589 }
2590};
2591
2592} // namespace llvm
2593
2594#endif // LLVM_CLANG_AST_DECLBASE_H