Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -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 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.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-10~++20200112100611+7fa5290d5bd/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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-10/lib/clang/10.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-10~++20200112100611+7fa5290d5bd/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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/StmtCXX.h"
22#include "clang/AST/StmtOpenMP.h"
23#include "clang/AST/StmtVisitor.h"
24#include "clang/AST/TypeOrdering.h"
25#include "clang/Basic/OpenMPKinds.h"
26#include "clang/Basic/PartialDiagnostic.h"
27#include "clang/Sema/Initialization.h"
28#include "clang/Sema/Lookup.h"
29#include "clang/Sema/Scope.h"
30#include "clang/Sema/ScopeInfo.h"
31#include "clang/Sema/SemaInternal.h"
32#include "llvm/ADT/IndexedMap.h"
33#include "llvm/ADT/PointerEmbeddedInt.h"
34#include "llvm/Frontend/OpenMP/OMPConstants.h"
35using namespace clang;
36using namespace llvm::omp;
37
38//===----------------------------------------------------------------------===//
39// Stack of data-sharing attributes for variables
40//===----------------------------------------------------------------------===//
41
42static const Expr *checkMapClauseExpressionBase(
43 Sema &SemaRef, Expr *E,
44 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
45 OpenMPClauseKind CKind, bool NoDiagnose);
46
47namespace {
48/// Default data sharing attributes, which can be applied to directive.
49enum DefaultDataSharingAttributes {
50 DSA_unspecified = 0, /// Data sharing attribute not specified.
51 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
52 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
53};
54
55/// Stack for tracking declarations used in OpenMP directives and
56/// clauses and their data-sharing attributes.
57class DSAStackTy {
58public:
59 struct DSAVarData {
60 OpenMPDirectiveKind DKind = OMPD_unknown;
61 OpenMPClauseKind CKind = OMPC_unknown;
62 const Expr *RefExpr = nullptr;
63 DeclRefExpr *PrivateCopy = nullptr;
64 SourceLocation ImplicitDSALoc;
65 DSAVarData() = default;
66 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
67 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
68 SourceLocation ImplicitDSALoc)
69 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
70 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
71 };
72 using OperatorOffsetTy =
73 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
74 using DoacrossDependMapTy =
75 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
76
77private:
78 struct DSAInfo {
79 OpenMPClauseKind Attributes = OMPC_unknown;
80 /// Pointer to a reference expression and a flag which shows that the
81 /// variable is marked as lastprivate(true) or not (false).
82 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
83 DeclRefExpr *PrivateCopy = nullptr;
84 };
85 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
86 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
87 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
88 using LoopControlVariablesMapTy =
89 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
90 /// Struct that associates a component with the clause kind where they are
91 /// found.
92 struct MappedExprComponentTy {
93 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
94 OpenMPClauseKind Kind = OMPC_unknown;
95 };
96 using MappedExprComponentsTy =
97 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
98 using CriticalsWithHintsTy =
99 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
100 struct ReductionData {
101 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
102 SourceRange ReductionRange;
103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104 ReductionData() = default;
105 void set(BinaryOperatorKind BO, SourceRange RR) {
106 ReductionRange = RR;
107 ReductionOp = BO;
108 }
109 void set(const Expr *RefExpr, SourceRange RR) {
110 ReductionRange = RR;
111 ReductionOp = RefExpr;
112 }
113 };
114 using DeclReductionMapTy =
115 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
116 struct DefaultmapInfo {
117 OpenMPDefaultmapClauseModifier ImplicitBehavior =
118 OMPC_DEFAULTMAP_MODIFIER_unknown;
119 SourceLocation SLoc;
120 DefaultmapInfo() = default;
121 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
122 : ImplicitBehavior(M), SLoc(Loc) {}
123 };
124
125 struct SharingMapTy {
126 DeclSAMapTy SharingMap;
127 DeclReductionMapTy ReductionMap;
128 UsedRefMapTy AlignedMap;
129 UsedRefMapTy NontemporalMap;
130 MappedExprComponentsTy MappedExprComponents;
131 LoopControlVariablesMapTy LCVMap;
132 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
133 SourceLocation DefaultAttrLoc;
134 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
135 OpenMPDirectiveKind Directive = OMPD_unknown;
136 DeclarationNameInfo DirectiveName;
137 Scope *CurScope = nullptr;
138 SourceLocation ConstructLoc;
139 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
140 /// get the data (loop counters etc.) about enclosing loop-based construct.
141 /// This data is required during codegen.
142 DoacrossDependMapTy DoacrossDepends;
143 /// First argument (Expr *) contains optional argument of the
144 /// 'ordered' clause, the second one is true if the regions has 'ordered'
145 /// clause, false otherwise.
146 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
147 unsigned AssociatedLoops = 1;
148 bool HasMutipleLoops = false;
149 const Decl *PossiblyLoopCounter = nullptr;
150 bool NowaitRegion = false;
151 bool CancelRegion = false;
152 bool LoopStart = false;
153 bool BodyComplete = false;
154 SourceLocation InnerTeamsRegionLoc;
155 /// Reference to the taskgroup task_reduction reference expression.
156 Expr *TaskgroupReductionRef = nullptr;
157 llvm::DenseSet<QualType> MappedClassesQualTypes;
158 /// List of globals marked as declare target link in this target region
159 /// (isOpenMPTargetExecutionDirective(Directive) == true).
160 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
161 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
162 Scope *CurScope, SourceLocation Loc)
163 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
164 ConstructLoc(Loc) {}
165 SharingMapTy() = default;
166 };
167
168 using StackTy = SmallVector<SharingMapTy, 4>;
169
170 /// Stack of used declaration and their data-sharing attributes.
171 DeclSAMapTy Threadprivates;
172 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
173 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
174 /// true, if check for DSA must be from parent directive, false, if
175 /// from current directive.
176 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
177 Sema &SemaRef;
178 bool ForceCapturing = false;
179 /// true if all the variables in the target executable directives must be
180 /// captured by reference.
181 bool ForceCaptureByReferenceInTargetExecutable = false;
182 CriticalsWithHintsTy Criticals;
183 unsigned IgnoredStackElements = 0;
184
185 /// Iterators over the stack iterate in order from innermost to outermost
186 /// directive.
187 using const_iterator = StackTy::const_reverse_iterator;
188 const_iterator begin() const {
189 return Stack.empty() ? const_iterator()
190 : Stack.back().first.rbegin() + IgnoredStackElements;
191 }
192 const_iterator end() const {
193 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
194 }
195 using iterator = StackTy::reverse_iterator;
196 iterator begin() {
197 return Stack.empty() ? iterator()
198 : Stack.back().first.rbegin() + IgnoredStackElements;
199 }
200 iterator end() {
201 return Stack.empty() ? iterator() : Stack.back().first.rend();
202 }
203
204 // Convenience operations to get at the elements of the stack.
205
206 bool isStackEmpty() const {
207 return Stack.empty() ||
208 Stack.back().second != CurrentNonCapturingFunctionScope ||
209 Stack.back().first.size() <= IgnoredStackElements;
210 }
211 size_t getStackSize() const {
212 return isStackEmpty() ? 0
213 : Stack.back().first.size() - IgnoredStackElements;
214 }
215
216 SharingMapTy *getTopOfStackOrNull() {
217 size_t Size = getStackSize();
218 if (Size == 0)
219 return nullptr;
220 return &Stack.back().first[Size - 1];
221 }
222 const SharingMapTy *getTopOfStackOrNull() const {
223 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
224 }
225 SharingMapTy &getTopOfStack() {
226 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 226, __PRETTY_FUNCTION__))
;
227 return *getTopOfStackOrNull();
228 }
229 const SharingMapTy &getTopOfStack() const {
230 return const_cast<DSAStackTy&>(*this).getTopOfStack();
231 }
232
233 SharingMapTy *getSecondOnStackOrNull() {
234 size_t Size = getStackSize();
235 if (Size <= 1)
236 return nullptr;
237 return &Stack.back().first[Size - 2];
238 }
239 const SharingMapTy *getSecondOnStackOrNull() const {
240 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
241 }
242
243 /// Get the stack element at a certain level (previously returned by
244 /// \c getNestingLevel).
245 ///
246 /// Note that nesting levels count from outermost to innermost, and this is
247 /// the reverse of our iteration order where new inner levels are pushed at
248 /// the front of the stack.
249 SharingMapTy &getStackElemAtLevel(unsigned Level) {
250 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 250, __PRETTY_FUNCTION__))
;
251 return Stack.back().first[Level];
252 }
253 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
254 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
255 }
256
257 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
258
259 /// Checks if the variable is a local for OpenMP region.
260 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
261
262 /// Vector of previously declared requires directives
263 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
264 /// omp_allocator_handle_t type.
265 QualType OMPAllocatorHandleT;
266 /// Expression for the predefined allocators.
267 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
268 nullptr};
269 /// Vector of previously encountered target directives
270 SmallVector<SourceLocation, 2> TargetLocations;
271
272public:
273 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
274
275 /// Sets omp_allocator_handle_t type.
276 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
277 /// Gets omp_allocator_handle_t type.
278 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
279 /// Sets the given default allocator.
280 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
281 Expr *Allocator) {
282 OMPPredefinedAllocators[AllocatorKind] = Allocator;
283 }
284 /// Returns the specified default allocator.
285 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
286 return OMPPredefinedAllocators[AllocatorKind];
287 }
288
289 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
12
Assuming field 'ClauseKindMode' is equal to OMPC_unknown
13
Returning zero, which participates in a condition later
290 OpenMPClauseKind getClauseParsingMode() const {
291 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 291, __PRETTY_FUNCTION__))
;
292 return ClauseKindMode;
293 }
294 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
295
296 bool isBodyComplete() const {
297 const SharingMapTy *Top = getTopOfStackOrNull();
298 return Top && Top->BodyComplete;
299 }
300 void setBodyComplete() {
301 getTopOfStack().BodyComplete = true;
302 }
303
304 bool isForceVarCapturing() const { return ForceCapturing; }
305 void setForceVarCapturing(bool V) { ForceCapturing = V; }
306
307 void setForceCaptureByReferenceInTargetExecutable(bool V) {
308 ForceCaptureByReferenceInTargetExecutable = V;
309 }
310 bool isForceCaptureByReferenceInTargetExecutable() const {
311 return ForceCaptureByReferenceInTargetExecutable;
312 }
313
314 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
315 Scope *CurScope, SourceLocation Loc) {
316 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 317, __PRETTY_FUNCTION__))
317 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 317, __PRETTY_FUNCTION__))
;
318 if (Stack.empty() ||
319 Stack.back().second != CurrentNonCapturingFunctionScope)
320 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
321 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
322 Stack.back().first.back().DefaultAttrLoc = Loc;
323 }
324
325 void pop() {
326 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 327, __PRETTY_FUNCTION__))
327 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 327, __PRETTY_FUNCTION__))
;
328 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 329, __PRETTY_FUNCTION__))
329 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 329, __PRETTY_FUNCTION__))
;
330 Stack.back().first.pop_back();
331 }
332
333 /// RAII object to temporarily leave the scope of a directive when we want to
334 /// logically operate in its parent.
335 class ParentDirectiveScope {
336 DSAStackTy &Self;
337 bool Active;
338 public:
339 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
340 : Self(Self), Active(false) {
341 if (Activate)
342 enable();
343 }
344 ~ParentDirectiveScope() { disable(); }
345 void disable() {
346 if (Active) {
347 --Self.IgnoredStackElements;
348 Active = false;
349 }
350 }
351 void enable() {
352 if (!Active) {
353 ++Self.IgnoredStackElements;
354 Active = true;
355 }
356 }
357 };
358
359 /// Marks that we're started loop parsing.
360 void loopInit() {
361 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 362, __PRETTY_FUNCTION__))
362 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 362, __PRETTY_FUNCTION__))
;
363 getTopOfStack().LoopStart = true;
364 }
365 /// Start capturing of the variables in the loop context.
366 void loopStart() {
367 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 368, __PRETTY_FUNCTION__))
368 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 368, __PRETTY_FUNCTION__))
;
369 getTopOfStack().LoopStart = false;
370 }
371 /// true, if variables are captured, false otherwise.
372 bool isLoopStarted() const {
373 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 374, __PRETTY_FUNCTION__))
374 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 374, __PRETTY_FUNCTION__))
;
375 return !getTopOfStack().LoopStart;
376 }
377 /// Marks (or clears) declaration as possibly loop counter.
378 void resetPossibleLoopCounter(const Decl *D = nullptr) {
379 getTopOfStack().PossiblyLoopCounter =
380 D ? D->getCanonicalDecl() : D;
381 }
382 /// Gets the possible loop counter decl.
383 const Decl *getPossiblyLoopCunter() const {
384 return getTopOfStack().PossiblyLoopCounter;
385 }
386 /// Start new OpenMP region stack in new non-capturing function.
387 void pushFunction() {
388 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 389, __PRETTY_FUNCTION__))
389 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 389, __PRETTY_FUNCTION__))
;
390 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
391 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 391, __PRETTY_FUNCTION__))
;
392 CurrentNonCapturingFunctionScope = CurFnScope;
393 }
394 /// Pop region stack for non-capturing function.
395 void popFunction(const FunctionScopeInfo *OldFSI) {
396 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 397, __PRETTY_FUNCTION__))
397 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 397, __PRETTY_FUNCTION__))
;
398 if (!Stack.empty() && Stack.back().second == OldFSI) {
399 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 399, __PRETTY_FUNCTION__))
;
400 Stack.pop_back();
401 }
402 CurrentNonCapturingFunctionScope = nullptr;
403 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
404 if (!isa<CapturingScopeInfo>(FSI)) {
405 CurrentNonCapturingFunctionScope = FSI;
406 break;
407 }
408 }
409 }
410
411 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
412 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
413 }
414 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
415 getCriticalWithHint(const DeclarationNameInfo &Name) const {
416 auto I = Criticals.find(Name.getAsString());
417 if (I != Criticals.end())
418 return I->second;
419 return std::make_pair(nullptr, llvm::APSInt());
420 }
421 /// If 'aligned' declaration for given variable \a D was not seen yet,
422 /// add it and return NULL; otherwise return previous occurrence's expression
423 /// for diagnostics.
424 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
425 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
426 /// add it and return NULL; otherwise return previous occurrence's expression
427 /// for diagnostics.
428 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
429
430 /// Register specified variable as loop control variable.
431 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
432 /// Check if the specified variable is a loop control variable for
433 /// current region.
434 /// \return The index of the loop control variable in the list of associated
435 /// for-loops (from outer to inner).
436 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
437 /// Check if the specified variable is a loop control variable for
438 /// parent region.
439 /// \return The index of the loop control variable in the list of associated
440 /// for-loops (from outer to inner).
441 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
442 /// Get the loop control variable for the I-th loop (or nullptr) in
443 /// parent directive.
444 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
445
446 /// Adds explicit data sharing attribute to the specified declaration.
447 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
448 DeclRefExpr *PrivateCopy = nullptr);
449
450 /// Adds additional information for the reduction items with the reduction id
451 /// represented as an operator.
452 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
453 BinaryOperatorKind BOK);
454 /// Adds additional information for the reduction items with the reduction id
455 /// represented as reduction identifier.
456 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
457 const Expr *ReductionRef);
458 /// Returns the location and reduction operation from the innermost parent
459 /// region for the given \p D.
460 const DSAVarData
461 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
462 BinaryOperatorKind &BOK,
463 Expr *&TaskgroupDescriptor) const;
464 /// Returns the location and reduction operation from the innermost parent
465 /// region for the given \p D.
466 const DSAVarData
467 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
468 const Expr *&ReductionRef,
469 Expr *&TaskgroupDescriptor) const;
470 /// Return reduction reference expression for the current taskgroup.
471 Expr *getTaskgroupReductionRef() const {
472 assert(getTopOfStack().Directive == OMPD_taskgroup &&((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 474, __PRETTY_FUNCTION__))
473 "taskgroup reference expression requested for non taskgroup "((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 474, __PRETTY_FUNCTION__))
474 "directive.")((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 474, __PRETTY_FUNCTION__))
;
475 return getTopOfStack().TaskgroupReductionRef;
476 }
477 /// Checks if the given \p VD declaration is actually a taskgroup reduction
478 /// descriptor variable at the \p Level of OpenMP regions.
479 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
480 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
481 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
482 ->getDecl() == VD;
483 }
484
485 /// Returns data sharing attributes from top of the stack for the
486 /// specified declaration.
487 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
488 /// Returns data-sharing attributes for the specified declaration.
489 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
490 /// Checks if the specified variables has data-sharing attributes which
491 /// match specified \a CPred predicate in any directive which matches \a DPred
492 /// predicate.
493 const DSAVarData
494 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
495 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
496 bool FromParent) const;
497 /// Checks if the specified variables has data-sharing attributes which
498 /// match specified \a CPred predicate in any innermost directive which
499 /// matches \a DPred predicate.
500 const DSAVarData
501 hasInnermostDSA(ValueDecl *D,
502 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
503 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
504 bool FromParent) const;
505 /// Checks if the specified variables has explicit data-sharing
506 /// attributes which match specified \a CPred predicate at the specified
507 /// OpenMP region.
508 bool hasExplicitDSA(const ValueDecl *D,
509 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
510 unsigned Level, bool NotLastprivate = false) const;
511
512 /// Returns true if the directive at level \Level matches in the
513 /// specified \a DPred predicate.
514 bool hasExplicitDirective(
515 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
516 unsigned Level) const;
517
518 /// Finds a directive which matches specified \a DPred predicate.
519 bool hasDirective(
520 const llvm::function_ref<bool(
521 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
522 DPred,
523 bool FromParent) const;
524
525 /// Returns currently analyzed directive.
526 OpenMPDirectiveKind getCurrentDirective() const {
527 const SharingMapTy *Top = getTopOfStackOrNull();
528 return Top ? Top->Directive : OMPD_unknown;
529 }
530 /// Returns directive kind at specified level.
531 OpenMPDirectiveKind getDirective(unsigned Level) const {
532 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 532, __PRETTY_FUNCTION__))
;
533 return getStackElemAtLevel(Level).Directive;
534 }
535 /// Returns the capture region at the specified level.
536 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
537 unsigned OpenMPCaptureLevel) const {
538 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
539 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
540 return CaptureRegions[OpenMPCaptureLevel];
541 }
542 /// Returns parent directive.
543 OpenMPDirectiveKind getParentDirective() const {
544 const SharingMapTy *Parent = getSecondOnStackOrNull();
545 return Parent ? Parent->Directive : OMPD_unknown;
546 }
547
548 /// Add requires decl to internal vector
549 void addRequiresDecl(OMPRequiresDecl *RD) {
550 RequiresDecls.push_back(RD);
551 }
552
553 /// Checks if the defined 'requires' directive has specified type of clause.
554 template <typename ClauseType>
555 bool hasRequiresDeclWithClause() {
556 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
557 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
558 return isa<ClauseType>(C);
559 });
560 });
561 }
562
563 /// Checks for a duplicate clause amongst previously declared requires
564 /// directives
565 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
566 bool IsDuplicate = false;
567 for (OMPClause *CNew : ClauseList) {
568 for (const OMPRequiresDecl *D : RequiresDecls) {
569 for (const OMPClause *CPrev : D->clauselists()) {
570 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
571 SemaRef.Diag(CNew->getBeginLoc(),
572 diag::err_omp_requires_clause_redeclaration)
573 << getOpenMPClauseName(CNew->getClauseKind());
574 SemaRef.Diag(CPrev->getBeginLoc(),
575 diag::note_omp_requires_previous_clause)
576 << getOpenMPClauseName(CPrev->getClauseKind());
577 IsDuplicate = true;
578 }
579 }
580 }
581 }
582 return IsDuplicate;
583 }
584
585 /// Add location of previously encountered target to internal vector
586 void addTargetDirLocation(SourceLocation LocStart) {
587 TargetLocations.push_back(LocStart);
588 }
589
590 // Return previously encountered target region locations.
591 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
592 return TargetLocations;
593 }
594
595 /// Set default data sharing attribute to none.
596 void setDefaultDSANone(SourceLocation Loc) {
597 getTopOfStack().DefaultAttr = DSA_none;
598 getTopOfStack().DefaultAttrLoc = Loc;
599 }
600 /// Set default data sharing attribute to shared.
601 void setDefaultDSAShared(SourceLocation Loc) {
602 getTopOfStack().DefaultAttr = DSA_shared;
603 getTopOfStack().DefaultAttrLoc = Loc;
604 }
605 /// Set default data mapping attribute to Modifier:Kind
606 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
607 OpenMPDefaultmapClauseKind Kind,
608 SourceLocation Loc) {
609 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
610 DMI.ImplicitBehavior = M;
611 DMI.SLoc = Loc;
612 }
613 /// Check whether the implicit-behavior has been set in defaultmap
614 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
615 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
616 OMPC_DEFAULTMAP_MODIFIER_unknown;
617 }
618
619 DefaultDataSharingAttributes getDefaultDSA() const {
620 return isStackEmpty() ? DSA_unspecified
621 : getTopOfStack().DefaultAttr;
622 }
623 SourceLocation getDefaultDSALocation() const {
624 return isStackEmpty() ? SourceLocation()
625 : getTopOfStack().DefaultAttrLoc;
626 }
627 OpenMPDefaultmapClauseModifier
628 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
629 return isStackEmpty()
630 ? OMPC_DEFAULTMAP_MODIFIER_unknown
631 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
632 }
633 OpenMPDefaultmapClauseModifier
634 getDefaultmapModifierAtLevel(unsigned Level,
635 OpenMPDefaultmapClauseKind Kind) const {
636 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
637 }
638 bool isDefaultmapCapturedByRef(unsigned Level,
639 OpenMPDefaultmapClauseKind Kind) const {
640 OpenMPDefaultmapClauseModifier M =
641 getDefaultmapModifierAtLevel(Level, Kind);
642 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
643 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
644 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
645 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
646 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
647 }
648 return true;
649 }
650 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
651 OpenMPDefaultmapClauseKind Kind) {
652 switch (Kind) {
653 case OMPC_DEFAULTMAP_scalar:
654 case OMPC_DEFAULTMAP_pointer:
655 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
656 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
657 (M == OMPC_DEFAULTMAP_MODIFIER_default);
658 case OMPC_DEFAULTMAP_aggregate:
659 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
660 default:
661 break;
662 }
663 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 663)
;
664 }
665 bool mustBeFirstprivateAtLevel(unsigned Level,
666 OpenMPDefaultmapClauseKind Kind) const {
667 OpenMPDefaultmapClauseModifier M =
668 getDefaultmapModifierAtLevel(Level, Kind);
669 return mustBeFirstprivateBase(M, Kind);
670 }
671 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
672 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
673 return mustBeFirstprivateBase(M, Kind);
674 }
675
676 /// Checks if the specified variable is a threadprivate.
677 bool isThreadPrivate(VarDecl *D) {
678 const DSAVarData DVar = getTopDSA(D, false);
679 return isOpenMPThreadPrivate(DVar.CKind);
680 }
681
682 /// Marks current region as ordered (it has an 'ordered' clause).
683 void setOrderedRegion(bool IsOrdered, const Expr *Param,
684 OMPOrderedClause *Clause) {
685 if (IsOrdered)
686 getTopOfStack().OrderedRegion.emplace(Param, Clause);
687 else
688 getTopOfStack().OrderedRegion.reset();
689 }
690 /// Returns true, if region is ordered (has associated 'ordered' clause),
691 /// false - otherwise.
692 bool isOrderedRegion() const {
693 if (const SharingMapTy *Top = getTopOfStackOrNull())
694 return Top->OrderedRegion.hasValue();
695 return false;
696 }
697 /// Returns optional parameter for the ordered region.
698 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
699 if (const SharingMapTy *Top = getTopOfStackOrNull())
700 if (Top->OrderedRegion.hasValue())
701 return Top->OrderedRegion.getValue();
702 return std::make_pair(nullptr, nullptr);
703 }
704 /// Returns true, if parent region is ordered (has associated
705 /// 'ordered' clause), false - otherwise.
706 bool isParentOrderedRegion() const {
707 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
708 return Parent->OrderedRegion.hasValue();
709 return false;
710 }
711 /// Returns optional parameter for the ordered region.
712 std::pair<const Expr *, OMPOrderedClause *>
713 getParentOrderedRegionParam() const {
714 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
715 if (Parent->OrderedRegion.hasValue())
716 return Parent->OrderedRegion.getValue();
717 return std::make_pair(nullptr, nullptr);
718 }
719 /// Marks current region as nowait (it has a 'nowait' clause).
720 void setNowaitRegion(bool IsNowait = true) {
721 getTopOfStack().NowaitRegion = IsNowait;
722 }
723 /// Returns true, if parent region is nowait (has associated
724 /// 'nowait' clause), false - otherwise.
725 bool isParentNowaitRegion() const {
726 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
727 return Parent->NowaitRegion;
728 return false;
729 }
730 /// Marks parent region as cancel region.
731 void setParentCancelRegion(bool Cancel = true) {
732 if (SharingMapTy *Parent = getSecondOnStackOrNull())
733 Parent->CancelRegion |= Cancel;
734 }
735 /// Return true if current region has inner cancel construct.
736 bool isCancelRegion() const {
737 const SharingMapTy *Top = getTopOfStackOrNull();
738 return Top ? Top->CancelRegion : false;
739 }
740
741 /// Set collapse value for the region.
742 void setAssociatedLoops(unsigned Val) {
743 getTopOfStack().AssociatedLoops = Val;
744 if (Val > 1)
745 getTopOfStack().HasMutipleLoops = true;
746 }
747 /// Return collapse value for region.
748 unsigned getAssociatedLoops() const {
749 const SharingMapTy *Top = getTopOfStackOrNull();
750 return Top ? Top->AssociatedLoops : 0;
751 }
752 /// Returns true if the construct is associated with multiple loops.
753 bool hasMutipleLoops() const {
754 const SharingMapTy *Top = getTopOfStackOrNull();
755 return Top ? Top->HasMutipleLoops : false;
756 }
757
758 /// Marks current target region as one with closely nested teams
759 /// region.
760 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
761 if (SharingMapTy *Parent = getSecondOnStackOrNull())
762 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
763 }
764 /// Returns true, if current region has closely nested teams region.
765 bool hasInnerTeamsRegion() const {
766 return getInnerTeamsRegionLoc().isValid();
767 }
768 /// Returns location of the nested teams region (if any).
769 SourceLocation getInnerTeamsRegionLoc() const {
770 const SharingMapTy *Top = getTopOfStackOrNull();
771 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
772 }
773
774 Scope *getCurScope() const {
775 const SharingMapTy *Top = getTopOfStackOrNull();
776 return Top ? Top->CurScope : nullptr;
777 }
778 SourceLocation getConstructLoc() const {
779 const SharingMapTy *Top = getTopOfStackOrNull();
780 return Top ? Top->ConstructLoc : SourceLocation();
781 }
782
783 /// Do the check specified in \a Check to all component lists and return true
784 /// if any issue is found.
785 bool checkMappableExprComponentListsForDecl(
786 const ValueDecl *VD, bool CurrentRegionOnly,
787 const llvm::function_ref<
788 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
789 OpenMPClauseKind)>
790 Check) const {
791 if (isStackEmpty())
792 return false;
793 auto SI = begin();
794 auto SE = end();
795
796 if (SI == SE)
797 return false;
798
799 if (CurrentRegionOnly)
800 SE = std::next(SI);
801 else
802 std::advance(SI, 1);
803
804 for (; SI != SE; ++SI) {
805 auto MI = SI->MappedExprComponents.find(VD);
806 if (MI != SI->MappedExprComponents.end())
807 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
808 MI->second.Components)
809 if (Check(L, MI->second.Kind))
810 return true;
811 }
812 return false;
813 }
814
815 /// Do the check specified in \a Check to all component lists at a given level
816 /// and return true if any issue is found.
817 bool checkMappableExprComponentListsForDeclAtLevel(
818 const ValueDecl *VD, unsigned Level,
819 const llvm::function_ref<
820 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
821 OpenMPClauseKind)>
822 Check) const {
823 if (getStackSize() <= Level)
824 return false;
825
826 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
827 auto MI = StackElem.MappedExprComponents.find(VD);
828 if (MI != StackElem.MappedExprComponents.end())
829 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
830 MI->second.Components)
831 if (Check(L, MI->second.Kind))
832 return true;
833 return false;
834 }
835
836 /// Create a new mappable expression component list associated with a given
837 /// declaration and initialize it with the provided list of components.
838 void addMappableExpressionComponents(
839 const ValueDecl *VD,
840 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
841 OpenMPClauseKind WhereFoundClauseKind) {
842 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
843 // Create new entry and append the new components there.
844 MEC.Components.resize(MEC.Components.size() + 1);
845 MEC.Components.back().append(Components.begin(), Components.end());
846 MEC.Kind = WhereFoundClauseKind;
847 }
848
849 unsigned getNestingLevel() const {
850 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 850, __PRETTY_FUNCTION__))
;
851 return getStackSize() - 1;
852 }
853 void addDoacrossDependClause(OMPDependClause *C,
854 const OperatorOffsetTy &OpsOffs) {
855 SharingMapTy *Parent = getSecondOnStackOrNull();
856 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 856, __PRETTY_FUNCTION__))
;
857 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
858 }
859 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
860 getDoacrossDependClauses() const {
861 const SharingMapTy &StackElem = getTopOfStack();
862 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
863 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
864 return llvm::make_range(Ref.begin(), Ref.end());
865 }
866 return llvm::make_range(StackElem.DoacrossDepends.end(),
867 StackElem.DoacrossDepends.end());
868 }
869
870 // Store types of classes which have been explicitly mapped
871 void addMappedClassesQualTypes(QualType QT) {
872 SharingMapTy &StackElem = getTopOfStack();
873 StackElem.MappedClassesQualTypes.insert(QT);
874 }
875
876 // Return set of mapped classes types
877 bool isClassPreviouslyMapped(QualType QT) const {
878 const SharingMapTy &StackElem = getTopOfStack();
879 return StackElem.MappedClassesQualTypes.count(QT) != 0;
880 }
881
882 /// Adds global declare target to the parent target region.
883 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
884 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 886, __PRETTY_FUNCTION__))
885 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 886, __PRETTY_FUNCTION__))
886 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 886, __PRETTY_FUNCTION__))
;
887 for (auto &Elem : *this) {
888 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
889 Elem.DeclareTargetLinkVarDecls.push_back(E);
890 return;
891 }
892 }
893 }
894
895 /// Returns the list of globals with declare target link if current directive
896 /// is target.
897 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
898 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 899, __PRETTY_FUNCTION__))
899 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 899, __PRETTY_FUNCTION__))
;
900 return getTopOfStack().DeclareTargetLinkVarDecls;
901 }
902};
903
904bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
905 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
906}
907
908bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
909 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
910 DKind == OMPD_unknown;
911}
912
913} // namespace
914
915static const Expr *getExprAsWritten(const Expr *E) {
916 if (const auto *FE = dyn_cast<FullExpr>(E))
917 E = FE->getSubExpr();
918
919 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
920 E = MTE->getSubExpr();
921
922 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
923 E = Binder->getSubExpr();
924
925 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
926 E = ICE->getSubExprAsWritten();
927 return E->IgnoreParens();
928}
929
930static Expr *getExprAsWritten(Expr *E) {
931 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
932}
933
934static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
935 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
936 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
937 D = ME->getMemberDecl();
938 const auto *VD = dyn_cast<VarDecl>(D);
939 const auto *FD = dyn_cast<FieldDecl>(D);
940 if (VD != nullptr) {
941 VD = VD->getCanonicalDecl();
942 D = VD;
943 } else {
944 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 944, __PRETTY_FUNCTION__))
;
945 FD = FD->getCanonicalDecl();
946 D = FD;
947 }
948 return D;
949}
950
951static ValueDecl *getCanonicalDecl(ValueDecl *D) {
952 return const_cast<ValueDecl *>(
953 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
954}
955
956DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
957 ValueDecl *D) const {
958 D = getCanonicalDecl(D);
959 auto *VD = dyn_cast<VarDecl>(D);
960 const auto *FD = dyn_cast<FieldDecl>(D);
961 DSAVarData DVar;
962 if (Iter == end()) {
963 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
964 // in a region but not in construct]
965 // File-scope or namespace-scope variables referenced in called routines
966 // in the region are shared unless they appear in a threadprivate
967 // directive.
968 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
969 DVar.CKind = OMPC_shared;
970
971 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
972 // in a region but not in construct]
973 // Variables with static storage duration that are declared in called
974 // routines in the region are shared.
975 if (VD && VD->hasGlobalStorage())
976 DVar.CKind = OMPC_shared;
977
978 // Non-static data members are shared by default.
979 if (FD)
980 DVar.CKind = OMPC_shared;
981
982 return DVar;
983 }
984
985 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
986 // in a Construct, C/C++, predetermined, p.1]
987 // Variables with automatic storage duration that are declared in a scope
988 // inside the construct are private.
989 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
990 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
991 DVar.CKind = OMPC_private;
992 return DVar;
993 }
994
995 DVar.DKind = Iter->Directive;
996 // Explicitly specified attributes and local variables with predetermined
997 // attributes.
998 if (Iter->SharingMap.count(D)) {
999 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1000 DVar.RefExpr = Data.RefExpr.getPointer();
1001 DVar.PrivateCopy = Data.PrivateCopy;
1002 DVar.CKind = Data.Attributes;
1003 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1004 return DVar;
1005 }
1006
1007 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1008 // in a Construct, C/C++, implicitly determined, p.1]
1009 // In a parallel or task construct, the data-sharing attributes of these
1010 // variables are determined by the default clause, if present.
1011 switch (Iter->DefaultAttr) {
1012 case DSA_shared:
1013 DVar.CKind = OMPC_shared;
1014 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1015 return DVar;
1016 case DSA_none:
1017 return DVar;
1018 case DSA_unspecified:
1019 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1020 // in a Construct, implicitly determined, p.2]
1021 // In a parallel construct, if no default clause is present, these
1022 // variables are shared.
1023 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1024 if ((isOpenMPParallelDirective(DVar.DKind) &&
1025 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1026 isOpenMPTeamsDirective(DVar.DKind)) {
1027 DVar.CKind = OMPC_shared;
1028 return DVar;
1029 }
1030
1031 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1032 // in a Construct, implicitly determined, p.4]
1033 // In a task construct, if no default clause is present, a variable that in
1034 // the enclosing context is determined to be shared by all implicit tasks
1035 // bound to the current team is shared.
1036 if (isOpenMPTaskingDirective(DVar.DKind)) {
1037 DSAVarData DVarTemp;
1038 const_iterator I = Iter, E = end();
1039 do {
1040 ++I;
1041 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1042 // Referenced in a Construct, implicitly determined, p.6]
1043 // In a task construct, if no default clause is present, a variable
1044 // whose data-sharing attribute is not determined by the rules above is
1045 // firstprivate.
1046 DVarTemp = getDSA(I, D);
1047 if (DVarTemp.CKind != OMPC_shared) {
1048 DVar.RefExpr = nullptr;
1049 DVar.CKind = OMPC_firstprivate;
1050 return DVar;
1051 }
1052 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1053 DVar.CKind =
1054 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1055 return DVar;
1056 }
1057 }
1058 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1059 // in a Construct, implicitly determined, p.3]
1060 // For constructs other than task, if no default clause is present, these
1061 // variables inherit their data-sharing attributes from the enclosing
1062 // context.
1063 return getDSA(++Iter, D);
1064}
1065
1066const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1067 const Expr *NewDE) {
1068 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1068, __PRETTY_FUNCTION__))
;
1069 D = getCanonicalDecl(D);
1070 SharingMapTy &StackElem = getTopOfStack();
1071 auto It = StackElem.AlignedMap.find(D);
1072 if (It == StackElem.AlignedMap.end()) {
1073 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1073, __PRETTY_FUNCTION__))
;
1074 StackElem.AlignedMap[D] = NewDE;
1075 return nullptr;
1076 }
1077 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1077, __PRETTY_FUNCTION__))
;
1078 return It->second;
1079}
1080
1081const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1082 const Expr *NewDE) {
1083 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1083, __PRETTY_FUNCTION__))
;
1084 D = getCanonicalDecl(D);
1085 SharingMapTy &StackElem = getTopOfStack();
1086 auto It = StackElem.NontemporalMap.find(D);
1087 if (It == StackElem.NontemporalMap.end()) {
1088 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1088, __PRETTY_FUNCTION__))
;
1089 StackElem.NontemporalMap[D] = NewDE;
1090 return nullptr;
1091 }
1092 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1092, __PRETTY_FUNCTION__))
;
1093 return It->second;
1094}
1095
1096void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1097 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1097, __PRETTY_FUNCTION__))
;
1098 D = getCanonicalDecl(D);
1099 SharingMapTy &StackElem = getTopOfStack();
1100 StackElem.LCVMap.try_emplace(
1101 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1102}
1103
1104const DSAStackTy::LCDeclInfo
1105DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1106 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1106, __PRETTY_FUNCTION__))
;
16
'?' condition is true
1107 D = getCanonicalDecl(D);
1108 const SharingMapTy &StackElem = getTopOfStack();
1109 auto It = StackElem.LCVMap.find(D);
1110 if (It != StackElem.LCVMap.end())
17
Assuming the condition is true
18
Taking true branch
1111 return It->second;
19
Value assigned to field 'first', which participates in a condition later
1112 return {0, nullptr};
1113}
1114
1115const DSAStackTy::LCDeclInfo
1116DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1117 const SharingMapTy *Parent = getSecondOnStackOrNull();
1118 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1118, __PRETTY_FUNCTION__))
;
1119 D = getCanonicalDecl(D);
1120 auto It = Parent->LCVMap.find(D);
1121 if (It != Parent->LCVMap.end())
1122 return It->second;
1123 return {0, nullptr};
1124}
1125
1126const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1127 const SharingMapTy *Parent = getSecondOnStackOrNull();
1128 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1128, __PRETTY_FUNCTION__))
;
1129 if (Parent->LCVMap.size() < I)
1130 return nullptr;
1131 for (const auto &Pair : Parent->LCVMap)
1132 if (Pair.second.first == I)
1133 return Pair.first;
1134 return nullptr;
1135}
1136
1137void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1138 DeclRefExpr *PrivateCopy) {
1139 D = getCanonicalDecl(D);
1140 if (A == OMPC_threadprivate) {
1141 DSAInfo &Data = Threadprivates[D];
1142 Data.Attributes = A;
1143 Data.RefExpr.setPointer(E);
1144 Data.PrivateCopy = nullptr;
1145 } else {
1146 DSAInfo &Data = getTopOfStack().SharingMap[D];
1147 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1150, __PRETTY_FUNCTION__))
1148 (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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1150, __PRETTY_FUNCTION__))
1149 (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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1150, __PRETTY_FUNCTION__))
1150 (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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1150, __PRETTY_FUNCTION__))
;
1151 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1152 Data.RefExpr.setInt(/*IntVal=*/true);
1153 return;
1154 }
1155 const bool IsLastprivate =
1156 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1157 Data.Attributes = A;
1158 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1159 Data.PrivateCopy = PrivateCopy;
1160 if (PrivateCopy) {
1161 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1162 Data.Attributes = A;
1163 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1164 Data.PrivateCopy = nullptr;
1165 }
1166 }
1167}
1168
1169/// Build a variable declaration for OpenMP loop iteration variable.
1170static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1171 StringRef Name, const AttrVec *Attrs = nullptr,
1172 DeclRefExpr *OrigRef = nullptr) {
1173 DeclContext *DC = SemaRef.CurContext;
1174 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1175 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1176 auto *Decl =
1177 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1178 if (Attrs) {
1179 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1180 I != E; ++I)
1181 Decl->addAttr(*I);
1182 }
1183 Decl->setImplicit();
1184 if (OrigRef) {
1185 Decl->addAttr(
1186 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1187 }
1188 return Decl;
1189}
1190
1191static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1192 SourceLocation Loc,
1193 bool RefersToCapture = false) {
1194 D->setReferenced();
1195 D->markUsed(S.Context);
1196 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1197 SourceLocation(), D, RefersToCapture, Loc, Ty,
1198 VK_LValue);
1199}
1200
1201void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1202 BinaryOperatorKind BOK) {
1203 D = getCanonicalDecl(D);
1204 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1204, __PRETTY_FUNCTION__))
;
1205 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1207, __PRETTY_FUNCTION__))
1206 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1207, __PRETTY_FUNCTION__))
1207 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1207, __PRETTY_FUNCTION__))
;
1208 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1209 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1212, __PRETTY_FUNCTION__))
1210 getTopOfStack().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1212, __PRETTY_FUNCTION__))
1211 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1212, __PRETTY_FUNCTION__))
1212 "items.")((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1212, __PRETTY_FUNCTION__))
;
1213 ReductionData.set(BOK, SR);
1214 Expr *&TaskgroupReductionRef =
1215 getTopOfStack().TaskgroupReductionRef;
1216 if (!TaskgroupReductionRef) {
1217 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1218 SemaRef.Context.VoidPtrTy, ".task_red.");
1219 TaskgroupReductionRef =
1220 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1221 }
1222}
1223
1224void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1225 const Expr *ReductionRef) {
1226 D = getCanonicalDecl(D);
1227 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1227, __PRETTY_FUNCTION__))
;
1228 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1230, __PRETTY_FUNCTION__))
1229 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1230, __PRETTY_FUNCTION__))
1230 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1230, __PRETTY_FUNCTION__))
;
1231 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1232 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1235, __PRETTY_FUNCTION__))
1233 getTopOfStack().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1235, __PRETTY_FUNCTION__))
1234 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1235, __PRETTY_FUNCTION__))
1235 "items.")((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1235, __PRETTY_FUNCTION__))
;
1236 ReductionData.set(ReductionRef, SR);
1237 Expr *&TaskgroupReductionRef =
1238 getTopOfStack().TaskgroupReductionRef;
1239 if (!TaskgroupReductionRef) {
1240 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1241 SemaRef.Context.VoidPtrTy, ".task_red.");
1242 TaskgroupReductionRef =
1243 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1244 }
1245}
1246
1247const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1248 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1249 Expr *&TaskgroupDescriptor) const {
1250 D = getCanonicalDecl(D);
1251 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1251, __PRETTY_FUNCTION__))
;
1252 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1253 const DSAInfo &Data = I->SharingMap.lookup(D);
1254 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1255 continue;
1256 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1257 if (!ReductionData.ReductionOp ||
1258 ReductionData.ReductionOp.is<const Expr *>())
1259 return DSAVarData();
1260 SR = ReductionData.ReductionRange;
1261 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1262 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1264, __PRETTY_FUNCTION__))
1263 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1264, __PRETTY_FUNCTION__))
1264 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1264, __PRETTY_FUNCTION__))
;
1265 TaskgroupDescriptor = I->TaskgroupReductionRef;
1266 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1267 Data.PrivateCopy, I->DefaultAttrLoc);
1268 }
1269 return DSAVarData();
1270}
1271
1272const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1273 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1274 Expr *&TaskgroupDescriptor) const {
1275 D = getCanonicalDecl(D);
1276 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1276, __PRETTY_FUNCTION__))
;
1277 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1278 const DSAInfo &Data = I->SharingMap.lookup(D);
1279 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1280 continue;
1281 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1282 if (!ReductionData.ReductionOp ||
1283 !ReductionData.ReductionOp.is<const Expr *>())
1284 return DSAVarData();
1285 SR = ReductionData.ReductionRange;
1286 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1287 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1289, __PRETTY_FUNCTION__))
1288 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1289, __PRETTY_FUNCTION__))
1289 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1289, __PRETTY_FUNCTION__))
;
1290 TaskgroupDescriptor = I->TaskgroupReductionRef;
1291 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1292 Data.PrivateCopy, I->DefaultAttrLoc);
1293 }
1294 return DSAVarData();
1295}
1296
1297bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1298 D = D->getCanonicalDecl();
1299 for (const_iterator E = end(); I != E; ++I) {
1300 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1301 isOpenMPTargetExecutionDirective(I->Directive)) {
1302 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1303 Scope *CurScope = getCurScope();
1304 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1305 CurScope = CurScope->getParent();
1306 return CurScope != TopScope;
1307 }
1308 }
1309 return false;
1310}
1311
1312static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1313 bool AcceptIfMutable = true,
1314 bool *IsClassType = nullptr) {
1315 ASTContext &Context = SemaRef.getASTContext();
1316 Type = Type.getNonReferenceType().getCanonicalType();
1317 bool IsConstant = Type.isConstant(Context);
1318 Type = Context.getBaseElementType(Type);
1319 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1320 ? Type->getAsCXXRecordDecl()
1321 : nullptr;
1322 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1323 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1324 RD = CTD->getTemplatedDecl();
1325 if (IsClassType)
1326 *IsClassType = RD;
1327 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1328 RD->hasDefinition() && RD->hasMutableFields());
1329}
1330
1331static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1332 QualType Type, OpenMPClauseKind CKind,
1333 SourceLocation ELoc,
1334 bool AcceptIfMutable = true,
1335 bool ListItemNotVar = false) {
1336 ASTContext &Context = SemaRef.getASTContext();
1337 bool IsClassType;
1338 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1339 unsigned Diag = ListItemNotVar
1340 ? diag::err_omp_const_list_item
1341 : IsClassType ? diag::err_omp_const_not_mutable_variable
1342 : diag::err_omp_const_variable;
1343 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1344 if (!ListItemNotVar && D) {
1345 const VarDecl *VD = dyn_cast<VarDecl>(D);
1346 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1347 VarDecl::DeclarationOnly;
1348 SemaRef.Diag(D->getLocation(),
1349 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1350 << D;
1351 }
1352 return true;
1353 }
1354 return false;
1355}
1356
1357const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1358 bool FromParent) {
1359 D = getCanonicalDecl(D);
1360 DSAVarData DVar;
1361
1362 auto *VD = dyn_cast<VarDecl>(D);
1363 auto TI = Threadprivates.find(D);
1364 if (TI != Threadprivates.end()) {
1365 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1366 DVar.CKind = OMPC_threadprivate;
1367 return DVar;
1368 }
1369 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1370 DVar.RefExpr = buildDeclRefExpr(
1371 SemaRef, VD, D->getType().getNonReferenceType(),
1372 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1373 DVar.CKind = OMPC_threadprivate;
1374 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1375 return DVar;
1376 }
1377 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1378 // in a Construct, C/C++, predetermined, p.1]
1379 // Variables appearing in threadprivate directives are threadprivate.
1380 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1381 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1382 SemaRef.getLangOpts().OpenMPUseTLS &&
1383 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1384 (VD && VD->getStorageClass() == SC_Register &&
1385 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1386 DVar.RefExpr = buildDeclRefExpr(
1387 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1388 DVar.CKind = OMPC_threadprivate;
1389 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1390 return DVar;
1391 }
1392 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1393 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1394 !isLoopControlVariable(D).first) {
1395 const_iterator IterTarget =
1396 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1397 return isOpenMPTargetExecutionDirective(Data.Directive);
1398 });
1399 if (IterTarget != end()) {
1400 const_iterator ParentIterTarget = IterTarget + 1;
1401 for (const_iterator Iter = begin();
1402 Iter != ParentIterTarget; ++Iter) {
1403 if (isOpenMPLocal(VD, Iter)) {
1404 DVar.RefExpr =
1405 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1406 D->getLocation());
1407 DVar.CKind = OMPC_threadprivate;
1408 return DVar;
1409 }
1410 }
1411 if (!isClauseParsingMode() || IterTarget != begin()) {
1412 auto DSAIter = IterTarget->SharingMap.find(D);
1413 if (DSAIter != IterTarget->SharingMap.end() &&
1414 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1415 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1416 DVar.CKind = OMPC_threadprivate;
1417 return DVar;
1418 }
1419 const_iterator End = end();
1420 if (!SemaRef.isOpenMPCapturedByRef(
1421 D, std::distance(ParentIterTarget, End),
1422 /*OpenMPCaptureLevel=*/0)) {
1423 DVar.RefExpr =
1424 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1425 IterTarget->ConstructLoc);
1426 DVar.CKind = OMPC_threadprivate;
1427 return DVar;
1428 }
1429 }
1430 }
1431 }
1432
1433 if (isStackEmpty())
1434 // Not in OpenMP execution region and top scope was already checked.
1435 return DVar;
1436
1437 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1438 // in a Construct, C/C++, predetermined, p.4]
1439 // Static data members are shared.
1440 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1441 // in a Construct, C/C++, predetermined, p.7]
1442 // Variables with static storage duration that are declared in a scope
1443 // inside the construct are shared.
1444 if (VD && VD->isStaticDataMember()) {
1445 // Check for explicitly specified attributes.
1446 const_iterator I = begin();
1447 const_iterator EndI = end();
1448 if (FromParent && I != EndI)
1449 ++I;
1450 auto It = I->SharingMap.find(D);
1451 if (It != I->SharingMap.end()) {
1452 const DSAInfo &Data = It->getSecond();
1453 DVar.RefExpr = Data.RefExpr.getPointer();
1454 DVar.PrivateCopy = Data.PrivateCopy;
1455 DVar.CKind = Data.Attributes;
1456 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1457 DVar.DKind = I->Directive;
1458 return DVar;
1459 }
1460
1461 DVar.CKind = OMPC_shared;
1462 return DVar;
1463 }
1464
1465 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1466 // The predetermined shared attribute for const-qualified types having no
1467 // mutable members was removed after OpenMP 3.1.
1468 if (SemaRef.LangOpts.OpenMP <= 31) {
1469 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1470 // in a Construct, C/C++, predetermined, p.6]
1471 // Variables with const qualified type having no mutable member are
1472 // shared.
1473 if (isConstNotMutableType(SemaRef, D->getType())) {
1474 // Variables with const-qualified type having no mutable member may be
1475 // listed in a firstprivate clause, even if they are static data members.
1476 DSAVarData DVarTemp = hasInnermostDSA(
1477 D,
1478 [](OpenMPClauseKind C) {
1479 return C == OMPC_firstprivate || C == OMPC_shared;
1480 },
1481 MatchesAlways, FromParent);
1482 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1483 return DVarTemp;
1484
1485 DVar.CKind = OMPC_shared;
1486 return DVar;
1487 }
1488 }
1489
1490 // Explicitly specified attributes and local variables with predetermined
1491 // attributes.
1492 const_iterator I = begin();
1493 const_iterator EndI = end();
1494 if (FromParent && I != EndI)
1495 ++I;
1496 auto It = I->SharingMap.find(D);
1497 if (It != I->SharingMap.end()) {
1498 const DSAInfo &Data = It->getSecond();
1499 DVar.RefExpr = Data.RefExpr.getPointer();
1500 DVar.PrivateCopy = Data.PrivateCopy;
1501 DVar.CKind = Data.Attributes;
1502 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1503 DVar.DKind = I->Directive;
1504 }
1505
1506 return DVar;
1507}
1508
1509const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1510 bool FromParent) const {
1511 if (isStackEmpty()) {
1512 const_iterator I;
1513 return getDSA(I, D);
1514 }
1515 D = getCanonicalDecl(D);
1516 const_iterator StartI = begin();
1517 const_iterator EndI = end();
1518 if (FromParent && StartI != EndI)
1519 ++StartI;
1520 return getDSA(StartI, D);
1521}
1522
1523const DSAStackTy::DSAVarData
1524DSAStackTy::hasDSA(ValueDecl *D,
1525 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1526 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1527 bool FromParent) const {
1528 if (isStackEmpty())
1529 return {};
1530 D = getCanonicalDecl(D);
1531 const_iterator I = begin();
1532 const_iterator EndI = end();
1533 if (FromParent && I != EndI)
1534 ++I;
1535 for (; I != EndI; ++I) {
1536 if (!DPred(I->Directive) &&
1537 !isImplicitOrExplicitTaskingRegion(I->Directive))
1538 continue;
1539 const_iterator NewI = I;
1540 DSAVarData DVar = getDSA(NewI, D);
1541 if (I == NewI && CPred(DVar.CKind))
1542 return DVar;
1543 }
1544 return {};
1545}
1546
1547const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1548 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1549 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1550 bool FromParent) const {
1551 if (isStackEmpty())
1552 return {};
1553 D = getCanonicalDecl(D);
1554 const_iterator StartI = begin();
1555 const_iterator EndI = end();
1556 if (FromParent && StartI != EndI)
1557 ++StartI;
1558 if (StartI == EndI || !DPred(StartI->Directive))
1559 return {};
1560 const_iterator NewI = StartI;
1561 DSAVarData DVar = getDSA(NewI, D);
1562 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1563}
1564
1565bool DSAStackTy::hasExplicitDSA(
1566 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1567 unsigned Level, bool NotLastprivate) const {
1568 if (getStackSize() <= Level)
1569 return false;
1570 D = getCanonicalDecl(D);
1571 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1572 auto I = StackElem.SharingMap.find(D);
1573 if (I != StackElem.SharingMap.end() &&
1574 I->getSecond().RefExpr.getPointer() &&
1575 CPred(I->getSecond().Attributes) &&
1576 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1577 return true;
1578 // Check predetermined rules for the loop control variables.
1579 auto LI = StackElem.LCVMap.find(D);
1580 if (LI != StackElem.LCVMap.end())
1581 return CPred(OMPC_private);
1582 return false;
1583}
1584
1585bool DSAStackTy::hasExplicitDirective(
1586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1587 unsigned Level) const {
1588 if (getStackSize() <= Level)
1589 return false;
1590 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1591 return DPred(StackElem.Directive);
1592}
1593
1594bool DSAStackTy::hasDirective(
1595 const llvm::function_ref<bool(OpenMPDirectiveKind,
1596 const DeclarationNameInfo &, SourceLocation)>
1597 DPred,
1598 bool FromParent) const {
1599 // We look only in the enclosing region.
1600 size_t Skip = FromParent ? 2 : 1;
1601 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1602 I != E; ++I) {
1603 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1604 return true;
1605 }
1606 return false;
1607}
1608
1609void Sema::InitDataSharingAttributesStack() {
1610 VarDataSharingAttributesStack = new DSAStackTy(*this);
1611}
1612
1613#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1614
1615void Sema::pushOpenMPFunctionRegion() {
1616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1617}
1618
1619void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1620 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1621}
1622
1623static bool isOpenMPDeviceDelayedContext(Sema &S) {
1624 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1625, __PRETTY_FUNCTION__))
1625 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1625, __PRETTY_FUNCTION__))
;
1626 return !S.isInOpenMPTargetExecutionDirective() &&
1627 !S.isInOpenMPDeclareTargetContext();
1628}
1629
1630namespace {
1631/// Status of the function emission on the host/device.
1632enum class FunctionEmissionStatus {
1633 Emitted,
1634 Discarded,
1635 Unknown,
1636};
1637} // anonymous namespace
1638
1639Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1640 unsigned DiagID) {
1641 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1642, __PRETTY_FUNCTION__))
1642 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1642, __PRETTY_FUNCTION__))
;
1643 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1644 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1645 switch (FES) {
1646 case FunctionEmissionStatus::Emitted:
1647 Kind = DeviceDiagBuilder::K_Immediate;
1648 break;
1649 case FunctionEmissionStatus::Unknown:
1650 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred
1651 : DeviceDiagBuilder::K_Immediate;
1652 break;
1653 case FunctionEmissionStatus::TemplateDiscarded:
1654 case FunctionEmissionStatus::OMPDiscarded:
1655 Kind = DeviceDiagBuilder::K_Nop;
1656 break;
1657 case FunctionEmissionStatus::CUDADiscarded:
1658 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1658)
;
1659 break;
1660 }
1661
1662 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1663}
1664
1665Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1666 unsigned DiagID) {
1667 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1668, __PRETTY_FUNCTION__))
1668 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1668, __PRETTY_FUNCTION__))
;
1669 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1670 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1671 switch (FES) {
1672 case FunctionEmissionStatus::Emitted:
1673 Kind = DeviceDiagBuilder::K_Immediate;
1674 break;
1675 case FunctionEmissionStatus::Unknown:
1676 Kind = DeviceDiagBuilder::K_Deferred;
1677 break;
1678 case FunctionEmissionStatus::TemplateDiscarded:
1679 case FunctionEmissionStatus::OMPDiscarded:
1680 case FunctionEmissionStatus::CUDADiscarded:
1681 Kind = DeviceDiagBuilder::K_Nop;
1682 break;
1683 }
1684
1685 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1686}
1687
1688void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
1689 bool CheckForDelayedContext) {
1690 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1691, __PRETTY_FUNCTION__))
1691 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1691, __PRETTY_FUNCTION__))
;
1692 assert(Callee && "Callee may not be null.")((Callee && "Callee may not be null.") ? static_cast<
void> (0) : __assert_fail ("Callee && \"Callee may not be null.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1692, __PRETTY_FUNCTION__))
;
1693 Callee = Callee->getMostRecentDecl();
1694 FunctionDecl *Caller = getCurFunctionDecl();
1695
1696 // host only function are not available on the device.
1697 if (Caller) {
1698 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1699 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1700 assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1702, __PRETTY_FUNCTION__))
1701 CalleeS != FunctionEmissionStatus::CUDADiscarded &&((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1702, __PRETTY_FUNCTION__))
1702 "CUDADiscarded unexpected in OpenMP device function check")((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1702, __PRETTY_FUNCTION__))
;
1703 if ((CallerS == FunctionEmissionStatus::Emitted ||
1704 (!isOpenMPDeviceDelayedContext(*this) &&
1705 CallerS == FunctionEmissionStatus::Unknown)) &&
1706 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1707 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
1708 OMPC_device_type, OMPC_DEVICE_TYPE_host);
1709 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1710 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1711 diag::note_omp_marked_device_type_here)
1712 << HostDevTy;
1713 return;
1714 }
1715 }
1716 // If the caller is known-emitted, mark the callee as known-emitted.
1717 // Otherwise, mark the call in our call graph so we can traverse it later.
1718 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
1719 (!Caller && !CheckForDelayedContext) ||
1720 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1721 markKnownEmitted(*this, Caller, Callee, Loc,
1722 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
1723 return CheckForDelayedContext &&
1724 S.getEmissionStatus(FD) ==
1725 FunctionEmissionStatus::Emitted;
1726 });
1727 else if (Caller)
1728 DeviceCallGraph[Caller].insert({Callee, Loc});
1729}
1730
1731void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
1732 bool CheckCaller) {
1733 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1734, __PRETTY_FUNCTION__))
1734 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1734, __PRETTY_FUNCTION__))
;
1735 assert(Callee && "Callee may not be null.")((Callee && "Callee may not be null.") ? static_cast<
void> (0) : __assert_fail ("Callee && \"Callee may not be null.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1735, __PRETTY_FUNCTION__))
;
1736 Callee = Callee->getMostRecentDecl();
1737 FunctionDecl *Caller = getCurFunctionDecl();
1738
1739 // device only function are not available on the host.
1740 if (Caller) {
1741 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1742 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1743 assert((((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1746, __PRETTY_FUNCTION__))
1744 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1746, __PRETTY_FUNCTION__))
1745 CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1746, __PRETTY_FUNCTION__))
1746 "CUDADiscarded unexpected in OpenMP host function check")(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1746, __PRETTY_FUNCTION__))
;
1747 if (CallerS == FunctionEmissionStatus::Emitted &&
1748 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1749 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
1750 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
1751 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1752 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1753 diag::note_omp_marked_device_type_here)
1754 << NoHostDevTy;
1755 return;
1756 }
1757 }
1758 // If the caller is known-emitted, mark the callee as known-emitted.
1759 // Otherwise, mark the call in our call graph so we can traverse it later.
1760 if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1761 if ((!CheckCaller && !Caller) ||
1762 (Caller &&
1763 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1764 markKnownEmitted(
1765 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) {
1766 return CheckCaller &&
1767 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted;
1768 });
1769 else if (Caller)
1770 DeviceCallGraph[Caller].insert({Callee, Loc});
1771 }
1772}
1773
1774void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1775 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice
&& "OpenMP device compilation mode is expected.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1776, __PRETTY_FUNCTION__))
1776 "OpenMP device compilation mode is expected.")((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice
&& "OpenMP device compilation mode is expected.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1776, __PRETTY_FUNCTION__))
;
1777 QualType Ty = E->getType();
1778 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1779 ((Ty->isFloat128Type() ||
1780 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
1781 !Context.getTargetInfo().hasFloat128Type()) ||
1782 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1783 !Context.getTargetInfo().hasInt128Type()))
1784 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type)
1785 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1786 << Context.getTargetInfo().getTriple().str() << E->getSourceRange();
1787}
1788
1789static OpenMPDefaultmapClauseKind
1790getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1791 if (LO.OpenMP <= 45) {
1792 if (VD->getType().getNonReferenceType()->isScalarType())
1793 return OMPC_DEFAULTMAP_scalar;
1794 return OMPC_DEFAULTMAP_aggregate;
1795 }
1796 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1797 return OMPC_DEFAULTMAP_pointer;
1798 if (VD->getType().getNonReferenceType()->isScalarType())
1799 return OMPC_DEFAULTMAP_scalar;
1800 return OMPC_DEFAULTMAP_aggregate;
1801}
1802
1803bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1804 unsigned OpenMPCaptureLevel) const {
1805 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1805, __PRETTY_FUNCTION__))
;
1806
1807 ASTContext &Ctx = getASTContext();
1808 bool IsByRef = true;
1809
1810 // Find the directive that is associated with the provided scope.
1811 D = cast<ValueDecl>(D->getCanonicalDecl());
1812 QualType Ty = D->getType();
1813
1814 bool IsVariableUsedInMapClause = false;
1815 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1816 // This table summarizes how a given variable should be passed to the device
1817 // given its type and the clauses where it appears. This table is based on
1818 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1819 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1820 //
1821 // =========================================================================
1822 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1823 // | |(tofrom:scalar)| | pvt | | | |
1824 // =========================================================================
1825 // | scl | | | | - | | bycopy|
1826 // | scl | | - | x | - | - | bycopy|
1827 // | scl | | x | - | - | - | null |
1828 // | scl | x | | | - | | byref |
1829 // | scl | x | - | x | - | - | bycopy|
1830 // | scl | x | x | - | - | - | null |
1831 // | scl | | - | - | - | x | byref |
1832 // | scl | x | - | - | - | x | byref |
1833 //
1834 // | agg | n.a. | | | - | | byref |
1835 // | agg | n.a. | - | x | - | - | byref |
1836 // | agg | n.a. | x | - | - | - | null |
1837 // | agg | n.a. | - | - | - | x | byref |
1838 // | agg | n.a. | - | - | - | x[] | byref |
1839 //
1840 // | ptr | n.a. | | | - | | bycopy|
1841 // | ptr | n.a. | - | x | - | - | bycopy|
1842 // | ptr | n.a. | x | - | - | - | null |
1843 // | ptr | n.a. | - | - | - | x | byref |
1844 // | ptr | n.a. | - | - | - | x[] | bycopy|
1845 // | ptr | n.a. | - | - | x | | bycopy|
1846 // | ptr | n.a. | - | - | x | x | bycopy|
1847 // | ptr | n.a. | - | - | x | x[] | bycopy|
1848 // =========================================================================
1849 // Legend:
1850 // scl - scalar
1851 // ptr - pointer
1852 // agg - aggregate
1853 // x - applies
1854 // - - invalid in this combination
1855 // [] - mapped with an array section
1856 // byref - should be mapped by reference
1857 // byval - should be mapped by value
1858 // null - initialize a local variable to null on the device
1859 //
1860 // Observations:
1861 // - All scalar declarations that show up in a map clause have to be passed
1862 // by reference, because they may have been mapped in the enclosing data
1863 // environment.
1864 // - If the scalar value does not fit the size of uintptr, it has to be
1865 // passed by reference, regardless the result in the table above.
1866 // - For pointers mapped by value that have either an implicit map or an
1867 // array section, the runtime library may pass the NULL value to the
1868 // device instead of the value passed to it by the compiler.
1869
1870 if (Ty->isReferenceType())
1871 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1872
1873 // Locate map clauses and see if the variable being captured is referred to
1874 // in any of those clauses. Here we only care about variables, not fields,
1875 // because fields are part of aggregates.
1876 bool IsVariableAssociatedWithSection = false;
1877
1878 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1879 D, Level,
1880 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1881 OMPClauseMappableExprCommon::MappableExprComponentListRef
1882 MapExprComponents,
1883 OpenMPClauseKind WhereFoundClauseKind) {
1884 // Only the map clause information influences how a variable is
1885 // captured. E.g. is_device_ptr does not require changing the default
1886 // behavior.
1887 if (WhereFoundClauseKind != OMPC_map)
1888 return false;
1889
1890 auto EI = MapExprComponents.rbegin();
1891 auto EE = MapExprComponents.rend();
1892
1893 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1893, __PRETTY_FUNCTION__))
;
1894
1895 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1896 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1897
1898 ++EI;
1899 if (EI == EE)
1900 return false;
1901
1902 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1903 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1904 isa<MemberExpr>(EI->getAssociatedExpression())) {
1905 IsVariableAssociatedWithSection = true;
1906 // There is nothing more we need to know about this variable.
1907 return true;
1908 }
1909
1910 // Keep looking for more map info.
1911 return false;
1912 });
1913
1914 if (IsVariableUsedInMapClause) {
1915 // If variable is identified in a map clause it is always captured by
1916 // reference except if it is a pointer that is dereferenced somehow.
1917 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1918 } else {
1919 // By default, all the data that has a scalar type is mapped by copy
1920 // (except for reduction variables).
1921 // Defaultmap scalar is mutual exclusive to defaultmap pointer
1922 IsByRef =
1923 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
1924 !Ty->isAnyPointerType()) ||
1925 !Ty->isScalarType() ||
1926 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
1927 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
1928 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1929 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1930 }
1931 }
1932
1933 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1934 IsByRef =
1935 ((IsVariableUsedInMapClause &&
1936 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1937 OMPD_target) ||
1938 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1939 D,
1940 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1941 Level, /*NotLastprivate=*/true)) &&
1942 // If the variable is artificial and must be captured by value - try to
1943 // capture by value.
1944 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1945 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1946 }
1947
1948 // When passing data by copy, we need to make sure it fits the uintptr size
1949 // and alignment, because the runtime library only deals with uintptr types.
1950 // If it does not fit the uintptr size, we need to pass the data by reference
1951 // instead.
1952 if (!IsByRef &&
1953 (Ctx.getTypeSizeInChars(Ty) >
1954 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1955 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1956 IsByRef = true;
1957 }
1958
1959 return IsByRef;
1960}
1961
1962unsigned Sema::getOpenMPNestingLevel() const {
1963 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1963, __PRETTY_FUNCTION__))
;
1964 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
1965}
1966
1967bool Sema::isInOpenMPTargetExecutionDirective() const {
1968 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
1969 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
1970 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
1971 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1972 SourceLocation) -> bool {
1973 return isOpenMPTargetExecutionDirective(K);
1974 },
1975 false);
1976}
1977
1978VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
1979 unsigned StopAt) {
1980 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 1980, __PRETTY_FUNCTION__))
;
6
Assuming field 'OpenMP' is not equal to 0
7
'?' condition is true
1981 D = getCanonicalDecl(D);
1982
1983 auto *VD = dyn_cast<VarDecl>(D);
8
Assuming 'D' is not a 'VarDecl'
1984 // Do not capture constexpr variables.
1985 if (VD
8.1
'VD' is null
&& VD->isConstexpr())
1986 return nullptr;
1987
1988 // If we want to determine whether the variable should be captured from the
1989 // perspective of the current capturing scope, and we've already left all the
1990 // capturing scopes of the top directive on the stack, check from the
1991 // perspective of its parent directive (if any) instead.
1992 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1993 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo
8.2
'CheckScopeInfo' is false
&& DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
1994
1995 // If we are attempting to capture a global variable in a directive with
1996 // 'target' we return true so that this global is also mapped to the device.
1997 //
1998 if (VD
8.3
'VD' is null
&& !VD->hasLocalStorage() &&
1999 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2000 if (isInOpenMPDeclareTargetContext()) {
2001 // Try to mark variable as declare target if it is used in capturing
2002 // regions.
2003 if (LangOpts.OpenMP <= 45 &&
2004 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2005 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2006 return nullptr;
2007 } else if (isInOpenMPTargetExecutionDirective()) {
2008 // If the declaration is enclosed in a 'declare target' directive,
2009 // then it should not be captured.
2010 //
2011 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2012 return nullptr;
2013 return VD;
2014 }
2015 }
2016
2017 if (CheckScopeInfo
8.4
'CheckScopeInfo' is false
) {
9
Taking false branch
2018 bool OpenMPFound = false;
2019 for (unsigned I = StopAt + 1; I > 0; --I) {
2020 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2021 if(!isa<CapturingScopeInfo>(FSI))
2022 return nullptr;
2023 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2024 if (RSI->CapRegionKind == CR_OpenMP) {
2025 OpenMPFound = true;
2026 break;
2027 }
2028 }
2029 if (!OpenMPFound)
2030 return nullptr;
2031 }
2032
2033 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown
&&
10
Assuming the condition is true
2034 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()
||
11
Calling 'DSAStackTy::isClauseParsingMode'
14
Returning from 'DSAStackTy::isClauseParsingMode'
2035 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2036 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D)
;
15
Calling 'DSAStackTy::isLoopControlVariable'
20
Returning from 'DSAStackTy::isLoopControlVariable'
2037 if (Info.first ||
21
Assuming field 'first' is 0
2038 (VD
21.1
'VD' is null
&& VD->hasLocalStorage() &&
2039 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2040 (VD
21.2
'VD' is null
&& DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2041 return VD ? VD : Info.second;
2042 DSAStackTy::DSAVarData DVarPrivate =
2043 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2044 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
22
Assuming field 'CKind' is equal to OMPC_unknown
2045 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2046 // Threadprivate variables must not be captured.
2047 if (isOpenMPThreadPrivate(DVarPrivate.CKind))
23
Assuming the condition is false
24
Taking false branch
2048 return nullptr;
2049 // The variable is not private or it is the variable in the directive with
2050 // default(none) clause and not used in any clause.
2051 DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(D, isOpenMPPrivate,
25
Null pointer value stored to 'DVarPrivate.PrivateCopy'
2052 [](OpenMPDirectiveKind) { return true; },
2053 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode())
;
2054 if (DVarPrivate.CKind
25.1
Field 'CKind' is not equal to OMPC_unknown
!= OMPC_unknown ||
2055 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none))
2056 return VD
25.2
'VD' is null
? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
26
'?' condition is false
27
Called C++ object pointer is null
2057 }
2058 return nullptr;
2059}
2060
2061void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2062 unsigned Level) const {
2063 SmallVector<OpenMPDirectiveKind, 4> Regions;
2064 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2065 FunctionScopesIndex -= Regions.size();
2066}
2067
2068void Sema::startOpenMPLoop() {
2069 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2069, __PRETTY_FUNCTION__))
;
2070 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2071 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2072}
2073
2074void Sema::startOpenMPCXXRangeFor() {
2075 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2075, __PRETTY_FUNCTION__))
;
2076 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2077 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2078 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2079 }
2080}
2081
2082bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
2083 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2083, __PRETTY_FUNCTION__))
;
2084 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2085 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2086 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2087 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2088 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2089 return true;
2090 }
2091 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2092 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2093 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2094 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2095 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2096 return true;
2097 }
2098 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2099 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2101 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2102 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2103 return true;
2104 }
2105 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2106 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2107 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2108 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2109 // Consider taskgroup reduction descriptor variable a private to avoid
2110 // possible capture in the region.
2111 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2112 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
2113 Level) &&
2114 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level));
2115}
2116
2117void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2118 unsigned Level) {
2119 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2119, __PRETTY_FUNCTION__))
;
2120 D = getCanonicalDecl(D);
2121 OpenMPClauseKind OMPC = OMPC_unknown;
2122 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2123 const unsigned NewLevel = I - 1;
2124 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
2125 [&OMPC](const OpenMPClauseKind K) {
2126 if (isOpenMPPrivate(K)) {
2127 OMPC = K;
2128 return true;
2129 }
2130 return false;
2131 },
2132 NewLevel))
2133 break;
2134 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2135 D, NewLevel,
2136 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2137 OpenMPClauseKind) { return true; })) {
2138 OMPC = OMPC_map;
2139 break;
2140 }
2141 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2142 NewLevel)) {
2143 OMPC = OMPC_map;
2144 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2145 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2146 OMPC = OMPC_firstprivate;
2147 break;
2148 }
2149 }
2150 if (OMPC != OMPC_unknown)
2151 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2152}
2153
2154bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
2155 unsigned Level) const {
2156 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2156, __PRETTY_FUNCTION__))
;
2157 // Return true if the current level is no longer enclosed in a target region.
2158
2159 const auto *VD = dyn_cast<VarDecl>(D);
2160 return VD && !VD->hasLocalStorage() &&
2161 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2162 Level);
2163}
2164
2165void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2166
2167void Sema::finalizeOpenMPDelayedAnalysis() {
2168 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2168, __PRETTY_FUNCTION__))
;
2169 // Diagnose implicit declare target functions and their callees.
2170 for (const auto &CallerCallees : DeviceCallGraph) {
2171 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2172 OMPDeclareTargetDeclAttr::getDeviceType(
2173 CallerCallees.getFirst()->getMostRecentDecl());
2174 // Ignore host functions during device analyzis.
2175 if (LangOpts.OpenMPIsDevice && DevTy &&
2176 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2177 continue;
2178 // Ignore nohost functions during host analyzis.
2179 if (!LangOpts.OpenMPIsDevice && DevTy &&
2180 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2181 continue;
2182 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation>
2183 &Callee : CallerCallees.getSecond()) {
2184 const FunctionDecl *FD = Callee.first->getMostRecentDecl();
2185 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2186 OMPDeclareTargetDeclAttr::getDeviceType(FD);
2187 if (LangOpts.OpenMPIsDevice && DevTy &&
2188 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2189 // Diagnose host function called during device codegen.
2190 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
2191 OMPC_device_type, OMPC_DEVICE_TYPE_host);
2192 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2193 << HostDevTy << 0;
2194 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2195 diag::note_omp_marked_device_type_here)
2196 << HostDevTy;
2197 continue;
2198 }
2199 if (!LangOpts.OpenMPIsDevice && DevTy &&
2200 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2201 // Diagnose nohost function called during host codegen.
2202 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2203 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2204 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2205 << NoHostDevTy << 1;
2206 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2207 diag::note_omp_marked_device_type_here)
2208 << NoHostDevTy;
2209 continue;
2210 }
2211 }
2212 }
2213}
2214
2215void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2216 const DeclarationNameInfo &DirName,
2217 Scope *CurScope, SourceLocation Loc) {
2218 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2219 PushExpressionEvaluationContext(
2220 ExpressionEvaluationContext::PotentiallyEvaluated);
2221}
2222
2223void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2224 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2225}
2226
2227void Sema::EndOpenMPClause() {
2228 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2229}
2230
2231static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2232 ArrayRef<OMPClause *> Clauses);
2233static std::pair<ValueDecl *, bool>
2234getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2235 SourceRange &ERange, bool AllowArraySection = false);
2236static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2237 bool WithInit);
2238
2239void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2240 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2241 // A variable of class type (or array thereof) that appears in a lastprivate
2242 // clause requires an accessible, unambiguous default constructor for the
2243 // class type, unless the list item is also specified in a firstprivate
2244 // clause.
2245 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2246 for (OMPClause *C : D->clauses()) {
2247 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2248 SmallVector<Expr *, 8> PrivateCopies;
2249 for (Expr *DE : Clause->varlists()) {
2250 if (DE->isValueDependent() || DE->isTypeDependent()) {
2251 PrivateCopies.push_back(nullptr);
2252 continue;
2253 }
2254 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2255 auto *VD = cast<VarDecl>(DRE->getDecl());
2256 QualType Type = VD->getType().getNonReferenceType();
2257 const DSAStackTy::DSAVarData DVar =
2258 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2259 if (DVar.CKind == OMPC_lastprivate) {
2260 // Generate helper private variable and initialize it with the
2261 // default value. The address of the original variable is replaced
2262 // by the address of the new private variable in CodeGen. This new
2263 // variable is not added to IdResolver, so the code in the OpenMP
2264 // region uses original variable for proper diagnostics.
2265 VarDecl *VDPrivate = buildVarDecl(
2266 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2267 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2268 ActOnUninitializedDecl(VDPrivate);
2269 if (VDPrivate->isInvalidDecl()) {
2270 PrivateCopies.push_back(nullptr);
2271 continue;
2272 }
2273 PrivateCopies.push_back(buildDeclRefExpr(
2274 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2275 } else {
2276 // The variable is also a firstprivate, so initialization sequence
2277 // for private copy is generated already.
2278 PrivateCopies.push_back(nullptr);
2279 }
2280 }
2281 Clause->setPrivateCopies(PrivateCopies);
2282 continue;
2283 }
2284 // Finalize nontemporal clause by handling private copies, if any.
2285 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2286 SmallVector<Expr *, 8> PrivateRefs;
2287 for (Expr *RefExpr : Clause->varlists()) {
2288 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2288, __PRETTY_FUNCTION__))
;
2289 SourceLocation ELoc;
2290 SourceRange ERange;
2291 Expr *SimpleRefExpr = RefExpr;
2292 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2293 if (Res.second)
2294 // It will be analyzed later.
2295 PrivateRefs.push_back(RefExpr);
2296 ValueDecl *D = Res.first;
2297 if (!D)
2298 continue;
2299
2300 const DSAStackTy::DSAVarData DVar =
2301 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2302 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2303 : SimpleRefExpr);
2304 }
2305 Clause->setPrivateRefs(PrivateRefs);
2306 continue;
2307 }
2308 }
2309 // Check allocate clauses.
2310 if (!CurContext->isDependentContext())
2311 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2312 }
2313
2314 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2315 DiscardCleanupsInEvaluationContext();
2316 PopExpressionEvaluationContext();
2317}
2318
2319static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2320 Expr *NumIterations, Sema &SemaRef,
2321 Scope *S, DSAStackTy *Stack);
2322
2323namespace {
2324
2325class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2326private:
2327 Sema &SemaRef;
2328
2329public:
2330 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2331 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2332 NamedDecl *ND = Candidate.getCorrectionDecl();
2333 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2334 return VD->hasGlobalStorage() &&
2335 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2336 SemaRef.getCurScope());
2337 }
2338 return false;
2339 }
2340
2341 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2342 return std::make_unique<VarDeclFilterCCC>(*this);
2343 }
2344
2345};
2346
2347class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2348private:
2349 Sema &SemaRef;
2350
2351public:
2352 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2353 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2354 NamedDecl *ND = Candidate.getCorrectionDecl();
2355 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2356 isa<FunctionDecl>(ND))) {
2357 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2358 SemaRef.getCurScope());
2359 }
2360 return false;
2361 }
2362
2363 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2364 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2365 }
2366};
2367
2368} // namespace
2369
2370ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2371 CXXScopeSpec &ScopeSpec,
2372 const DeclarationNameInfo &Id,
2373 OpenMPDirectiveKind Kind) {
2374 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2375 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2376
2377 if (Lookup.isAmbiguous())
2378 return ExprError();
2379
2380 VarDecl *VD;
2381 if (!Lookup.isSingleResult()) {
2382 VarDeclFilterCCC CCC(*this);
2383 if (TypoCorrection Corrected =
2384 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2385 CTK_ErrorRecovery)) {
2386 diagnoseTypo(Corrected,
2387 PDiag(Lookup.empty()
2388 ? diag::err_undeclared_var_use_suggest
2389 : diag::err_omp_expected_var_arg_suggest)
2390 << Id.getName());
2391 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2392 } else {
2393 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2394 : diag::err_omp_expected_var_arg)
2395 << Id.getName();
2396 return ExprError();
2397 }
2398 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2399 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2400 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2401 return ExprError();
2402 }
2403 Lookup.suppressDiagnostics();
2404
2405 // OpenMP [2.9.2, Syntax, C/C++]
2406 // Variables must be file-scope, namespace-scope, or static block-scope.
2407 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2408 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2409 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2410 bool IsDecl =
2411 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2412 Diag(VD->getLocation(),
2413 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2414 << VD;
2415 return ExprError();
2416 }
2417
2418 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2419 NamedDecl *ND = CanonicalVD;
2420 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2421 // A threadprivate directive for file-scope variables must appear outside
2422 // any definition or declaration.
2423 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2424 !getCurLexicalContext()->isTranslationUnit()) {
2425 Diag(Id.getLoc(), diag::err_omp_var_scope)
2426 << getOpenMPDirectiveName(Kind) << VD;
2427 bool IsDecl =
2428 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2429 Diag(VD->getLocation(),
2430 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2431 << VD;
2432 return ExprError();
2433 }
2434 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2435 // A threadprivate directive for static class member variables must appear
2436 // in the class definition, in the same scope in which the member
2437 // variables are declared.
2438 if (CanonicalVD->isStaticDataMember() &&
2439 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2440 Diag(Id.getLoc(), diag::err_omp_var_scope)
2441 << getOpenMPDirectiveName(Kind) << VD;
2442 bool IsDecl =
2443 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2444 Diag(VD->getLocation(),
2445 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2446 << VD;
2447 return ExprError();
2448 }
2449 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2450 // A threadprivate directive for namespace-scope variables must appear
2451 // outside any definition or declaration other than the namespace
2452 // definition itself.
2453 if (CanonicalVD->getDeclContext()->isNamespace() &&
2454 (!getCurLexicalContext()->isFileContext() ||
2455 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2456 Diag(Id.getLoc(), diag::err_omp_var_scope)
2457 << getOpenMPDirectiveName(Kind) << VD;
2458 bool IsDecl =
2459 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2460 Diag(VD->getLocation(),
2461 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2462 << VD;
2463 return ExprError();
2464 }
2465 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2466 // A threadprivate directive for static block-scope variables must appear
2467 // in the scope of the variable and not in a nested scope.
2468 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2469 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2470 Diag(Id.getLoc(), diag::err_omp_var_scope)
2471 << getOpenMPDirectiveName(Kind) << VD;
2472 bool IsDecl =
2473 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2474 Diag(VD->getLocation(),
2475 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2476 << VD;
2477 return ExprError();
2478 }
2479
2480 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2481 // A threadprivate directive must lexically precede all references to any
2482 // of the variables in its list.
2483 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2484 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2485 Diag(Id.getLoc(), diag::err_omp_var_used)
2486 << getOpenMPDirectiveName(Kind) << VD;
2487 return ExprError();
2488 }
2489
2490 QualType ExprType = VD->getType().getNonReferenceType();
2491 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2492 SourceLocation(), VD,
2493 /*RefersToEnclosingVariableOrCapture=*/false,
2494 Id.getLoc(), ExprType, VK_LValue);
2495}
2496
2497Sema::DeclGroupPtrTy
2498Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2499 ArrayRef<Expr *> VarList) {
2500 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2501 CurContext->addDecl(D);
2502 return DeclGroupPtrTy::make(DeclGroupRef(D));
2503 }
2504 return nullptr;
2505}
2506
2507namespace {
2508class LocalVarRefChecker final
2509 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2510 Sema &SemaRef;
2511
2512public:
2513 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2514 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2515 if (VD->hasLocalStorage()) {
2516 SemaRef.Diag(E->getBeginLoc(),
2517 diag::err_omp_local_var_in_threadprivate_init)
2518 << E->getSourceRange();
2519 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2520 << VD << VD->getSourceRange();
2521 return true;
2522 }
2523 }
2524 return false;
2525 }
2526 bool VisitStmt(const Stmt *S) {
2527 for (const Stmt *Child : S->children()) {
2528 if (Child && Visit(Child))
2529 return true;
2530 }
2531 return false;
2532 }
2533 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2534};
2535} // namespace
2536
2537OMPThreadPrivateDecl *
2538Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2539 SmallVector<Expr *, 8> Vars;
2540 for (Expr *RefExpr : VarList) {
2541 auto *DE = cast<DeclRefExpr>(RefExpr);
2542 auto *VD = cast<VarDecl>(DE->getDecl());
2543 SourceLocation ILoc = DE->getExprLoc();
2544
2545 // Mark variable as used.
2546 VD->setReferenced();
2547 VD->markUsed(Context);
2548
2549 QualType QType = VD->getType();
2550 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2551 // It will be analyzed later.
2552 Vars.push_back(DE);
2553 continue;
2554 }
2555
2556 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2557 // A threadprivate variable must not have an incomplete type.
2558 if (RequireCompleteType(ILoc, VD->getType(),
2559 diag::err_omp_threadprivate_incomplete_type)) {
2560 continue;
2561 }
2562
2563 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2564 // A threadprivate variable must not have a reference type.
2565 if (VD->getType()->isReferenceType()) {
2566 Diag(ILoc, diag::err_omp_ref_type_arg)
2567 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2568 bool IsDecl =
2569 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2570 Diag(VD->getLocation(),
2571 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2572 << VD;
2573 continue;
2574 }
2575
2576 // Check if this is a TLS variable. If TLS is not being supported, produce
2577 // the corresponding diagnostic.
2578 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2579 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2580 getLangOpts().OpenMPUseTLS &&
2581 getASTContext().getTargetInfo().isTLSSupported())) ||
2582 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2583 !VD->isLocalVarDecl())) {
2584 Diag(ILoc, diag::err_omp_var_thread_local)
2585 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2586 bool IsDecl =
2587 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2588 Diag(VD->getLocation(),
2589 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2590 << VD;
2591 continue;
2592 }
2593
2594 // Check if initial value of threadprivate variable reference variable with
2595 // local storage (it is not supported by runtime).
2596 if (const Expr *Init = VD->getAnyInitializer()) {
2597 LocalVarRefChecker Checker(*this);
2598 if (Checker.Visit(Init))
2599 continue;
2600 }
2601
2602 Vars.push_back(RefExpr);
2603 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
2604 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2605 Context, SourceRange(Loc, Loc)));
2606 if (ASTMutationListener *ML = Context.getASTMutationListener())
2607 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2608 }
2609 OMPThreadPrivateDecl *D = nullptr;
2610 if (!Vars.empty()) {
2611 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2612 Vars);
2613 D->setAccess(AS_public);
2614 }
2615 return D;
2616}
2617
2618static OMPAllocateDeclAttr::AllocatorTypeTy
2619getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2620 if (!Allocator)
2621 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2622 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2623 Allocator->isInstantiationDependent() ||
2624 Allocator->containsUnexpandedParameterPack())
2625 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2626 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2627 const Expr *AE = Allocator->IgnoreParenImpCasts();
2628 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2629 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2630 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2631 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2632 llvm::FoldingSetNodeID AEId, DAEId;
2633 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2634 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2635 if (AEId == DAEId) {
2636 AllocatorKindRes = AllocatorKind;
2637 break;
2638 }
2639 }
2640 return AllocatorKindRes;
2641}
2642
2643static bool checkPreviousOMPAllocateAttribute(
2644 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2645 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2646 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2647 return false;
2648 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2649 Expr *PrevAllocator = A->getAllocator();
2650 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2651 getAllocatorKind(S, Stack, PrevAllocator);
2652 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2653 if (AllocatorsMatch &&
2654 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2655 Allocator && PrevAllocator) {
2656 const Expr *AE = Allocator->IgnoreParenImpCasts();
2657 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2658 llvm::FoldingSetNodeID AEId, PAEId;
2659 AE->Profile(AEId, S.Context, /*Canonical=*/true);
2660 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2661 AllocatorsMatch = AEId == PAEId;
2662 }
2663 if (!AllocatorsMatch) {
2664 SmallString<256> AllocatorBuffer;
2665 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2666 if (Allocator)
2667 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2668 SmallString<256> PrevAllocatorBuffer;
2669 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2670 if (PrevAllocator)
2671 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2672 S.getPrintingPolicy());
2673
2674 SourceLocation AllocatorLoc =
2675 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2676 SourceRange AllocatorRange =
2677 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2678 SourceLocation PrevAllocatorLoc =
2679 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2680 SourceRange PrevAllocatorRange =
2681 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2682 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2683 << (Allocator ? 1 : 0) << AllocatorStream.str()
2684 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2685 << AllocatorRange;
2686 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2687 << PrevAllocatorRange;
2688 return true;
2689 }
2690 return false;
2691}
2692
2693static void
2694applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
2695 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2696 Expr *Allocator, SourceRange SR) {
2697 if (VD->hasAttr<OMPAllocateDeclAttr>())
2698 return;
2699 if (Allocator &&
2700 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2701 Allocator->isInstantiationDependent() ||
2702 Allocator->containsUnexpandedParameterPack()))
2703 return;
2704 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2705 Allocator, SR);
2706 VD->addAttr(A);
2707 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
2708 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2709}
2710
2711Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2712 SourceLocation Loc, ArrayRef<Expr *> VarList,
2713 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2714 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2714, __PRETTY_FUNCTION__))
;
2715 Expr *Allocator = nullptr;
2716 if (Clauses.empty()) {
2717 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2718 // allocate directives that appear in a target region must specify an
2719 // allocator clause unless a requires directive with the dynamic_allocators
2720 // clause is present in the same compilation unit.
2721 if (LangOpts.OpenMPIsDevice &&
2722 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
2723 targetDiag(Loc, diag::err_expected_allocator_clause);
2724 } else {
2725 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2726 }
2727 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2728 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
2729 SmallVector<Expr *, 8> Vars;
2730 for (Expr *RefExpr : VarList) {
2731 auto *DE = cast<DeclRefExpr>(RefExpr);
2732 auto *VD = cast<VarDecl>(DE->getDecl());
2733
2734 // Check if this is a TLS variable or global register.
2735 if (VD->getTLSKind() != VarDecl::TLS_None ||
2736 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2737 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2738 !VD->isLocalVarDecl()))
2739 continue;
2740
2741 // If the used several times in the allocate directive, the same allocator
2742 // must be used.
2743 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
2744 AllocatorKind, Allocator))
2745 continue;
2746
2747 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2748 // If a list item has a static storage type, the allocator expression in the
2749 // allocator clause must be a constant expression that evaluates to one of
2750 // the predefined memory allocator values.
2751 if (Allocator && VD->hasGlobalStorage()) {
2752 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2753 Diag(Allocator->getExprLoc(),
2754 diag::err_omp_expected_predefined_allocator)
2755 << Allocator->getSourceRange();
2756 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2757 VarDecl::DeclarationOnly;
2758 Diag(VD->getLocation(),
2759 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2760 << VD;
2761 continue;
2762 }
2763 }
2764
2765 Vars.push_back(RefExpr);
2766 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2767 DE->getSourceRange());
2768 }
2769 if (Vars.empty())
2770 return nullptr;
2771 if (!Owner)
2772 Owner = getCurLexicalContext();
2773 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
2774 D->setAccess(AS_public);
2775 Owner->addDecl(D);
2776 return DeclGroupPtrTy::make(DeclGroupRef(D));
2777}
2778
2779Sema::DeclGroupPtrTy
2780Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2781 ArrayRef<OMPClause *> ClauseList) {
2782 OMPRequiresDecl *D = nullptr;
2783 if (!CurContext->isFileContext()) {
2784 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2785 } else {
2786 D = CheckOMPRequiresDecl(Loc, ClauseList);
2787 if (D) {
2788 CurContext->addDecl(D);
2789 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
2790 }
2791 }
2792 return DeclGroupPtrTy::make(DeclGroupRef(D));
2793}
2794
2795OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2796 ArrayRef<OMPClause *> ClauseList) {
2797 /// For target specific clauses, the requires directive cannot be
2798 /// specified after the handling of any of the target regions in the
2799 /// current compilation unit.
2800 ArrayRef<SourceLocation> TargetLocations =
2801 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
2802 if (!TargetLocations.empty()) {
2803 for (const OMPClause *CNew : ClauseList) {
2804 // Check if any of the requires clauses affect target regions.
2805 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2806 isa<OMPUnifiedAddressClause>(CNew) ||
2807 isa<OMPReverseOffloadClause>(CNew) ||
2808 isa<OMPDynamicAllocatorsClause>(CNew)) {
2809 Diag(Loc, diag::err_omp_target_before_requires)
2810 << getOpenMPClauseName(CNew->getClauseKind());
2811 for (SourceLocation TargetLoc : TargetLocations) {
2812 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2813 }
2814 }
2815 }
2816 }
2817
2818 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
2819 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2820 ClauseList);
2821 return nullptr;
2822}
2823
2824static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2825 const ValueDecl *D,
2826 const DSAStackTy::DSAVarData &DVar,
2827 bool IsLoopIterVar = false) {
2828 if (DVar.RefExpr) {
2829 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2830 << getOpenMPClauseName(DVar.CKind);
2831 return;
2832 }
2833 enum {
2834 PDSA_StaticMemberShared,
2835 PDSA_StaticLocalVarShared,
2836 PDSA_LoopIterVarPrivate,
2837 PDSA_LoopIterVarLinear,
2838 PDSA_LoopIterVarLastprivate,
2839 PDSA_ConstVarShared,
2840 PDSA_GlobalVarShared,
2841 PDSA_TaskVarFirstprivate,
2842 PDSA_LocalVarPrivate,
2843 PDSA_Implicit
2844 } Reason = PDSA_Implicit;
2845 bool ReportHint = false;
2846 auto ReportLoc = D->getLocation();
2847 auto *VD = dyn_cast<VarDecl>(D);
2848 if (IsLoopIterVar) {
2849 if (DVar.CKind == OMPC_private)
2850 Reason = PDSA_LoopIterVarPrivate;
2851 else if (DVar.CKind == OMPC_lastprivate)
2852 Reason = PDSA_LoopIterVarLastprivate;
2853 else
2854 Reason = PDSA_LoopIterVarLinear;
2855 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2856 DVar.CKind == OMPC_firstprivate) {
2857 Reason = PDSA_TaskVarFirstprivate;
2858 ReportLoc = DVar.ImplicitDSALoc;
2859 } else if (VD && VD->isStaticLocal())
2860 Reason = PDSA_StaticLocalVarShared;
2861 else if (VD && VD->isStaticDataMember())
2862 Reason = PDSA_StaticMemberShared;
2863 else if (VD && VD->isFileVarDecl())
2864 Reason = PDSA_GlobalVarShared;
2865 else if (D->getType().isConstant(SemaRef.getASTContext()))
2866 Reason = PDSA_ConstVarShared;
2867 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2868 ReportHint = true;
2869 Reason = PDSA_LocalVarPrivate;
2870 }
2871 if (Reason != PDSA_Implicit) {
2872 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2873 << Reason << ReportHint
2874 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2875 } else if (DVar.ImplicitDSALoc.isValid()) {
2876 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2877 << getOpenMPClauseName(DVar.CKind);
2878 }
2879}
2880
2881static OpenMPMapClauseKind
2882getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
2883 bool IsAggregateOrDeclareTarget) {
2884 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
2885 switch (M) {
2886 case OMPC_DEFAULTMAP_MODIFIER_alloc:
2887 Kind = OMPC_MAP_alloc;
2888 break;
2889 case OMPC_DEFAULTMAP_MODIFIER_to:
2890 Kind = OMPC_MAP_to;
2891 break;
2892 case OMPC_DEFAULTMAP_MODIFIER_from:
2893 Kind = OMPC_MAP_from;
2894 break;
2895 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
2896 Kind = OMPC_MAP_tofrom;
2897 break;
2898 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
2899 case OMPC_DEFAULTMAP_MODIFIER_last:
2900 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2900)
;
2901 case OMPC_DEFAULTMAP_MODIFIER_none:
2902 case OMPC_DEFAULTMAP_MODIFIER_default:
2903 case OMPC_DEFAULTMAP_MODIFIER_unknown:
2904 // IsAggregateOrDeclareTarget could be true if:
2905 // 1. the implicit behavior for aggregate is tofrom
2906 // 2. it's a declare target link
2907 if (IsAggregateOrDeclareTarget) {
2908 Kind = OMPC_MAP_tofrom;
2909 break;
2910 }
2911 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2911)
;
2912 }
2913 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 2913, __PRETTY_FUNCTION__))
;
2914 return Kind;
2915}
2916
2917namespace {
2918class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2919 DSAStackTy *Stack;
2920 Sema &SemaRef;
2921 bool ErrorFound = false;
2922 bool TryCaptureCXXThisMembers = false;
2923 CapturedStmt *CS = nullptr;
2924 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2925 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
2926 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2927 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2928
2929 void VisitSubCaptures(OMPExecutableDirective *S) {
2930 // Check implicitly captured variables.
2931 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2932 return;
2933 visitSubCaptures(S->getInnermostCapturedStmt());
2934 // Try to capture inner this->member references to generate correct mappings
2935 // and diagnostics.
2936 if (TryCaptureCXXThisMembers ||
2937 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2938 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
2939 [](const CapturedStmt::Capture &C) {
2940 return C.capturesThis();
2941 }))) {
2942 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
2943 TryCaptureCXXThisMembers = true;
2944 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
2945 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
2946 }
2947 }
2948
2949public:
2950 void VisitDeclRefExpr(DeclRefExpr *E) {
2951 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
2952 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
2953 E->isInstantiationDependent())
2954 return;
2955 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2956 // Check the datasharing rules for the expressions in the clauses.
2957 if (!CS) {
2958 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2959 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2960 Visit(CED->getInit());
2961 return;
2962 }
2963 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2964 // Do not analyze internal variables and do not enclose them into
2965 // implicit clauses.
2966 return;
2967 VD = VD->getCanonicalDecl();
2968 // Skip internally declared variables.
2969 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
2970 return;
2971
2972 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2973 // Check if the variable has explicit DSA set and stop analysis if it so.
2974 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2975 return;
2976
2977 // Skip internally declared static variables.
2978 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2979 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2980 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
2981 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
2982 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2983 return;
2984
2985 SourceLocation ELoc = E->getExprLoc();
2986 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2987 // The default(none) clause requires that each variable that is referenced
2988 // in the construct, and does not have a predetermined data-sharing
2989 // attribute, must have its data-sharing attribute explicitly determined
2990 // by being listed in a data-sharing attribute clause.
2991 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2992 isImplicitOrExplicitTaskingRegion(DKind) &&
2993 VarsWithInheritedDSA.count(VD) == 0) {
2994 VarsWithInheritedDSA[VD] = E;
2995 return;
2996 }
2997
2998 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
2999 // If implicit-behavior is none, each variable referenced in the
3000 // construct that does not have a predetermined data-sharing attribute
3001 // and does not appear in a to or link clause on a declare target
3002 // directive must be listed in a data-mapping attribute clause, a
3003 // data-haring attribute clause (including a data-sharing attribute
3004 // clause on a combined construct where target. is one of the
3005 // constituent constructs), or an is_device_ptr clause.
3006 OpenMPDefaultmapClauseKind ClauseKind =
3007 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3008 if (SemaRef.getLangOpts().OpenMP >= 50) {
3009 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3010 OMPC_DEFAULTMAP_MODIFIER_none;
3011 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3012 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3013 // Only check for data-mapping attribute and is_device_ptr here
3014 // since we have already make sure that the declaration does not
3015 // have a data-sharing attribute above
3016 if (!Stack->checkMappableExprComponentListsForDecl(
3017 VD, /*CurrentRegionOnly=*/true,
3018 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3019 MapExprComponents,
3020 OpenMPClauseKind) {
3021 auto MI = MapExprComponents.rbegin();
3022 auto ME = MapExprComponents.rend();
3023 return MI != ME && MI->getAssociatedDeclaration() == VD;
3024 })) {
3025 VarsWithInheritedDSA[VD] = E;
3026 return;
3027 }
3028 }
3029 }
3030
3031 if (isOpenMPTargetExecutionDirective(DKind) &&
3032 !Stack->isLoopControlVariable(VD).first) {
3033 if (!Stack->checkMappableExprComponentListsForDecl(
3034 VD, /*CurrentRegionOnly=*/true,
3035 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3036 StackComponents,
3037 OpenMPClauseKind) {
3038 // Variable is used if it has been marked as an array, array
3039 // section or the variable iself.
3040 return StackComponents.size() == 1 ||
3041 std::all_of(
3042 std::next(StackComponents.rbegin()),
3043 StackComponents.rend(),
3044 [](const OMPClauseMappableExprCommon::
3045 MappableComponent &MC) {
3046 return MC.getAssociatedDeclaration() ==
3047 nullptr &&
3048 (isa<OMPArraySectionExpr>(
3049 MC.getAssociatedExpression()) ||
3050 isa<ArraySubscriptExpr>(
3051 MC.getAssociatedExpression()));
3052 });
3053 })) {
3054 bool IsFirstprivate = false;
3055 // By default lambdas are captured as firstprivates.
3056 if (const auto *RD =
3057 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3058 IsFirstprivate = RD->isLambda();
3059 IsFirstprivate =
3060 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3061 if (IsFirstprivate) {
3062 ImplicitFirstprivate.emplace_back(E);
3063 } else {
3064 OpenMPDefaultmapClauseModifier M =
3065 Stack->getDefaultmapModifier(ClauseKind);
3066 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3067 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3068 ImplicitMap[Kind].emplace_back(E);
3069 }
3070 return;
3071 }
3072 }
3073
3074 // OpenMP [2.9.3.6, Restrictions, p.2]
3075 // A list item that appears in a reduction clause of the innermost
3076 // enclosing worksharing or parallel construct may not be accessed in an
3077 // explicit task.
3078 DVar = Stack->hasInnermostDSA(
3079 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3080 [](OpenMPDirectiveKind K) {
3081 return isOpenMPParallelDirective(K) ||
3082 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3083 },
3084 /*FromParent=*/true);
3085 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3086 ErrorFound = true;
3087 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3088 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3089 return;
3090 }
3091
3092 // Define implicit data-sharing attributes for task.
3093 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3094 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3095 !Stack->isLoopControlVariable(VD).first) {
3096 ImplicitFirstprivate.push_back(E);
3097 return;
3098 }
3099
3100 // Store implicitly used globals with declare target link for parent
3101 // target.
3102 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3103 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3104 Stack->addToParentTargetRegionLinkGlobals(E);
3105 return;
3106 }
3107 }
3108 }
3109 void VisitMemberExpr(MemberExpr *E) {
3110 if (E->isTypeDependent() || E->isValueDependent() ||
3111 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3112 return;
3113 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3114 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3115 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
3116 if (!FD)
3117 return;
3118 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3119 // Check if the variable has explicit DSA set and stop analysis if it
3120 // so.
3121 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3122 return;
3123
3124 if (isOpenMPTargetExecutionDirective(DKind) &&
3125 !Stack->isLoopControlVariable(FD).first &&
3126 !Stack->checkMappableExprComponentListsForDecl(
3127 FD, /*CurrentRegionOnly=*/true,
3128 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3129 StackComponents,
3130 OpenMPClauseKind) {
3131 return isa<CXXThisExpr>(
3132 cast<MemberExpr>(
3133 StackComponents.back().getAssociatedExpression())
3134 ->getBase()
3135 ->IgnoreParens());
3136 })) {
3137 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3138 // A bit-field cannot appear in a map clause.
3139 //
3140 if (FD->isBitField())
3141 return;
3142
3143 // Check to see if the member expression is referencing a class that
3144 // has already been explicitly mapped
3145 if (Stack->isClassPreviouslyMapped(TE->getType()))
3146 return;
3147
3148 OpenMPDefaultmapClauseModifier Modifier =
3149 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3150 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3151 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3152 ImplicitMap[Kind].emplace_back(E);
3153 return;
3154 }
3155
3156 SourceLocation ELoc = E->getExprLoc();
3157 // OpenMP [2.9.3.6, Restrictions, p.2]
3158 // A list item that appears in a reduction clause of the innermost
3159 // enclosing worksharing or parallel construct may not be accessed in
3160 // an explicit task.
3161 DVar = Stack->hasInnermostDSA(
3162 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3163 [](OpenMPDirectiveKind K) {
3164 return isOpenMPParallelDirective(K) ||
3165 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3166 },
3167 /*FromParent=*/true);
3168 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3169 ErrorFound = true;
3170 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3171 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3172 return;
3173 }
3174
3175 // Define implicit data-sharing attributes for task.
3176 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3177 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3178 !Stack->isLoopControlVariable(FD).first) {
3179 // Check if there is a captured expression for the current field in the
3180 // region. Do not mark it as firstprivate unless there is no captured
3181 // expression.
3182 // TODO: try to make it firstprivate.
3183 if (DVar.CKind != OMPC_unknown)
3184 ImplicitFirstprivate.push_back(E);
3185 }
3186 return;
3187 }
3188 if (isOpenMPTargetExecutionDirective(DKind)) {
3189 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3190 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3191 /*NoDiagnose=*/true))
3192 return;
3193 const auto *VD = cast<ValueDecl>(
3194 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3195 if (!Stack->checkMappableExprComponentListsForDecl(
3196 VD, /*CurrentRegionOnly=*/true,
3197 [&CurComponents](
3198 OMPClauseMappableExprCommon::MappableExprComponentListRef
3199 StackComponents,
3200 OpenMPClauseKind) {
3201 auto CCI = CurComponents.rbegin();
3202 auto CCE = CurComponents.rend();
3203 for (const auto &SC : llvm::reverse(StackComponents)) {
3204 // Do both expressions have the same kind?
3205 if (CCI->getAssociatedExpression()->getStmtClass() !=
3206 SC.getAssociatedExpression()->getStmtClass())
3207 if (!(isa<OMPArraySectionExpr>(
3208 SC.getAssociatedExpression()) &&
3209 isa<ArraySubscriptExpr>(
3210 CCI->getAssociatedExpression())))
3211 return false;
3212
3213 const Decl *CCD = CCI->getAssociatedDeclaration();
3214 const Decl *SCD = SC.getAssociatedDeclaration();
3215 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3216 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3217 if (SCD != CCD)
3218 return false;
3219 std::advance(CCI, 1);
3220 if (CCI == CCE)
3221 break;
3222 }
3223 return true;
3224 })) {
3225 Visit(E->getBase());
3226 }
3227 } else if (!TryCaptureCXXThisMembers) {
3228 Visit(E->getBase());
3229 }
3230 }
3231 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3232 for (OMPClause *C : S->clauses()) {
3233 // Skip analysis of arguments of implicitly defined firstprivate clause
3234 // for task|target directives.
3235 // Skip analysis of arguments of implicitly defined map clause for target
3236 // directives.
3237 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3238 C->isImplicit())) {
3239 for (Stmt *CC : C->children()) {
3240 if (CC)
3241 Visit(CC);
3242 }
3243 }
3244 }
3245 // Check implicitly captured variables.
3246 VisitSubCaptures(S);
3247 }
3248 void VisitStmt(Stmt *S) {
3249 for (Stmt *C : S->children()) {
3250 if (C) {
3251 // Check implicitly captured variables in the task-based directives to
3252 // check if they must be firstprivatized.
3253 Visit(C);
3254 }
3255 }
3256 }
3257
3258 void visitSubCaptures(CapturedStmt *S) {
3259 for (const CapturedStmt::Capture &Cap : S->captures()) {
3260 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3261 continue;
3262 VarDecl *VD = Cap.getCapturedVar();
3263 // Do not try to map the variable if it or its sub-component was mapped
3264 // already.
3265 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3266 Stack->checkMappableExprComponentListsForDecl(
3267 VD, /*CurrentRegionOnly=*/true,
3268 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3269 OpenMPClauseKind) { return true; }))
3270 continue;
3271 DeclRefExpr *DRE = buildDeclRefExpr(
3272 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3273 Cap.getLocation(), /*RefersToCapture=*/true);
3274 Visit(DRE);
3275 }
3276 }
3277 bool isErrorFound() const { return ErrorFound; }
3278 ArrayRef<Expr *> getImplicitFirstprivate() const {
3279 return ImplicitFirstprivate;
3280 }
3281 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3282 return ImplicitMap[Kind];
3283 }
3284 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3285 return VarsWithInheritedDSA;
3286 }
3287
3288 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3289 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3290 // Process declare target link variables for the target directives.
3291 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3292 for (DeclRefExpr *E : Stack->getLinkGlobals())
3293 Visit(E);
3294 }
3295 }
3296};
3297} // namespace
3298
3299void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3300 switch (DKind) {
3301 case OMPD_parallel:
3302 case OMPD_parallel_for:
3303 case OMPD_parallel_for_simd:
3304 case OMPD_parallel_sections:
3305 case OMPD_parallel_master:
3306 case OMPD_teams:
3307 case OMPD_teams_distribute:
3308 case OMPD_teams_distribute_simd: {
3309 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3310 QualType KmpInt32PtrTy =
3311 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3312 Sema::CapturedParamNameType Params[] = {
3313 std::make_pair(".global_tid.", KmpInt32PtrTy),
3314 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3315 std::make_pair(StringRef(), QualType()) // __context with shared vars
3316 };
3317 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3318 Params);
3319 break;
3320 }
3321 case OMPD_target_teams:
3322 case OMPD_target_parallel:
3323 case OMPD_target_parallel_for:
3324 case OMPD_target_parallel_for_simd:
3325 case OMPD_target_teams_distribute:
3326 case OMPD_target_teams_distribute_simd: {
3327 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3328 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3329 QualType KmpInt32PtrTy =
3330 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3331 QualType Args[] = {VoidPtrTy};
3332 FunctionProtoType::ExtProtoInfo EPI;
3333 EPI.Variadic = true;
3334 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3335 Sema::CapturedParamNameType Params[] = {
3336 std::make_pair(".global_tid.", KmpInt32Ty),
3337 std::make_pair(".part_id.", KmpInt32PtrTy),
3338 std::make_pair(".privates.", VoidPtrTy),
3339 std::make_pair(
3340 ".copy_fn.",
3341 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3342 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3343 std::make_pair(StringRef(), QualType()) // __context with shared vars
3344 };
3345 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3346 Params, /*OpenMPCaptureLevel=*/0);
3347 // Mark this captured region as inlined, because we don't use outlined
3348 // function directly.
3349 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3350 AlwaysInlineAttr::CreateImplicit(
3351 Context, {}, AttributeCommonInfo::AS_Keyword,
3352 AlwaysInlineAttr::Keyword_forceinline));
3353 Sema::CapturedParamNameType ParamsTarget[] = {
3354 std::make_pair(StringRef(), QualType()) // __context with shared vars
3355 };
3356 // Start a captured region for 'target' with no implicit parameters.
3357 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3358 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3359 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3360 std::make_pair(".global_tid.", KmpInt32PtrTy),
3361 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3362 std::make_pair(StringRef(), QualType()) // __context with shared vars
3363 };
3364 // Start a captured region for 'teams' or 'parallel'. Both regions have
3365 // the same implicit parameters.
3366 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3367 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3368 break;
3369 }
3370 case OMPD_target:
3371 case OMPD_target_simd: {
3372 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3373 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3374 QualType KmpInt32PtrTy =
3375 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3376 QualType Args[] = {VoidPtrTy};
3377 FunctionProtoType::ExtProtoInfo EPI;
3378 EPI.Variadic = true;
3379 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3380 Sema::CapturedParamNameType Params[] = {
3381 std::make_pair(".global_tid.", KmpInt32Ty),
3382 std::make_pair(".part_id.", KmpInt32PtrTy),
3383 std::make_pair(".privates.", VoidPtrTy),
3384 std::make_pair(
3385 ".copy_fn.",
3386 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3387 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3388 std::make_pair(StringRef(), QualType()) // __context with shared vars
3389 };
3390 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3391 Params, /*OpenMPCaptureLevel=*/0);
3392 // Mark this captured region as inlined, because we don't use outlined
3393 // function directly.
3394 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3395 AlwaysInlineAttr::CreateImplicit(
3396 Context, {}, AttributeCommonInfo::AS_Keyword,
3397 AlwaysInlineAttr::Keyword_forceinline));
3398 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3399 std::make_pair(StringRef(), QualType()),
3400 /*OpenMPCaptureLevel=*/1);
3401 break;
3402 }
3403 case OMPD_simd:
3404 case OMPD_for:
3405 case OMPD_for_simd:
3406 case OMPD_sections:
3407 case OMPD_section:
3408 case OMPD_single:
3409 case OMPD_master:
3410 case OMPD_critical:
3411 case OMPD_taskgroup:
3412 case OMPD_distribute:
3413 case OMPD_distribute_simd:
3414 case OMPD_ordered:
3415 case OMPD_atomic:
3416 case OMPD_target_data: {
3417 Sema::CapturedParamNameType Params[] = {
3418 std::make_pair(StringRef(), QualType()) // __context with shared vars
3419 };
3420 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3421 Params);
3422 break;
3423 }
3424 case OMPD_task: {
3425 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3426 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3427 QualType KmpInt32PtrTy =
3428 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3429 QualType Args[] = {VoidPtrTy};
3430 FunctionProtoType::ExtProtoInfo EPI;
3431 EPI.Variadic = true;
3432 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3433 Sema::CapturedParamNameType Params[] = {
3434 std::make_pair(".global_tid.", KmpInt32Ty),
3435 std::make_pair(".part_id.", KmpInt32PtrTy),
3436 std::make_pair(".privates.", VoidPtrTy),
3437 std::make_pair(
3438 ".copy_fn.",
3439 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3440 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3441 std::make_pair(StringRef(), QualType()) // __context with shared vars
3442 };
3443 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3444 Params);
3445 // Mark this captured region as inlined, because we don't use outlined
3446 // function directly.
3447 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3448 AlwaysInlineAttr::CreateImplicit(
3449 Context, {}, AttributeCommonInfo::AS_Keyword,
3450 AlwaysInlineAttr::Keyword_forceinline));
3451 break;
3452 }
3453 case OMPD_taskloop:
3454 case OMPD_taskloop_simd:
3455 case OMPD_master_taskloop:
3456 case OMPD_master_taskloop_simd: {
3457 QualType KmpInt32Ty =
3458 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3459 .withConst();
3460 QualType KmpUInt64Ty =
3461 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3462 .withConst();
3463 QualType KmpInt64Ty =
3464 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3465 .withConst();
3466 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3467 QualType KmpInt32PtrTy =
3468 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3469 QualType Args[] = {VoidPtrTy};
3470 FunctionProtoType::ExtProtoInfo EPI;
3471 EPI.Variadic = true;
3472 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3473 Sema::CapturedParamNameType Params[] = {
3474 std::make_pair(".global_tid.", KmpInt32Ty),
3475 std::make_pair(".part_id.", KmpInt32PtrTy),
3476 std::make_pair(".privates.", VoidPtrTy),
3477 std::make_pair(
3478 ".copy_fn.",
3479 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3480 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3481 std::make_pair(".lb.", KmpUInt64Ty),
3482 std::make_pair(".ub.", KmpUInt64Ty),
3483 std::make_pair(".st.", KmpInt64Ty),
3484 std::make_pair(".liter.", KmpInt32Ty),
3485 std::make_pair(".reductions.", VoidPtrTy),
3486 std::make_pair(StringRef(), QualType()) // __context with shared vars
3487 };
3488 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3489 Params);
3490 // Mark this captured region as inlined, because we don't use outlined
3491 // function directly.
3492 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3493 AlwaysInlineAttr::CreateImplicit(
3494 Context, {}, AttributeCommonInfo::AS_Keyword,
3495 AlwaysInlineAttr::Keyword_forceinline));
3496 break;
3497 }
3498 case OMPD_parallel_master_taskloop:
3499 case OMPD_parallel_master_taskloop_simd: {
3500 QualType KmpInt32Ty =
3501 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3502 .withConst();
3503 QualType KmpUInt64Ty =
3504 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3505 .withConst();
3506 QualType KmpInt64Ty =
3507 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3508 .withConst();
3509 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3510 QualType KmpInt32PtrTy =
3511 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3512 Sema::CapturedParamNameType ParamsParallel[] = {
3513 std::make_pair(".global_tid.", KmpInt32PtrTy),
3514 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3515 std::make_pair(StringRef(), QualType()) // __context with shared vars
3516 };
3517 // Start a captured region for 'parallel'.
3518 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3519 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3520 QualType Args[] = {VoidPtrTy};
3521 FunctionProtoType::ExtProtoInfo EPI;
3522 EPI.Variadic = true;
3523 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3524 Sema::CapturedParamNameType Params[] = {
3525 std::make_pair(".global_tid.", KmpInt32Ty),
3526 std::make_pair(".part_id.", KmpInt32PtrTy),
3527 std::make_pair(".privates.", VoidPtrTy),
3528 std::make_pair(
3529 ".copy_fn.",
3530 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3531 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3532 std::make_pair(".lb.", KmpUInt64Ty),
3533 std::make_pair(".ub.", KmpUInt64Ty),
3534 std::make_pair(".st.", KmpInt64Ty),
3535 std::make_pair(".liter.", KmpInt32Ty),
3536 std::make_pair(".reductions.", VoidPtrTy),
3537 std::make_pair(StringRef(), QualType()) // __context with shared vars
3538 };
3539 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3540 Params, /*OpenMPCaptureLevel=*/2);
3541 // Mark this captured region as inlined, because we don't use outlined
3542 // function directly.
3543 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3544 AlwaysInlineAttr::CreateImplicit(
3545 Context, {}, AttributeCommonInfo::AS_Keyword,
3546 AlwaysInlineAttr::Keyword_forceinline));
3547 break;
3548 }
3549 case OMPD_distribute_parallel_for_simd:
3550 case OMPD_distribute_parallel_for: {
3551 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3552 QualType KmpInt32PtrTy =
3553 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3554 Sema::CapturedParamNameType Params[] = {
3555 std::make_pair(".global_tid.", KmpInt32PtrTy),
3556 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3557 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3558 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3559 std::make_pair(StringRef(), QualType()) // __context with shared vars
3560 };
3561 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3562 Params);
3563 break;
3564 }
3565 case OMPD_target_teams_distribute_parallel_for:
3566 case OMPD_target_teams_distribute_parallel_for_simd: {
3567 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3568 QualType KmpInt32PtrTy =
3569 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3570 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3571
3572 QualType Args[] = {VoidPtrTy};
3573 FunctionProtoType::ExtProtoInfo EPI;
3574 EPI.Variadic = true;
3575 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3576 Sema::CapturedParamNameType Params[] = {
3577 std::make_pair(".global_tid.", KmpInt32Ty),
3578 std::make_pair(".part_id.", KmpInt32PtrTy),
3579 std::make_pair(".privates.", VoidPtrTy),
3580 std::make_pair(
3581 ".copy_fn.",
3582 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3583 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3584 std::make_pair(StringRef(), QualType()) // __context with shared vars
3585 };
3586 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3587 Params, /*OpenMPCaptureLevel=*/0);
3588 // Mark this captured region as inlined, because we don't use outlined
3589 // function directly.
3590 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3591 AlwaysInlineAttr::CreateImplicit(
3592 Context, {}, AttributeCommonInfo::AS_Keyword,
3593 AlwaysInlineAttr::Keyword_forceinline));
3594 Sema::CapturedParamNameType ParamsTarget[] = {
3595 std::make_pair(StringRef(), QualType()) // __context with shared vars
3596 };
3597 // Start a captured region for 'target' with no implicit parameters.
3598 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3599 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3600
3601 Sema::CapturedParamNameType ParamsTeams[] = {
3602 std::make_pair(".global_tid.", KmpInt32PtrTy),
3603 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3604 std::make_pair(StringRef(), QualType()) // __context with shared vars
3605 };
3606 // Start a captured region for 'target' with no implicit parameters.
3607 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3608 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3609
3610 Sema::CapturedParamNameType ParamsParallel[] = {
3611 std::make_pair(".global_tid.", KmpInt32PtrTy),
3612 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3613 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3614 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3615 std::make_pair(StringRef(), QualType()) // __context with shared vars
3616 };
3617 // Start a captured region for 'teams' or 'parallel'. Both regions have
3618 // the same implicit parameters.
3619 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3620 ParamsParallel, /*OpenMPCaptureLevel=*/3);
3621 break;
3622 }
3623
3624 case OMPD_teams_distribute_parallel_for:
3625 case OMPD_teams_distribute_parallel_for_simd: {
3626 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3627 QualType KmpInt32PtrTy =
3628 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3629
3630 Sema::CapturedParamNameType ParamsTeams[] = {
3631 std::make_pair(".global_tid.", KmpInt32PtrTy),
3632 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3633 std::make_pair(StringRef(), QualType()) // __context with shared vars
3634 };
3635 // Start a captured region for 'target' with no implicit parameters.
3636 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3637 ParamsTeams, /*OpenMPCaptureLevel=*/0);
3638
3639 Sema::CapturedParamNameType ParamsParallel[] = {
3640 std::make_pair(".global_tid.", KmpInt32PtrTy),
3641 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3642 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3643 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3644 std::make_pair(StringRef(), QualType()) // __context with shared vars
3645 };
3646 // Start a captured region for 'teams' or 'parallel'. Both regions have
3647 // the same implicit parameters.
3648 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3649 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3650 break;
3651 }
3652 case OMPD_target_update:
3653 case OMPD_target_enter_data:
3654 case OMPD_target_exit_data: {
3655 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3656 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3657 QualType KmpInt32PtrTy =
3658 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3659 QualType Args[] = {VoidPtrTy};
3660 FunctionProtoType::ExtProtoInfo EPI;
3661 EPI.Variadic = true;
3662 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3663 Sema::CapturedParamNameType Params[] = {
3664 std::make_pair(".global_tid.", KmpInt32Ty),
3665 std::make_pair(".part_id.", KmpInt32PtrTy),
3666 std::make_pair(".privates.", VoidPtrTy),
3667 std::make_pair(
3668 ".copy_fn.",
3669 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3670 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3671 std::make_pair(StringRef(), QualType()) // __context with shared vars
3672 };
3673 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3674 Params);
3675 // Mark this captured region as inlined, because we don't use outlined
3676 // function directly.
3677 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3678 AlwaysInlineAttr::CreateImplicit(
3679 Context, {}, AttributeCommonInfo::AS_Keyword,
3680 AlwaysInlineAttr::Keyword_forceinline));
3681 break;
3682 }
3683 case OMPD_threadprivate:
3684 case OMPD_allocate:
3685 case OMPD_taskyield:
3686 case OMPD_barrier:
3687 case OMPD_taskwait:
3688 case OMPD_cancellation_point:
3689 case OMPD_cancel:
3690 case OMPD_flush:
3691 case OMPD_declare_reduction:
3692 case OMPD_declare_mapper:
3693 case OMPD_declare_simd:
3694 case OMPD_declare_target:
3695 case OMPD_end_declare_target:
3696 case OMPD_requires:
3697 case OMPD_declare_variant:
3698 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 3698)
;
3699 case OMPD_unknown:
3700 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 3700)
;
3701 }
3702}
3703
3704int Sema::getNumberOfConstructScopes(unsigned Level) const {
3705 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
3706}
3707
3708int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3709 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3710 getOpenMPCaptureRegions(CaptureRegions, DKind);
3711 return CaptureRegions.size();
3712}
3713
3714static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
3715 Expr *CaptureExpr, bool WithInit,
3716 bool AsExpression) {
3717 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 3717, __PRETTY_FUNCTION__))
;
3718 ASTContext &C = S.getASTContext();
3719 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
3720 QualType Ty = Init->getType();
3721 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
3722 if (S.getLangOpts().CPlusPlus) {
3723 Ty = C.getLValueReferenceType(Ty);
3724 } else {
3725 Ty = C.getPointerType(Ty);
3726 ExprResult Res =
3727 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3728 if (!Res.isUsable())
3729 return nullptr;
3730 Init = Res.get();
3731 }
3732 WithInit = true;
3733 }
3734 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
3735 CaptureExpr->getBeginLoc());
3736 if (!WithInit)
3737 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3738 S.CurContext->addHiddenDecl(CED);
3739 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
3740 return CED;
3741}
3742
3743static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3744 bool WithInit) {
3745 OMPCapturedExprDecl *CD;
3746 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
5
Calling 'Sema::isOpenMPCapturedDecl'
3747 CD = cast<OMPCapturedExprDecl>(VD);
3748 else
3749 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3750 /*AsExpression=*/false);
3751 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3752 CaptureExpr->getExprLoc());
3753}
3754
3755static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
3756 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
3757 if (!Ref) {
3758 OMPCapturedExprDecl *CD = buildCaptureDecl(
3759 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3760 /*WithInit=*/true, /*AsExpression=*/true);
3761 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3762 CaptureExpr->getExprLoc());
3763 }
3764 ExprResult Res = Ref;
3765 if (!S.getLangOpts().CPlusPlus &&
3766 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
3767 Ref->getType()->isPointerType()) {
3768 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
3769 if (!Res.isUsable())
3770 return ExprError();
3771 }
3772 return S.DefaultLvalueConversion(Res.get());
3773}
3774
3775namespace {
3776// OpenMP directives parsed in this section are represented as a
3777// CapturedStatement with an associated statement. If a syntax error
3778// is detected during the parsing of the associated statement, the
3779// compiler must abort processing and close the CapturedStatement.
3780//
3781// Combined directives such as 'target parallel' have more than one
3782// nested CapturedStatements. This RAII ensures that we unwind out
3783// of all the nested CapturedStatements when an error is found.
3784class CaptureRegionUnwinderRAII {
3785private:
3786 Sema &S;
3787 bool &ErrorFound;
3788 OpenMPDirectiveKind DKind = OMPD_unknown;
3789
3790public:
3791 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3792 OpenMPDirectiveKind DKind)
3793 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3794 ~CaptureRegionUnwinderRAII() {
3795 if (ErrorFound) {
3796 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3797 while (--ThisCaptureLevel >= 0)
3798 S.ActOnCapturedRegionError();
3799 }
3800 }
3801};
3802} // namespace
3803
3804void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
3805 // Capture variables captured by reference in lambdas for target-based
3806 // directives.
3807 if (!CurContext->isDependentContext() &&
3808 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
3809 isOpenMPTargetDataManagementDirective(
3810 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
3811 QualType Type = V->getType();
3812 if (const auto *RD = Type.getCanonicalType()
3813 .getNonReferenceType()
3814 ->getAsCXXRecordDecl()) {
3815 bool SavedForceCaptureByReferenceInTargetExecutable =
3816 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
3817 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
3818 /*V=*/true);
3819 if (RD->isLambda()) {
3820 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3821 FieldDecl *ThisCapture;
3822 RD->getCaptureFields(Captures, ThisCapture);
3823 for (const LambdaCapture &LC : RD->captures()) {
3824 if (LC.getCaptureKind() == LCK_ByRef) {
3825 VarDecl *VD = LC.getCapturedVar();
3826 DeclContext *VDC = VD->getDeclContext();
3827 if (!VDC->Encloses(CurContext))
3828 continue;
3829 MarkVariableReferenced(LC.getLocation(), VD);
3830 } else if (LC.getCaptureKind() == LCK_This) {
3831 QualType ThisTy = getCurrentThisType();
3832 if (!ThisTy.isNull() &&
3833 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
3834 CheckCXXThisCapture(LC.getLocation());
3835 }
3836 }
3837 }
3838 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
3839 SavedForceCaptureByReferenceInTargetExecutable);
3840 }
3841 }
3842}
3843
3844StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3845 ArrayRef<OMPClause *> Clauses) {
3846 bool ErrorFound = false;
3847 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3848 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
3849 if (!S.isUsable()) {
3850 ErrorFound = true;
3851 return StmtError();
3852 }
3853
3854 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3855 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
3856 OMPOrderedClause *OC = nullptr;
3857 OMPScheduleClause *SC = nullptr;
3858 SmallVector<const OMPLinearClause *, 4> LCs;
3859 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
3860 // This is required for proper codegen.
3861 for (OMPClause *Clause : Clauses) {
3862 if (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
3863 Clause->getClauseKind() == OMPC_in_reduction) {
3864 // Capture taskgroup task_reduction descriptors inside the tasking regions
3865 // with the corresponding in_reduction items.
3866 auto *IRC = cast<OMPInReductionClause>(Clause);
3867 for (Expr *E : IRC->taskgroup_descriptors())
3868 if (E)
3869 MarkDeclarationsReferencedInExpr(E);
3870 }
3871 if (isOpenMPPrivate(Clause->getClauseKind()) ||
3872 Clause->getClauseKind() == OMPC_copyprivate ||
3873 (getLangOpts().OpenMPUseTLS &&
3874 getASTContext().getTargetInfo().isTLSSupported() &&
3875 Clause->getClauseKind() == OMPC_copyin)) {
3876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
3877 // Mark all variables in private list clauses as used in inner region.
3878 for (Stmt *VarRef : Clause->children()) {
3879 if (auto *E = cast_or_null<Expr>(VarRef)) {
3880 MarkDeclarationsReferencedInExpr(E);
3881 }
3882 }
3883 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
3884 } else if (CaptureRegions.size() > 1 ||
3885 CaptureRegions.back() != OMPD_unknown) {
3886 if (auto *C = OMPClauseWithPreInit::get(Clause))
3887 PICs.push_back(C);
3888 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
3889 if (Expr *E = C->getPostUpdateExpr())
3890 MarkDeclarationsReferencedInExpr(E);
3891 }
3892 }
3893 if (Clause->getClauseKind() == OMPC_schedule)
3894 SC = cast<OMPScheduleClause>(Clause);
3895 else if (Clause->getClauseKind() == OMPC_ordered)
3896 OC = cast<OMPOrderedClause>(Clause);
3897 else if (Clause->getClauseKind() == OMPC_linear)
3898 LCs.push_back(cast<OMPLinearClause>(Clause));
3899 }
3900 // OpenMP, 2.7.1 Loop Construct, Restrictions
3901 // The nonmonotonic modifier cannot be specified if an ordered clause is
3902 // specified.
3903 if (SC &&
3904 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3905 SC->getSecondScheduleModifier() ==
3906 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3907 OC) {
3908 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3909 ? SC->getFirstScheduleModifierLoc()
3910 : SC->getSecondScheduleModifierLoc(),
3911 diag::err_omp_schedule_nonmonotonic_ordered)
3912 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3913 ErrorFound = true;
3914 }
3915 if (!LCs.empty() && OC && OC->getNumForLoops()) {
3916 for (const OMPLinearClause *C : LCs) {
3917 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
3918 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3919 }
3920 ErrorFound = true;
3921 }
3922 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
3923 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
3924 OC->getNumForLoops()) {
3925 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3926 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
3927 ErrorFound = true;
3928 }
3929 if (ErrorFound) {
3930 return StmtError();
3931 }
3932 StmtResult SR = S;
3933 unsigned CompletedRegions = 0;
3934 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3935 // Mark all variables in private list clauses as used in inner region.
3936 // Required for proper codegen of combined directives.
3937 // TODO: add processing for other clauses.
3938 if (ThisCaptureRegion != OMPD_unknown) {
3939 for (const clang::OMPClauseWithPreInit *C : PICs) {
3940 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3941 // Find the particular capture region for the clause if the
3942 // directive is a combined one with multiple capture regions.
3943 // If the directive is not a combined one, the capture region
3944 // associated with the clause is OMPD_unknown and is generated
3945 // only once.
3946 if (CaptureRegion == ThisCaptureRegion ||
3947 CaptureRegion == OMPD_unknown) {
3948 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3949 for (Decl *D : DS->decls())
3950 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3951 }
3952 }
3953 }
3954 }
3955 if (++CompletedRegions == CaptureRegions.size())
3956 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
3957 SR = ActOnCapturedRegionEnd(SR.get());
3958 }
3959 return SR;
3960}
3961
3962static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3963 OpenMPDirectiveKind CancelRegion,
3964 SourceLocation StartLoc) {
3965 // CancelRegion is only needed for cancel and cancellation_point.
3966 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3967 return false;
3968
3969 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3970 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3971 return false;
3972
3973 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3974 << getOpenMPDirectiveName(CancelRegion);
3975 return true;
3976}
3977
3978static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
3979 OpenMPDirectiveKind CurrentRegion,
3980 const DeclarationNameInfo &CurrentName,
3981 OpenMPDirectiveKind CancelRegion,
3982 SourceLocation StartLoc) {
3983 if (Stack->getCurScope()) {
3984 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3985 OpenMPDirectiveKind OffendingRegion = ParentRegion;
3986 bool NestingProhibited = false;
3987 bool CloseNesting = true;
3988 bool OrphanSeen = false;
3989 enum {
3990 NoRecommend,
3991 ShouldBeInParallelRegion,
3992 ShouldBeInOrderedRegion,
3993 ShouldBeInTargetRegion,
3994 ShouldBeInTeamsRegion
3995 } Recommend = NoRecommend;
3996 if (isOpenMPSimdDirective(ParentRegion) &&
3997 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
3998 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
3999 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) {
4000 // OpenMP [2.16, Nesting of Regions]
4001 // OpenMP constructs may not be nested inside a simd region.
4002 // OpenMP [2.8.1,simd Construct, Restrictions]
4003 // An ordered construct with the simd clause is the only OpenMP
4004 // construct that can appear in the simd region.
4005 // Allowing a SIMD construct nested in another SIMD construct is an
4006 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4007 // message.
4008 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4009 // The only OpenMP constructs that can be encountered during execution of
4010 // a simd region are the atomic construct, the loop construct, the simd
4011 // construct and the ordered construct with the simd clause.
4012 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4013 ? diag::err_omp_prohibited_region_simd
4014 : diag::warn_omp_nesting_simd)
4015 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4016 return CurrentRegion != OMPD_simd;
4017 }
4018 if (ParentRegion == OMPD_atomic) {
4019 // OpenMP [2.16, Nesting of Regions]
4020 // OpenMP constructs may not be nested inside an atomic region.
4021 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4022 return true;
4023 }
4024 if (CurrentRegion == OMPD_section) {
4025 // OpenMP [2.7.2, sections Construct, Restrictions]
4026 // Orphaned section directives are prohibited. That is, the section
4027 // directives must appear within the sections construct and must not be
4028 // encountered elsewhere in the sections region.
4029 if (ParentRegion != OMPD_sections &&
4030 ParentRegion != OMPD_parallel_sections) {
4031 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4032 << (ParentRegion != OMPD_unknown)
4033 << getOpenMPDirectiveName(ParentRegion);
4034 return true;
4035 }
4036 return false;
4037 }
4038 // Allow some constructs (except teams and cancellation constructs) to be
4039 // orphaned (they could be used in functions, called from OpenMP regions
4040 // with the required preconditions).
4041 if (ParentRegion == OMPD_unknown &&
4042 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4043 CurrentRegion != OMPD_cancellation_point &&
4044 CurrentRegion != OMPD_cancel)
4045 return false;
4046 if (CurrentRegion == OMPD_cancellation_point ||
4047 CurrentRegion == OMPD_cancel) {
4048 // OpenMP [2.16, Nesting of Regions]
4049 // A cancellation point construct for which construct-type-clause is
4050 // taskgroup must be nested inside a task construct. A cancellation
4051 // point construct for which construct-type-clause is not taskgroup must
4052 // be closely nested inside an OpenMP construct that matches the type
4053 // specified in construct-type-clause.
4054 // A cancel construct for which construct-type-clause is taskgroup must be
4055 // nested inside a task construct. A cancel construct for which
4056 // construct-type-clause is not taskgroup must be closely nested inside an
4057 // OpenMP construct that matches the type specified in
4058 // construct-type-clause.
4059 NestingProhibited =
4060 !((CancelRegion == OMPD_parallel &&
4061 (ParentRegion == OMPD_parallel ||
4062 ParentRegion == OMPD_target_parallel)) ||
4063 (CancelRegion == OMPD_for &&
4064 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4065 ParentRegion == OMPD_target_parallel_for ||
4066 ParentRegion == OMPD_distribute_parallel_for ||
4067 ParentRegion == OMPD_teams_distribute_parallel_for ||
4068 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4069 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
4070 (CancelRegion == OMPD_sections &&
4071 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4072 ParentRegion == OMPD_parallel_sections)));
4073 OrphanSeen = ParentRegion == OMPD_unknown;
4074 } else if (CurrentRegion == OMPD_master) {
4075 // OpenMP [2.16, Nesting of Regions]
4076 // A master region may not be closely nested inside a worksharing,
4077 // atomic, or explicit task region.
4078 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4079 isOpenMPTaskingDirective(ParentRegion);
4080 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4081 // OpenMP [2.16, Nesting of Regions]
4082 // A critical region may not be nested (closely or otherwise) inside a
4083 // critical region with the same name. Note that this restriction is not
4084 // sufficient to prevent deadlock.
4085 SourceLocation PreviousCriticalLoc;
4086 bool DeadLock = Stack->hasDirective(
4087 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4088 const DeclarationNameInfo &DNI,
4089 SourceLocation Loc) {
4090 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4091 PreviousCriticalLoc = Loc;
4092 return true;
4093 }
4094 return false;
4095 },
4096 false /* skip top directive */);
4097 if (DeadLock) {
4098 SemaRef.Diag(StartLoc,
4099 diag::err_omp_prohibited_region_critical_same_name)
4100 << CurrentName.getName();
4101 if (PreviousCriticalLoc.isValid())
4102 SemaRef.Diag(PreviousCriticalLoc,
4103 diag::note_omp_previous_critical_region);
4104 return true;
4105 }
4106 } else if (CurrentRegion == OMPD_barrier) {
4107 // OpenMP [2.16, Nesting of Regions]
4108 // A barrier region may not be closely nested inside a worksharing,
4109 // explicit task, critical, ordered, atomic, or master region.
4110 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4111 isOpenMPTaskingDirective(ParentRegion) ||
4112 ParentRegion == OMPD_master ||
4113 ParentRegion == OMPD_parallel_master ||
4114 ParentRegion == OMPD_critical ||
4115 ParentRegion == OMPD_ordered;
4116 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4117 !isOpenMPParallelDirective(CurrentRegion) &&
4118 !isOpenMPTeamsDirective(CurrentRegion)) {
4119 // OpenMP [2.16, Nesting of Regions]
4120 // A worksharing region may not be closely nested inside a worksharing,
4121 // explicit task, critical, ordered, atomic, or master region.
4122 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4123 isOpenMPTaskingDirective(ParentRegion) ||
4124 ParentRegion == OMPD_master ||
4125 ParentRegion == OMPD_parallel_master ||
4126 ParentRegion == OMPD_critical ||
4127 ParentRegion == OMPD_ordered;
4128 Recommend = ShouldBeInParallelRegion;
4129 } else if (CurrentRegion == OMPD_ordered) {
4130 // OpenMP [2.16, Nesting of Regions]
4131 // An ordered region may not be closely nested inside a critical,
4132 // atomic, or explicit task region.
4133 // An ordered region must be closely nested inside a loop region (or
4134 // parallel loop region) with an ordered clause.
4135 // OpenMP [2.8.1,simd Construct, Restrictions]
4136 // An ordered construct with the simd clause is the only OpenMP construct
4137 // that can appear in the simd region.
4138 NestingProhibited = ParentRegion == OMPD_critical ||
4139 isOpenMPTaskingDirective(ParentRegion) ||
4140 !(isOpenMPSimdDirective(ParentRegion) ||
4141 Stack->isParentOrderedRegion());
4142 Recommend = ShouldBeInOrderedRegion;
4143 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4144 // OpenMP [2.16, Nesting of Regions]
4145 // If specified, a teams construct must be contained within a target
4146 // construct.
4147 NestingProhibited =
4148 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4149 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4150 ParentRegion != OMPD_target);
4151 OrphanSeen = ParentRegion == OMPD_unknown;
4152 Recommend = ShouldBeInTargetRegion;
4153 }
4154 if (!NestingProhibited &&
4155 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4156 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4157 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4158 // OpenMP [2.16, Nesting of Regions]
4159 // distribute, parallel, parallel sections, parallel workshare, and the
4160 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4161 // constructs that can be closely nested in the teams region.
4162 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4163 !isOpenMPDistributeDirective(CurrentRegion);
4164 Recommend = ShouldBeInParallelRegion;
4165 }
4166 if (!NestingProhibited &&
4167 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4168 // OpenMP 4.5 [2.17 Nesting of Regions]
4169 // The region associated with the distribute construct must be strictly
4170 // nested inside a teams region
4171 NestingProhibited =
4172 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4173 Recommend = ShouldBeInTeamsRegion;
4174 }
4175 if (!NestingProhibited &&
4176 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4177 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4178 // OpenMP 4.5 [2.17 Nesting of Regions]
4179 // If a target, target update, target data, target enter data, or
4180 // target exit data construct is encountered during execution of a
4181 // target region, the behavior is unspecified.
4182 NestingProhibited = Stack->hasDirective(
4183 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4184 SourceLocation) {
4185 if (isOpenMPTargetExecutionDirective(K)) {
4186 OffendingRegion = K;
4187 return true;
4188 }
4189 return false;
4190 },
4191 false /* don't skip top directive */);
4192 CloseNesting = false;
4193 }
4194 if (NestingProhibited) {
4195 if (OrphanSeen) {
4196 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4197 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4198 } else {
4199 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4200 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4201 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4202 }
4203 return true;
4204 }
4205 }
4206 return false;
4207}
4208
4209struct Kind2Unsigned {
4210 using argument_type = OpenMPDirectiveKind;
4211 unsigned operator()(argument_type DK) { return unsigned(DK); }
4212};
4213static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4214 ArrayRef<OMPClause *> Clauses,
4215 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4216 bool ErrorFound = false;
4217 unsigned NamedModifiersNumber = 0;
4218 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4219 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1);
4220 SmallVector<SourceLocation, 4> NameModifierLoc;
4221 for (const OMPClause *C : Clauses) {
4222 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4223 // At most one if clause without a directive-name-modifier can appear on
4224 // the directive.
4225 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4226 if (FoundNameModifiers[CurNM]) {
4227 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4228 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4229 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4230 ErrorFound = true;
4231 } else if (CurNM != OMPD_unknown) {
4232 NameModifierLoc.push_back(IC->getNameModifierLoc());
4233 ++NamedModifiersNumber;
4234 }
4235 FoundNameModifiers[CurNM] = IC;
4236 if (CurNM == OMPD_unknown)
4237 continue;
4238 // Check if the specified name modifier is allowed for the current
4239 // directive.
4240 // At most one if clause with the particular directive-name-modifier can
4241 // appear on the directive.
4242 bool MatchFound = false;
4243 for (auto NM : AllowedNameModifiers) {
4244 if (CurNM == NM) {
4245 MatchFound = true;
4246 break;
4247 }
4248 }
4249 if (!MatchFound) {
4250 S.Diag(IC->getNameModifierLoc(),
4251 diag::err_omp_wrong_if_directive_name_modifier)
4252 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4253 ErrorFound = true;
4254 }
4255 }
4256 }
4257 // If any if clause on the directive includes a directive-name-modifier then
4258 // all if clauses on the directive must include a directive-name-modifier.
4259 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4260 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4261 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4262 diag::err_omp_no_more_if_clause);
4263 } else {
4264 std::string Values;
4265 std::string Sep(", ");
4266 unsigned AllowedCnt = 0;
4267 unsigned TotalAllowedNum =
4268 AllowedNameModifiers.size() - NamedModifiersNumber;
4269 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4270 ++Cnt) {
4271 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4272 if (!FoundNameModifiers[NM]) {
4273 Values += "'";
4274 Values += getOpenMPDirectiveName(NM);
4275 Values += "'";
4276 if (AllowedCnt + 2 == TotalAllowedNum)
4277 Values += " or ";
4278 else if (AllowedCnt + 1 != TotalAllowedNum)
4279 Values += Sep;
4280 ++AllowedCnt;
4281 }
4282 }
4283 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4284 diag::err_omp_unnamed_if_clause)
4285 << (TotalAllowedNum > 1) << Values;
4286 }
4287 for (SourceLocation Loc : NameModifierLoc) {
4288 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4289 }
4290 ErrorFound = true;
4291 }
4292 return ErrorFound;
4293}
4294
4295static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4296 SourceLocation &ELoc,
4297 SourceRange &ERange,
4298 bool AllowArraySection) {
4299 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4300 RefExpr->containsUnexpandedParameterPack())
4301 return std::make_pair(nullptr, true);
4302
4303 // OpenMP [3.1, C/C++]
4304 // A list item is a variable name.
4305 // OpenMP [2.9.3.3, Restrictions, p.1]
4306 // A variable that is part of another variable (as an array or
4307 // structure element) cannot appear in a private clause.
4308 RefExpr = RefExpr->IgnoreParens();
4309 enum {
4310 NoArrayExpr = -1,
4311 ArraySubscript = 0,
4312 OMPArraySection = 1
4313 } IsArrayExpr = NoArrayExpr;
4314 if (AllowArraySection) {
4315 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4316 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4317 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4318 Base = TempASE->getBase()->IgnoreParenImpCasts();
4319 RefExpr = Base;
4320 IsArrayExpr = ArraySubscript;
4321 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4322 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4323 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4324 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4325 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4326 Base = TempASE->getBase()->IgnoreParenImpCasts();
4327 RefExpr = Base;
4328 IsArrayExpr = OMPArraySection;
4329 }
4330 }
4331 ELoc = RefExpr->getExprLoc();
4332 ERange = RefExpr->getSourceRange();
4333 RefExpr = RefExpr->IgnoreParenImpCasts();
4334 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4335 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4336 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4337 (S.getCurrentThisType().isNull() || !ME ||
4338 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4339 !isa<FieldDecl>(ME->getMemberDecl()))) {
4340 if (IsArrayExpr != NoArrayExpr) {
4341 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4342 << ERange;
4343 } else {
4344 S.Diag(ELoc,
4345 AllowArraySection
4346 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4347 : diag::err_omp_expected_var_name_member_expr)
4348 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4349 }
4350 return std::make_pair(nullptr, false);
4351 }
4352 return std::make_pair(
4353 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4354}
4355
4356static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4357 ArrayRef<OMPClause *> Clauses) {
4358 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4359, __PRETTY_FUNCTION__))
4359 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4359, __PRETTY_FUNCTION__))
;
4360 auto AllocateRange =
4361 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4362 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4363 DeclToCopy;
4364 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4365 return isOpenMPPrivate(C->getClauseKind());
4366 });
4367 for (OMPClause *Cl : PrivateRange) {
4368 MutableArrayRef<Expr *>::iterator I, It, Et;
4369 if (Cl->getClauseKind() == OMPC_private) {
4370 auto *PC = cast<OMPPrivateClause>(Cl);
4371 I = PC->private_copies().begin();
4372 It = PC->varlist_begin();
4373 Et = PC->varlist_end();
4374 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4375 auto *PC = cast<OMPFirstprivateClause>(Cl);
4376 I = PC->private_copies().begin();
4377 It = PC->varlist_begin();
4378 Et = PC->varlist_end();
4379 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4380 auto *PC = cast<OMPLastprivateClause>(Cl);
4381 I = PC->private_copies().begin();
4382 It = PC->varlist_begin();
4383 Et = PC->varlist_end();
4384 } else if (Cl->getClauseKind() == OMPC_linear) {
4385 auto *PC = cast<OMPLinearClause>(Cl);
4386 I = PC->privates().begin();
4387 It = PC->varlist_begin();
4388 Et = PC->varlist_end();
4389 } else if (Cl->getClauseKind() == OMPC_reduction) {
4390 auto *PC = cast<OMPReductionClause>(Cl);
4391 I = PC->privates().begin();
4392 It = PC->varlist_begin();
4393 Et = PC->varlist_end();
4394 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4395 auto *PC = cast<OMPTaskReductionClause>(Cl);
4396 I = PC->privates().begin();
4397 It = PC->varlist_begin();
4398 Et = PC->varlist_end();
4399 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4400 auto *PC = cast<OMPInReductionClause>(Cl);
4401 I = PC->privates().begin();
4402 It = PC->varlist_begin();
4403 Et = PC->varlist_end();
4404 } else {
4405 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4405)
;
4406 }
4407 for (Expr *E : llvm::make_range(It, Et)) {
4408 if (!*I) {
4409 ++I;
4410 continue;
4411 }
4412 SourceLocation ELoc;
4413 SourceRange ERange;
4414 Expr *SimpleRefExpr = E;
4415 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4416 /*AllowArraySection=*/true);
4417 DeclToCopy.try_emplace(Res.first,
4418 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4419 ++I;
4420 }
4421 }
4422 for (OMPClause *C : AllocateRange) {
4423 auto *AC = cast<OMPAllocateClause>(C);
4424 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4425 getAllocatorKind(S, Stack, AC->getAllocator());
4426 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4427 // For task, taskloop or target directives, allocation requests to memory
4428 // allocators with the trait access set to thread result in unspecified
4429 // behavior.
4430 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4431 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4432 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4433 S.Diag(AC->getAllocator()->getExprLoc(),
4434 diag::warn_omp_allocate_thread_on_task_target_directive)
4435 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4436 }
4437 for (Expr *E : AC->varlists()) {
4438 SourceLocation ELoc;
4439 SourceRange ERange;
4440 Expr *SimpleRefExpr = E;
4441 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4442 ValueDecl *VD = Res.first;
4443 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4444 if (!isOpenMPPrivate(Data.CKind)) {
4445 S.Diag(E->getExprLoc(),
4446 diag::err_omp_expected_private_copy_for_allocate);
4447 continue;
4448 }
4449 VarDecl *PrivateVD = DeclToCopy[VD];
4450 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4451 AllocatorKind, AC->getAllocator()))
4452 continue;
4453 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4454 E->getSourceRange());
4455 }
4456 }
4457}
4458
4459StmtResult Sema::ActOnOpenMPExecutableDirective(
4460 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4461 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4462 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4463 StmtResult Res = StmtError();
4464 // First check CancelRegion which is then used in checkNestingOfRegions.
4465 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4466 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
4467 StartLoc))
4468 return StmtError();
4469
4470 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4471 VarsWithInheritedDSAType VarsWithInheritedDSA;
4472 bool ErrorFound = false;
4473 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4474 if (AStmt && !CurContext->isDependentContext()) {
4475 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4475, __PRETTY_FUNCTION__))
;
4476
4477 // Check default data sharing attributes for referenced variables.
4478 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
4479 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4480 Stmt *S = AStmt;
4481 while (--ThisCaptureLevel >= 0)
4482 S = cast<CapturedStmt>(S)->getCapturedStmt();
4483 DSAChecker.Visit(S);
4484 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4485 !isOpenMPTaskingDirective(Kind)) {
4486 // Visit subcaptures to generate implicit clauses for captured vars.
4487 auto *CS = cast<CapturedStmt>(AStmt);
4488 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4489 getOpenMPCaptureRegions(CaptureRegions, Kind);
4490 // Ignore outer tasking regions for target directives.
4491 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4492 CS = cast<CapturedStmt>(CS->getCapturedStmt());
4493 DSAChecker.visitSubCaptures(CS);
4494 }
4495 if (DSAChecker.isErrorFound())
4496 return StmtError();
4497 // Generate list of implicitly defined firstprivate variables.
4498 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4499
4500 SmallVector<Expr *, 4> ImplicitFirstprivates(
4501 DSAChecker.getImplicitFirstprivate().begin(),
4502 DSAChecker.getImplicitFirstprivate().end());
4503 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
4504 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
4505 ArrayRef<Expr *> ImplicitMap =
4506 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
4507 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
4508 }
4509 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
4510 for (OMPClause *C : Clauses) {
4511 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
4512 for (Expr *E : IRC->taskgroup_descriptors())
4513 if (E)
4514 ImplicitFirstprivates.emplace_back(E);
4515 }
4516 }
4517 if (!ImplicitFirstprivates.empty()) {
4518 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4519 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
4520 SourceLocation())) {
4521 ClausesWithImplicit.push_back(Implicit);
4522 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4523 ImplicitFirstprivates.size();
4524 } else {
4525 ErrorFound = true;
4526 }
4527 }
4528 int ClauseKindCnt = -1;
4529 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
4530 ++ClauseKindCnt;
4531 if (ImplicitMap.empty())
4532 continue;
4533 CXXScopeSpec MapperIdScopeSpec;
4534 DeclarationNameInfo MapperId;
4535 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
4536 if (OMPClause *Implicit = ActOnOpenMPMapClause(
4537 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
4538 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
4539 ImplicitMap, OMPVarListLocTy())) {
4540 ClausesWithImplicit.emplace_back(Implicit);
4541 ErrorFound |=
4542 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
4543 } else {
4544 ErrorFound = true;
4545 }
4546 }
4547 }
4548
4549 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
4550 switch (Kind) {
4551 case OMPD_parallel:
4552 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4553 EndLoc);
4554 AllowedNameModifiers.push_back(OMPD_parallel);
4555 break;
4556 case OMPD_simd:
4557 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4558 VarsWithInheritedDSA);
4559 if (LangOpts.OpenMP >= 50)
4560 AllowedNameModifiers.push_back(OMPD_simd);
4561 break;
4562 case OMPD_for:
4563 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4564 VarsWithInheritedDSA);
4565 break;
4566 case OMPD_for_simd:
4567 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4568 EndLoc, VarsWithInheritedDSA);
4569 if (LangOpts.OpenMP >= 50)
4570 AllowedNameModifiers.push_back(OMPD_simd);
4571 break;
4572 case OMPD_sections:
4573 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4574 EndLoc);
4575 break;
4576 case OMPD_section:
4577 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4578, __PRETTY_FUNCTION__))
4578 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4578, __PRETTY_FUNCTION__))
;
4579 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4580 break;
4581 case OMPD_single:
4582 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4583 EndLoc);
4584 break;
4585 case OMPD_master:
4586 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4587, __PRETTY_FUNCTION__))
4587 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4587, __PRETTY_FUNCTION__))
;
4588 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4589 break;
4590 case OMPD_critical:
4591 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4592 StartLoc, EndLoc);
4593 break;
4594 case OMPD_parallel_for:
4595 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4596 EndLoc, VarsWithInheritedDSA);
4597 AllowedNameModifiers.push_back(OMPD_parallel);
4598 break;
4599 case OMPD_parallel_for_simd:
4600 Res = ActOnOpenMPParallelForSimdDirective(
4601 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4602 AllowedNameModifiers.push_back(OMPD_parallel);
4603 if (LangOpts.OpenMP >= 50)
4604 AllowedNameModifiers.push_back(OMPD_simd);
4605 break;
4606 case OMPD_parallel_master:
4607 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
4608 StartLoc, EndLoc);
4609 AllowedNameModifiers.push_back(OMPD_parallel);
4610 break;
4611 case OMPD_parallel_sections:
4612 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4613 StartLoc, EndLoc);
4614 AllowedNameModifiers.push_back(OMPD_parallel);
4615 break;
4616 case OMPD_task:
4617 Res =
4618 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4619 AllowedNameModifiers.push_back(OMPD_task);
4620 break;
4621 case OMPD_taskyield:
4622 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4623, __PRETTY_FUNCTION__))
4623 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4623, __PRETTY_FUNCTION__))
;
4624 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4625, __PRETTY_FUNCTION__))
4625 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4625, __PRETTY_FUNCTION__))
;
4626 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4627 break;
4628 case OMPD_barrier:
4629 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4630, __PRETTY_FUNCTION__))
4630 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4630, __PRETTY_FUNCTION__))
;
4631 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4632, __PRETTY_FUNCTION__))
4632 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4632, __PRETTY_FUNCTION__))
;
4633 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4634 break;
4635 case OMPD_taskwait:
4636 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4637, __PRETTY_FUNCTION__))
4637 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4637, __PRETTY_FUNCTION__))
;
4638 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4639, __PRETTY_FUNCTION__))
4639 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4639, __PRETTY_FUNCTION__))
;
4640 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4641 break;
4642 case OMPD_taskgroup:
4643 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4644 EndLoc);
4645 break;
4646 case OMPD_flush:
4647 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4648, __PRETTY_FUNCTION__))
4648 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4648, __PRETTY_FUNCTION__))
;
4649 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4650 break;
4651 case OMPD_ordered:
4652 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4653 EndLoc);
4654 break;
4655 case OMPD_atomic:
4656 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4657 EndLoc);
4658 break;
4659 case OMPD_teams:
4660 Res =
4661 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4662 break;
4663 case OMPD_target:
4664 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4665 EndLoc);
4666 AllowedNameModifiers.push_back(OMPD_target);
4667 break;
4668 case OMPD_target_parallel:
4669 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4670 StartLoc, EndLoc);
4671 AllowedNameModifiers.push_back(OMPD_target);
4672 AllowedNameModifiers.push_back(OMPD_parallel);
4673 break;
4674 case OMPD_target_parallel_for:
4675 Res = ActOnOpenMPTargetParallelForDirective(
4676 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4677 AllowedNameModifiers.push_back(OMPD_target);
4678 AllowedNameModifiers.push_back(OMPD_parallel);
4679 break;
4680 case OMPD_cancellation_point:
4681 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4682, __PRETTY_FUNCTION__))
4682 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4682, __PRETTY_FUNCTION__))
;
4683 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4684, __PRETTY_FUNCTION__))
4684 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4684, __PRETTY_FUNCTION__))
;
4685 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4686 break;
4687 case OMPD_cancel:
4688 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4689, __PRETTY_FUNCTION__))
4689 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4689, __PRETTY_FUNCTION__))
;
4690 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4691 CancelRegion);
4692 AllowedNameModifiers.push_back(OMPD_cancel);
4693 break;
4694 case OMPD_target_data:
4695 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4696 EndLoc);
4697 AllowedNameModifiers.push_back(OMPD_target_data);
4698 break;
4699 case OMPD_target_enter_data:
4700 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4701 EndLoc, AStmt);
4702 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4703 break;
4704 case OMPD_target_exit_data:
4705 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4706 EndLoc, AStmt);
4707 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4708 break;
4709 case OMPD_taskloop:
4710 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4711 EndLoc, VarsWithInheritedDSA);
4712 AllowedNameModifiers.push_back(OMPD_taskloop);
4713 break;
4714 case OMPD_taskloop_simd:
4715 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4716 EndLoc, VarsWithInheritedDSA);
4717 AllowedNameModifiers.push_back(OMPD_taskloop);
4718 if (LangOpts.OpenMP >= 50)
4719 AllowedNameModifiers.push_back(OMPD_simd);
4720 break;
4721 case OMPD_master_taskloop:
4722 Res = ActOnOpenMPMasterTaskLoopDirective(
4723 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4724 AllowedNameModifiers.push_back(OMPD_taskloop);
4725 break;
4726 case OMPD_master_taskloop_simd:
4727 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4728 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4729 AllowedNameModifiers.push_back(OMPD_taskloop);
4730 if (LangOpts.OpenMP >= 50)
4731 AllowedNameModifiers.push_back(OMPD_simd);
4732 break;
4733 case OMPD_parallel_master_taskloop:
4734 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4735 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4736 AllowedNameModifiers.push_back(OMPD_taskloop);
4737 AllowedNameModifiers.push_back(OMPD_parallel);
4738 break;
4739 case OMPD_parallel_master_taskloop_simd:
4740 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
4741 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4742 AllowedNameModifiers.push_back(OMPD_taskloop);
4743 AllowedNameModifiers.push_back(OMPD_parallel);
4744 if (LangOpts.OpenMP >= 50)
4745 AllowedNameModifiers.push_back(OMPD_simd);
4746 break;
4747 case OMPD_distribute:
4748 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4749 EndLoc, VarsWithInheritedDSA);
4750 break;
4751 case OMPD_target_update:
4752 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4753 EndLoc, AStmt);
4754 AllowedNameModifiers.push_back(OMPD_target_update);
4755 break;
4756 case OMPD_distribute_parallel_for:
4757 Res = ActOnOpenMPDistributeParallelForDirective(
4758 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4759 AllowedNameModifiers.push_back(OMPD_parallel);
4760 break;
4761 case OMPD_distribute_parallel_for_simd:
4762 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4763 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4764 AllowedNameModifiers.push_back(OMPD_parallel);
4765 if (LangOpts.OpenMP >= 50)
4766 AllowedNameModifiers.push_back(OMPD_simd);
4767 break;
4768 case OMPD_distribute_simd:
4769 Res = ActOnOpenMPDistributeSimdDirective(
4770 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4771 if (LangOpts.OpenMP >= 50)
4772 AllowedNameModifiers.push_back(OMPD_simd);
4773 break;
4774 case OMPD_target_parallel_for_simd:
4775 Res = ActOnOpenMPTargetParallelForSimdDirective(
4776 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4777 AllowedNameModifiers.push_back(OMPD_target);
4778 AllowedNameModifiers.push_back(OMPD_parallel);
4779 if (LangOpts.OpenMP >= 50)
4780 AllowedNameModifiers.push_back(OMPD_simd);
4781 break;
4782 case OMPD_target_simd:
4783 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4784 EndLoc, VarsWithInheritedDSA);
4785 AllowedNameModifiers.push_back(OMPD_target);
4786 if (LangOpts.OpenMP >= 50)
4787 AllowedNameModifiers.push_back(OMPD_simd);
4788 break;
4789 case OMPD_teams_distribute:
4790 Res = ActOnOpenMPTeamsDistributeDirective(
4791 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4792 break;
4793 case OMPD_teams_distribute_simd:
4794 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4795 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4796 if (LangOpts.OpenMP >= 50)
4797 AllowedNameModifiers.push_back(OMPD_simd);
4798 break;
4799 case OMPD_teams_distribute_parallel_for_simd:
4800 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4801 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4802 AllowedNameModifiers.push_back(OMPD_parallel);
4803 if (LangOpts.OpenMP >= 50)
4804 AllowedNameModifiers.push_back(OMPD_simd);
4805 break;
4806 case OMPD_teams_distribute_parallel_for:
4807 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4808 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4809 AllowedNameModifiers.push_back(OMPD_parallel);
4810 break;
4811 case OMPD_target_teams:
4812 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4813 EndLoc);
4814 AllowedNameModifiers.push_back(OMPD_target);
4815 break;
4816 case OMPD_target_teams_distribute:
4817 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4818 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4819 AllowedNameModifiers.push_back(OMPD_target);
4820 break;
4821 case OMPD_target_teams_distribute_parallel_for:
4822 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4823 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4824 AllowedNameModifiers.push_back(OMPD_target);
4825 AllowedNameModifiers.push_back(OMPD_parallel);
4826 break;
4827 case OMPD_target_teams_distribute_parallel_for_simd:
4828 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4829 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4830 AllowedNameModifiers.push_back(OMPD_target);
4831 AllowedNameModifiers.push_back(OMPD_parallel);
4832 if (LangOpts.OpenMP >= 50)
4833 AllowedNameModifiers.push_back(OMPD_simd);
4834 break;
4835 case OMPD_target_teams_distribute_simd:
4836 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4837 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4838 AllowedNameModifiers.push_back(OMPD_target);
4839 if (LangOpts.OpenMP >= 50)
4840 AllowedNameModifiers.push_back(OMPD_simd);
4841 break;
4842 case OMPD_declare_target:
4843 case OMPD_end_declare_target:
4844 case OMPD_threadprivate:
4845 case OMPD_allocate:
4846 case OMPD_declare_reduction:
4847 case OMPD_declare_mapper:
4848 case OMPD_declare_simd:
4849 case OMPD_requires:
4850 case OMPD_declare_variant:
4851 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4851)
;
4852 case OMPD_unknown:
4853 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4853)
;
4854 }
4855
4856 ErrorFound = Res.isInvalid() || ErrorFound;
4857
4858 // Check variables in the clauses if default(none) was specified.
4859 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none) {
4860 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
4861 for (OMPClause *C : Clauses) {
4862 switch (C->getClauseKind()) {
4863 case OMPC_num_threads:
4864 case OMPC_dist_schedule:
4865 // Do not analyse if no parent teams directive.
4866 if (isOpenMPTeamsDirective(Kind))
4867 break;
4868 continue;
4869 case OMPC_if:
4870 if (isOpenMPTeamsDirective(Kind) &&
4871 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4872 break;
4873 if (isOpenMPParallelDirective(Kind) &&
4874 isOpenMPTaskLoopDirective(Kind) &&
4875 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
4876 break;
4877 continue;
4878 case OMPC_schedule:
4879 break;
4880 case OMPC_grainsize:
4881 case OMPC_num_tasks:
4882 case OMPC_final:
4883 case OMPC_priority:
4884 // Do not analyze if no parent parallel directive.
4885 if (isOpenMPParallelDirective(Kind))
4886 break;
4887 continue;
4888 case OMPC_ordered:
4889 case OMPC_device:
4890 case OMPC_num_teams:
4891 case OMPC_thread_limit:
4892 case OMPC_hint:
4893 case OMPC_collapse:
4894 case OMPC_safelen:
4895 case OMPC_simdlen:
4896 case OMPC_default:
4897 case OMPC_proc_bind:
4898 case OMPC_private:
4899 case OMPC_firstprivate:
4900 case OMPC_lastprivate:
4901 case OMPC_shared:
4902 case OMPC_reduction:
4903 case OMPC_task_reduction:
4904 case OMPC_in_reduction:
4905 case OMPC_linear:
4906 case OMPC_aligned:
4907 case OMPC_copyin:
4908 case OMPC_copyprivate:
4909 case OMPC_nowait:
4910 case OMPC_untied:
4911 case OMPC_mergeable:
4912 case OMPC_allocate:
4913 case OMPC_read:
4914 case OMPC_write:
4915 case OMPC_update:
4916 case OMPC_capture:
4917 case OMPC_seq_cst:
4918 case OMPC_depend:
4919 case OMPC_threads:
4920 case OMPC_simd:
4921 case OMPC_map:
4922 case OMPC_nogroup:
4923 case OMPC_defaultmap:
4924 case OMPC_to:
4925 case OMPC_from:
4926 case OMPC_use_device_ptr:
4927 case OMPC_is_device_ptr:
4928 case OMPC_nontemporal:
4929 continue;
4930 case OMPC_allocator:
4931 case OMPC_flush:
4932 case OMPC_threadprivate:
4933 case OMPC_uniform:
4934 case OMPC_unknown:
4935 case OMPC_unified_address:
4936 case OMPC_unified_shared_memory:
4937 case OMPC_reverse_offload:
4938 case OMPC_dynamic_allocators:
4939 case OMPC_atomic_default_mem_order:
4940 case OMPC_device_type:
4941 case OMPC_match:
4942 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 4942)
;
4943 }
4944 for (Stmt *CC : C->children()) {
4945 if (CC)
4946 DSAChecker.Visit(CC);
4947 }
4948 }
4949 for (auto &P : DSAChecker.getVarsWithInheritedDSA())
4950 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
4951 }
4952 for (const auto &P : VarsWithInheritedDSA) {
4953 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
4954 continue;
4955 ErrorFound = true;
4956 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none) {
4957 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4958 << P.first << P.second->getSourceRange();
4959 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
4960 } else if (getLangOpts().OpenMP >= 50) {
4961 Diag(P.second->getExprLoc(),
4962 diag::err_omp_defaultmap_no_attr_for_variable)
4963 << P.first << P.second->getSourceRange();
4964 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
4965 diag::note_omp_defaultmap_attr_none);
4966 }
4967 }
4968
4969 if (!AllowedNameModifiers.empty())
4970 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4971 ErrorFound;
4972
4973 if (ErrorFound)
4974 return StmtError();
4975
4976 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
4977 Res.getAs<OMPExecutableDirective>()
4978 ->getStructuredBlock()
4979 ->setIsOMPStructuredBlock(true);
4980 }
4981
4982 if (!CurContext->isDependentContext() &&
4983 isOpenMPTargetExecutionDirective(Kind) &&
4984 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
4985 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
4986 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
4987 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
4988 // Register target to DSA Stack.
4989 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
4990 }
4991
4992 return Res;
4993}
4994
4995Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
4996 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
4997 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
4998 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
4999 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5000 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5000, __PRETTY_FUNCTION__))
;
5001 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5001, __PRETTY_FUNCTION__))
;
5002 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5002, __PRETTY_FUNCTION__))
;
5003 if (!DG || DG.get().isNull())
5004 return DeclGroupPtrTy();
5005
5006 const int SimdId = 0;
5007 if (!DG.get().isSingleDecl()) {
5008 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5009 << SimdId;
5010 return DG;
5011 }
5012 Decl *ADecl = DG.get().getSingleDecl();
5013 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5014 ADecl = FTD->getTemplatedDecl();
5015
5016 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5017 if (!FD) {
5018 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5019 return DeclGroupPtrTy();
5020 }
5021
5022 // OpenMP [2.8.2, declare simd construct, Description]
5023 // The parameter of the simdlen clause must be a constant positive integer
5024 // expression.
5025 ExprResult SL;
5026 if (Simdlen)
5027 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5028 // OpenMP [2.8.2, declare simd construct, Description]
5029 // The special this pointer can be used as if was one of the arguments to the
5030 // function in any of the linear, aligned, or uniform clauses.
5031 // The uniform clause declares one or more arguments to have an invariant
5032 // value for all concurrent invocations of the function in the execution of a
5033 // single SIMD loop.
5034 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5035 const Expr *UniformedLinearThis = nullptr;
5036 for (const Expr *E : Uniforms) {
5037 E = E->IgnoreParenImpCasts();
5038 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5039 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5040 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5041 FD->getParamDecl(PVD->getFunctionScopeIndex())
5042 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5043 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5044 continue;
5045 }
5046 if (isa<CXXThisExpr>(E)) {
5047 UniformedLinearThis = E;
5048 continue;
5049 }
5050 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5051 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5052 }
5053 // OpenMP [2.8.2, declare simd construct, Description]
5054 // The aligned clause declares that the object to which each list item points
5055 // is aligned to the number of bytes expressed in the optional parameter of
5056 // the aligned clause.
5057 // The special this pointer can be used as if was one of the arguments to the
5058 // function in any of the linear, aligned, or uniform clauses.
5059 // The type of list items appearing in the aligned clause must be array,
5060 // pointer, reference to array, or reference to pointer.
5061 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5062 const Expr *AlignedThis = nullptr;
5063 for (const Expr *E : Aligneds) {
5064 E = E->IgnoreParenImpCasts();
5065 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5066 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5067 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5068 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5069 FD->getParamDecl(PVD->getFunctionScopeIndex())
5070 ->getCanonicalDecl() == CanonPVD) {
5071 // OpenMP [2.8.1, simd construct, Restrictions]
5072 // A list-item cannot appear in more than one aligned clause.
5073 if (AlignedArgs.count(CanonPVD) > 0) {
5074 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5075 << 1 << getOpenMPClauseName(OMPC_aligned)
5076 << E->getSourceRange();
5077 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5078 diag::note_omp_explicit_dsa)
5079 << getOpenMPClauseName(OMPC_aligned);
5080 continue;
5081 }
5082 AlignedArgs[CanonPVD] = E;
5083 QualType QTy = PVD->getType()
5084 .getNonReferenceType()
5085 .getUnqualifiedType()
5086 .getCanonicalType();
5087 const Type *Ty = QTy.getTypePtrOrNull();
5088 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5089 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5090 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5091 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5092 }
5093 continue;
5094 }
5095 }
5096 if (isa<CXXThisExpr>(E)) {
5097 if (AlignedThis) {
5098 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5099 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5100 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5101 << getOpenMPClauseName(OMPC_aligned);
5102 }
5103 AlignedThis = E;
5104 continue;
5105 }
5106 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5107 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5108 }
5109 // The optional parameter of the aligned clause, alignment, must be a constant
5110 // positive integer expression. If no optional parameter is specified,
5111 // implementation-defined default alignments for SIMD instructions on the
5112 // target platforms are assumed.
5113 SmallVector<const Expr *, 4> NewAligns;
5114 for (Expr *E : Alignments) {
5115 ExprResult Align;
5116 if (E)
5117 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5118 NewAligns.push_back(Align.get());
5119 }
5120 // OpenMP [2.8.2, declare simd construct, Description]
5121 // The linear clause declares one or more list items to be private to a SIMD
5122 // lane and to have a linear relationship with respect to the iteration space
5123 // of a loop.
5124 // The special this pointer can be used as if was one of the arguments to the
5125 // function in any of the linear, aligned, or uniform clauses.
5126 // When a linear-step expression is specified in a linear clause it must be
5127 // either a constant integer expression or an integer-typed parameter that is
5128 // specified in a uniform clause on the directive.
5129 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5130 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5131 auto MI = LinModifiers.begin();
5132 for (const Expr *E : Linears) {
5133 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5134 ++MI;
5135 E = E->IgnoreParenImpCasts();
5136 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5137 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5138 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5139 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5140 FD->getParamDecl(PVD->getFunctionScopeIndex())
5141 ->getCanonicalDecl() == CanonPVD) {
5142 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5143 // A list-item cannot appear in more than one linear clause.
5144 if (LinearArgs.count(CanonPVD) > 0) {
5145 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5146 << getOpenMPClauseName(OMPC_linear)
5147 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5148 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5149 diag::note_omp_explicit_dsa)
5150 << getOpenMPClauseName(OMPC_linear);
5151 continue;
5152 }
5153 // Each argument can appear in at most one uniform or linear clause.
5154 if (UniformedArgs.count(CanonPVD) > 0) {
5155 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5156 << getOpenMPClauseName(OMPC_linear)
5157 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5158 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5159 diag::note_omp_explicit_dsa)
5160 << getOpenMPClauseName(OMPC_uniform);
5161 continue;
5162 }
5163 LinearArgs[CanonPVD] = E;
5164 if (E->isValueDependent() || E->isTypeDependent() ||
5165 E->isInstantiationDependent() ||
5166 E->containsUnexpandedParameterPack())
5167 continue;
5168 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5169 PVD->getOriginalType());
5170 continue;
5171 }
5172 }
5173 if (isa<CXXThisExpr>(E)) {
5174 if (UniformedLinearThis) {
5175 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5176 << getOpenMPClauseName(OMPC_linear)
5177 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5178 << E->getSourceRange();
5179 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5180 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5181 : OMPC_linear);
5182 continue;
5183 }
5184 UniformedLinearThis = E;
5185 if (E->isValueDependent() || E->isTypeDependent() ||
5186 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5187 continue;
5188 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5189 E->getType());
5190 continue;
5191 }
5192 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5193 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5194 }
5195 Expr *Step = nullptr;
5196 Expr *NewStep = nullptr;
5197 SmallVector<Expr *, 4> NewSteps;
5198 for (Expr *E : Steps) {
5199 // Skip the same step expression, it was checked already.
5200 if (Step == E || !E) {
5201 NewSteps.push_back(E ? NewStep : nullptr);
5202 continue;
5203 }
5204 Step = E;
5205 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5206 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5207 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5208 if (UniformedArgs.count(CanonPVD) == 0) {
5209 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5210 << Step->getSourceRange();
5211 } else if (E->isValueDependent() || E->isTypeDependent() ||
5212 E->isInstantiationDependent() ||
5213 E->containsUnexpandedParameterPack() ||
5214 CanonPVD->getType()->hasIntegerRepresentation()) {
5215 NewSteps.push_back(Step);
5216 } else {
5217 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5218 << Step->getSourceRange();
5219 }
5220 continue;
5221 }
5222 NewStep = Step;
5223 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5224 !Step->isInstantiationDependent() &&
5225 !Step->containsUnexpandedParameterPack()) {
5226 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5227 .get();
5228 if (NewStep)
5229 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5230 }
5231 NewSteps.push_back(NewStep);
5232 }
5233 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5234 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5235 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5236 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5237 const_cast<Expr **>(Linears.data()), Linears.size(),
5238 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5239 NewSteps.data(), NewSteps.size(), SR);
5240 ADecl->addAttr(NewAttr);
5241 return DG;
5242}
5243
5244static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5245 QualType NewType) {
5246 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5247, __PRETTY_FUNCTION__))
5247 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5247, __PRETTY_FUNCTION__))
;
5248 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5249, __PRETTY_FUNCTION__))
5249 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5249, __PRETTY_FUNCTION__))
;
5250 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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5251, __PRETTY_FUNCTION__))
5251 "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-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5251, __PRETTY_FUNCTION__))
;
5252 // Synthesize parameters with the same types.
5253 FD->setType(NewType);
5254 SmallVector<ParmVarDecl *, 16> Params;
5255 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5256 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5257 SourceLocation(), nullptr, P->getType(),
5258 /*TInfo=*/nullptr, SC_None, nullptr);
5259 Param->setScopeInfo(0, Params.size());
5260 Param->setImplicit();
5261 Params.push_back(Param);
5262 }
5263
5264 FD->setParams(Params);
5265}
5266
5267Optional<std::pair<FunctionDecl *, Expr *>>
5268Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
5269 Expr *VariantRef, SourceRange SR) {
5270 if (!DG || DG.get().isNull())
5271 return None;
5272
5273 const int VariantId = 1;
5274 // Must be applied only to single decl.
5275 if (!DG.get().isSingleDecl()) {
5276 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5277 << VariantId << SR;
5278 return None;
5279 }
5280 Decl *ADecl = DG.get().getSingleDecl();
5281 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5282 ADecl = FTD->getTemplatedDecl();
5283
5284 // Decl must be a function.
5285 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5286 if (!FD) {
5287 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5288 << VariantId << SR;
5289 return None;
5290 }
5291
5292 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
5293 return FD->hasAttrs() &&
5294 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5295 FD->hasAttr<TargetAttr>());
5296 };
5297 // OpenMP is not compatible with CPU-specific attributes.
5298 if (HasMultiVersionAttributes(FD)) {
5299 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
5300 << SR;
5301 return None;
5302 }
5303
5304 // Allow #pragma omp declare variant only if the function is not used.
5305 if (FD->isUsed(false))
5306 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
5307 << FD->getLocation();
5308
5309 // Check if the function was emitted already.
5310 const FunctionDecl *Definition;
5311 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5312 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
5313 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
5314 << FD->getLocation();
5315
5316 // The VariantRef must point to function.
5317 if (!VariantRef) {
5318 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
5319 return None;
5320 }
5321
5322 // Do not check templates, wait until instantiation.
5323 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() ||
5324 VariantRef->containsUnexpandedParameterPack() ||
5325 VariantRef->isInstantiationDependent() || FD->isDependentContext())
5326 return std::make_pair(FD, VariantRef);
5327
5328 // Convert VariantRef expression to the type of the original function to
5329 // resolve possible conflicts.
5330 ExprResult VariantRefCast;
5331 if (LangOpts.CPlusPlus) {
5332 QualType FnPtrType;
5333 auto *Method = dyn_cast<CXXMethodDecl>(FD);
5334 if (Method && !Method->isStatic()) {
5335 const Type *ClassType =
5336 Context.getTypeDeclType(Method->getParent()).getTypePtr();
5337 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
5338 ExprResult ER;
5339 {
5340 // Build adrr_of unary op to correctly handle type checks for member
5341 // functions.
5342 Sema::TentativeAnalysisScope Trap(*this);
5343 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
5344 VariantRef);
5345 }
5346 if (!ER.isUsable()) {
5347 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5348 << VariantId << VariantRef->getSourceRange();
5349 return None;
5350 }
5351 VariantRef = ER.get();
5352 } else {
5353 FnPtrType = Context.getPointerType(FD->getType());
5354 }
5355 ImplicitConversionSequence ICS =
5356 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
5357 /*SuppressUserConversions=*/false,
5358 /*AllowExplicit=*/false,
5359 /*InOverloadResolution=*/false,
5360 /*CStyle=*/false,
5361 /*AllowObjCWritebackConversion=*/false);
5362 if (ICS.isFailure()) {
5363 Diag(VariantRef->getExprLoc(),
5364 diag::err_omp_declare_variant_incompat_types)
5365 << VariantRef->getType()
5366 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
5367 << VariantRef->getSourceRange();
5368 return None;
5369 }
5370 VariantRefCast = PerformImplicitConversion(
5371 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
5372 if (!VariantRefCast.isUsable())
5373 return None;
5374 // Drop previously built artificial addr_of unary op for member functions.
5375 if (Method && !Method->isStatic()) {
5376 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
5377 if (auto *UO = dyn_cast<UnaryOperator>(
5378 PossibleAddrOfVariantRef->IgnoreImplicit()))
5379 VariantRefCast = UO->getSubExpr();
5380 }
5381 } else {
5382 VariantRefCast = VariantRef;
5383 }
5384
5385 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
5386 if (!ER.isUsable() ||
5387 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5388 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5389 << VariantId << VariantRef->getSourceRange();
5390 return None;
5391 }
5392
5393 // The VariantRef must point to function.
5394 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
5395 if (!DRE) {
5396 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5397 << VariantId << VariantRef->getSourceRange();
5398 return None;
5399 }
5400 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5401 if (!NewFD) {
5402 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5403 << VariantId << VariantRef->getSourceRange();
5404 return None;
5405 }
5406
5407 // Check if function types are compatible in C.
5408 if (!LangOpts.CPlusPlus) {
5409 QualType NewType =
5410 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
5411 if (NewType.isNull()) {
5412 Diag(VariantRef->getExprLoc(),
5413 diag::err_omp_declare_variant_incompat_types)
5414 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
5415 return None;
5416 }
5417 if (NewType->isFunctionProtoType()) {
5418 if (FD->getType()->isFunctionNoProtoType())
5419 setPrototype(*this, FD, NewFD, NewType);
5420 else if (NewFD->getType()->isFunctionNoProtoType())
5421 setPrototype(*this, NewFD, FD, NewType);
5422 }
5423 }
5424
5425 // Check if variant function is not marked with declare variant directive.
5426 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5427 Diag(VariantRef->getExprLoc(),
5428 diag::warn_omp_declare_variant_marked_as_declare_variant)
5429 << VariantRef->getSourceRange();
5430 SourceRange SR =
5431 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5432 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
5433 return None;
5434 }
5435
5436 enum DoesntSupport {
5437 VirtFuncs = 1,
5438 Constructors = 3,
5439 Destructors = 4,
5440 DeletedFuncs = 5,
5441 DefaultedFuncs = 6,
5442 ConstexprFuncs = 7,
5443 ConstevalFuncs = 8,
5444 };
5445 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5446 if (CXXFD->isVirtual()) {
5447 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5448 << VirtFuncs;
5449 return None;
5450 }
5451
5452 if (isa<CXXConstructorDecl>(FD)) {
5453 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5454 << Constructors;
5455 return None;
5456 }
5457
5458 if (isa<CXXDestructorDecl>(FD)) {
5459 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5460 << Destructors;
5461 return None;
5462 }
5463 }
5464
5465 if (FD->isDeleted()) {
5466 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5467 << DeletedFuncs;
5468 return None;
5469 }
5470
5471 if (FD->isDefaulted()) {
5472 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5473 << DefaultedFuncs;
5474 return None;
5475 }
5476
5477 if (FD->isConstexpr()) {
5478 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5479 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
5480 return None;
5481 }
5482
5483 // Check general compatibility.
5484 if (areMultiversionVariantFunctionsCompatible(
5485 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
5486 PartialDiagnosticAt(SourceLocation(),
5487 PartialDiagnostic::NullDiagnostic()),
5488 PartialDiagnosticAt(
5489 VariantRef->getExprLoc(),
5490 PDiag(diag::err_omp_declare_variant_doesnt_support)),
5491 PartialDiagnosticAt(VariantRef->getExprLoc(),
5492 PDiag(diag::err_omp_declare_variant_diff)
5493 << FD->getLocation()),
5494 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
5495 /*CLinkageMayDiffer=*/true))
5496 return None;
5497 return std::make_pair(FD, cast<Expr>(DRE));
5498}
5499
5500void Sema::ActOnOpenMPDeclareVariantDirective(
5501 FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
5502 ArrayRef<OMPCtxSelectorData> Data) {
5503 if (Data.empty())
5504 return;
5505 SmallVector<Expr *, 4> CtxScores;
5506 SmallVector<unsigned, 4> CtxSets;
5507 SmallVector<unsigned, 4> Ctxs;
5508 SmallVector<StringRef, 4> ImplVendors, DeviceKinds;
5509 bool IsError = false;
5510 for (const OMPCtxSelectorData &D : Data) {
5511 OpenMPContextSelectorSetKind CtxSet = D.CtxSet;
5512 OpenMPContextSelectorKind Ctx = D.Ctx;
5513 if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown)
5514 return;
5515 Expr *Score = nullptr;
5516 if (D.Score.isUsable()) {
5517 Score = D.Score.get();
5518 if (!Score->isTypeDependent() && !Score->isValueDependent() &&
5519 !Score->isInstantiationDependent() &&
5520 !Score->containsUnexpandedParameterPack()) {
5521 Score =
5522 PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score)
5523 .get();
5524 if (Score)
5525 Score = VerifyIntegerConstantExpression(Score).get();
5526 }
5527 } else {
5528 // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors.
5529 // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and
5530 // 2^(l+2), respectively, where l is the number of traits in the construct
5531 // set.
5532 // TODO: implement correct logic for isa and arch traits.
5533 // TODO: take the construct context set into account when it is
5534 // implemented.
5535 int L = 0; // Currently set the number of traits in construct set to 0,
5536 // since the construct trait set in not supported yet.
5537 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind)
5538 Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get();
5539 else
5540 Score = ActOnIntegerConstant(SourceLocation(), 0).get();
5541 }
5542 switch (Ctx) {
5543 case OMP_CTX_vendor:
5544 assert(CtxSet == OMP_CTX_SET_implementation &&((CtxSet == OMP_CTX_SET_implementation && "Expected implementation context selector set."
) ? static_cast<void> (0) : __assert_fail ("CtxSet == OMP_CTX_SET_implementation && \"Expected implementation context selector set.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5545, __PRETTY_FUNCTION__))
5545 "Expected implementation context selector set.")((CtxSet == OMP_CTX_SET_implementation && "Expected implementation context selector set."
) ? static_cast<void> (0) : __assert_fail ("CtxSet == OMP_CTX_SET_implementation && \"Expected implementation context selector set.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5545, __PRETTY_FUNCTION__))
;
5546 ImplVendors.append(D.Names.begin(), D.Names.end());
5547 break;
5548 case OMP_CTX_kind:
5549 assert(CtxSet == OMP_CTX_SET_device &&((CtxSet == OMP_CTX_SET_device && "Expected device context selector set."
) ? static_cast<void> (0) : __assert_fail ("CtxSet == OMP_CTX_SET_device && \"Expected device context selector set.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5550, __PRETTY_FUNCTION__))
5550 "Expected device context selector set.")((CtxSet == OMP_CTX_SET_device && "Expected device context selector set."
) ? static_cast<void> (0) : __assert_fail ("CtxSet == OMP_CTX_SET_device && \"Expected device context selector set.\""
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5550, __PRETTY_FUNCTION__))
;
5551 DeviceKinds.append(D.Names.begin(), D.Names.end());
5552 break;
5553 case OMP_CTX_unknown:
5554 llvm_unreachable("Unknown context selector kind.")::llvm::llvm_unreachable_internal("Unknown context selector kind."
, "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/clang/lib/Sema/SemaOpenMP.cpp"
, 5554)
;
5555 }
5556 IsError = IsError || !Score;
5557 CtxSets.push_back(CtxSet);
5558 Ctxs.push_back(Ctx);
5559 CtxScores.push_back(Score);
5560 }
5561 if (!IsError) {
5562 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
5563 Context, VariantRef, CtxScores.begin(), CtxScores.size(),
5564 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(),
5565 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(),
5566 DeviceKinds.size(), SR);